mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-10 16:43:33 +02:00
Reworked LV2 plug-ing support.
This enables all platforms to use LV2 plugins in non-GUI mode. There is still some work to do, like subgroup handling and better scalepoint handling.
This commit is contained in:
34
lib-src/lv2/build
Executable file
34
lib-src/lv2/build
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
function waf
|
||||
{
|
||||
pkg=$1
|
||||
pushd >/dev/null ${pkg}
|
||||
shift
|
||||
python waf --prefix="." --include="." $@ build || exit 1
|
||||
popd >/dev/null
|
||||
|
||||
export PKG_CONFIG_PATH="$(pwd)/${pkg}/build:${PKG_CONFIG_PATH}"
|
||||
export CFLAGS="-I$(pwd)/${pkg} ${CFLAGS}"
|
||||
export LDFLAGS="-L$(pwd)/${pkg} -l${pkg}-0 ${LDFLAGS}"
|
||||
|
||||
if [ -e ${pkg}/build/*.a ]
|
||||
then
|
||||
mkdir -p obj
|
||||
pushd obj
|
||||
ar vx ../${pkg}/build/*.a
|
||||
ar vq ../liblv2.a *
|
||||
popd
|
||||
rm -rf obj
|
||||
fi
|
||||
}
|
||||
|
||||
[ -e liblv2.a ] && exit 0
|
||||
|
||||
waf lv2 --no-plugins
|
||||
waf serd --no-utils --static --no-shared
|
||||
waf sord --no-utils --static --no-shared
|
||||
waf sratom --static --no-shared
|
||||
waf lilv --no-utils --static --no-shared
|
||||
|
||||
exit 0
|
6
lib-src/lv2/clean
Executable file
6
lib-src/lv2/clean
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf {lv2,serd,sord,sratom,lilv}/{build,.waf*,.lock*}
|
||||
rm -rf {liblv2.a,include}
|
||||
|
||||
exit 0
|
49
lib-src/lv2/configure
vendored
Executable file
49
lib-src/lv2/configure
vendored
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
function waf
|
||||
{
|
||||
pkg="$1"
|
||||
shift
|
||||
pushd >/dev/null ${pkg}
|
||||
python waf --prefix="." --include="." $@ configure || exit 1
|
||||
popd >/dev/null
|
||||
|
||||
if [ "${pkg}" == "lv2" ]
|
||||
then
|
||||
eval $(sed -e "/^VERSION/!d;s/ //g;s/.*VERSION/version/" ${pkg}/wscript)
|
||||
major=""
|
||||
else
|
||||
eval $(sed -e "/^[A-Z]*_VERSION/!d;s/ //g;s/.*VERSION/version/" ${pkg}/wscript)
|
||||
major="-${version%%.*}"
|
||||
fi
|
||||
|
||||
cat <<EOF >${pkg}/build/${pkg}${major}.pc
|
||||
prefix=$(pwd)/${pkg}
|
||||
exec_prefix=\${prefix}
|
||||
libdir=\${exec_prefix}/lib
|
||||
includedir=.
|
||||
|
||||
Name: ${pkg}
|
||||
Version: ${version}
|
||||
Description: Temporary fake config file
|
||||
Libs: -L\${libdir} -l${pkg}${major} -ldl
|
||||
Cflags: -I\${includedir}/${pkg}${major}
|
||||
EOF
|
||||
|
||||
export PKG_CONFIG_PATH="$(pwd)/${pkg}/build:${PKG_CONFIG_PATH}"
|
||||
export CFLAGS="-I$(pwd)/${pkg} ${CFLAGS}"
|
||||
export LDFLAGS="-L$(pwd)/${pkg} -l${pkg}-${major} ${LDFLAGS}"
|
||||
|
||||
ln -s ../${pkg}/${pkg} include
|
||||
}
|
||||
|
||||
rm -rf include
|
||||
mkdir -p include
|
||||
|
||||
waf lv2 --no-plugins
|
||||
waf serd --no-utils --static --no-shared
|
||||
waf sord --no-utils --static --no-shared
|
||||
waf sratom --static --no-shared
|
||||
waf lilv --no-utils --static --no-shared
|
||||
|
||||
exit 0
|
@@ -30,7 +30,6 @@ extern "C" {
|
||||
# include <windows.h>
|
||||
# define dlopen(path, flags) LoadLibrary(path)
|
||||
# define dlclose(lib) FreeLibrary((HMODULE)lib)
|
||||
# define dlsym GetProcAddress
|
||||
# ifdef _MSC_VER
|
||||
# define __func__ __FUNCTION__
|
||||
# define INFINITY DBL_MAX + DBL_MAX
|
||||
@@ -363,9 +362,13 @@ typedef void (*VoidFunc)(void);
|
||||
static inline VoidFunc
|
||||
lilv_dlfunc(void* handle, const char* symbol)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (VoidFunc)GetProcAddress((HMODULE)handle, symbol);
|
||||
#else
|
||||
typedef VoidFunc (*VoidFuncGetter)(void*, const char*);
|
||||
VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym;
|
||||
return dlfunc(handle, symbol);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LILV_DYN_MANIFEST
|
||||
|
347
lib-src/lv2/serd/src/serdnode.c
Normal file
347
lib-src/lv2/serd/src/serdnode.c
Normal file
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
Copyright 2011-2012 David Robillard <http://drobilla.net>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "serd_internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# define isnan(x) _isnan(x)
|
||||
# define isinf(x) (!_finite(x))
|
||||
#endif
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_from_string(SerdType type, const uint8_t* buf)
|
||||
{
|
||||
if (!buf) {
|
||||
return SERD_NODE_NULL;
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
size_t buf_n_bytes = 0;
|
||||
const size_t buf_n_chars = serd_strlen(buf, &buf_n_bytes, &flags);
|
||||
SerdNode ret = { buf, buf_n_bytes, buf_n_chars, flags, type };
|
||||
return ret;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_copy(const SerdNode* node)
|
||||
{
|
||||
if (!node || !node->buf) {
|
||||
return SERD_NODE_NULL;
|
||||
}
|
||||
|
||||
SerdNode copy = *node;
|
||||
uint8_t* buf = (uint8_t*)malloc(copy.n_bytes + 1);
|
||||
memcpy(buf, node->buf, copy.n_bytes + 1);
|
||||
copy.buf = buf;
|
||||
return copy;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
bool
|
||||
serd_node_equals(const SerdNode* a, const SerdNode* b)
|
||||
{
|
||||
return (a == b)
|
||||
|| (a->type == b->type
|
||||
&& a->n_bytes == b->n_bytes
|
||||
&& a->n_chars == b->n_chars
|
||||
&& ((a->buf == b->buf) || !memcmp((const char*)a->buf,
|
||||
(const char*)b->buf,
|
||||
a->n_bytes + 1)));
|
||||
}
|
||||
|
||||
static size_t
|
||||
serd_uri_string_length(const SerdURI* uri)
|
||||
{
|
||||
size_t len = uri->path_base.len;
|
||||
|
||||
#define ADD_LEN(field, n_delims) \
|
||||
if ((field).len) { len += (field).len + (n_delims); }
|
||||
|
||||
ADD_LEN(uri->path, 1); // + possible leading `/'
|
||||
ADD_LEN(uri->scheme, 1); // + trailing `:'
|
||||
ADD_LEN(uri->authority, 2); // + leading `//'
|
||||
ADD_LEN(uri->query, 1); // + leading `?'
|
||||
ADD_LEN(uri->fragment, 1); // + leading `#'
|
||||
|
||||
return len + 2; // + 2 for authority `//'
|
||||
}
|
||||
|
||||
static size_t
|
||||
string_sink(const void* buf, size_t len, void* stream)
|
||||
{
|
||||
uint8_t** ptr = (uint8_t**)stream;
|
||||
memcpy(*ptr, buf, len);
|
||||
*ptr += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_uri_from_node(const SerdNode* uri_node,
|
||||
const SerdURI* base,
|
||||
SerdURI* out)
|
||||
{
|
||||
return (uri_node->type == SERD_URI)
|
||||
? serd_node_new_uri_from_string(uri_node->buf, base, out)
|
||||
: SERD_NODE_NULL;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_uri_from_string(const uint8_t* str,
|
||||
const SerdURI* base,
|
||||
SerdURI* out)
|
||||
{
|
||||
if (!str || str[0] == '\0') {
|
||||
return serd_node_new_uri(base, NULL, out); // Empty URI => Base URI
|
||||
}
|
||||
SerdURI uri;
|
||||
serd_uri_parse(str, &uri);
|
||||
return serd_node_new_uri(&uri, base, out); // Resolve/Serialise
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_uri_path_char(const uint8_t c)
|
||||
{
|
||||
if (is_alpha(c) || is_digit(c)) {
|
||||
return true;
|
||||
}
|
||||
switch (c) {
|
||||
case '-': case '.': case '_': case '~': // unreserved
|
||||
case ':': case '@': // pchar
|
||||
case '/': // separator
|
||||
// sub-delims
|
||||
case '!': case '$': case '&': case '\'': case '(': case ')':
|
||||
case '*': case '+': case ',': case ';': case '=':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_file_uri(const uint8_t* path,
|
||||
const uint8_t* hostname,
|
||||
SerdURI* out,
|
||||
bool escape)
|
||||
{
|
||||
const size_t path_len = strlen((const char*)path);
|
||||
const size_t hostname_len = hostname ? strlen((const char*)hostname) : 0;
|
||||
const bool evil = is_windows_path(path);
|
||||
size_t uri_len = 0;
|
||||
uint8_t* uri = NULL;
|
||||
|
||||
if (path[0] == '/' || is_windows_path(path)) {
|
||||
uri_len = strlen("file://") + hostname_len + evil;
|
||||
uri = (uint8_t*)malloc(uri_len + 1);
|
||||
snprintf((char*)uri, uri_len + 1, "file://%s%s",
|
||||
hostname ? (const char*)hostname : "",
|
||||
evil ? "/" : "");
|
||||
}
|
||||
|
||||
SerdChunk chunk = { uri, uri_len };
|
||||
for (size_t i = 0; i < path_len; ++i) {
|
||||
if (evil && path[i] == '\\') {
|
||||
serd_chunk_sink("/", 1, &chunk);
|
||||
} else if (path[i] == '%') {
|
||||
serd_chunk_sink("%%", 2, &chunk);
|
||||
} else if (!escape || is_uri_path_char(path[i])) {
|
||||
serd_chunk_sink(path + i, 1, &chunk);
|
||||
} else {
|
||||
char escape_str[4] = { '%', 0, 0, 0 };
|
||||
snprintf(escape_str + 1, sizeof(escape_str) - 1, "%X", path[i]);
|
||||
serd_chunk_sink(escape_str, 3, &chunk);
|
||||
}
|
||||
}
|
||||
serd_chunk_sink_finish(&chunk);
|
||||
|
||||
if (out) {
|
||||
serd_uri_parse(chunk.buf, out);
|
||||
}
|
||||
|
||||
return serd_node_from_string(SERD_URI, chunk.buf);
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
|
||||
{
|
||||
SerdURI abs_uri = *uri;
|
||||
if (base) {
|
||||
serd_uri_resolve(uri, base, &abs_uri);
|
||||
}
|
||||
|
||||
const size_t len = serd_uri_string_length(&abs_uri);
|
||||
uint8_t* buf = (uint8_t*)malloc(len + 1);
|
||||
|
||||
SerdNode node = { buf, len, len, 0, SERD_URI }; // FIXME: UTF-8
|
||||
|
||||
uint8_t* ptr = buf;
|
||||
const size_t actual_len = serd_uri_serialise(&abs_uri, string_sink, &ptr);
|
||||
|
||||
buf[actual_len] = '\0';
|
||||
node.n_bytes = actual_len;
|
||||
node.n_chars = actual_len;
|
||||
|
||||
if (out) {
|
||||
serd_uri_parse(buf, out); // TODO: cleverly avoid double parse
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_decimal(double d, unsigned frac_digits)
|
||||
{
|
||||
if (isnan(d) || isinf(d)) {
|
||||
return SERD_NODE_NULL;
|
||||
}
|
||||
|
||||
const double abs_d = fabs(d);
|
||||
const unsigned int_digits = (unsigned)fmax(1.0, ceil(log10(abs_d + 1)));
|
||||
char* buf = (char*)calloc(int_digits + frac_digits + 3, 1);
|
||||
SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL };
|
||||
const double int_part = floor(abs_d);
|
||||
|
||||
// Point s to decimal point location
|
||||
char* s = buf + int_digits;
|
||||
if (d < 0.0) {
|
||||
*buf = '-';
|
||||
++s;
|
||||
}
|
||||
|
||||
// Write integer part (right to left)
|
||||
char* t = s - 1;
|
||||
uint64_t dec = (uint64_t)int_part;
|
||||
do {
|
||||
*t-- = '0' + (dec % 10);
|
||||
} while ((dec /= 10) > 0);
|
||||
|
||||
*s++ = '.';
|
||||
|
||||
// Write fractional part (right to left)
|
||||
double frac_part = fabs(d - int_part);
|
||||
if (frac_part < DBL_EPSILON) {
|
||||
*s++ = '0';
|
||||
node.n_bytes = node.n_chars = (s - buf);
|
||||
} else {
|
||||
uint64_t frac = frac_part * pow(10.0, (int)frac_digits) + 0.5;
|
||||
s += frac_digits - 1;
|
||||
unsigned i = 0;
|
||||
|
||||
// Skip trailing zeros
|
||||
for (; i < frac_digits - 1 && !(frac % 10); ++i, --s, frac /= 10) {}
|
||||
|
||||
node.n_bytes = node.n_chars = (s - buf) + 1;
|
||||
|
||||
// Write digits from last trailing zero to decimal point
|
||||
for (; i < frac_digits; ++i) {
|
||||
*s-- = '0' + (frac % 10);
|
||||
frac /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_integer(int64_t i)
|
||||
{
|
||||
int64_t abs_i = (i < 0) ? -i : i;
|
||||
const unsigned digits = fmax(1.0, ceil(log10((double)abs_i + 1)));
|
||||
char* buf = (char*)calloc(digits + 2, 1);
|
||||
SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL };
|
||||
|
||||
// Point s to the end
|
||||
char* s = buf + digits - 1;
|
||||
if (i < 0) {
|
||||
*buf = '-';
|
||||
++s;
|
||||
}
|
||||
|
||||
node.n_bytes = node.n_chars = (s - buf) + 1;
|
||||
|
||||
// Write integer part (right to left)
|
||||
do {
|
||||
*s-- = '0' + (abs_i % 10);
|
||||
} while ((abs_i /= 10) > 0);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
Base64 encoding table.
|
||||
@see <a href="http://tools.ietf.org/html/rfc3548#section-3">RFC3986 S3</a>.
|
||||
*/
|
||||
static const uint8_t b64_map[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/**
|
||||
Encode 3 raw bytes to 4 base64 characters.
|
||||
*/
|
||||
static inline void
|
||||
encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
|
||||
{
|
||||
out[0] = b64_map[in[0] >> 2];
|
||||
out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
|
||||
out[2] = ((n_in > 1)
|
||||
? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
|
||||
: (uint8_t)'=');
|
||||
out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
|
||||
}
|
||||
|
||||
SERD_API
|
||||
SerdNode
|
||||
serd_node_new_blob(const void* buf, size_t size, bool wrap_lines)
|
||||
{
|
||||
const size_t len = ((size + 2) / 3) * 4 + (wrap_lines ? (size / 57) : 0);
|
||||
uint8_t* str = (uint8_t*)calloc(1, len + 2);
|
||||
SerdNode node = { str, len, len, 0, SERD_LITERAL };
|
||||
for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
|
||||
uint8_t in[4] = { 0, 0, 0, 0 };
|
||||
size_t n_in = MIN(3, size - i);
|
||||
memcpy(in, (const uint8_t*)buf + i, n_in);
|
||||
|
||||
if (wrap_lines && i > 0 && (i % 57) == 0) {
|
||||
str[j++] = '\n';
|
||||
node.flags |= SERD_HAS_NEWLINE;
|
||||
}
|
||||
|
||||
encode_chunk(str + j, in, n_in);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
SERD_API
|
||||
void
|
||||
serd_node_free(SerdNode* node)
|
||||
{
|
||||
if (node->buf) {
|
||||
free((uint8_t*)node->buf);
|
||||
node->buf = NULL;
|
||||
}
|
||||
}
|
351
lib-src/lv2/serdnode.patch
Normal file
351
lib-src/lv2/serdnode.patch
Normal file
@@ -0,0 +1,351 @@
|
||||
diff -ruN src.orig/serdnode.c src/serdnode.c
|
||||
--- src.orig/serdnode.c 1969-12-31 18:00:00.000000000 -0600
|
||||
+++ src/serdnode.c 2013-10-27 06:02:53.825178800 -0500
|
||||
@@ -0,0 +1,347 @@
|
||||
+/*
|
||||
+ Copyright 2011-2012 David Robillard <http://drobilla.net>
|
||||
+
|
||||
+ Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ purpose with or without fee is hereby granted, provided that the above
|
||||
+ copyright notice and this permission notice appear in all copies.
|
||||
+
|
||||
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+*/
|
||||
+
|
||||
+#include "serd_internal.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <math.h>
|
||||
+#include <float.h>
|
||||
+
|
||||
+#ifdef _WIN32
|
||||
+# define isnan(x) _isnan(x)
|
||||
+# define isinf(x) (!_finite(x))
|
||||
+#endif
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_from_string(SerdType type, const uint8_t* buf)
|
||||
+{
|
||||
+ if (!buf) {
|
||||
+ return SERD_NODE_NULL;
|
||||
+ }
|
||||
+
|
||||
+ uint32_t flags = 0;
|
||||
+ size_t buf_n_bytes = 0;
|
||||
+ const size_t buf_n_chars = serd_strlen(buf, &buf_n_bytes, &flags);
|
||||
+ SerdNode ret = { buf, buf_n_bytes, buf_n_chars, flags, type };
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_copy(const SerdNode* node)
|
||||
+{
|
||||
+ if (!node || !node->buf) {
|
||||
+ return SERD_NODE_NULL;
|
||||
+ }
|
||||
+
|
||||
+ SerdNode copy = *node;
|
||||
+ uint8_t* buf = (uint8_t*)malloc(copy.n_bytes + 1);
|
||||
+ memcpy(buf, node->buf, copy.n_bytes + 1);
|
||||
+ copy.buf = buf;
|
||||
+ return copy;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+bool
|
||||
+serd_node_equals(const SerdNode* a, const SerdNode* b)
|
||||
+{
|
||||
+ return (a == b)
|
||||
+ || (a->type == b->type
|
||||
+ && a->n_bytes == b->n_bytes
|
||||
+ && a->n_chars == b->n_chars
|
||||
+ && ((a->buf == b->buf) || !memcmp((const char*)a->buf,
|
||||
+ (const char*)b->buf,
|
||||
+ a->n_bytes + 1)));
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+serd_uri_string_length(const SerdURI* uri)
|
||||
+{
|
||||
+ size_t len = uri->path_base.len;
|
||||
+
|
||||
+#define ADD_LEN(field, n_delims) \
|
||||
+ if ((field).len) { len += (field).len + (n_delims); }
|
||||
+
|
||||
+ ADD_LEN(uri->path, 1); // + possible leading `/'
|
||||
+ ADD_LEN(uri->scheme, 1); // + trailing `:'
|
||||
+ ADD_LEN(uri->authority, 2); // + leading `//'
|
||||
+ ADD_LEN(uri->query, 1); // + leading `?'
|
||||
+ ADD_LEN(uri->fragment, 1); // + leading `#'
|
||||
+
|
||||
+ return len + 2; // + 2 for authority `//'
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+string_sink(const void* buf, size_t len, void* stream)
|
||||
+{
|
||||
+ uint8_t** ptr = (uint8_t**)stream;
|
||||
+ memcpy(*ptr, buf, len);
|
||||
+ *ptr += len;
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_uri_from_node(const SerdNode* uri_node,
|
||||
+ const SerdURI* base,
|
||||
+ SerdURI* out)
|
||||
+{
|
||||
+ return (uri_node->type == SERD_URI)
|
||||
+ ? serd_node_new_uri_from_string(uri_node->buf, base, out)
|
||||
+ : SERD_NODE_NULL;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_uri_from_string(const uint8_t* str,
|
||||
+ const SerdURI* base,
|
||||
+ SerdURI* out)
|
||||
+{
|
||||
+ if (!str || str[0] == '\0') {
|
||||
+ return serd_node_new_uri(base, NULL, out); // Empty URI => Base URI
|
||||
+ }
|
||||
+ SerdURI uri;
|
||||
+ serd_uri_parse(str, &uri);
|
||||
+ return serd_node_new_uri(&uri, base, out); // Resolve/Serialise
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+is_uri_path_char(const uint8_t c)
|
||||
+{
|
||||
+ if (is_alpha(c) || is_digit(c)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ switch (c) {
|
||||
+ case '-': case '.': case '_': case '~': // unreserved
|
||||
+ case ':': case '@': // pchar
|
||||
+ case '/': // separator
|
||||
+ // sub-delims
|
||||
+ case '!': case '$': case '&': case '\'': case '(': case ')':
|
||||
+ case '*': case '+': case ',': case ';': case '=':
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_file_uri(const uint8_t* path,
|
||||
+ const uint8_t* hostname,
|
||||
+ SerdURI* out,
|
||||
+ bool escape)
|
||||
+{
|
||||
+ const size_t path_len = strlen((const char*)path);
|
||||
+ const size_t hostname_len = hostname ? strlen((const char*)hostname) : 0;
|
||||
+ const bool evil = is_windows_path(path);
|
||||
+ size_t uri_len = 0;
|
||||
+ uint8_t* uri = NULL;
|
||||
+
|
||||
+ if (path[0] == '/' || is_windows_path(path)) {
|
||||
+ uri_len = strlen("file://") + hostname_len + evil;
|
||||
+ uri = (uint8_t*)malloc(uri_len + 1);
|
||||
+ snprintf((char*)uri, uri_len + 1, "file://%s%s",
|
||||
+ hostname ? (const char*)hostname : "",
|
||||
+ evil ? "/" : "");
|
||||
+ }
|
||||
+
|
||||
+ SerdChunk chunk = { uri, uri_len };
|
||||
+ for (size_t i = 0; i < path_len; ++i) {
|
||||
+ if (evil && path[i] == '\\') {
|
||||
+ serd_chunk_sink("/", 1, &chunk);
|
||||
+ } else if (path[i] == '%') {
|
||||
+ serd_chunk_sink("%%", 2, &chunk);
|
||||
+ } else if (!escape || is_uri_path_char(path[i])) {
|
||||
+ serd_chunk_sink(path + i, 1, &chunk);
|
||||
+ } else {
|
||||
+ char escape_str[4] = { '%', 0, 0, 0 };
|
||||
+ snprintf(escape_str + 1, sizeof(escape_str) - 1, "%X", path[i]);
|
||||
+ serd_chunk_sink(escape_str, 3, &chunk);
|
||||
+ }
|
||||
+ }
|
||||
+ serd_chunk_sink_finish(&chunk);
|
||||
+
|
||||
+ if (out) {
|
||||
+ serd_uri_parse(chunk.buf, out);
|
||||
+ }
|
||||
+
|
||||
+ return serd_node_from_string(SERD_URI, chunk.buf);
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
|
||||
+{
|
||||
+ SerdURI abs_uri = *uri;
|
||||
+ if (base) {
|
||||
+ serd_uri_resolve(uri, base, &abs_uri);
|
||||
+ }
|
||||
+
|
||||
+ const size_t len = serd_uri_string_length(&abs_uri);
|
||||
+ uint8_t* buf = (uint8_t*)malloc(len + 1);
|
||||
+
|
||||
+ SerdNode node = { buf, len, len, 0, SERD_URI }; // FIXME: UTF-8
|
||||
+
|
||||
+ uint8_t* ptr = buf;
|
||||
+ const size_t actual_len = serd_uri_serialise(&abs_uri, string_sink, &ptr);
|
||||
+
|
||||
+ buf[actual_len] = '\0';
|
||||
+ node.n_bytes = actual_len;
|
||||
+ node.n_chars = actual_len;
|
||||
+
|
||||
+ if (out) {
|
||||
+ serd_uri_parse(buf, out); // TODO: cleverly avoid double parse
|
||||
+ }
|
||||
+
|
||||
+ return node;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_decimal(double d, unsigned frac_digits)
|
||||
+{
|
||||
+ if (isnan(d) || isinf(d)) {
|
||||
+ return SERD_NODE_NULL;
|
||||
+ }
|
||||
+
|
||||
+ const double abs_d = fabs(d);
|
||||
+ const unsigned int_digits = (unsigned)fmax(1.0, ceil(log10(abs_d + 1)));
|
||||
+ char* buf = (char*)calloc(int_digits + frac_digits + 3, 1);
|
||||
+ SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL };
|
||||
+ const double int_part = floor(abs_d);
|
||||
+
|
||||
+ // Point s to decimal point location
|
||||
+ char* s = buf + int_digits;
|
||||
+ if (d < 0.0) {
|
||||
+ *buf = '-';
|
||||
+ ++s;
|
||||
+ }
|
||||
+
|
||||
+ // Write integer part (right to left)
|
||||
+ char* t = s - 1;
|
||||
+ uint64_t dec = (uint64_t)int_part;
|
||||
+ do {
|
||||
+ *t-- = '0' + (dec % 10);
|
||||
+ } while ((dec /= 10) > 0);
|
||||
+
|
||||
+ *s++ = '.';
|
||||
+
|
||||
+ // Write fractional part (right to left)
|
||||
+ double frac_part = fabs(d - int_part);
|
||||
+ if (frac_part < DBL_EPSILON) {
|
||||
+ *s++ = '0';
|
||||
+ node.n_bytes = node.n_chars = (s - buf);
|
||||
+ } else {
|
||||
+ uint64_t frac = frac_part * pow(10.0, (int)frac_digits) + 0.5;
|
||||
+ s += frac_digits - 1;
|
||||
+ unsigned i = 0;
|
||||
+
|
||||
+ // Skip trailing zeros
|
||||
+ for (; i < frac_digits - 1 && !(frac % 10); ++i, --s, frac /= 10) {}
|
||||
+
|
||||
+ node.n_bytes = node.n_chars = (s - buf) + 1;
|
||||
+
|
||||
+ // Write digits from last trailing zero to decimal point
|
||||
+ for (; i < frac_digits; ++i) {
|
||||
+ *s-- = '0' + (frac % 10);
|
||||
+ frac /= 10;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return node;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_integer(int64_t i)
|
||||
+{
|
||||
+ int64_t abs_i = (i < 0) ? -i : i;
|
||||
+ const unsigned digits = fmax(1.0, ceil(log10((double)abs_i + 1)));
|
||||
+ char* buf = (char*)calloc(digits + 2, 1);
|
||||
+ SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL };
|
||||
+
|
||||
+ // Point s to the end
|
||||
+ char* s = buf + digits - 1;
|
||||
+ if (i < 0) {
|
||||
+ *buf = '-';
|
||||
+ ++s;
|
||||
+ }
|
||||
+
|
||||
+ node.n_bytes = node.n_chars = (s - buf) + 1;
|
||||
+
|
||||
+ // Write integer part (right to left)
|
||||
+ do {
|
||||
+ *s-- = '0' + (abs_i % 10);
|
||||
+ } while ((abs_i /= 10) > 0);
|
||||
+
|
||||
+ return node;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ Base64 encoding table.
|
||||
+ @see <a href="http://tools.ietf.org/html/rfc3548#section-3">RFC3986 S3</a>.
|
||||
+*/
|
||||
+static const uint8_t b64_map[] =
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
+
|
||||
+/**
|
||||
+ Encode 3 raw bytes to 4 base64 characters.
|
||||
+*/
|
||||
+static inline void
|
||||
+encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
|
||||
+{
|
||||
+ out[0] = b64_map[in[0] >> 2];
|
||||
+ out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
|
||||
+ out[2] = ((n_in > 1)
|
||||
+ ? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
|
||||
+ : (uint8_t)'=');
|
||||
+ out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+SerdNode
|
||||
+serd_node_new_blob(const void* buf, size_t size, bool wrap_lines)
|
||||
+{
|
||||
+ const size_t len = ((size + 2) / 3) * 4 + (wrap_lines ? (size / 57) : 0);
|
||||
+ uint8_t* str = (uint8_t*)calloc(1, len + 2);
|
||||
+ SerdNode node = { str, len, len, 0, SERD_LITERAL };
|
||||
+ for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
|
||||
+ uint8_t in[4] = { 0, 0, 0, 0 };
|
||||
+ size_t n_in = MIN(3, size - i);
|
||||
+ memcpy(in, (const uint8_t*)buf + i, n_in);
|
||||
+
|
||||
+ if (wrap_lines && i > 0 && (i % 57) == 0) {
|
||||
+ str[j++] = '\n';
|
||||
+ node.flags |= SERD_HAS_NEWLINE;
|
||||
+ }
|
||||
+
|
||||
+ encode_chunk(str + j, in, n_in);
|
||||
+ }
|
||||
+ return node;
|
||||
+}
|
||||
+
|
||||
+SERD_API
|
||||
+void
|
||||
+serd_node_free(SerdNode* node)
|
||||
+{
|
||||
+ if (node->buf) {
|
||||
+ free((uint8_t*)node->buf);
|
||||
+ node->buf = NULL;
|
||||
+ }
|
||||
+}
|
24
lib-src/lv2/usegetprocaddress.patch
Normal file
24
lib-src/lv2/usegetprocaddress.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
--- lilv/src/orig_lilv_internal.h 2012-11-23 00:00:15.000000000 -0600
|
||||
+++ lilv/src/lilv_internal.h 2013-10-27 05:18:03.970327900 -0500
|
||||
@@ -30,7 +30,6 @@
|
||||
# include <windows.h>
|
||||
# define dlopen(path, flags) LoadLibrary(path)
|
||||
# define dlclose(lib) FreeLibrary((HMODULE)lib)
|
||||
-# define dlsym GetProcAddress
|
||||
# ifdef _MSC_VER
|
||||
# define __func__ __FUNCTION__
|
||||
# define INFINITY DBL_MAX + DBL_MAX
|
||||
@@ -363,9 +362,13 @@
|
||||
static inline VoidFunc
|
||||
lilv_dlfunc(void* handle, const char* symbol)
|
||||
{
|
||||
+#ifdef _WIN32
|
||||
+ return (VoidFunc)GetProcAddress((HMODULE)handle, symbol);
|
||||
+#else
|
||||
typedef VoidFunc (*VoidFuncGetter)(void*, const char*);
|
||||
VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym;
|
||||
return dlfunc(handle, symbol);
|
||||
+#endif
|
||||
}
|
||||
|
||||
#ifdef LILV_DYN_MANIFEST
|
15
lib-src/lv2/windows/lilv_config.h
Executable file
15
lib-src/lv2/windows/lilv_config.h
Executable file
@@ -0,0 +1,15 @@
|
||||
/* WARNING! All changes made to this file will be lost! */
|
||||
|
||||
#ifndef W_LILV_CONFIG_H_WAF
|
||||
#define W_LILV_CONFIG_H_WAF
|
||||
|
||||
#define LILV_NEW_LV2 1
|
||||
/* #undef HAVE_FLOCK */
|
||||
/* #undef HAVE_FILENO */
|
||||
/* #undef HAVE_CLOCK_GETTIME */
|
||||
#define LILV_VERSION "0.16.0"
|
||||
#define LILV_PATH_SEP ";"
|
||||
#define LILV_DIR_SEP "\\"
|
||||
#define LILV_DEFAULT_LV2_PATH "%APPDATA%\\LV2;%COMMONPROGRAMFILES%\\LV2"
|
||||
|
||||
#endif /* W_LILV_CONFIG_H_WAF */
|
12
lib-src/lv2/windows/serd_config.h
Executable file
12
lib-src/lv2/windows/serd_config.h
Executable file
@@ -0,0 +1,12 @@
|
||||
/* WARNING! All changes made to this file will be lost! */
|
||||
|
||||
#ifndef W_SERD_CONFIG_H_WAF
|
||||
#define W_SERD_CONFIG_H_WAF
|
||||
|
||||
/* #undef HAVE_FMAX */
|
||||
/* #undef HAVE_POSIX_MEMALIGN */
|
||||
/* #undef HAVE_POSIX_FADVISE */
|
||||
/* #undef HAVE_FILENO */
|
||||
#define SERD_VERSION "0.18.2"
|
||||
|
||||
#endif /* W_SERD_CONFIG_H_WAF */
|
8
lib-src/lv2/windows/sord_config.h
Executable file
8
lib-src/lv2/windows/sord_config.h
Executable file
@@ -0,0 +1,8 @@
|
||||
/* WARNING! All changes made to this file will be lost! */
|
||||
|
||||
#ifndef W_SORD_CONFIG_H_WAF
|
||||
#define W_SORD_CONFIG_H_WAF
|
||||
|
||||
#define SORD_VERSION "0.12.0"
|
||||
|
||||
#endif /* W_SORD_CONFIG_H_WAF */
|
8
lib-src/lv2/windows/sratom_config.h
Executable file
8
lib-src/lv2/windows/sratom_config.h
Executable file
@@ -0,0 +1,8 @@
|
||||
/* WARNING! All changes made to this file will be lost! */
|
||||
|
||||
#ifndef W_SRATOM_CONFIG_H_WAF
|
||||
#define W_SRATOM_CONFIG_H_WAF
|
||||
|
||||
#define SRATOM_VERSION "0.4.2"
|
||||
|
||||
#endif /* W_SRATOM_CONFIG_H_WAF */
|
Reference in New Issue
Block a user