Browse Source

Add initial files

tags/1.9.4
falkTX 12 years ago
parent
commit
22343cce38
100 changed files with 23933 additions and 8 deletions
  1. +3
    -0
      .gitignore
  2. +2
    -2
      data/carla
  3. +1
    -1
      data/carla-control
  4. +5
    -5
      data/carla-standalone
  5. +62
    -0
      source/libs/Makefile
  6. +51
    -0
      source/libs/jackbridge/Makefile
  7. +259
    -0
      source/libs/jackbridge/jackbridge.c
  8. +111
    -0
      source/libs/jackbridge/jackbridge.h
  9. +96
    -0
      source/libs/lilv/Makefile
  10. +35
    -0
      source/libs/lilv/config/lilv_config.h
  11. +21
    -0
      source/libs/lilv/config/serd_config.h
  12. +10
    -0
      source/libs/lilv/config/sord_config.h
  13. +11
    -0
      source/libs/lilv/config/sratom_config.h
  14. +20
    -0
      source/libs/lilv/custom-patches/lilv_fix-mingw-build.patch
  15. +137
    -0
      source/libs/lilv/custom-patches/lilv_ui-features+lilvmm.patch
  16. +11
    -0
      source/libs/lilv/custom-patches/lilvmm_fix-leaks.patch
  17. +8
    -0
      source/libs/lilv/lilv-0.14.4/AUTHORS
  18. +13
    -0
      source/libs/lilv/lilv-0.14.4/COPYING
  19. +59
    -0
      source/libs/lilv/lilv-0.14.4/INSTALL
  20. +90
    -0
      source/libs/lilv/lilv-0.14.4/NEWS
  21. +29
    -0
      source/libs/lilv/lilv-0.14.4/PACKAGING
  22. +11
    -0
      source/libs/lilv/lilv-0.14.4/README
  23. +38
    -0
      source/libs/lilv/lilv-0.14.4/bindings/lilv.i
  24. +96
    -0
      source/libs/lilv/lilv-0.14.4/bindings/python/lv2_apply.py
  25. +9
    -0
      source/libs/lilv/lilv-0.14.4/bindings/python/lv2_list.py
  26. +33
    -0
      source/libs/lilv/lilv-0.14.4/doc/lv2info.1
  27. +30
    -0
      source/libs/lilv/lilv-0.14.4/doc/lv2ls.1
  28. +1792
    -0
      source/libs/lilv/lilv-0.14.4/doc/reference.doxygen.in
  29. +563
    -0
      source/libs/lilv/lilv-0.14.4/doc/style.css
  30. +11
    -0
      source/libs/lilv/lilv-0.14.4/lilv.pc.in
  31. +29
    -0
      source/libs/lilv/lilv-0.14.4/lilv.ttl
  32. +1723
    -0
      source/libs/lilv/lilv-0.14.4/lilv/lilv.h
  33. +332
    -0
      source/libs/lilv/lilv-0.14.4/lilv/lilvmm.hpp
  34. +214
    -0
      source/libs/lilv/lilv-0.14.4/src/collections.c
  35. +126
    -0
      source/libs/lilv/lilv-0.14.4/src/instance.c
  36. +111
    -0
      source/libs/lilv/lilv-0.14.4/src/lib.c
  37. +382
    -0
      source/libs/lilv/lilv-0.14.4/src/lilv_internal.h
  38. +396
    -0
      source/libs/lilv/lilv-0.14.4/src/node.c
  39. +1077
    -0
      source/libs/lilv/lilv-0.14.4/src/plugin.c
  40. +96
    -0
      source/libs/lilv/lilv-0.14.4/src/pluginclass.c
  41. +264
    -0
      source/libs/lilv/lilv-0.14.4/src/port.c
  42. +140
    -0
      source/libs/lilv/lilv-0.14.4/src/query.c
  43. +52
    -0
      source/libs/lilv/lilv-0.14.4/src/scalepoint.c
  44. +1097
    -0
      source/libs/lilv/lilv-0.14.4/src/state.c
  45. +184
    -0
      source/libs/lilv/lilv-0.14.4/src/ui.c
  46. +604
    -0
      source/libs/lilv/lilv-0.14.4/src/util.c
  47. +822
    -0
      source/libs/lilv/lilv-0.14.4/src/world.c
  48. +88
    -0
      source/libs/lilv/lilv-0.14.4/src/zix/common.h
  49. +716
    -0
      source/libs/lilv/lilv-0.14.4/src/zix/tree.c
  50. +148
    -0
      source/libs/lilv/lilv-0.14.4/src/zix/tree.h
  51. +1581
    -0
      source/libs/lilv/lilv-0.14.4/test/lilv_test.c
  52. +7
    -0
      source/libs/lilv/lilv-0.14.4/test/manifest.ttl.in
  53. +384
    -0
      source/libs/lilv/lilv-0.14.4/test/test_plugin.c
  54. +40
    -0
      source/libs/lilv/lilv-0.14.4/test/test_plugin.ttl.in
  55. +52
    -0
      source/libs/lilv/lilv-0.14.4/utils/bench.h
  56. +38
    -0
      source/libs/lilv/lilv-0.14.4/utils/lilv-bench.c
  57. +59
    -0
      source/libs/lilv/lilv-0.14.4/utils/lilv.bash_completion
  58. +226
    -0
      source/libs/lilv/lilv-0.14.4/utils/lv2bench.c
  59. +437
    -0
      source/libs/lilv/lilv-0.14.4/utils/lv2info.c
  60. +93
    -0
      source/libs/lilv/lilv-0.14.4/utils/lv2ls.c
  61. +73
    -0
      source/libs/lilv/lilv-0.14.4/utils/uri_table.h
  62. BIN
      source/libs/lilv/lilv-0.14.4/waf
  63. +378
    -0
      source/libs/lilv/lilv-0.14.4/wscript
  64. +31
    -0
      source/libs/lilv/lilv.c
  65. +1
    -0
      source/libs/lilv/serd-0.18.2/AUTHORS
  66. +13
    -0
      source/libs/lilv/serd-0.18.2/COPYING
  67. +59
    -0
      source/libs/lilv/serd-0.18.2/INSTALL
  68. +98
    -0
      source/libs/lilv/serd-0.18.2/NEWS
  69. +29
    -0
      source/libs/lilv/serd-0.18.2/PACKAGING
  70. +10
    -0
      source/libs/lilv/serd-0.18.2/README
  71. +187
    -0
      source/libs/lilv/serd-0.18.2/doc/layout.xml
  72. +1792
    -0
      source/libs/lilv/serd-0.18.2/doc/reference.doxygen.in
  73. +72
    -0
      source/libs/lilv/serd-0.18.2/doc/serdi.1
  74. +563
    -0
      source/libs/lilv/serd-0.18.2/doc/style.css
  75. +10
    -0
      source/libs/lilv/serd-0.18.2/serd.pc.in
  76. +963
    -0
      source/libs/lilv/serd-0.18.2/serd/serd.h
  77. +271
    -0
      source/libs/lilv/serd-0.18.2/src/env.c
  78. +347
    -0
      source/libs/lilv/serd-0.18.2/src/node.c
  79. +1585
    -0
      source/libs/lilv/serd-0.18.2/src/reader.c
  80. +306
    -0
      source/libs/lilv/serd-0.18.2/src/serd_internal.h
  81. +253
    -0
      source/libs/lilv/serd-0.18.2/src/serdi.c
  82. +165
    -0
      source/libs/lilv/serd-0.18.2/src/string.c
  83. +504
    -0
      source/libs/lilv/serd-0.18.2/src/uri.c
  84. +807
    -0
      source/libs/lilv/serd-0.18.2/src/writer.c
  85. +20
    -0
      source/libs/lilv/serd-0.18.2/tests/README.txt
  86. +219
    -0
      source/libs/lilv/serd-0.18.2/tests/UTF-8.ttl
  87. +2
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-00.ttl
  88. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-01.ttl
  89. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-02.ttl
  90. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-03.ttl
  91. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-04.ttl
  92. +4
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-05.ttl
  93. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-06.ttl
  94. +4
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-07.ttl
  95. +2
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-08.ttl
  96. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-09.ttl
  97. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-10.ttl
  98. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-11.ttl
  99. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-12.ttl
  100. +3
    -0
      source/libs/lilv/serd-0.18.2/tests/bad-13.ttl

+ 3
- 0
.gitignore View File

@@ -104,3 +104,6 @@ c++/carla-native/zynaddsubfx/UI/SUBnoteUI.cc
c++/carla-native/zynaddsubfx/UI/SUBnoteUI.h c++/carla-native/zynaddsubfx/UI/SUBnoteUI.h
c++/carla-native/zynaddsubfx/UI/VirKeyboard.cc c++/carla-native/zynaddsubfx/UI/VirKeyboard.cc
c++/carla-native/zynaddsubfx/UI/VirKeyboard.h c++/carla-native/zynaddsubfx/UI/VirKeyboard.h

# Other
libs/jackbridge/jack/

+ 2
- 2
data/carla View File

@@ -7,5 +7,5 @@ else
fi fi


INSTALL_PREFIX="X-PREFIX-X" INSTALL_PREFIX="X-PREFIX-X"
export PATH="$INSTALL_PREFIX"/lib/cadence:$PATH
exec $PYTHON $INSTALL_PREFIX/share/cadence/src/carla.py --with-libprefix="$INSTALL_PREFIX" "$@"
export PATH="$INSTALL_PREFIX"/lib/carla:$PATH
exec $PYTHON $INSTALL_PREFIX/share/carla/carla.py --with-libprefix="$INSTALL_PREFIX" "$@"

+ 1
- 1
data/carla-control View File

@@ -7,4 +7,4 @@ else
fi fi


INSTALL_PREFIX="X-PREFIX-X" INSTALL_PREFIX="X-PREFIX-X"
exec $PYTHON $INSTALL_PREFIX/share/cadence/src/carla_control.py "$@"
exec $PYTHON $INSTALL_PREFIX/share/carla/carla_control.py "$@"

+ 5
- 5
data/carla-standalone View File

@@ -2,7 +2,7 @@
# Script to start Carla bridges # Script to start Carla bridges


INSTALL_PREFIX="X-PREFIX-X" INSTALL_PREFIX="X-PREFIX-X"
CADENCE_PREFIX="$INSTALL_PREFIX"/lib/cadence
CARLA_PREFIX="$INSTALL_PREFIX"/lib/carla


# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Check for enough arguments # Check for enough arguments
@@ -58,17 +58,17 @@ if [ $RUN_ARCH == "win64" ]; then
fi fi


# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Check for existing cadence folder
# Check for existing carla folder


if [ ! -d $CADENCE_PREFIX ]; then
echo "$0: Cadence folder non-existing, is it installed?"
if [ ! -d $CARLA_PREFIX ]; then
echo "$0: Carla folder does not exist, is it installed?"
exit exit
fi fi


# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Check for existing arch binary # Check for existing arch binary


CARLA_EXEC="$CADENCE_PREFIX/carla-bridge-$RUN_ARCH"
CARLA_EXEC="$CARLA_PREFIX/carla-bridge-$RUN_ARCH"


if [ ! -f $CARLA_EXEC ]; then if [ ! -f $CARLA_EXEC ]; then
echo "$0: Invalid arch (may not be installed)" echo "$0: Invalid arch (may not be installed)"


+ 62
- 0
source/libs/Makefile View File

@@ -0,0 +1,62 @@
#!/usr/bin/make -f
# Makefile for carla libs #
# ----------------------------------------- #
# Created by falkTX
#

all:

# --------------------------------------------------------------

jackbridge-win32.dll:
$(MAKE) -C jackbridge win32

jackbridge-win64.dll:
$(MAKE) -C jackbridge win64

jackbridge-win32.dll.so:
$(MAKE) -C jackbridge wine32

jackbridge-win64.dll.so:
$(MAKE) -C jackbridge wine64

# --------------------------------------------------------------

lilv.a:
$(MAKE) -C lilv

lilv_posix32.a:
$(MAKE) -C lilv posix32

lilv_posix64.a:
$(MAKE) -C lilv posix64

lilv_win32.a:
$(MAKE) -C lilv win32

lilv_win64.a:
$(MAKE) -C lilv win64

# --------------------------------------------------------------

rtmempool.a:
$(MAKE) -C rtmempool

rtmempool_posix32.a:
$(MAKE) -C rtmempool posix32

rtmempool_posix64.a:
$(MAKE) -C rtmempool posix64

rtmempool_win32.a:
$(MAKE) -C rtmempool win32

rtmempool_win64.a:
$(MAKE) -C rtmempool win64

# --------------------------------------------------------------

clean:
rm -f *.a *.def *.dll *.so
$(MAKE) clean -C lilv
$(MAKE) clean -C rtmempool

+ 51
- 0
source/libs/jackbridge/Makefile View File

@@ -0,0 +1,51 @@
#!/usr/bin/make -f
# Makefile for jackbridge #
# ------------------------------------- #
# Created by falkTX
#

include ../../Makefile.mk

# --------------------------------------------------------------

WINECC ?= winegcc

BUILD_C_FLAGS += -DJACKBRIDGE_EXPORT -I.
LINK_FLAGS += -shared

WIN_BUILD_FLAGS = $(BUILD_C_FLAGS) -DJACKBRIDGE_DUMMY -w
WIN_32BIT_FLAGS = $(32BIT_FLAGS)
WIN_64BIT_FLAGS = $(64BIT_FLAGS)
WIN_LINK_FLAGS = $(LINK_FLAGS)

WINE_BUILD_FLAGS = $(BUILD_C_FLAGS) -fPIC
WINE_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32/wine -L/usr/lib/i386-linux-gnu/wine
WINE_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64/wine -L/usr/lib/x86_64-linux-gnu/wine
WINE_LINK_FLAGS = $(LINK_FLAGS) $(shell pkg-config --libs jack) -ldl

OBJS = jackbridge.c

# --------------------------------------------------------------

all:

win32: ../jackbridge-win32.dll
win64: ../jackbridge-win64.dll
wine32: ../jackbridge-win32.dll.so
wine64: ../jackbridge-win64.dll.so

# --------------------------------------------------------------

../jackbridge-win32.dll: $(OBJS)
$(CC) $^ $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -Wl,--output-def,$@.def,--out-implib,$@.a -o $@ && $(STRIP) $@

../jackbridge-win64.dll: $(OBJS)
$(CC) $^ $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -Wl,--output-def,$@.def,--out-implib,$@.a -o $@ && $(STRIP) $@

../jackbridge-win32.dll.so: $(OBJS) ../jackbridge-win32.dll.def
$(WINECC) $^ $(WINE_BUILD_FLAGS) $(WINE_32BIT_FLAGS) $(WINE_LINK_FLAGS) -mno-cygwin -o $@ && $(STRIP) $@

../jackbridge-win64.dll.so: $(OBJS) ../jackbridge-win64.dll.def
$(WINECC) $^ $(WINE_BUILD_FLAGS) $(WINE_64BIT_FLAGS) $(WINE_LINK_FLAGS) -mno-cygwin -o $@ && $(STRIP) $@

# --------------------------------------------------------------

+ 259
- 0
source/libs/jackbridge/jackbridge.c View File

@@ -0,0 +1,259 @@
/*
* JackBridge
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "jackbridge.h"

// -----------------------------------------------------------------------------

jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...)
{
#ifndef JACKBRIDGE_DUMMY
return jack_client_open(client_name, options, status);
#else
return NULL;
#endif
}

int jackbridge_client_close(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_client_close(client);
#else
return 0;
#endif
}

int jackbridge_client_name_size()
{
#ifndef JACKBRIDGE_DUMMY
return jack_client_name_size();
#else
return 0;
#endif
}

char* jackbridge_get_client_name(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_get_client_name(client);
#else
return NULL;
#endif
}

int jackbridge_port_name_size()
{
#ifndef JACKBRIDGE_DUMMY
return jack_port_name_size();
#else
return 0;
#endif
}

int jackbridge_recompute_total_latencies(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_recompute_total_latencies(client);
#else
return 0;
#endif
}

void jackbridge_port_get_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range)
{
#ifndef JACKBRIDGE_DUMMY
jack_port_get_latency_range(port, mode, range);
#endif
}

void jackbridge_port_set_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range)
{
#ifndef JACKBRIDGE_DUMMY
jack_port_set_latency_range(port, mode, range);
#endif
}

int jackbridge_activate(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_activate(client);
#else
return 0;
#endif
}

int jackbridge_deactivate(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_deactivate(client);
#else
return 0;
#endif
}

void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown_callback, void* arg)
{
#ifndef JACKBRIDGE_DUMMY
jack_on_shutdown(client, shutdown_callback, arg);
#endif
}

int jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg)
{
#ifndef JACKBRIDGE_DUMMY
return jack_set_latency_callback(client, latency_callback, arg);
#else
return 0;
#endif
}

int jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
{
#ifndef JACKBRIDGE_DUMMY
return jack_set_process_callback(client, process_callback, arg);
#else
return 0;
#endif
}

int jackbridge_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback freewheel_callback, void* arg)
{
#ifndef JACKBRIDGE_DUMMY
return jack_set_freewheel_callback(client, freewheel_callback, arg);
#else
return 0;
#endif
}

int jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg)
{
#ifndef JACKBRIDGE_DUMMY
return jack_set_buffer_size_callback(client, bufsize_callback, arg);
#else
return 0;
#endif
}

int jackbridge_set_sample_rate_callback(jack_client_t* client, JackSampleRateCallback srate_callback, void* arg)
{
#ifndef JACKBRIDGE_DUMMY
return jack_set_sample_rate_callback(client, srate_callback, arg);
#else
return 0;
#endif
}

jack_nframes_t jackbridge_get_sample_rate(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_get_sample_rate(client);
#else
return 0;
#endif
}

jack_nframes_t jackbridge_get_buffer_size(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
return jack_get_buffer_size(client);
#else
return 0;
#endif
}

jack_port_t* jackbridge_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
{
#ifndef JACKBRIDGE_DUMMY
return jack_port_register(client, port_name, port_type, flags, buffer_size);
#else
return NULL;
#endif
}

int jackbridge_port_unregister(jack_client_t* client, jack_port_t* port)
{
#ifndef JACKBRIDGE_DUMMY
return jack_port_unregister(client, port);
#else
return 0;
#endif
}

void* jackbridge_port_get_buffer(jack_port_t* port, jack_nframes_t nframes)
{
#ifndef JACKBRIDGE_DUMMY
return jack_port_get_buffer(port, nframes);
#else
return NULL;
#endif
}

// -----------------------------------------------------------------------------

uint32_t jackbridge_midi_get_event_count(void* port_buffer)
{
#ifndef JACKBRIDGE_DUMMY
return jack_midi_get_event_count(port_buffer);
#else
return 0;
#endif
}

int jackbridge_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index)
{
#ifndef JACKBRIDGE_DUMMY
return jack_midi_event_get(event, port_buffer, event_index);
#else
return 0;
#endif
}

void jackbridge_midi_clear_buffer(void* port_buffer)
{
#ifndef JACKBRIDGE_DUMMY
jack_midi_clear_buffer(port_buffer);
#endif
}

jack_midi_data_t* jackbridge_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size)
{
#ifndef JACKBRIDGE_DUMMY
return jack_midi_event_reserve(port_buffer, time, data_size);
#else
return NULL;
#endif
}

int jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size)
{
#ifndef JACKBRIDGE_DUMMY
return jack_midi_event_write(port_buffer, time, data, data_size);
#else
return 0;
#endif
}

// -----------------------------------------------------------------------------

jack_transport_state_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos)
{
#ifndef JACKBRIDGE_DUMMY
return jack_transport_query(client, pos);
#else
return JackTransportStopped;
#endif
}

+ 111
- 0
source/libs/jackbridge/jackbridge.h View File

@@ -0,0 +1,111 @@
/*
* JackBridge
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#ifndef __JACKBRIDGE_H__
#define __JACKBRIDGE_H__

#if defined(_WIN32) && ! defined(__WINE__)
# include <stdint.h>
# include <windows.h>
# define BRIDGE_EXPORT __declspec (dllexport)
#else
# define BRIDGE_EXPORT __attribute__ ((visibility("default")))
#endif

#ifdef __WINE__
# define GNU_WIN32 // fix jack_native_thread_t
#endif

#include <jack/jack.h>
#include <jack/midiport.h>
#include <jack/transport.h>

#ifdef JACKBRIDGE_EXPORT

#ifdef __cplusplus
extern "C" {
#endif

BRIDGE_EXPORT jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...);
BRIDGE_EXPORT int jackbridge_client_close(jack_client_t* client);
BRIDGE_EXPORT int jackbridge_client_name_size();
BRIDGE_EXPORT char* jackbridge_get_client_name(jack_client_t* client);
BRIDGE_EXPORT int jackbridge_port_name_size();
BRIDGE_EXPORT int jackbridge_recompute_total_latencies(jack_client_t* client);
BRIDGE_EXPORT void jackbridge_port_get_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range);
BRIDGE_EXPORT void jackbridge_port_set_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range);
BRIDGE_EXPORT int jackbridge_activate(jack_client_t* client);
BRIDGE_EXPORT int jackbridge_deactivate(jack_client_t* client);
BRIDGE_EXPORT void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown_callback, void* arg);
BRIDGE_EXPORT int jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg);
BRIDGE_EXPORT int jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg);
BRIDGE_EXPORT int jackbridge_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback freewheel_callback, void* arg);
BRIDGE_EXPORT int jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg);
BRIDGE_EXPORT int jackbridge_set_sample_rate_callback(jack_client_t* client, JackSampleRateCallback srate_callback, void* arg);
BRIDGE_EXPORT jack_nframes_t jackbridge_get_sample_rate(jack_client_t* client);
BRIDGE_EXPORT jack_nframes_t jackbridge_get_buffer_size(jack_client_t* client);
BRIDGE_EXPORT jack_port_t* jackbridge_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size);
BRIDGE_EXPORT int jackbridge_port_unregister(jack_client_t* client, jack_port_t* port);
BRIDGE_EXPORT void* jackbridge_port_get_buffer(jack_port_t* port, jack_nframes_t nframes);

BRIDGE_EXPORT uint32_t jackbridge_midi_get_event_count(void* port_buffer);
BRIDGE_EXPORT int jackbridge_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index);
BRIDGE_EXPORT void jackbridge_midi_clear_buffer(void* port_buffer);
BRIDGE_EXPORT jack_midi_data_t* jackbridge_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size);
BRIDGE_EXPORT int jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size);

BRIDGE_EXPORT jack_transport_state_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos);

#ifdef __cplusplus
}
#endif

#else // JACKBRIDGE_EXPORT

#define jackbridge_client_open jack_client_open
#define jackbridge_client_close jack_client_close
#define jackbridge_client_name_size jack_client_name_size
#define jackbridge_get_client_name jack_get_client_name
#define jackbridge_port_name_size jack_port_name_size
#define jackbridge_recompute_total_latencies jack_recompute_total_latencies
#define jackbridge_port_get_latency_range jack_port_get_latency_range
#define jackbridge_port_set_latency_range jack_port_set_latency_range
#define jackbridge_activate jack_activate
#define jackbridge_deactivate jack_deactivate
#define jackbridge_on_shutdown jack_on_shutdown
#define jackbridge_set_latency_callback jack_set_latency_callback
#define jackbridge_set_process_callback jack_set_process_callback
#define jackbridge_set_freewheel_callback jack_set_freewheel_callback
#define jackbridge_set_buffer_size_callback jack_set_buffer_size_callback
#define jackbridge_set_sample_rate_callback jack_set_sample_rate_callback
#define jackbridge_get_sample_rate jack_get_sample_rate
#define jackbridge_get_buffer_size jack_get_buffer_size
#define jackbridge_port_register jack_port_register
#define jackbridge_port_unregister jack_port_unregister
#define jackbridge_port_get_buffer jack_port_get_buffer

#define jackbridge_midi_get_event_count jack_midi_get_event_count
#define jackbridge_midi_event_get jack_midi_event_get
#define jackbridge_midi_clear_buffer jack_midi_clear_buffer
#define jackbridge_midi_event_reserve jack_midi_event_reserve
#define jackbridge_midi_event_write jack_midi_event_write

#define jackbridge_transport_query jack_transport_query

#endif // JACKBRIDGE_EXPORT

#endif // __JACKBRIDGE_H__

+ 96
- 0
source/libs/lilv/Makefile View File

@@ -0,0 +1,96 @@
#!/usr/bin/make -f
# Makefile for lilv #
# ----------------------- #
# Created by falkTX
#

include ../../Makefile.mk

# --------------------------------------------------------------

SERD_VERSION = 0.18.2
SORD_VERSION = 0.10.4
SRATOM_VERSION = 0.4.0
LILV_VERSION = 0.14.4

BUILD_C_FLAGS += -fvisibility=hidden -fPIC -w
BUILD_C_FLAGS += -Iconfig -I../../includes

OBJS = serd.o sord.o sratom.o lilv.o
OBJS_posix32 = serd_posix32.o sord_posix32.o sratom_posix32.o lilv_posix32.o
OBJS_posix64 = serd_posix64.o sord_posix64.o sratom_posix64.o lilv_posix64.o
OBJS_win32 = serd_win32.o sord_win32.o sratom_win32.o lilv_win32.o
OBJS_win64 = serd_win64.o sord_win64.o sratom_win64.o lilv_win64.o

# --------------------------------------------------------------

all: ../lilv.a

posix32: ../lilv_posix32.a
posix64: ../lilv_posix64.a
win32: ../lilv_win32.a
win64: ../lilv_win64.a

# --------------------------------------------------------------

../lilv.a: $(OBJS)
$(AR) rs $@ $^

../lilv_posix32.a: $(OBJS_posix32)
$(AR) rs $@ $^

../lilv_posix64.a: $(OBJS_posix64)
$(AR) rs $@ $^

../lilv_win32.a: $(OBJS_win32)
$(AR) rs $@ $^

../lilv_win64.a: $(OBJS_win64)
$(AR) rs $@ $^

# --------------------------------------------------------------

serd.o: serd.c
$(CC) $< $(BUILD_C_FLAGS) -Iserd-$(SERD_VERSION) -c -o $@

sord.o: sord.c
$(CC) $< $(BUILD_C_FLAGS) -Isord-$(SORD_VERSION) -Isord-$(SORD_VERSION)/src -c -o $@

sratom.o: sratom.c
$(CC) $< $(BUILD_C_FLAGS) -Isratom-$(SRATOM_VERSION) -c -o $@

lilv.o: lilv.c
$(CC) $< $(BUILD_C_FLAGS) -Ililv-$(LILV_VERSION) -Ililv-$(LILV_VERSION)/src -c -o $@

# --------------------------------------------------------------

serd_%32.o: serd.c
$(CC) $< $(BUILD_C_FLAGS) -Iserd-$(SERD_VERSION) $(32BIT_FLAGS) -c -o $@

sord_%32.o: sord.c
$(CC) $< $(BUILD_C_FLAGS) -Isord-$(SORD_VERSION) -Isord-$(SORD_VERSION)/src $(32BIT_FLAGS) -c -o $@

sratom_%32.o: sratom.c
$(CC) $< $(BUILD_C_FLAGS) -Isratom-$(SRATOM_VERSION) $(32BIT_FLAGS) -c -o $@

lilv_%32.o: lilv.c
$(CC) $< $(BUILD_C_FLAGS) -Ililv-$(LILV_VERSION) -Ililv-$(LILV_VERSION)/src $(32BIT_FLAGS) -c -o $@

# --------------------------------------------------------------

serd_%64.o: serd.c
$(CC) $< $(BUILD_C_FLAGS) -Iserd-$(SERD_VERSION) $(64BIT_FLAGS) -c -o $@

sord_%64.o: sord.c
$(CC) $< $(BUILD_C_FLAGS) -Isord-$(SORD_VERSION) -Isord-$(SORD_VERSION)/src $(64BIT_FLAGS) -c -o $@

sratom_%64.o: sratom.c
$(CC) $< $(BUILD_C_FLAGS) -Isratom-$(SRATOM_VERSION) $(64BIT_FLAGS) -c -o $@

lilv_%64.o: lilv.c
$(CC) $< $(BUILD_C_FLAGS) -Ililv-$(LILV_VERSION) -Ililv-$(LILV_VERSION)/src $(64BIT_FLAGS) -c -o $@

# --------------------------------------------------------------

clean:
rm -f *.o

+ 35
- 0
source/libs/lilv/config/lilv_config.h View File

@@ -0,0 +1,35 @@

#ifndef _LILV_CONFIG_H_
#define _LILV_CONFIG_H_

#define LILV_VERSION "0.14.4"
#define LILV_NEW_LV2 1

#define HAVE_LV2 1
#define HAVE_SERD 1
#define HAVE_SORD 1
#define HAVE_SRATOM 1

#define HAVE_FILENO 1
#define HAVE_CLOCK_GETTIME 1

#ifdef __WIN32__
#define LILV_PATH_SEP ";"
#define LILV_DIR_SEP "\\"
#else
#define LILV_PATH_SEP ":"
#define LILV_DIR_SEP "/"
#define HAVE_FLOCK 1
#endif

#if defined(__APPLE__)
#define LILV_DEFAULT_LV2_PATH "~/.lv2:/usr/local/lib/lv2:/usr/lib/lv2:/Library/Audio/Plug-Ins/LV2"
#elif defined(__HAIKU__)
#define LILV_DEFAULT_LV2_PATH "~/.lv2:/boot/common/add-ons/lv2"
#elif defined(__WIN32__)
#define LILV_DEFAULT_LV2_PATH "%APPDATA%\\LV2;%COMMONPROGRAMFILES%\\LV2"
#else
#define LILV_DEFAULT_LV2_PATH "~/.lv2:/usr/lib/lv2:/usr/local/lib/lv2"
#endif

#endif /* _LILV_CONFIG_H_ */

+ 21
- 0
source/libs/lilv/config/serd_config.h View File

@@ -0,0 +1,21 @@

#ifndef _SERD_CONFIG_H_
#define _SERD_CONFIG_H_

#define SERD_VERSION "0.18.2"

#if defined(__APPLE__) || defined(__HAIKU__)
#define HAVE_FMAX 1
#define HAVE_FILENO 1
#define HAVE_POSIX_MEMALIGN 1
#elif defined(__WIN32__)
#define HAVE_FMAX 1
#define HAVE_FILENO 1
#else
#define HAVE_FMAX 1
#define HAVE_FILENO 1
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_POSIX_FADVISE 1
#endif

#endif /* _SERD_CONFIG_H_ */

+ 10
- 0
source/libs/lilv/config/sord_config.h View File

@@ -0,0 +1,10 @@

#ifndef _SORD_CONFIG_H_
#define _SORD_CONFIG_H_

#define SORD_VERSION "0.10.4"

#define HAVE_SERD 1
#define HAVE_PCRE 1

#endif /* _SORD_CONFIG_H_ */

+ 11
- 0
source/libs/lilv/config/sratom_config.h View File

@@ -0,0 +1,11 @@

#ifndef _SRATOM_CONFIG_H_
#define _SRATOM_CONFIG_H_

#define SRATOM_VERSION "0.4.0"

#define HAVE_LV2 1
#define HAVE_SERD 1
#define HAVE_SORD 1

#endif /* _SRATOM_CONFIG_H_ */

+ 20
- 0
source/libs/lilv/custom-patches/lilv_fix-mingw-build.patch View File

@@ -0,0 +1,20 @@
diff -U 3 -H -b -B -d -r -N -- lilv-0.14.4.old/src/util.c lilv-0.14.4/src/util.c
--- lilv-0.14.4.old/src/util.c 2012-08-09 21:51:00.000000000 +0100
+++ lilv-0.14.4/src/util.c 2012-09-15 01:20:07.908701939 +0100
@@ -29,7 +29,6 @@
#include <string.h>
#ifdef _WIN32
-# define _WIN32_WINNT 0x0600 /* for CreateSymbolicLink */
# include <windows.h>
# include <direct.h>
# include <io.h>
@@ -426,7 +425,7 @@
int ret = 0;
if (strcmp(oldpath, newpath)) {
#ifdef _WIN32
- ret = !CreateSymbolicLink(newpath, oldpath, 0);
+ ret = 0;
#else
ret = symlink(oldpath, newpath);
#endif

+ 137
- 0
source/libs/lilv/custom-patches/lilv_ui-features+lilvmm.patch View File

@@ -0,0 +1,137 @@
diff -U 3 -H -d -r -N -- lilv-0.14.4.old/lilv/lilv.h lilv-0.14.4/lilv/lilv.h
--- lilv-0.14.4.old/lilv/lilv.h 2012-09-07 19:00:48.464571333 +0100
+++ lilv-0.14.4/lilv/lilv.h 2012-09-07 18:54:00.626548936 +0100
@@ -1693,6 +1693,25 @@
lilv_ui_get_binary_uri(const LilvUI* ui);
/**
+ Custom calls
+*/
+LILV_API
+LilvNodes*
+lilv_ui_get_supported_features(const LilvUI* ui);
+
+LILV_API
+LilvNodes*
+lilv_ui_get_required_features(const LilvUI* ui);
+
+LILV_API
+LilvNodes*
+lilv_ui_get_optional_features(const LilvUI* ui);
+
+LILV_API
+LilvNodes*
+lilv_ui_get_extension_data(const LilvUI* ui);
+
+/**
@}
@}
*/
diff -U 3 -H -d -r -N -- lilv-0.14.4.old/lilv/lilvmm.hpp lilv-0.14.4/lilv/lilvmm.hpp
--- lilv-0.14.4.old/lilv/lilvmm.hpp 2012-07-18 02:42:43.000000000 +0100
+++ lilv-0.14.4/lilv/lilvmm.hpp 2012-09-07 18:53:14.134318379 +0100
@@ -136,6 +136,7 @@
struct Nodes {
LILV_WRAP_COLL(Nodes, Node, nodes);
LILV_WRAP1(bool, nodes, contains, const Node, node);
+ LILV_WRAP0(Node, nodes, get_first);
};
struct Port {
@@ -167,6 +168,26 @@
const LilvPort* me;
};
+struct UI {
+ inline UI(const LilvUI* c_obj) : me(c_obj) {}
+ LILV_WRAP_CONVERSION(const LilvUI);
+
+ LILV_WRAP0(Node, ui, get_uri);
+ LILV_WRAP1(bool, ui, is_a, LilvNode*, ui_class);
+ LILV_WRAP0(Node, ui, get_bundle_uri);
+ LILV_WRAP0(Node, ui, get_binary_uri);
+ LILV_WRAP0(Nodes, ui, get_supported_features);
+ LILV_WRAP0(Nodes, ui, get_required_features);
+ LILV_WRAP0(Nodes, ui, get_optional_features);
+ LILV_WRAP0(Nodes, ui, get_extension_data);
+
+ const LilvUI* me;
+};
+
+struct UIs {
+ LILV_WRAP_COLL(UIs, UI, uis);
+};
+
struct Plugin {
inline Plugin(const LilvPlugin* c_obj) : me(c_obj) {}
LILV_WRAP_CONVERSION(const LilvPlugin);
@@ -190,6 +211,8 @@
LILV_WRAP0(Node, plugin, get_author_email);
LILV_WRAP0(Node, plugin, get_author_homepage);
LILV_WRAP0(bool, plugin, is_replaced);
+ LILV_WRAP0(Nodes, plugin, get_extension_data);
+ LILV_WRAP0(UIs, plugin, get_uis);
inline Port get_port_by_index(unsigned index) {
return Port(me, lilv_plugin_get_port_by_index(me, index));
diff -U 3 -H -d -r -N -- lilv-0.14.4.old/src/ui.c lilv-0.14.4/src/ui.c
--- lilv-0.14.4.old/src/ui.c 2012-09-07 19:00:48.464571333 +0100
+++ lilv-0.14.4/src/ui.c 2012-09-07 18:59:51.652289664 +0100
@@ -128,3 +128,57 @@
assert(ui->binary_uri);
return ui->binary_uri;
}
+
+static LilvNodes*
+lilv_ui_get_value_internal(const LilvUI* ui,
+ const SordNode* predicate)
+{
+ return lilv_world_query_values_internal(
+ ui->world, ui->uri->node, predicate, NULL);
+}
+
+LILV_API
+LilvNodes*
+lilv_ui_get_supported_features(const LilvUI* ui)
+{
+ LilvNodes* optional = lilv_ui_get_optional_features(ui);
+ LilvNodes* required = lilv_ui_get_required_features(ui);
+ LilvNodes* result = lilv_nodes_new();
+
+ LILV_FOREACH(nodes, i, optional)
+ zix_tree_insert((ZixTree*)result,
+ lilv_node_duplicate(lilv_nodes_get(optional, i)),
+ NULL);
+ LILV_FOREACH(nodes, i, required)
+ zix_tree_insert((ZixTree*)result,
+ lilv_node_duplicate(lilv_nodes_get(required, i)),
+ NULL);
+
+ lilv_nodes_free(optional);
+ lilv_nodes_free(required);
+
+ return result;
+}
+
+LILV_API
+LilvNodes*
+lilv_ui_get_required_features(const LilvUI* ui)
+{
+ return lilv_ui_get_value_internal(
+ ui, ui->world->uris.lv2_requiredFeature);
+}
+
+LILV_API
+LilvNodes*
+lilv_ui_get_optional_features(const LilvUI* ui)
+{
+ return lilv_ui_get_value_internal(
+ ui, ui->world->uris.lv2_optionalFeature);
+}
+
+LILV_API
+LilvNodes*
+lilv_ui_get_extension_data(const LilvUI* ui)
+{
+ return lilv_ui_get_value_internal(ui, ui->world->uris.lv2_extensionData);
+}

+ 11
- 0
source/libs/lilv/custom-patches/lilvmm_fix-leaks.patch View File

@@ -0,0 +1,11 @@
diff -U 3 -H -b -B -d -r -N -- lilv-0.14.4.old/lilv/lilvmm.hpp lilv-0.14.4/lilv/lilvmm.hpp
--- lilv-0.14.4.old/lilv/lilvmm.hpp 2012-09-13 12:47:55.000000000 +0100
+++ lilv-0.14.4/lilv/lilvmm.hpp 2012-09-13 12:48:10.950555311 +0100
@@ -60,6 +60,7 @@
#endif
struct Node {
+ inline Node(LilvNode* node) : me(node) {}
inline Node(const LilvNode* node) : me(lilv_node_duplicate(node)) {}
inline Node(const Node& copy) : me(lilv_node_duplicate(copy.me)) {}

+ 8
- 0
source/libs/lilv/lilv-0.14.4/AUTHORS View File

@@ -0,0 +1,8 @@
Author:
David Robillard <d@drobilla.net>

GTK2 GUI and I18N support:
Lars Luthman <lars.luthman@gmail.com>

Dynamic manifest support:
Stefano D'Angelo

+ 13
- 0
source/libs/lilv/lilv-0.14.4/COPYING View File

@@ -0,0 +1,13 @@
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.

+ 59
- 0
source/libs/lilv/lilv-0.14.4/INSTALL View File

@@ -0,0 +1,59 @@
Installation Instructions
=========================

Basic Installation
------------------

Building this software requires only Python. To install with default options:

./waf configure
./waf
./waf install

You may need to become root for the install stage, for example:

sudo ./waf install

Configuration Options
---------------------

All supported options can be viewed using the command:

./waf --help

Most options only need to be passed during the configure stage, for example:

./waf configure --prefix=/usr
./waf
./waf install

Compiler Configuration
----------------------

Several standard environment variables can be used to control how compilers are
invoked:

* CC: Path to C compiler
* CFLAGS: C compiler options
* CXX: Path to C++ compiler
* CXXFLAGS: C++ compiler options
* CPPFLAGS: C preprocessor options
* LINKFLAGS: Linker options

Installation Directories
------------------------

The --prefix option (or the PREFIX environment variable) can be used to change
the prefix which all files are installed under. There are also several options
allowing for more fine-tuned control, see the --help output for details.

Packaging
---------

Everything can be installed to a specific root directory by passing a --destdir
option to the install stage (or setting the DESTDIR environment variable),
which adds a prefix to all install paths. For example:

./waf configure --prefix=/usr
./waf
./waf install --destdir=/tmp/package

+ 90
- 0
source/libs/lilv/lilv-0.14.4/NEWS View File

@@ -0,0 +1,90 @@
lilv (0.14.4) stable;

* Deprecate old flawed Lilv::Instance constructors
* Fix documentation for ui_type parameter of lilv_ui_is_supported()
* Fix crash when lv2info is run with an invalid URI argument
* Gracefully handle failure to save plugin state and print error message
* Reduce memory usage (per node)
* Simpler node implementation always backed by a SordNode
* Make all 'zix' symbols private to avoid symbol clashes in static builds
* Add lv2bench utility
* Fix various hyper-strict warnings
* Do not require a C++ compiler to build
* Add option to build utilities as static binaries
* Upgrade to waf 1.7.2
* lilvmm.hpp: Make Lilv::Instance handle features and failed instantiations
* lilvmm.hpp: Add Lilv::Instance::get_handle()
* lilvmm.hpp: Add Lilv::Instance::get_extension_data()

-- David Robillard <d@drobilla.net> Thu, 23 Aug 2012 01:38:29 -0400

lilv (0.14.2) stable;

* Fix dynmanifest support

-- David Robillard <d@drobilla.net> Thu, 19 Apr 2012 16:11:31 -0400

lilv (0.14.0) stable;

* Add lilv_plugin_get_extension_data
* Use path variables in pkgconfig files
* Install man page to DATADIR (e.g. PREFIX/share/man, not PREFIX/man)
* Make Lilv::uri_to_path static inline (fix linking errors)
* Use correct URI for dcterms:replaces (for hiding old plugins):
"http://purl.org/dc/terms/replaces"
* Fix compilation on BSD
* Only load dynmanifest libraries once per bundle, not once per plugin
* Fix lilv_world_find_nodes to work with wildcard subjects
* Add lilv_plugin_get_related to get resources related to plugins that
are not directly rdfs:seeAlso linked (e.g. presets)
* Add lilv_world_load_resource for related resources (e.g. presets)
* Print presets in lv2info
* Remove locale smashing kludges and use new serd functions for converting
nodes to/from numbers.
* Add LilvState API for handling plugin state. This makes it simple to
save and restore plugin state both in memory and on disk, as well as
save presets in a host-sharable way since the disk format is identical
to the LV2 presets format.
* Update old references to lv2_list (now lv2ls)
* Support compilation as C++ under MSVC++.
* Remove use of wordexp.
* Add lilv_plugin_get_port_by_designation() and lilv_port_get_index() as an
improved generic alternative to lilv_plugin_get_latency_port_index().
* Add lilv_plugin_get_project() and get author information from project if
it is not given directly on the plugin.

-- David Robillard <d@drobilla.net> Wed, 18 Apr 2012 20:06:28 -0400

lilv (0.5.0) stable;

* Remove glib dependency
* Add lv2core as a pkg-config dependency (for lv2.h header include)
* Obey prefix when installing bash completion script
* Support integer minimum, maximum, and default port values in
lilv_plugin_get_port_ranges_float
* Add ability to build static library

-- David Robillard <d@drobilla.net> Thu, 29 Sep 2011 00:00:00 -0400

lilv (0.4.4) stable;

* Fix building python bindings
* Make free methods tolerate being called on NULL
* Remove lv2jack (replaced by jalv)
* Fix parsing extra plugin data files in other bundles
* Fix lilv_ui_is_supported when Lilv is built independently

-- David Robillard <d@drobilla.net> Sat, 11 Jun 2011 11:20:11 -0400

lilv (0.4.2) stable;

* Fix compilation issues on some systems
* Fix build system Python 3 compatibility

-- David Robillard <d@drobilla.net> Wed, 25 May 2011 19:00:00 -0400

lilv (0.4.0) stable;

* Initial version (forked from SLV2)

-- David Robillard <d@drobilla.net> Tue, 24 May 2011 23:00:00 -0400

+ 29
- 0
source/libs/lilv/lilv-0.14.4/PACKAGING View File

@@ -0,0 +1,29 @@
This library is designed to allow parallel installation of different major
versions. To facilitate this, the shared library name, include directory, and
pkg-config file are suffixed with the major version number of the library.

For example, if this library was named "foo" and at version 1.x.y:

/usr/include/foo-1/foo/foo.h
/usr/lib/foo-1.so.1.x.y
/usr/lib/pkgconfig/foo-1.pc

Dependencies check for pkg-config name "foo-1" and will build
against a compatible version 1, regardless any other installed versions.

*** IMPORTANT GUIDELINES FOR PACKAGERS ***

Packages should follow the same conventions as above, i.e. include the major
version (and only the major version) in the name of the package. Continuing the
example above, the package(s) would be named foo-1 and foo-1-dev. This way,
if/when version 2 comes out, it may be installed at the same time as version 1
without breaking anything.

Please do not create packages of this library that do not follow these
guidelines, you will break things and cause unnecessary headaches. Please do
not use any number as a suffix other than the actual major version number of the
upstream source package.

Because program and documentation names are not versioned, these should be
included in separate packages which may replace previous versions, since
there is little use in having parallel installations of them.

+ 11
- 0
source/libs/lilv/lilv-0.14.4/README View File

@@ -0,0 +1,11 @@
Lilv
----

Lilv is a library for LV2 hosts intended to make using LV2 Plugins as simple
as possible (without sacrificing capabilities).

More information about LV2 plugins can be found at <http://lv2plug.in>.

More information about Lilv can be found at <http://drobilla.net/software/lilv>.

-- David Robillard <d@drobilla.net>

+ 38
- 0
source/libs/lilv/lilv-0.14.4/bindings/lilv.i View File

@@ -0,0 +1,38 @@
%module lilv
%{
#include "lilv/lilv.h"
#include "lilv/lilvmm.hpp"
%}

%include "lilv/lilv.h"
%include "lilv/lilvmm.hpp"

namespace Lilv {

%extend Plugins {
%pythoncode %{
def __iter__(self):
class Iterator(object):
def __init__(self, plugins):
self.plugins = plugins
self.iter = plugins.begin()
def next(self):
self.iter = self.plugins.next(self.iter)
if not self.plugins.is_end(self.iter):
return self.plugins.get(self.iter)
else:
raise StopIteration

return Iterator(self)
%}
};

%extend Node {
%pythoncode %{
def __str__(self):
return self.get_turtle_token()
%}
};

} /* namespace Lilv */

+ 96
- 0
source/libs/lilv/lilv-0.14.4/bindings/python/lv2_apply.py View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import math
import lilv
import sys
import wave
import numpy

# Read command line arguments
if len(sys.argv) != 4:
print 'USAGE: lv2_apply.py PLUGIN_URI INPUT_WAV OUTPUT_WAV'
sys.exit(1)

# Initialise Lilv
world = lilv.World()
world.load_all()

plugin_uri = world.new_uri(sys.argv[1])
wav_in_path = sys.argv[2]
wav_out_path = sys.argv[3]


# Find plugin
plugin = world.get_all_plugins().get_by_uri(plugin_uri)
if not plugin:
print "Unknown plugin `%s'\n" % plugin_uri
sys.exit(1)

lv2_InputPort = world.new_uri(lilv.LILV_URI_INPUT_PORT)
lv2_OutputPort = world.new_uri(lilv.LILV_URI_OUTPUT_PORT)
lv2_AudioPort = world.new_uri(lilv.LILV_URI_AUDIO_PORT)

n_audio_in = plugin.get_num_ports_of_class(lv2_InputPort, lv2_AudioPort)
n_audio_out = plugin.get_num_ports_of_class(lv2_OutputPort, lv2_AudioPort)
if n_audio_out == 0:
print "Plugin has no audio outputs\n"
sys.exit(1)

# Open input file
wav_in = wave.open(wav_in_path, 'r')
if not wav_in:
print "Failed to open input `%s'\n" % wav_in_path
sys.exit(1)
if wav_in.getnchannels() != n_audio_in:
print "Input has %d channels, but plugin has %d audio inputs\n" % (
wav_in.getnchannels(), n_audio_in)
sys.exit(1)

# Open output file
wav_out = wave.open(wav_out_path, 'w')
if not wav_out:
print "Failed to open output `%s'\n" % wav_out_path
sys.exit(1)

# Set output file to same format as input (except possibly nchannels)
wav_out.setparams(wav_in.getparams())
wav_out.setnchannels(n_audio_out)

rate = wav_in.getframerate()
nframes = wav_in.getnframes()

# Instantiate plugin
instance = lilv.Instance(plugin, rate)

def read_float(wf, nframes):
wav = wf.readframes(nframes)
if wf.getsampwidth() == 4:
wav = wave.struct.unpack("<%ul" % (len(wav) / 4), wav)
wav = [ i / float(math.pow(2, 32)) for i in wav ]
elif wf.getsampwidth() == 2:
wav = wave.struct.unpack("<%uh" % (len(wav) / 2), wav)
wav = [ i / float(math.pow(2, 16)) for i in wav ]
else:
wav = wave.struct.unpack("%uB" % (len(wav)), wav)
wav = [ s - 128 for s in wav ]
wav = [ i / float(math.pow(2, 8)) for i in wav ]

n_channels = wf.getnchannels()
wavs = []
if n_channels > 1:
for i in xrange(n_channels):
wavs.append([ wav[j] for j in xrange(0, len(wav), n_channels) ])
else:
wavs = [ wav ]

return wavs

in_buf = read_float(wav_in, nframes)

# TODO: buffer marshaling
#instance.connect_port(3, in_buf)

print '%s => %s => %s @ %d Hz' % (wav_in_path, plugin.get_name(), wav_out_path, rate)

instance.connect_port(3, in_buf)

+ 9
- 0
source/libs/lilv/lilv-0.14.4/bindings/python/lv2_list.py View File

@@ -0,0 +1,9 @@
#!/usr/bin/env python

import lilv

world = lilv.World()
world.load_all()

for i in world.get_all_plugins():
print(i.get_uri())

+ 33
- 0
source/libs/lilv/lilv-0.14.4/doc/lv2info.1 View File

@@ -0,0 +1,33 @@
.TH LV2INFO 1 "8 Jan 2012"

.SH NAME
.B lv2info \- print information about an installed LV2 plugin.
.SH SYNOPSIS
.B lv2info PLUGIN_URI

.SH OPTIONS
.TP
\fB\-p FILE
Write Turtle description of plugin to FILE

.TP
\fB\-m FILE
Add record of plugin to manifest FILE

.TP
\fB\-\-help\fR
Display help and exit

.TP
\fB\-\-version\fR
Display version information and exit

.SH SEE ALSO
.BR lilv(3),
.BR lv2ls(1)

.SH AUTHOR
lv2info was written by David Robillard <d@drobilla.net>
.PP
This manual page was written by Jaromír Mikes <mira.mikes@seznam.cz>
and David Robillard <d@drobilla.net>

+ 30
- 0
source/libs/lilv/lilv-0.14.4/doc/lv2ls.1 View File

@@ -0,0 +1,30 @@
.TH LV2LS 1 "17 Jan 2012"

.SH NAME
.B lv2ls \- List all installed LV2 plugins.

.SH SYNOPSIS
.B lv2ls [OPTION]...

.SH OPTIONS
.TP
\fB\-n\fR, \fB\-\-names\fR
Show names instead of URIs

.TP
\fB\-\-help\fR
Display help and exit

.TP
\fB\-\-version\fR
Display version information and exit

.SH SEE ALSO
.BR lilv(3),
.BR lv2info(1)

.SH AUTHOR
lv2ls was written by David Robillard <d@drobilla.net>
.PP
This manual page was written by Jaromír Mikes <mira.mikes@seznam.cz>
and David Robillard <d@drobilla.net>

+ 1792
- 0
source/libs/lilv/lilv-0.14.4/doc/reference.doxygen.in
File diff suppressed because it is too large
View File


+ 563
- 0
source/libs/lilv/lilv-0.14.4/doc/style.css View File

@@ -0,0 +1,563 @@
body {
font-size: medium;
font-family: sans-serif;
}

#top {
background-color: #F3F3F3;
margin: 0;
padding: 0;
border-bottom: 1px solid #DDD;
margin-bottom: 1ex;
font-size: xx-large;
font-weight: bold;
}

div.header {
display: none;
}

.tabs {
display: none;
}

h1 h2 h3 h4 h5 h6 {
font-weight: bold;
}

h1 {
font-size: 164%;
}

h2 {
font-size: 132%;
}

h3 {
font-size: 124%;
}

h4 {
font-size: 116%;
}

h5 {
font-size: 108%;
}

h6 {
font-size: 100%;
}

p {
margin: 0 0 1ex 0;
}

br {
display: none;
}

dt {
font-weight: 700;
}

div.multicol {
}

p.startli,p.startdd,p.starttd {
margin-top: 2px;
}

p.endli {
margin-bottom: 0;
}

p.enddd {
margin-bottom: 4px;
}

p.endtd {
margin-bottom: 2px;
}

caption {
font-weight: 700;
}

span.legend {
font-size: 70%;
text-align: center;
}

h3.version {
font-size: 90%;
text-align: center;
}

div.qindex,div.navtab {
background-color: #EBEFF6;
border: 1px solid #A3B4D7;
text-align: center;
margin: 2px;
padding: 2px;
}

div.qindex,div.navpath {
width: 100%;
line-height: 140%;
}

div.navtab {
margin-right: 15px;
}

/* @group Link Styling */
a {
color: #3D8C57;
text-decoration: none;
}

.contents a:visited {
color: #50755E;
}

a:hover {
text-decoration: underline;
}

a.qindexHL {
background-color: #9CAFD4;
color: #FFF;
border: 1px double #869DCA;
}

a.code {
color: #4665A2;
}

a.codeRef {
color: #4665A2;
}

/* @end */
dl.el {
margin-left: -1cm;
}

.fragment {
font-family: monospace, fixed;
font-size: 105%;
}

pre.fragment {
border: 1px solid #C4C4C4;
background-color: #F9F9F9;
padding: 4px 6px;
margin: 4px 8px 4px 2px;
overflow: auto;
font-size: 9pt;
line-height: 125%;
}

div.ah {
background-color: #000;
font-weight: 700;
color: #FFF;
margin-bottom: 3px;
margin-top: 3px;
padding: .2em;
border: thin solid #333;
}

div.groupHeader {
margin-left: 16px;
margin-top: 12px;
margin-bottom: 6px;
font-weight: 700;
}

div.groupText {
margin-left: 16px;
font-style: italic;
}

body {
background: #FFF;
color: #000;
margin: 0;
}

div.contents {
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
}

td.indexkey {
background-color: #EBEFF6;
font-weight: 700;
border: 1px solid #C4CFE5;
margin: 2px 0;
padding: 2px 10px;
}

td.indexvalue {
background-color: #EBEFF6;
border: 1px solid #C4CFE5;
padding: 2px 10px;
margin: 2px 0;
}

tr.memlist {
background-color: #EEF1F7;
}

p.formulaDsp {
text-align: center;
}

img.formulaDsp {
}

img.formulaInl {
vertical-align: middle;
}

div.center {
text-align: center;
margin-top: 0;
margin-bottom: 0;
padding: 0;
}

div.center img {
border: 0;
}

address.footer {
text-align: right;
padding: 0 0.25em 0.25em 0;
}

img.footer {
border: 0;
vertical-align: middle;
}

/* @group Code Colorization */
span.keyword {
color: green;
}

span.keywordtype {
color: #604020;
}

span.keywordflow {
color: #e08000;
}

span.comment {
color: maroon;
}

span.preprocessor {
color: #806020;
}

span.stringliteral {
color: #002080;
}

span.charliteral {
color: teal;
}

span.vhdldigit {
color: #F0F;
}

span.vhdlkeyword {
color: #700070;
}

span.vhdllogic {
color: red;
}

/* @end */
td.tiny {
font-size: 75%;
}

.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #A3B4D7;
}

th.dirtab {
background: #EBEFF6;
font-weight: 700;
}

hr {
height: 0;
border: none;
border-top: 1px solid #DDD;
margin: 2em 0 1em;
}

hr.footer {
height: 1px;
}

/* @group Member Descriptions */
table.memberdecls {
border-spacing: 0;
font-size: small;
}

.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams {
background-color: #FBFBFB;
margin: 0;
padding: 0.25ex;
}

.mdescLeft,.mdescRight {
color: #555;
}

.memItemLeft,.memItemRight,.memTemplParams {
border-top: 1px solid #DDD;
}

.memItemLeft,.memTemplItemLeft {
white-space: nowrap;
padding-left: 2em;
}

.memTemplParams {
color: #464646;
white-space: nowrap;
}

/* @end */
/* @group Member Details */
/* Styles for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #4665A2;
font-weight: bold;
}

.memnav {
background-color: #EBEFF6;
border: 1px solid #A3B4D7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}

.memitem {
padding: 0;
margin: 1ex 0 2ex 0;
border: 1px solid #CCC;
}

.memname {
white-space: nowrap;
font-weight: bold;
}

.memproto {
border-bottom: 1px solid #DDD;
padding: 0.5ex;
font-weight: bold;
background-color: #F3F3F3;
}

.memdoc {
padding: 1ex;
background-color: #FBFBFB;
border-top-width: 0;
}

.paramkey {
text-align: right;
}

.paramtype {
white-space: nowrap;
}

.paramname {
color: #602020;
white-space: nowrap;
}

.paramname em {
font-style: normal;
}

/* @end */
/* @group Directory (tree) */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin: 0;
}

/* these are for tree view when used as main index */
.directory {
font-size: 9pt;
font-weight: bold;
margin: 5px;
}

.directory h3 {
margin: 0;
margin-top: 1em;
font-size: 11pt;
}

.directory > h3 {
margin-top: 0;
}

.directory p {
margin: 0;
white-space: nowrap;
}

.directory div {
display: none;
margin: 0;
}

.directory img {
vertical-align: -30%;
}

/* these are for tree view when not used as main index */
.directory-alt {
font-size: 100%;
font-weight: bold;
}

.directory-alt h3 {
margin: 0;
margin-top: 1em;
font-size: 11pt;
}

.directory-alt > h3 {
margin-top: 0;
}

.directory-alt p {
margin: 0;
white-space: nowrap;
}

.directory-alt div {
display: none;
margin: 0;
}

.directory-alt img {
vertical-align: -30%;
}

/* @end */
div.dynheader {
margin-top: 8px;
}

address {
font-style: normal;
color: #2A3D61;
}

table.doxtable {
border-collapse: collapse;
margin: 0.5ex;
}

table.doxtable td,table.doxtable th {
border: 1px solid #DDD;
padding: 3px 7px 2px;
}

table.doxtable th {
background-color: #F3F3F3;
color: #000;
padding-bottom: 4px;
padding-top: 5px;
text-align: left;
font-weight: bold;
}

.tabsearch {
top: 0;
left: 10px;
height: 36px;
z-index: 101;
overflow: hidden;
font-size: 13px;
}

.navpath ul {
font-size: 11px;
height: 30px;
line-height: 30px;
color: #8AA0CC;
border: 1px solid #C2CDE4;
overflow: hidden;
margin: 0;
padding: 0;
}

.navpath li {
list-style-type: none;
float: left;
padding-left: 10px;
padding-right: 15px;
color: #364D7C;
}

.navpath a {
height: 32px;
display: block;
text-decoration: none;
outline: none;
}

.navpath a:hover {
color: #6884BD;
}

div.summary {
float: right;
font-size: 8pt;
padding-right: 5px;
width: 50%;
text-align: right;
}

div.summary a {
white-space: nowrap;
}

div.header {
background-color: #F3F3F3;
margin: 0;
border-bottom: 1px solid #DDD;
}

div.headertitle {
padding: 5px 5px 5px 10px;
font-size: 180%;
font-weight: bold;
}

+ 11
- 0
source/libs/lilv/lilv-0.14.4/lilv.pc.in View File

@@ -0,0 +1,11 @@
prefix=@PREFIX@
exec_prefix=@EXEC_PREFIX@
libdir=@LIBDIR@
includedir=@INCLUDEDIR@

Name: Lilv
Version: @LILV_VERSION@
Description: Simple C library for hosting LV2 plugins
Requires: lv2core @LILV_PKG_DEPS@
Libs: -L${libdir} -l@LIB_LILV@ -ldl
Cflags: -I${includedir}/lilv-@LILV_MAJOR_VERSION@

+ 29
- 0
source/libs/lilv/lilv-0.14.4/lilv.ttl View File

@@ -0,0 +1,29 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <http://usefulinc.com/ns/doap#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<http://drobilla.net/software/lilv>
a :Project ;
:bug-database <http://dev.drobilla.net/query?status=new&status=assigned&status=reopened&component=LILV&order=priority> ;
:developer [
a foaf:Person ;
rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ;
foaf:homepage <http://drobilla.net> ;
foaf:mbox_sha1sum "253b3c58086250260bac1232d744d150274ad308" ;
foaf:name "David Robillard"
] ;
:download-page <http://download.drobilla.net> ;
:homepage <http://drobilla.net/software/lilv> ;
:license <http://usefulinc.com/doap/licenses/gpl> ;
:name "LILV" ;
:programming-language "C", "Turtle" ;
:repository [
:browse <http://dev.drobilla.net/browser/trunk/lilv> ;
:location <http://svn.drobilla.net/lad/trunk/lilv> ;
a :SVNRepository
] ;
:shortdesc "Library for simple use of LV2 plugins" ;
:shortname "LILV" .



+ 1723
- 0
source/libs/lilv/lilv-0.14.4/lilv/lilv.h
File diff suppressed because it is too large
View File


+ 332
- 0
source/libs/lilv/lilv-0.14.4/lilv/lilvmm.hpp View File

@@ -0,0 +1,332 @@
/*
Copyright 2007-2011 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.
*/

#ifndef LILV_LILVMM_HPP
#define LILV_LILVMM_HPP

#include "lilv/lilv.h"

#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define LILV_DEPRECATED __attribute__((__deprecated__))
#else
# define LILV_DEPRECATED
#endif

namespace Lilv {

static inline const char*
uri_to_path(const char* uri) {
return lilv_uri_to_path(uri);
}

#define LILV_WRAP0(RT, prefix, name) \
inline RT name() { return lilv_ ## prefix ## _ ## name (me); }

#define LILV_WRAP0_VOID(prefix, name) \
inline void name() { lilv_ ## prefix ## _ ## name(me); }

#define LILV_WRAP1(RT, prefix, name, T1, a1) \
inline RT name(T1 a1) { return lilv_ ## prefix ## _ ## name (me, a1); }

#define LILV_WRAP1_VOID(prefix, name, T1, a1) \
inline void name(T1 a1) { lilv_ ## prefix ## _ ## name(me, a1); }

#define LILV_WRAP2(RT, prefix, name, T1, a1, T2, a2) \
inline RT name(T1 a1, T2 a2) { \
return lilv_ ## prefix ## _ ## name(me, a1, a2); \
}

#define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \
inline void name(T1 a1, T2 a2) { lilv_ ## prefix ## _ ## name(me, a1, a2); }

#ifndef SWIG
#define LILV_WRAP_CONVERSION(CT) \
inline operator CT*() const { return me; }
#else
#define LILV_WRAP_CONVERSION(CT)
#endif

struct Node {
inline Node(LilvNode* node) : me(node) {}
inline Node(const LilvNode* node) : me(lilv_node_duplicate(node)) {}
inline Node(const Node& copy) : me(lilv_node_duplicate(copy.me)) {}

inline ~Node() { lilv_node_free(me); }

inline bool equals(const Node& other) const {
return lilv_node_equals(me, other.me);
}

inline bool operator==(const Node& other) const { return equals(other); }

LILV_WRAP_CONVERSION(LilvNode);

LILV_WRAP0(char*, node, get_turtle_token);
LILV_WRAP0(bool, node, is_uri);
LILV_WRAP0(const char*, node, as_uri);
LILV_WRAP0(bool, node, is_blank);
LILV_WRAP0(const char*, node, as_blank);
LILV_WRAP0(bool, node, is_literal);
LILV_WRAP0(bool, node, is_string);
LILV_WRAP0(const char*, node, as_string);
LILV_WRAP0(bool, node, is_float);
LILV_WRAP0(float, node, as_float);
LILV_WRAP0(bool, node, is_int);
LILV_WRAP0(int, node, as_int);
LILV_WRAP0(bool, node, is_bool);
LILV_WRAP0(bool, node, as_bool);

LilvNode* me;
};

struct ScalePoint {
inline ScalePoint(const LilvScalePoint* c_obj) : me(c_obj) {}
LILV_WRAP_CONVERSION(const LilvScalePoint);

LILV_WRAP0(const LilvNode*, scale_point, get_label);
LILV_WRAP0(const LilvNode*, scale_point, get_value);

const LilvScalePoint* me;
};

struct PluginClass {
inline PluginClass(const LilvPluginClass* c_obj) : me(c_obj) {}
LILV_WRAP_CONVERSION(const LilvPluginClass);

LILV_WRAP0(Node, plugin_class, get_parent_uri);
LILV_WRAP0(Node, plugin_class, get_uri);
LILV_WRAP0(Node, plugin_class, get_label);
LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children);

const LilvPluginClass* me;
};

#define LILV_WRAP_COLL(CT, ET, prefix) \
inline CT(const Lilv ## CT* c_obj) : me(c_obj) {} \
LILV_WRAP_CONVERSION(const Lilv ## CT); \
LILV_WRAP0(unsigned, prefix, size); \
LILV_WRAP1(const ET, prefix, get, LilvIter*, i); \
LILV_WRAP0(LilvIter*, prefix, begin); \
LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i); \
LILV_WRAP1(bool, prefix, is_end, LilvIter*, i); \
const Lilv ## CT* me; \

struct PluginClasses {
LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes);
LILV_WRAP1(const PluginClass, plugin_classes,
get_by_uri, const LilvNode*, uri);
};

struct ScalePoints {
LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points);
};

struct Nodes {
LILV_WRAP_COLL(Nodes, Node, nodes);
LILV_WRAP1(bool, nodes, contains, const Node, node);
LILV_WRAP0(Node, nodes, get_first);
};

struct Port {
inline Port(const LilvPlugin* p, const LilvPort* c_obj)
: parent(p), me(c_obj)
{}

LILV_WRAP_CONVERSION(const LilvPort);

#define LILV_PORT_WRAP0(RT, name) \
inline RT name () { return lilv_port_ ## name (parent, me); }

#define LILV_PORT_WRAP1(RT, name, T1, a1) \
inline RT name (T1 a1) { return lilv_port_ ## name (parent, me, a1); }

LILV_PORT_WRAP1(LilvNodes*, get_value, LilvNode*, predicate);
LILV_PORT_WRAP0(LilvNodes*, get_properties)
LILV_PORT_WRAP1(bool, has_property, LilvNode*, property_uri);
LILV_PORT_WRAP1(bool, supports_event, LilvNode*, event_uri);
LILV_PORT_WRAP0(const LilvNode*, get_symbol);
LILV_PORT_WRAP0(LilvNode*, get_name);
LILV_PORT_WRAP0(const LilvNodes*, get_classes);
LILV_PORT_WRAP1(bool, is_a, LilvNode*, port_class);
LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points);

// TODO: get_range (output parameters)

const LilvPlugin* parent;
const LilvPort* me;
};

struct UI {
inline UI(const LilvUI* c_obj) : me(c_obj) {}
LILV_WRAP_CONVERSION(const LilvUI);

LILV_WRAP0(Node, ui, get_uri);
LILV_WRAP1(bool, ui, is_a, LilvNode*, ui_class);
LILV_WRAP0(Node, ui, get_bundle_uri);
LILV_WRAP0(Node, ui, get_binary_uri);
LILV_WRAP0(Nodes, ui, get_supported_features);
LILV_WRAP0(Nodes, ui, get_required_features);
LILV_WRAP0(Nodes, ui, get_optional_features);
LILV_WRAP0(Nodes, ui, get_extension_data);

const LilvUI* me;
};

struct UIs {
LILV_WRAP_COLL(UIs, UI, uis);
};

struct Plugin {
inline Plugin(const LilvPlugin* c_obj) : me(c_obj) {}
LILV_WRAP_CONVERSION(const LilvPlugin);

LILV_WRAP0(bool, plugin, verify);
LILV_WRAP0(Node, plugin, get_uri);
LILV_WRAP0(Node, plugin, get_bundle_uri);
LILV_WRAP0(Nodes, plugin, get_data_uris);
LILV_WRAP0(Node, plugin, get_library_uri);
LILV_WRAP0(Node, plugin, get_name);
LILV_WRAP0(PluginClass, plugin, get_class);
LILV_WRAP1(Nodes, plugin, get_value, Node, pred);
LILV_WRAP1(bool, plugin, has_feature, Node, feature_uri);
LILV_WRAP0(Nodes, plugin, get_supported_features);
LILV_WRAP0(Nodes, plugin, get_required_features);
LILV_WRAP0(Nodes, plugin, get_optional_features);
LILV_WRAP0(unsigned, plugin, get_num_ports);
LILV_WRAP0(bool, plugin, has_latency);
LILV_WRAP0(unsigned, plugin, get_latency_port_index);
LILV_WRAP0(Node, plugin, get_author_name);
LILV_WRAP0(Node, plugin, get_author_email);
LILV_WRAP0(Node, plugin, get_author_homepage);
LILV_WRAP0(bool, plugin, is_replaced);
LILV_WRAP0(Nodes, plugin, get_extension_data);
LILV_WRAP0(UIs, plugin, get_uis);

inline Port get_port_by_index(unsigned index) {
return Port(me, lilv_plugin_get_port_by_index(me, index));
}

inline Port get_port_by_symbol(LilvNode* symbol) {
return Port(me, lilv_plugin_get_port_by_symbol(me, symbol));
}

inline void get_port_ranges_float(float* min_values,
float* max_values,
float* def_values) {
return lilv_plugin_get_port_ranges_float(
me, min_values, max_values, def_values);
}

inline unsigned get_num_ports_of_class(LilvNode* class_1,
LilvNode* class_2) {
// TODO: varargs
return lilv_plugin_get_num_ports_of_class(me, class_1, class_2, NULL);
}

const LilvPlugin* me;
};

struct Plugins {
LILV_WRAP_COLL(Plugins, Plugin, plugins);
LILV_WRAP1(const Plugin, plugins, get_by_uri, const LilvNode*, uri);
};

struct Instance {
inline Instance(LilvInstance* instance) : me(instance) {}

LILV_DEPRECATED
inline Instance(Plugin plugin, double sample_rate) {
me = lilv_plugin_instantiate(plugin, sample_rate, NULL);
}

LILV_DEPRECATED inline Instance(Plugin plugin,
double sample_rate,
LV2_Feature* const* features) {
me = lilv_plugin_instantiate(plugin, sample_rate, features);
}

static inline Instance* create(Plugin plugin,
double sample_rate,
LV2_Feature* const* features) {
LilvInstance* me = lilv_plugin_instantiate(
plugin, sample_rate, features);

return me ? new Instance(me) : NULL;
}

LILV_WRAP_CONVERSION(LilvInstance);

LILV_WRAP2_VOID(instance, connect_port,
unsigned, port_index,
void*, data_location);

LILV_WRAP0_VOID(instance, activate);
LILV_WRAP1_VOID(instance, run, unsigned, sample_count);
LILV_WRAP0_VOID(instance, deactivate);

inline const void* get_extension_data(const char* uri) {
return lilv_instance_get_extension_data(me, uri);
}

inline const LV2_Descriptor* get_descriptor() {
return lilv_instance_get_descriptor(me);
}

inline LV2_Handle get_handle() {
return lilv_instance_get_handle(me);
}

LilvInstance* me;
};

struct World {
inline World() : me(lilv_world_new()) {}
inline ~World() { lilv_world_free(me); }

inline LilvNode* new_uri(const char* uri) {
return lilv_new_uri(me, uri);
}
inline LilvNode* new_string(const char* str) {
return lilv_new_string(me, str);
}
inline LilvNode* new_int(int val) {
return lilv_new_int(me, val);
}
inline LilvNode* new_float(float val) {
return lilv_new_float(me, val);
}
inline LilvNode* new_bool(bool val) {
return lilv_new_bool(me, val);
}
inline Nodes find_nodes(const LilvNode* subject,
const LilvNode* predicate,
const LilvNode* object) {
return lilv_world_find_nodes(me, subject, predicate, object);
}

LILV_WRAP2_VOID(world, set_option, const char*, uri, LilvNode*, value);
LILV_WRAP0_VOID(world, load_all);
LILV_WRAP1_VOID(world, load_bundle, LilvNode*, bundle_uri);
LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class);
LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes);
LILV_WRAP0(const Plugins, world, get_all_plugins);

LilvWorld* me;
};

} /* namespace Lilv */

#endif /* LILV_LILVMM_HPP */

+ 214
- 0
source/libs/lilv/lilv-0.14.4/src/collections.c View File

@@ -0,0 +1,214 @@
/*
Copyright 2008-2011 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 "lilv_internal.h"

int
lilv_ptr_cmp(const void* a, const void* b, void* user_data)
{
return (intptr_t)a - (intptr_t)b;
}

int
lilv_resource_node_cmp(const void* a, const void* b, void* user_data)
{
const SordNode* an = ((const LilvNode*)a)->node;
const SordNode* bn = ((const LilvNode*)b)->node;
return (intptr_t)an - (intptr_t)bn;
}

/* Generic collection functions */

static inline LilvCollection*
lilv_collection_new(ZixComparator cmp, ZixDestroyFunc destructor)
{
return zix_tree_new(false, cmp, NULL, destructor);
}

void
lilv_collection_free(LilvCollection* coll)
{
if (coll)
zix_tree_free((ZixTree*)coll);
}

unsigned
lilv_collection_size(const LilvCollection* coll)
{
return (coll ? zix_tree_size((const ZixTree*)coll) : 0);
}

LilvIter*
lilv_collection_begin(const LilvCollection* collection)
{
if (collection) {
return (LilvIter*)zix_tree_begin((ZixTree*)collection);
}
return NULL;
}

void*
lilv_collection_get(const LilvCollection* collection,
const LilvIter* i)
{
return zix_tree_get((ZixTreeIter*)i);
}

/* Constructors */

LilvScalePoints*
lilv_scale_points_new(void)
{
return lilv_collection_new(lilv_ptr_cmp,
(ZixDestroyFunc)lilv_scale_point_free);
}

LilvNodes*
lilv_nodes_new(void)
{
return lilv_collection_new(lilv_ptr_cmp,
(ZixDestroyFunc)lilv_node_free);
}

LilvUIs*
lilv_uis_new(void)
{
return lilv_collection_new(lilv_header_compare_by_uri,
(ZixDestroyFunc)lilv_ui_free);
}

LilvPluginClasses*
lilv_plugin_classes_new(void)
{
return lilv_collection_new(lilv_header_compare_by_uri,
(ZixDestroyFunc)lilv_plugin_class_free);
}

/* URI based accessors (for collections of things with URIs) */

LILV_API
const LilvPluginClass*
lilv_plugin_classes_get_by_uri(const LilvPluginClasses* coll,
const LilvNode* uri)
{
return (LilvPluginClass*)lilv_collection_get_by_uri(
(const ZixTree*)coll, uri);
}

LILV_API
const LilvUI*
lilv_uis_get_by_uri(const LilvUIs* coll, const LilvNode* uri)
{
return (LilvUI*)lilv_collection_get_by_uri((const ZixTree*)coll, uri);
}

/* Plugins */

LilvPlugins*
lilv_plugins_new(void)
{
return lilv_collection_new(lilv_header_compare_by_uri, NULL);
}

LILV_API
const LilvPlugin*
lilv_plugins_get_by_uri(const LilvPlugins* list, const LilvNode* uri)
{
return (LilvPlugin*)lilv_collection_get_by_uri((const ZixTree*)list, uri);
}

/* Nodes */

LILV_API
bool
lilv_nodes_contains(const LilvNodes* list, const LilvNode* value)
{
LILV_FOREACH(nodes, i, list)
if (lilv_node_equals(lilv_nodes_get(list, i), value))
return true;

return false;
}

/* Iterator */

#define LILV_COLLECTION_IMPL(prefix, CT, ET) \
LILV_API \
unsigned \
prefix##_size(const CT* collection) { \
return lilv_collection_size(collection); \
} \
\
LILV_API \
LilvIter* \
prefix##_begin(const CT* collection) { \
return lilv_collection_begin(collection); \
} \
\
LILV_API \
const ET* \
prefix##_get(const CT* collection, LilvIter* i) { \
return (ET*)lilv_collection_get(collection, i); \
} \
\
LILV_API \
LilvIter* \
prefix##_next(const CT* collection, LilvIter* i) { \
return zix_tree_iter_next((ZixTreeIter*)i); \
} \
\
LILV_API \
bool \
prefix##_is_end(const CT* collection, LilvIter* i) { \
return zix_tree_iter_is_end((ZixTreeIter*)i); \
}

LILV_COLLECTION_IMPL(lilv_plugin_classes, LilvPluginClasses, LilvPluginClass)
LILV_COLLECTION_IMPL(lilv_scale_points, LilvScalePoints, LilvScalePoint)
LILV_COLLECTION_IMPL(lilv_uis, LilvUIs, LilvUI)
LILV_COLLECTION_IMPL(lilv_nodes, LilvNodes, LilvNode)
LILV_COLLECTION_IMPL(lilv_plugins, LilvPlugins, LilvPlugin)

LILV_API
void
lilv_plugin_classes_free(LilvPluginClasses* collection) {
lilv_collection_free(collection);
}

LILV_API
void
lilv_scale_points_free(LilvScalePoints* collection) {
lilv_collection_free(collection);
}

LILV_API
void
lilv_uis_free(LilvUIs* collection) {
lilv_collection_free(collection);
}

LILV_API
void
lilv_nodes_free(LilvNodes* collection) {
lilv_collection_free(collection);
}

LILV_API
LilvNode*
lilv_nodes_get_first(const LilvNodes* collection) {
return (LilvNode*)lilv_collection_get(collection,
lilv_collection_begin(collection));
}

+ 126
- 0
source/libs/lilv/lilv-0.14.4/src/instance.c View File

@@ -0,0 +1,126 @@
/*
Copyright 2007-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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lilv_internal.h"

LILV_API
LilvInstance*
lilv_plugin_instantiate(const LilvPlugin* plugin,
double sample_rate,
const LV2_Feature*const* features)
{
lilv_plugin_load_if_necessary(plugin);

LilvInstance* result = NULL;

const LV2_Feature** local_features = NULL;
if (features == NULL) {
local_features = (const LV2_Feature**)malloc(sizeof(LV2_Feature));
local_features[0] = NULL;
}

const LilvNode* const lib_uri = lilv_plugin_get_library_uri(plugin);
const LilvNode* const bundle_uri = lilv_plugin_get_bundle_uri(plugin);

const char* bundle_path = lilv_uri_to_path(
lilv_node_as_uri(lilv_plugin_get_bundle_uri(plugin)));

LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features);
if (!lib) {
return NULL;
}

// Parse bundle URI to use as base URI
const char* bundle_uri_str = lilv_node_as_uri(bundle_uri);
SerdURI base_uri;
if (serd_uri_parse((const uint8_t*)bundle_uri_str, &base_uri)) {
lilv_lib_close(lib);
return NULL;
}

// Search for plugin by URI
for (uint32_t i = 0; true; ++i) {
const LV2_Descriptor* ld = lilv_lib_get_plugin(lib, i);
if (!ld) {
LILV_ERRORF("No plugin <%s> in <%s>\n",
lilv_node_as_uri(lilv_plugin_get_uri(plugin)),
lilv_node_as_uri(lib_uri));
lilv_lib_close(lib);
break; // return NULL
}

// Resolve library plugin URI against base URI
SerdURI abs_uri;
SerdNode abs_uri_node = serd_node_new_uri_from_string(
(const uint8_t*)ld->URI, &base_uri, &abs_uri);
if (!abs_uri_node.buf) {
LILV_ERRORF("Failed to parse plugin URI `%s'\n", ld->URI);
lilv_lib_close(lib);
break;
}

if (!strcmp((const char*)abs_uri_node.buf,
lilv_node_as_uri(lilv_plugin_get_uri(plugin)))) {
// Create LilvInstance to return
result = (LilvInstance*)malloc(sizeof(LilvInstance));
result->lv2_descriptor = ld;
result->lv2_handle = ld->instantiate(
ld, sample_rate, bundle_path,
(features) ? features : local_features);
result->pimpl = lib;
serd_node_free(&abs_uri_node);
break;
} else {
serd_node_free(&abs_uri_node);
}
}

if (result) {
// Failed to instantiate
if (result->lv2_handle == NULL) {
free(result);
return NULL;
}

// "Connect" all ports to NULL (catches bugs)
for (uint32_t i = 0; i < lilv_plugin_get_num_ports(plugin); ++i)
result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL);
}

free(local_features);

return result;
}

LILV_API
void
lilv_instance_free(LilvInstance* instance)
{
if (!instance)
return;

instance->lv2_descriptor->cleanup(instance->lv2_handle);
instance->lv2_descriptor = NULL;
lilv_lib_close((LilvLib*)instance->pimpl);
instance->pimpl = NULL;
free(instance);
}


+ 111
- 0
source/libs/lilv/lilv-0.14.4/src/lib.c View File

@@ -0,0 +1,111 @@
/*
Copyright 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 "lilv_internal.h"

LilvLib*
lilv_lib_open(LilvWorld* world,
const LilvNode* uri,
const char* bundle_path,
const LV2_Feature*const* features)
{
ZixTreeIter* i = NULL;
const struct LilvHeader key = { world, (LilvNode*)uri };
if (!zix_tree_find(world->libs, &key, &i)) {
LilvLib* llib = (LilvLib*)zix_tree_get(i);
++llib->refs;
return llib;
}

const char* const lib_uri = lilv_node_as_uri(uri);
const char* const lib_path = lilv_uri_to_path(lib_uri);
if (!lib_path) {
return NULL;
}

dlerror();
void* lib = dlopen(lib_path, RTLD_NOW);
if (!lib) {
LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror());
return NULL;
}

LV2_Descriptor_Function df = (LV2_Descriptor_Function)
lilv_dlfunc(lib, "lv2_descriptor");

#ifdef LILV_NEW_LV2
LV2_Lib_Descriptor_Function ldf = (LV2_Lib_Descriptor_Function)
lilv_dlfunc(lib, "lv2_lib_descriptor");

const LV2_Lib_Descriptor* desc = NULL;
if (ldf) {
desc = ldf(bundle_path, features);
if (!desc) {
LILV_ERRORF("Call to `lv2_lib_descriptor' in %s failed\n", lib_path);
return NULL;
}
} else
#endif
if (!df) {
LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n",
lib_path);
dlclose(lib);
return NULL;
}

LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib));
llib->world = world;
llib->uri = lilv_node_duplicate(uri);
llib->lib = lib;
llib->lv2_descriptor = df;
#ifdef LILV_NEW_LV2
llib->desc = desc;
#endif
llib->refs = 1;

zix_tree_insert(world->libs, llib, NULL);
return llib;
}

const LV2_Descriptor*
lilv_lib_get_plugin(LilvLib* lib, uint32_t index)
{
if (lib->lv2_descriptor) {
return lib->lv2_descriptor(index);
}
#ifdef LILV_NEW_LV2
if (lib->desc) {
return lib->desc->get_plugin(lib->desc->handle, index);
}
#endif
return NULL;
}

void
lilv_lib_close(LilvLib* lib)
{
if (--lib->refs == 0) {
dlclose(lib->lib);

ZixTreeIter* i = NULL;
if (lib->world->libs && !zix_tree_find(lib->world->libs, lib, &i)) {
zix_tree_remove(lib->world->libs, i);
}

lilv_node_free(lib->uri);
free(lib);
}
}

+ 382
- 0
source/libs/lilv/lilv-0.14.4/src/lilv_internal.h View File

@@ -0,0 +1,382 @@
/*
Copyright 2007-2011 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.
*/

#ifndef LILV_INTERNAL_H
#define LILV_INTERNAL_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <float.h>

#ifdef _WIN32
# 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
# define NAN INFINITY - INFINITY
# define snprintf _snprintf
# endif
static inline char* dlerror(void) { return "Unknown error"; }
#else
# include <dlfcn.h>
#endif

#include "serd/serd.h"
#include "sord/sord.h"

#include "zix/tree.h"

#include "lilv_config.h"
#include "lilv/lilv.h"

#ifdef LILV_DYN_MANIFEST
# include "lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h"
#endif

/*
*
* Types
*
*/

typedef struct LilvSpecImpl LilvSpec;

typedef void LilvCollection;

struct LilvPortImpl {
SordNode* node; ///< RDF node
uint32_t index; ///< lv2:index
LilvNode* symbol; ///< lv2:symbol
LilvNodes* classes; ///< rdf:type
};

struct LilvSpecImpl {
SordNode* spec;
SordNode* bundle;
LilvNodes* data_uris;
struct LilvSpecImpl* next;
};

/**
Header of an LilvPlugin, LilvPluginClass, or LilvUI.
Any of these structs may be safely casted to LilvHeader, which is used to
implement collections using the same comparator.
*/
struct LilvHeader {
LilvWorld* world;
LilvNode* uri;
};

#ifdef LILV_DYN_MANIFEST
typedef struct {
LilvNode* bundle;
void* lib;
LV2_Dyn_Manifest_Handle handle;
uint32_t refs;
} LilvDynManifest;
#endif

typedef struct {
LilvWorld* world;
LilvNode* uri;
void* lib;
LV2_Descriptor_Function lv2_descriptor;
#ifdef LILV_NEW_LV2
const LV2_Lib_Descriptor* desc;
#endif
uint32_t refs;
} LilvLib;

struct LilvPluginImpl {
LilvWorld* world;
LilvNode* plugin_uri;
LilvNode* bundle_uri; ///< Bundle plugin was loaded from
LilvNode* binary_uri; ///< lv2:binary
#ifdef LILV_DYN_MANIFEST
LilvDynManifest* dynmanifest;
#endif
const LilvPluginClass* plugin_class;
LilvNodes* data_uris; ///< rdfs::seeAlso
LilvPort** ports;
uint32_t num_ports;
bool loaded;
bool replaced;
};

struct LilvPluginClassImpl {
LilvWorld* world;
LilvNode* uri;
LilvNode* parent_uri;
LilvNode* label;
};

struct LilvInstancePimpl {
LilvWorld* world;
LilvLib* lib;
};

typedef struct {
bool dyn_manifest;
bool filter_language;
} LilvOptions;

struct LilvWorldImpl {
SordWorld* world;
SordModel* model;
SerdReader* reader;
unsigned n_read_files;
LilvPluginClass* lv2_plugin_class;
LilvPluginClasses* plugin_classes;
LilvSpec* specs;
LilvPlugins* plugins;
LilvNodes* loaded_files;
ZixTree* libs;
struct {
SordNode* dc_replaces;
SordNode* dman_DynManifest;
SordNode* doap_name;
SordNode* lv2_Plugin;
SordNode* lv2_Specification;
SordNode* lv2_appliesTo;
SordNode* lv2_binary;
SordNode* lv2_default;
SordNode* lv2_designation;
SordNode* lv2_extensionData;
SordNode* lv2_index;
SordNode* lv2_maximum;
SordNode* lv2_minimum;
SordNode* lv2_name;
SordNode* lv2_optionalFeature;
SordNode* lv2_port;
SordNode* lv2_portProperty;
SordNode* lv2_reportsLatency;
SordNode* lv2_requiredFeature;
SordNode* lv2_symbol;
SordNode* null_uri;
SordNode* pset_value;
SordNode* rdf_a;
SordNode* rdf_value;
SordNode* rdfs_Class;
SordNode* rdfs_label;
SordNode* rdfs_seeAlso;
SordNode* rdfs_subClassOf;
SordNode* xsd_base64Binary;
SordNode* xsd_boolean;
SordNode* xsd_decimal;
SordNode* xsd_double;
SordNode* xsd_integer;
} uris;
LilvOptions opt;
};

typedef enum {
LILV_VALUE_URI,
LILV_VALUE_STRING,
LILV_VALUE_INT,
LILV_VALUE_FLOAT,
LILV_VALUE_BOOL,
LILV_VALUE_BLANK,
LILV_VALUE_BLOB
} LilvNodeType;

struct LilvNodeImpl {
LilvWorld* world;
SordNode* node;
LilvNodeType type;
union {
int int_val;
float float_val;
bool bool_val;
} val;
};

struct LilvScalePointImpl {
LilvNode* value;
LilvNode* label;
};

struct LilvUIImpl {
LilvWorld* world;
LilvNode* uri;
LilvNode* bundle_uri;
LilvNode* binary_uri;
LilvNodes* classes;
};

/*
*
* Functions
*
*/

LilvPort* lilv_port_new(LilvWorld* world,
const SordNode* node,
uint32_t index,
const char* symbol);
void lilv_port_free(const LilvPlugin* plugin, LilvPort* port);

LilvPlugin* lilv_plugin_new(LilvWorld* world,
LilvNode* uri,
LilvNode* bundle_uri);
void lilv_plugin_load_if_necessary(const LilvPlugin* p);
void lilv_plugin_free(LilvPlugin* plugin);
LilvNode* lilv_plugin_get_unique(const LilvPlugin* p,
const SordNode* subject,
const SordNode* predicate);

void lilv_collection_free(LilvCollection* collection);
unsigned lilv_collection_size(const LilvCollection* collection);
LilvIter* lilv_collection_begin(const LilvCollection* collection);
void* lilv_collection_get(const LilvCollection* collection,
const LilvIter* i);

LilvPluginClass* lilv_plugin_class_new(LilvWorld* world,
const SordNode* parent_uri,
const SordNode* uri,
const char* label);

void lilv_plugin_class_free(LilvPluginClass* plugin_class);

LilvLib*
lilv_lib_open(LilvWorld* world,
const LilvNode* uri,
const char* bundle_path,
const LV2_Feature*const* features);

const LV2_Descriptor* lilv_lib_get_plugin(LilvLib* lib, uint32_t index);
void lilv_lib_close(LilvLib* lib);

LilvNodes* lilv_nodes_new(void);
LilvPlugins* lilv_plugins_new(void);
LilvScalePoints* lilv_scale_points_new(void);
LilvPluginClasses* lilv_plugin_classes_new(void);
LilvUIs* lilv_uis_new(void);

const uint8_t* lilv_world_blank_node_prefix(LilvWorld* world);
void lilv_world_load_file(LilvWorld* world, const char* file_uri);

LilvUI* lilv_ui_new(LilvWorld* world,
LilvNode* uri,
LilvNode* type_uri,
LilvNode* binary_uri);

void lilv_ui_free(LilvUI* ui);

LilvNode* lilv_node_new(LilvWorld* world,
LilvNodeType type,
const char* val);
LilvNode* lilv_node_new_from_node(LilvWorld* world,
const SordNode* node);
const SordNode* lilv_node_as_node(const LilvNode* value);

int lilv_header_compare_by_uri(const void* a, const void* b, void* user_data);

int
lilv_ptr_cmp(const void* a, const void* b, void* user_data);

int
lilv_resource_node_cmp(const void* a, const void* b, void* user_data);

struct LilvHeader*
lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri);

LilvScalePoint* lilv_scale_point_new(LilvNode* value, LilvNode* label);
void lilv_scale_point_free(LilvScalePoint* point);

SordIter*
lilv_world_query_internal(LilvWorld* world,
const SordNode* subject,
const SordNode* predicate,
const SordNode* object);

LilvNodes*
lilv_world_query_values_internal(LilvWorld* world,
const SordNode* subject,
const SordNode* predicate,
const SordNode* object);

#define FOREACH_MATCH(iter) \
for (; !sord_iter_end(iter); sord_iter_next(iter))

LilvNodes* lilv_nodes_from_stream_objects(LilvWorld* w,
SordIter* stream,
SordQuadIndex field);

char* lilv_strjoin(const char* first, ...);
char* lilv_strdup(const char* str);
char* lilv_get_lang(void);
char* lilv_expand(const char* path);
char* lilv_dirname(const char* path);
int lilv_copy_file(const char* src, const char* dst);
bool lilv_path_exists(const char* path, void* ignored);
char* lilv_path_absolute(const char* path);
bool lilv_path_is_absolute(const char* path);
char* lilv_get_latest_copy(const char* path, const char* copy_path);
char* lilv_path_relative_to(const char* path, const char* base);
bool lilv_path_is_child(const char* path, const char* dir);
int lilv_flock(FILE* file, bool lock);
char* lilv_realpath(const char* path);
int lilv_symlink(const char* oldpath, const char* newpath);
int lilv_mkdir_p(const char* path);
char* lilv_path_join(const char* a, const char* b);
bool lilv_file_equals(const char* a_path, const char* b_path);

char*
lilv_find_free_path(const char* in_path,
bool (*exists)(const char*, void*), void* user_data);

void
lilv_dir_for_each(const char* path,
void* data,
void (*f)(const char* path, const char* name, void* data));

typedef void (*VoidFunc)(void);

/** dlsym wrapper to return a function pointer (without annoying warning) */
static inline VoidFunc
lilv_dlfunc(void* handle, const char* symbol)
{
typedef VoidFunc (*VoidFuncGetter)(void*, const char*);
VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym;
return dlfunc(handle, symbol);
}

#ifdef LILV_DYN_MANIFEST
static const LV2_Feature* const dman_features = { NULL };
#endif

#define LILV_ERROR(str) fprintf(stderr, "%s(): error: " str, \
__func__)
#define LILV_ERRORF(fmt, ...) fprintf(stderr, "%s(): error: " fmt, \
__func__, __VA_ARGS__)
#define LILV_WARN(str) fprintf(stderr, "%s(): warning: " str, \
__func__)
#define LILV_WARNF(fmt, ...) fprintf(stderr, "%s(): warning: " fmt, \
__func__, __VA_ARGS__)

#ifdef __cplusplus
}
#endif

#endif /* LILV_INTERNAL_H */

+ 396
- 0
source/libs/lilv/lilv-0.14.4/src/node.c View File

@@ -0,0 +1,396 @@
/*
Copyright 2007-2011 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 <assert.h>
#include <stdlib.h>
#include <string.h>

#include "lilv_internal.h"

static void
lilv_node_set_numerics_from_string(LilvNode* val, size_t len)
{
const char* str = (const char*)sord_node_get_string(val->node);
char* endptr;

switch (val->type) {
case LILV_VALUE_URI:
case LILV_VALUE_BLANK:
case LILV_VALUE_STRING:
case LILV_VALUE_BLOB:
break;
case LILV_VALUE_INT:
val->val.int_val = strtol(str, &endptr, 10);
break;
case LILV_VALUE_FLOAT:
val->val.float_val = serd_strtod(str, &endptr);
break;
case LILV_VALUE_BOOL:
val->val.bool_val = !strcmp(str, "true");
break;
}
}

/** Note that if @a type is numeric or boolean, the returned value is corrupt
* until lilv_node_set_numerics_from_string is called. It is not
* automatically called from here to avoid overhead and imprecision when the
* exact string value is known.
*/
LilvNode*
lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str)
{
LilvNode* val = (LilvNode*)malloc(sizeof(LilvNode));
val->world = world;
val->type = type;

const uint8_t* ustr = (const uint8_t*)str;
switch (type) {
case LILV_VALUE_URI:
val->node = sord_new_uri(world->world, ustr);
break;
case LILV_VALUE_BLANK:
val->node = sord_new_blank(world->world, ustr);
break;
case LILV_VALUE_STRING:
val->node = sord_new_literal(world->world, NULL, ustr, NULL);
break;
case LILV_VALUE_INT:
val->node = sord_new_literal(
world->world, world->uris.xsd_integer, ustr, NULL);
break;
case LILV_VALUE_FLOAT:
val->node = sord_new_literal(
world->world, world->uris.xsd_decimal, ustr, NULL);
break;
case LILV_VALUE_BOOL:
val->node = sord_new_literal(
world->world, world->uris.xsd_boolean, ustr, NULL);
break;
case LILV_VALUE_BLOB:
val->node = sord_new_literal(
world->world, world->uris.xsd_base64Binary, ustr, NULL);
break;
}

return val;
}

/** Create a new LilvNode from @a node, or return NULL if impossible */
LilvNode*
lilv_node_new_from_node(LilvWorld* world, const SordNode* node)
{
LilvNode* result = NULL;
SordNode* datatype_uri = NULL;
LilvNodeType type = LILV_VALUE_STRING;
size_t len = 0;

switch (sord_node_get_type(node)) {
case SORD_URI:
result = (LilvNode*)malloc(sizeof(LilvNode));
result->world = (LilvWorld*)world;
result->type = LILV_VALUE_URI;
result->node = sord_node_copy(node);
break;
case SORD_BLANK:
result = (LilvNode*)malloc(sizeof(LilvNode));
result->world = (LilvWorld*)world;
result->type = LILV_VALUE_BLANK;
result->node = sord_node_copy(node);
break;
case SORD_LITERAL:
datatype_uri = sord_node_get_datatype(node);
if (datatype_uri) {
if (sord_node_equals(datatype_uri, world->uris.xsd_boolean))
type = LILV_VALUE_BOOL;
else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal)
|| sord_node_equals(datatype_uri, world->uris.xsd_double))
type = LILV_VALUE_FLOAT;
else if (sord_node_equals(datatype_uri, world->uris.xsd_integer))
type = LILV_VALUE_INT;
else if (sord_node_equals(datatype_uri,
world->uris.xsd_base64Binary))
type = LILV_VALUE_BLOB;
else
LILV_ERRORF("Unknown datatype `%s'\n",
sord_node_get_string(datatype_uri));
}
result = lilv_node_new(
world, type, (const char*)sord_node_get_string_counted(node, &len));
lilv_node_set_numerics_from_string(result, len);
break;
default:
assert(false);
}

return result;
}

LILV_API
LilvNode*
lilv_new_uri(LilvWorld* world, const char* uri)
{
return lilv_node_new(world, LILV_VALUE_URI, uri);
}

LILV_API
LilvNode*
lilv_new_string(LilvWorld* world, const char* str)
{
return lilv_node_new(world, LILV_VALUE_STRING, str);
}

LILV_API
LilvNode*
lilv_new_int(LilvWorld* world, int val)
{
char str[32];
snprintf(str, sizeof(str), "%d", val);
LilvNode* ret = lilv_node_new(world, LILV_VALUE_INT, str);
ret->val.int_val = val;
return ret;
}

LILV_API
LilvNode*
lilv_new_float(LilvWorld* world, float val)
{
char str[32];
snprintf(str, sizeof(str), "%f", val);
LilvNode* ret = lilv_node_new(world, LILV_VALUE_FLOAT, str);
ret->val.float_val = val;
return ret;
}

LILV_API
LilvNode*
lilv_new_bool(LilvWorld* world, bool val)
{
LilvNode* ret = lilv_node_new(world, LILV_VALUE_BOOL,
val ? "true" : "false");
ret->val.bool_val = val;
return ret;
}

LILV_API
LilvNode*
lilv_node_duplicate(const LilvNode* val)
{
if (!val) {
return NULL;
}

LilvNode* result = (LilvNode*)malloc(sizeof(LilvNode));
result->world = val->world;
result->node = sord_node_copy(val->node);
result->val = val->val;
result->type = val->type;
return result;
}

LILV_API
void
lilv_node_free(LilvNode* val)
{
if (val) {
sord_node_free(val->world->world, val->node);
free(val);
}
}

LILV_API
bool
lilv_node_equals(const LilvNode* value, const LilvNode* other)
{
if (value == NULL && other == NULL)
return true;
else if (value == NULL || other == NULL)
return false;
else if (value->type != other->type)
return false;

switch (value->type) {
case LILV_VALUE_URI:
case LILV_VALUE_BLANK:
case LILV_VALUE_STRING:
case LILV_VALUE_BLOB:
return sord_node_equals(value->node, other->node);
case LILV_VALUE_INT:
return (value->val.int_val == other->val.int_val);
case LILV_VALUE_FLOAT:
return (value->val.float_val == other->val.float_val);
case LILV_VALUE_BOOL:
return (value->val.bool_val == other->val.bool_val);
}

return false; /* shouldn't get here */
}

LILV_API
char*
lilv_node_get_turtle_token(const LilvNode* value)
{
const char* str = (const char*)sord_node_get_string(value->node);
size_t len = 0;
char* result = NULL;
SerdNode node;

switch (value->type) {
case LILV_VALUE_URI:
len = strlen(str) + 3;
result = (char*)calloc(len, 1);
snprintf(result, len, "<%s>", str);
break;
case LILV_VALUE_BLANK:
len = strlen(str) + 3;
result = (char*)calloc(len, 1);
snprintf(result, len, "_:%s", str);
break;
case LILV_VALUE_STRING:
case LILV_VALUE_BOOL:
case LILV_VALUE_BLOB:
result = lilv_strdup(str);
break;
case LILV_VALUE_INT:
node = serd_node_new_integer(value->val.int_val);
result = (char*)node.buf;
break;
case LILV_VALUE_FLOAT:
node = serd_node_new_decimal(value->val.float_val, 8);
result = (char*)node.buf;
break;
}

return result;
}

LILV_API
bool
lilv_node_is_uri(const LilvNode* value)
{
return (value && value->type == LILV_VALUE_URI);
}

LILV_API
const char*
lilv_node_as_uri(const LilvNode* value)
{
assert(lilv_node_is_uri(value));
return (const char*)sord_node_get_string(value->node);
}

const SordNode*
lilv_node_as_node(const LilvNode* value)
{
assert(lilv_node_is_uri(value));
return value->node;
}

LILV_API
bool
lilv_node_is_blank(const LilvNode* value)
{
return (value && value->type == LILV_VALUE_BLANK);
}

LILV_API
const char*
lilv_node_as_blank(const LilvNode* value)
{
assert(lilv_node_is_blank(value));
return (const char*)sord_node_get_string(value->node);
}

LILV_API
bool
lilv_node_is_literal(const LilvNode* value)
{
if (!value)
return false;

switch (value->type) {
case LILV_VALUE_STRING:
case LILV_VALUE_INT:
case LILV_VALUE_FLOAT:
return true;
default:
return false;
}
}

LILV_API
bool
lilv_node_is_string(const LilvNode* value)
{
return (value && value->type == LILV_VALUE_STRING);
}

LILV_API
const char*
lilv_node_as_string(const LilvNode* value)
{
return value ? (const char*)sord_node_get_string(value->node) : NULL;
}

LILV_API
bool
lilv_node_is_int(const LilvNode* value)
{
return (value && value->type == LILV_VALUE_INT);
}

LILV_API
int
lilv_node_as_int(const LilvNode* value)
{
assert(value);
assert(lilv_node_is_int(value));
return value->val.int_val;
}

LILV_API
bool
lilv_node_is_float(const LilvNode* value)
{
return (value && value->type == LILV_VALUE_FLOAT);
}

LILV_API
float
lilv_node_as_float(const LilvNode* value)
{
assert(lilv_node_is_float(value) || lilv_node_is_int(value));
if (lilv_node_is_float(value)) {
return value->val.float_val;
} else { // lilv_node_is_int(value)
return (float)value->val.int_val;
}
}

LILV_API
bool
lilv_node_is_bool(const LilvNode* value)
{
return (value && value->type == LILV_VALUE_BOOL);
}

LILV_API
bool
lilv_node_as_bool(const LilvNode* value)
{
assert(value);
assert(lilv_node_is_bool(value));
return value->val.bool_val;
}

+ 1077
- 0
source/libs/lilv/lilv-0.14.4/src/plugin.c
File diff suppressed because it is too large
View File


+ 96
- 0
source/libs/lilv/lilv-0.14.4/src/pluginclass.c View File

@@ -0,0 +1,96 @@
/*
Copyright 2007-2011 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 <assert.h>
#include <stdlib.h>
#include <string.h>

#include "lilv_internal.h"

LilvPluginClass*
lilv_plugin_class_new(LilvWorld* world,
const SordNode* parent_node,
const SordNode* uri,
const char* label)
{
if (parent_node && sord_node_get_type(parent_node) != SORD_URI) {
return NULL; // Not an LV2 plugin superclass (FIXME: discover properly)
}
LilvPluginClass* pc = (LilvPluginClass*)malloc(sizeof(LilvPluginClass));
pc->world = world;
pc->uri = lilv_node_new_from_node(world, uri);
pc->label = lilv_node_new(world, LILV_VALUE_STRING, label);
pc->parent_uri = (parent_node)
? lilv_node_new_from_node(world, parent_node)
: NULL;
return pc;
}

void
lilv_plugin_class_free(LilvPluginClass* plugin_class)
{
assert(plugin_class->uri);
lilv_node_free(plugin_class->uri);
lilv_node_free(plugin_class->parent_uri);
lilv_node_free(plugin_class->label);
free(plugin_class);
}

LILV_API
const LilvNode*
lilv_plugin_class_get_parent_uri(const LilvPluginClass* plugin_class)
{
if (plugin_class->parent_uri)
return plugin_class->parent_uri;
else
return NULL;
}

LILV_API
const LilvNode*
lilv_plugin_class_get_uri(const LilvPluginClass* plugin_class)
{
assert(plugin_class->uri);
return plugin_class->uri;
}

LILV_API
const LilvNode*
lilv_plugin_class_get_label(const LilvPluginClass* plugin_class)
{
return plugin_class->label;
}

LILV_API
LilvPluginClasses*
lilv_plugin_class_get_children(const LilvPluginClass* plugin_class)
{
// Returned list doesn't own categories
LilvPluginClasses* all = plugin_class->world->plugin_classes;
LilvPluginClasses* result = zix_tree_new(false, lilv_ptr_cmp, NULL, NULL);

for (ZixTreeIter* i = zix_tree_begin((ZixTree*)all);
i != zix_tree_end((ZixTree*)all);
i = zix_tree_iter_next(i)) {
const LilvPluginClass* c = (LilvPluginClass*)zix_tree_get(i);
const LilvNode* parent = lilv_plugin_class_get_parent_uri(c);
if (parent && lilv_node_equals(lilv_plugin_class_get_uri(plugin_class),
parent))
zix_tree_insert((ZixTree*)result, (LilvPluginClass*)c, NULL);
}

return result;
}

+ 264
- 0
source/libs/lilv/lilv-0.14.4/src/port.c View File

@@ -0,0 +1,264 @@
/*
Copyright 2007-2011 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 <assert.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lv2/event.h"

#include "lilv_internal.h"

LilvPort*
lilv_port_new(LilvWorld* world,
const SordNode* node,
uint32_t index,
const char* symbol)
{
LilvPort* port = (LilvPort*)malloc(sizeof(LilvPort));
port->node = sord_node_copy(node);
port->index = index;
port->symbol = lilv_node_new(world, LILV_VALUE_STRING, symbol);
port->classes = lilv_nodes_new();
return port;
}

void
lilv_port_free(const LilvPlugin* plugin, LilvPort* port)
{
if (port) {
sord_node_free(plugin->world->world, port->node);
lilv_nodes_free(port->classes);
lilv_node_free(port->symbol);
free(port);
}
}

LILV_API
bool
lilv_port_is_a(const LilvPlugin* plugin,
const LilvPort* port,
const LilvNode* port_class)
{
LILV_FOREACH(nodes, i, port->classes)
if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class))
return true;

return false;
}

LILV_API
bool
lilv_port_has_property(const LilvPlugin* p,
const LilvPort* port,
const LilvNode* property)
{
assert(property);
SordIter* results = lilv_world_query_internal(
p->world,
port->node,
p->world->uris.lv2_portProperty,
lilv_node_as_node(property));

const bool ret = !sord_iter_end(results);
sord_iter_free(results);
return ret;
}

LILV_API
bool
lilv_port_supports_event(const LilvPlugin* p,
const LilvPort* port,
const LilvNode* event)
{
assert(event);
SordIter* results = lilv_world_query_internal(
p->world,
port->node,
sord_new_uri(p->world->world, (const uint8_t*)LV2_EVENT__supportsEvent),
lilv_node_as_node(event));

const bool ret = !sord_iter_end(results);
sord_iter_free(results);
return ret;
}

static LilvNodes*
lilv_port_get_value_by_node(const LilvPlugin* p,
const LilvPort* port,
const SordNode* predicate)
{
assert(sord_node_get_type(predicate) == SORD_URI);

SordIter* results = lilv_world_query_internal(
p->world,
port->node,
predicate,
NULL);

return lilv_nodes_from_stream_objects(p->world, results, SORD_OBJECT);
}

LILV_API
LilvNodes*
lilv_port_get_value(const LilvPlugin* p,
const LilvPort* port,
const LilvNode* predicate)
{
if (!lilv_node_is_uri(predicate)) {
LILV_ERRORF("Predicate `%s' is not a URI\n",
sord_node_get_string(predicate->node));
return NULL;
}

return lilv_port_get_value_by_node(
p, port,
lilv_node_as_node(predicate));
}

LILV_API
uint32_t
lilv_port_get_index(const LilvPlugin* p,
const LilvPort* port)
{
return port->index;
}

LILV_API
const LilvNode*
lilv_port_get_symbol(const LilvPlugin* p,
const LilvPort* port)
{
return port->symbol;
}

LILV_API
LilvNode*
lilv_port_get_name(const LilvPlugin* p,
const LilvPort* port)
{
LilvNodes* results = lilv_port_get_value_by_node(
p, port, p->world->uris.lv2_name);

LilvNode* ret = NULL;
if (results) {
LilvNode* val = lilv_nodes_get_first(results);
if (lilv_node_is_string(val))
ret = lilv_node_duplicate(val);
lilv_nodes_free(results);
}

if (!ret)
LILV_WARNF("Plugin <%s> port has no (mandatory) doap:name\n",
lilv_node_as_string(lilv_plugin_get_uri(p)));

return ret;
}

LILV_API
const LilvNodes*
lilv_port_get_classes(const LilvPlugin* p,
const LilvPort* port)
{
return port->classes;
}

LILV_API
void
lilv_port_get_range(const LilvPlugin* p,
const LilvPort* port,
LilvNode** def,
LilvNode** min,
LilvNode** max)
{
if (def) {
LilvNodes* defaults = lilv_port_get_value_by_node(
p, port, p->world->uris.lv2_default);
*def = defaults
? lilv_node_duplicate(lilv_nodes_get_first(defaults))
: NULL;
lilv_nodes_free(defaults);
}
if (min) {
LilvNodes* minimums = lilv_port_get_value_by_node(
p, port, p->world->uris.lv2_minimum);
*min = minimums
? lilv_node_duplicate(lilv_nodes_get_first(minimums))
: NULL;
lilv_nodes_free(minimums);
}
if (max) {
LilvNodes* maximums = lilv_port_get_value_by_node(
p, port, p->world->uris.lv2_maximum);
*max = maximums
? lilv_node_duplicate(lilv_nodes_get_first(maximums))
: NULL;
lilv_nodes_free(maximums);
}
}

LILV_API
LilvScalePoints*
lilv_port_get_scale_points(const LilvPlugin* p,
const LilvPort* port)
{
SordIter* points = lilv_world_query_internal(
p->world,
port->node,
sord_new_uri(p->world->world, (const uint8_t*)LV2_CORE__scalePoint),
NULL);

LilvScalePoints* ret = NULL;
if (!sord_iter_end(points))
ret = lilv_scale_points_new();

FOREACH_MATCH(points) {
const SordNode* point = sord_iter_get_node(points, SORD_OBJECT);

LilvNode* value = lilv_plugin_get_unique(
p,
point,
p->world->uris.rdf_value);

LilvNode* label = lilv_plugin_get_unique(
p,
point,
p->world->uris.rdfs_label);

if (value && label) {
zix_tree_insert(
(ZixTree*)ret, lilv_scale_point_new(value, label), NULL);
}
}
sord_iter_free(points);

assert(!ret || lilv_nodes_size(ret) > 0);
return ret;
}

LILV_API
LilvNodes*
lilv_port_get_properties(const LilvPlugin* p,
const LilvPort* port)
{
LilvNode* pred = lilv_node_new_from_node(
p->world, p->world->uris.lv2_portProperty);
LilvNodes* ret = lilv_port_get_value(p, port, pred);
lilv_node_free(pred);
return ret;
}

+ 140
- 0
source/libs/lilv/lilv-0.14.4/src/query.c View File

@@ -0,0 +1,140 @@
/*
Copyright 2007-2011 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 <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>

#include "lilv_internal.h"

typedef enum {
LILV_LANG_MATCH_NONE, ///< Language does not match at all
LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match
LILV_LANG_MATCH_EXACT ///< Exact (language and country) match
} LilvLangMatch;

static LilvLangMatch
lilv_lang_matches(const char* a, const char* b)
{
if (!strcmp(a, b)) {
return LILV_LANG_MATCH_EXACT;
}

const char* a_dash = strchr(a, '-');
const size_t a_lang_len = a_dash ? (size_t)(a_dash - a) : strlen(a);
const char* b_dash = strchr(b, '-');
const size_t b_lang_len = b_dash ? (size_t)(b_dash - b) : strlen(b);

if (a_lang_len == b_lang_len && !strncmp(a, b, a_lang_len)) {
return LILV_LANG_MATCH_PARTIAL;
}

return LILV_LANG_MATCH_NONE;
}

static LilvNodes*
lilv_nodes_from_stream_objects_i18n(LilvWorld* world,
SordIter* stream,
SordQuadIndex field)
{
LilvNodes* values = lilv_nodes_new();
const SordNode* nolang = NULL; // Untranslated value
const SordNode* partial = NULL; // Partial language match
char* syslang = lilv_get_lang();
FOREACH_MATCH(stream) {
const SordNode* value = sord_iter_get_node(stream, field);
if (sord_node_get_type(value) == SORD_LITERAL) {
const char* lang = sord_node_get_language(value);
LilvLangMatch lm = LILV_LANG_MATCH_NONE;
if (lang) {
lm = (syslang)
? lilv_lang_matches(lang, syslang)
: LILV_LANG_MATCH_PARTIAL;
} else {
nolang = value;
if (!syslang) {
lm = LILV_LANG_MATCH_EXACT;
}
}

if (lm == LILV_LANG_MATCH_EXACT) {
// Exact language match, add to results
zix_tree_insert((ZixTree*)values,
lilv_node_new_from_node(world, value),
NULL);
} else if (lm == LILV_LANG_MATCH_PARTIAL) {
// Partial language match, save in case we find no exact
partial = value;
}
} else {
zix_tree_insert((ZixTree*)values,
lilv_node_new_from_node(world, value),
NULL);
}
}
sord_iter_free(stream);
free(syslang);

if (lilv_nodes_size(values) > 0) {
return values;
}

const SordNode* best = nolang;
if (syslang && partial) {
// Partial language match for system language
best = partial;
} else if (!best) {
// No languages matches at all, and no untranslated value
// Use any value, if possible
best = partial;
}

if (best) {
zix_tree_insert(
(ZixTree*)values, lilv_node_new_from_node(world, best), NULL);
} else {
// No matches whatsoever
lilv_nodes_free(values);
values = NULL;
}

return values;
}

LilvNodes*
lilv_nodes_from_stream_objects(LilvWorld* world,
SordIter* stream,
SordQuadIndex field)
{
if (sord_iter_end(stream)) {
sord_iter_free(stream);
return NULL;
} else if (world->opt.filter_language) {
return lilv_nodes_from_stream_objects_i18n(world, stream, field);
} else {
LilvNodes* values = lilv_nodes_new();
FOREACH_MATCH(stream) {
const SordNode* value = sord_iter_get_node(stream, field);
LilvNode* node = lilv_node_new_from_node(world, value);
if (node) {
zix_tree_insert((ZixTree*)values, node, NULL);
}
}
sord_iter_free(stream);
return values;
}
}

+ 52
- 0
source/libs/lilv/lilv-0.14.4/src/scalepoint.c View File

@@ -0,0 +1,52 @@
/*
Copyright 2007-2011 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 "lilv_internal.h"

/** Ownership of value and label is taken */
LilvScalePoint*
lilv_scale_point_new(LilvNode* value, LilvNode* label)
{
LilvScalePoint* point = (LilvScalePoint*)malloc(
sizeof(struct LilvScalePointImpl));
point->value = value;
point->label = label;
return point;
}

void
lilv_scale_point_free(LilvScalePoint* point)
{
if (point) {
lilv_node_free(point->value);
lilv_node_free(point->label);
free(point);
}
}

LILV_API
const LilvNode*
lilv_scale_point_get_value(const LilvScalePoint* p)
{
return p->value;
}

LILV_API
const LilvNode*
lilv_scale_point_get_label(const LilvScalePoint* p)
{
return p->label;
}

+ 1097
- 0
source/libs/lilv/lilv-0.14.4/src/state.c
File diff suppressed because it is too large
View File


+ 184
- 0
source/libs/lilv/lilv-0.14.4/src/ui.c View File

@@ -0,0 +1,184 @@
/*
Copyright 2007-2011 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 <assert.h>
#include <stdlib.h>
#include <string.h>

#include "lilv_internal.h"

LilvUI*
lilv_ui_new(LilvWorld* world,
LilvNode* uri,
LilvNode* type_uri,
LilvNode* binary_uri)
{
assert(uri);
assert(type_uri);
assert(binary_uri);

LilvUI* ui = (LilvUI*)malloc(sizeof(LilvUI));
ui->world = world;
ui->uri = uri;
ui->binary_uri = binary_uri;

// FIXME: kludge
char* bundle = lilv_strdup(lilv_node_as_string(ui->binary_uri));
char* last_slash = strrchr(bundle, '/') + 1;
*last_slash = '\0';
ui->bundle_uri = lilv_new_uri(world, bundle);
free(bundle);

ui->classes = lilv_nodes_new();
zix_tree_insert((ZixTree*)ui->classes, type_uri, NULL);

return ui;
}

void
lilv_ui_free(LilvUI* ui)
{
lilv_node_free(ui->uri);
ui->uri = NULL;

lilv_node_free(ui->bundle_uri);
ui->bundle_uri = NULL;

lilv_node_free(ui->binary_uri);
ui->binary_uri = NULL;

lilv_nodes_free(ui->classes);

free(ui);
}

LILV_API
const LilvNode*
lilv_ui_get_uri(const LilvUI* ui)
{
assert(ui);
assert(ui->uri);
return ui->uri;
}

LILV_API
unsigned
lilv_ui_is_supported(const LilvUI* ui,
LilvUISupportedFunc supported_func,
const LilvNode* container_type,
const LilvNode** ui_type)
{
const LilvNodes* classes = lilv_ui_get_classes(ui);
LILV_FOREACH(nodes, c, classes) {
const LilvNode* type = lilv_nodes_get(classes, c);
const unsigned q = supported_func(lilv_node_as_uri(container_type),
lilv_node_as_uri(type));
if (q) {
if (ui_type) {
*ui_type = type;
}
return q;
}
}

return 0;
}

LILV_API
const LilvNodes*
lilv_ui_get_classes(const LilvUI* ui)
{
return ui->classes;
}

LILV_API
bool
lilv_ui_is_a(const LilvUI* ui, const LilvNode* ui_class_uri)
{
return lilv_nodes_contains(ui->classes, ui_class_uri);
}

LILV_API
const LilvNode*
lilv_ui_get_bundle_uri(const LilvUI* ui)
{
assert(ui);
assert(ui->bundle_uri);
return ui->bundle_uri;
}

LILV_API
const LilvNode*
lilv_ui_get_binary_uri(const LilvUI* ui)
{
assert(ui);
assert(ui->binary_uri);
return ui->binary_uri;
}

static LilvNodes*
lilv_ui_get_value_internal(const LilvUI* ui,
const SordNode* predicate)
{
return lilv_world_query_values_internal(
ui->world, ui->uri->node, predicate, NULL);
}

LILV_API
LilvNodes*
lilv_ui_get_supported_features(const LilvUI* ui)
{
LilvNodes* optional = lilv_ui_get_optional_features(ui);
LilvNodes* required = lilv_ui_get_required_features(ui);
LilvNodes* result = lilv_nodes_new();

LILV_FOREACH(nodes, i, optional)
zix_tree_insert((ZixTree*)result,
lilv_node_duplicate(lilv_nodes_get(optional, i)),
NULL);
LILV_FOREACH(nodes, i, required)
zix_tree_insert((ZixTree*)result,
lilv_node_duplicate(lilv_nodes_get(required, i)),
NULL);

lilv_nodes_free(optional);
lilv_nodes_free(required);

return result;
}

LILV_API
LilvNodes*
lilv_ui_get_required_features(const LilvUI* ui)
{
return lilv_ui_get_value_internal(
ui, ui->world->uris.lv2_requiredFeature);
}

LILV_API
LilvNodes*
lilv_ui_get_optional_features(const LilvUI* ui)
{
return lilv_ui_get_value_internal(
ui, ui->world->uris.lv2_optionalFeature);
}

LILV_API
LilvNodes*
lilv_ui_get_extension_data(const LilvUI* ui)
{
return lilv_ui_get_value_internal(ui, ui->world->uris.lv2_extensionData);
}

+ 604
- 0
source/libs/lilv/lilv-0.14.4/src/util.c View File

@@ -0,0 +1,604 @@
/*
Copyright 2007-2011 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.
*/

#define _POSIX_C_SOURCE 1 /* for fileno */
#define _BSD_SOURCE 1 /* for realpath, symlink */

#ifdef __APPLE__
# define _DARWIN_C_SOURCE 1 /* for flock */
#endif

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
# include <windows.h>
# include <direct.h>
# include <io.h>
# define F_OK 0
# define mkdir(path, flags) _mkdir(path)
#else
# include <dirent.h>
# include <unistd.h>
#endif

#include <sys/stat.h>
#include <sys/types.h>

#include "lilv_internal.h"

#if defined(HAVE_FLOCK) && defined(HAVE_FILENO)
# include <sys/file.h>
#endif

#ifndef PAGE_SIZE
# define PAGE_SIZE 4096
#endif

char*
lilv_strjoin(const char* first, ...)
{
size_t len = strlen(first);
char* result = (char*)malloc(len + 1);

memcpy(result, first, len);

va_list args;
va_start(args, first);
while (1) {
const char* const s = va_arg(args, const char *);
if (s == NULL)
break;

const size_t this_len = strlen(s);
if (!(result = (char*)realloc(result, len + this_len + 1))) {
free(result);
LILV_ERROR("realloc() failed\n");
return NULL;
}

memcpy(result + len, s, this_len);
len += this_len;
}
va_end(args);

result[len] = '\0';

return result;
}

char*
lilv_strdup(const char* str)
{
if (!str) {
return NULL;
}

const size_t len = strlen(str);
char* dup = (char*)malloc(len + 1);
memcpy(dup, str, len + 1);
return dup;
}

const char*
lilv_uri_to_path(const char* uri)
{
return (const char*)serd_uri_to_path((const uint8_t*)uri);
}

/** Return the current LANG converted to Turtle (i.e. RFC3066) style.
* For example, if LANG is set to "en_CA.utf-8", this returns "en-ca".
*/
char*
lilv_get_lang(void)
{
const char* const env_lang = getenv("LANG");
if (!env_lang || !strcmp(env_lang, "")
|| !strcmp(env_lang, "C") || !strcmp(env_lang, "POSIX")) {
return NULL;
}

const size_t env_lang_len = strlen(env_lang);
char* const lang = (char*)malloc(env_lang_len + 1);
for (size_t i = 0; i < env_lang_len + 1; ++i) {
if (env_lang[i] == '_') {
lang[i] = '-'; // Convert _ to -
} else if (env_lang[i] >= 'A' && env_lang[i] <= 'Z') {
lang[i] = env_lang[i] + ('a' - 'A'); // Convert to lowercase
} else if (env_lang[i] >= 'a' && env_lang[i] <= 'z') {
lang[i] = env_lang[i]; // Lowercase letter, copy verbatim
} else if (env_lang[i] >= '0' && env_lang[i] <= '9') {
lang[i] = env_lang[i]; // Digit, copy verbatim
} else if (env_lang[i] == '\0' || env_lang[i] == '.') {
// End, or start of suffix (e.g. en_CA.utf-8), finished
lang[i] = '\0';
break;
} else {
LILV_ERRORF("Illegal LANG `%s' ignored\n", env_lang);
free(lang);
return NULL;
}
}

return lang;
}

/** Append suffix to dst, update dst_len, and return the realloc'd result. */
static char*
strappend(char* dst, size_t* dst_len, const char* suffix, size_t suffix_len)
{
dst = (char*)realloc(dst, *dst_len + suffix_len + 1);
memcpy(dst + *dst_len, suffix, suffix_len);
dst[(*dst_len += suffix_len)] = '\0';
return dst;
}

/** Append the value of the environment variable var to dst. */
static char*
append_var(char* dst, size_t* dst_len, const char* var)
{
// Get value from environment
const char* val = getenv(var);
if (val) { // Value found, append it
return strappend(dst, dst_len, val, strlen(val));
} else { // No value found, append variable reference as-is
return strappend(strappend(dst, dst_len, "$", 1),
dst_len, var, strlen(var));
}
}

/** Expand variables (e.g. POSIX ~ or $FOO, Windows %FOO%) in @a path. */
char*
lilv_expand(const char* path)
{
#ifdef _WIN32
char* out = (char*)malloc(MAX_PATH);
ExpandEnvironmentStrings(path, out, MAX_PATH);
#else
char* out = NULL;
size_t len = 0;

const char* start = path; // Start of current chunk to copy
for (const char* s = path; *s;) {
if (*s == '$') {
// Hit $ (variable reference, e.g. $VAR_NAME)
for (const char* t = s + 1; ; ++t) {
if (!*t || (!isupper(*t) && !isdigit(*t) && *t != '_')) {
// Append preceding chunk
out = strappend(out, &len, start, s - start);

// Append variable value (or $VAR_NAME if not found)
char* var = (char*)calloc(t - s, 1);
memcpy(var, s + 1, t - s - 1);
out = append_var(out, &len, var);
free(var);

// Continue after variable reference
start = s = t;
break;
}
}
} else if (*s == '~' && (*(s + 1) == '/' || !*(s + 1))) {
// Hit ~ before slash or end of string (home directory reference)
out = strappend(out, &len, start, s - start);
out = append_var(out, &len, "HOME");
start = ++s;
} else {
++s;
}
}

if (*start) {
out = strappend(out, &len, start, strlen(start));
}
#endif

return out;
}

static bool
lilv_is_dir_sep(const char c)
{
return c == '/' || c == LILV_DIR_SEP[0];
}

char*
lilv_dirname(const char* path)
{
const char* s = path + strlen(path) - 1; // Last character
for (; s > path && lilv_is_dir_sep(*s); --s) {} // Last non-slash
for (; s > path && !lilv_is_dir_sep(*s); --s) {} // Last internal slash
for (; s > path && lilv_is_dir_sep(*s); --s) {} // Skip duplicates

if (s == path) { // Hit beginning
return lilv_is_dir_sep(*s) ? lilv_strdup("/") : lilv_strdup(".");
} else { // Pointing to the last character of the result (inclusive)
char* dirname = (char*)malloc(s - path + 2);
memcpy(dirname, path, s - path + 1);
dirname[s - path + 1] = '\0';
return dirname;
}
}

bool
lilv_path_exists(const char* path, void* ignored)
{
return !access(path, F_OK);
}

char*
lilv_find_free_path(const char* in_path,
bool (*exists)(const char*, void*), void* user_data)
{
const size_t in_path_len = strlen(in_path);
char* path = (char*)malloc(in_path_len + 7);
memcpy(path, in_path, in_path_len + 1);

for (int i = 2; i < 1000000; ++i) {
if (!exists(path, user_data)) {
return path;
}
snprintf(path, in_path_len + 7, "%s.%u", in_path, i);
}

return NULL;
}

int
lilv_copy_file(const char* src, const char* dst)
{
FILE* in = fopen(src, "r");
if (!in) {
LILV_ERRORF("error opening %s (%s)\n", src, strerror(errno));
return 1;
}

FILE* out = fopen(dst, "w");
if (!out) {
LILV_ERRORF("error opening %s (%s)\n", dst, strerror(errno));
fclose(in);
return 2;
}

char* page = (char*)malloc(PAGE_SIZE);
size_t n_read = 0;
while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) {
if (fwrite(page, 1, n_read, out) != n_read) {
LILV_ERRORF("write to %s failed (%s)\n", dst, strerror(errno));
break;
}
}

const int ret = ferror(in) || ferror(out);
if (ferror(in)) {
LILV_ERRORF("read from %s failed (%s)\n", src, strerror(errno));
}

free(page);
fclose(in);
fclose(out);

return ret;
}

bool
lilv_path_is_absolute(const char* path)
{
if (lilv_is_dir_sep(path[0])) {
return true;
}

#ifdef _WIN32
if (isalpha(path[0]) && path[1] == ':' && lilv_is_dir_sep(path[2])) {
return true;
}
#endif

return false;
}

char*
lilv_path_absolute(const char* path)
{
if (lilv_path_is_absolute(path)) {
return lilv_strdup(path);
} else {
char* cwd = getcwd(NULL, 0);
char* abs_path = lilv_path_join(cwd, path);
free(cwd);
return abs_path;
}
}

char*
lilv_path_join(const char* a, const char* b)
{
if (!a) {
return lilv_strdup(b);
}

const size_t a_len = strlen(a);
const size_t b_len = b ? strlen(b) : 0;
const size_t pre_len = a_len - (lilv_is_dir_sep(a[a_len - 1]) ? 1 : 0);
char* path = (char*)calloc(1, a_len + b_len + 2);
memcpy(path, a, pre_len);
path[pre_len] = '/';
if (b) {
memcpy(path + pre_len + 1,
b + (lilv_is_dir_sep(b[0]) ? 1 : 0),
lilv_is_dir_sep(b[0]) ? b_len - 1 : b_len);
}
return path;
}

static void
lilv_size_mtime(const char* path, off_t* size, time_t* time)
{
struct stat buf;
if (stat(path, &buf)) {
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
}

if (size) {
*size = buf.st_size;
}
if (time) {
*time = buf.st_mtime;
}
}

typedef struct {
char* pattern;
off_t orig_size;
time_t time;
char* latest;
} Latest;

static void
update_latest(const char* path, const char* name, void* data)
{
Latest* latest = (Latest*)data;
char* entry_path = lilv_path_join(path, name);
unsigned num;
if (sscanf(entry_path, latest->pattern, &num) == 1) {
off_t entry_size = 0;
time_t entry_time = 0;
lilv_size_mtime(entry_path, &entry_size, &entry_time);
if (entry_size == latest->orig_size && entry_time >= latest->time) {
free(latest->latest);
latest->latest = entry_path;
}
}
if (entry_path != latest->latest) {
free(entry_path);
}
}

/** Return the latest copy of the file at @c path that is newer. */
char*
lilv_get_latest_copy(const char* path, const char* copy_path)
{
char* copy_dir = lilv_dirname(copy_path);
Latest latest = { lilv_strjoin(copy_path, "%u", NULL), 0, 0, NULL };
lilv_size_mtime(path, &latest.orig_size, &latest.time);

lilv_dir_for_each(copy_dir, &latest, update_latest);

free(latest.pattern);
free(copy_dir);
return latest.latest;
}

char*
lilv_realpath(const char* path)
{
#ifdef _WIN32
char* out = (char*)malloc(MAX_PATH);
GetFullPathName(path, MAX_PATH, out, NULL);
return out;
#else
char* real_path = realpath(path, NULL);
return real_path ? real_path : lilv_strdup(path);
#endif
}

int
lilv_symlink(const char* oldpath, const char* newpath)
{
int ret = 0;
if (strcmp(oldpath, newpath)) {
#ifdef _WIN32
ret = 0;
#else
ret = symlink(oldpath, newpath);
#endif
}
if (ret) {
LILV_ERRORF("Failed to link %s => %s (%s)\n",
newpath, oldpath, strerror(errno));
}
return ret;
}

char*
lilv_path_relative_to(const char* path, const char* base)
{
const size_t path_len = strlen(path);
const size_t base_len = strlen(base);
const size_t min_len = (path_len < base_len) ? path_len : base_len;

// Find the last separator common to both paths
size_t last_shared_sep = 0;
for (size_t i = 0; i < min_len && path[i] == base[i]; ++i) {
if (lilv_is_dir_sep(path[i])) {
last_shared_sep = i;
}
}

if (last_shared_sep == 0) {
// No common components, return path
return lilv_strdup(path);
}

// Find the number of up references ("..") required
size_t up = 0;
for (size_t i = last_shared_sep + 1; i < base_len; ++i) {
if (lilv_is_dir_sep(base[i])) {
++up;
}
}

// Write up references
const size_t suffix_len = path_len - last_shared_sep;
char* rel = (char*)calloc(1, suffix_len + (up * 3) + 1);
for (size_t i = 0; i < up; ++i) {
memcpy(rel + (i * 3), "../", 3);
}

// Write suffix
memcpy(rel + (up * 3), path + last_shared_sep + 1, suffix_len);
return rel;
}

bool
lilv_path_is_child(const char* path, const char* dir)
{
if (path && dir) {
const size_t path_len = strlen(path);
const size_t dir_len = strlen(dir);
return dir && path_len >= dir_len && !strncmp(path, dir, dir_len);
}
return false;
}

int
lilv_flock(FILE* file, bool lock)
{
#if defined(HAVE_FLOCK) && defined(HAVE_FILENO)
return flock(fileno(file), lock ? LOCK_EX : LOCK_UN);
#else
return 0;
#endif
}

void
lilv_dir_for_each(const char* path,
void* data,
void (*f)(const char* path, const char* name, void* data))
{
#ifdef _WIN32
char* pat = lilv_path_join(path, "*");
WIN32_FIND_DATA fd;
HANDLE fh = FindFirstFile(pat, &fd);
if (fh != INVALID_HANDLE_VALUE) {
do {
f(path, fd.cFileName, data);
} while (FindNextFile(fh, &fd));
}
free(pat);
#else
DIR* dir = opendir(path);
if (dir) {
struct dirent entry;
struct dirent* result;
while (!readdir_r(dir, &entry, &result) && result) {
f(path, entry.d_name, data);
}
closedir(dir);
}
#endif
}

int
lilv_mkdir_p(const char* dir_path)
{
char* path = lilv_strdup(dir_path);
const size_t path_len = strlen(path);
for (size_t i = 1; i <= path_len; ++i) {
if (path[i] == LILV_DIR_SEP[0] || path[i] == '\0') {
path[i] = '\0';
if (mkdir(path, 0755) && errno != EEXIST) {
LILV_ERRORF("Failed to create %s (%s)\n",
path, strerror(errno));
free(path);
return 1;
}
path[i] = LILV_DIR_SEP[0];
}
}

free(path);
return 0;
}

static off_t
lilv_file_size(const char* path)
{
struct stat buf;
if (stat(path, &buf)) {
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
return 0;
}
return buf.st_size;
}

bool
lilv_file_equals(const char* a_path, const char* b_path)
{
if (!strcmp(a_path, b_path)) {
return true; // Paths match
}

bool match = false;
FILE* a_file = NULL;
FILE* b_file = NULL;
char* const a_real = lilv_realpath(a_path);
char* const b_real = lilv_realpath(b_path);
if (!a_real || !b_real) {
match = false; // Missing file matches nothing
} else if (!strcmp(a_real, b_real)) {
match = true; // Real paths match
} else if (lilv_file_size(a_path) != lilv_file_size(b_path)) {
match = false; // Sizes differ
} else if (!(a_file = fopen(a_real, "rb"))) {
match = false; // Missing file matches nothing
} else if (!(b_file = fopen(b_real, "rb"))) {
match = false; // Missing file matches nothing
} else {
match = true;
// TODO: Improve performance by reading chunks
while (!feof(a_file) && !feof(b_file)) {
if (fgetc(a_file) != fgetc(b_file)) {
match = false;
break;
}
}
}

if (a_file) {
fclose(a_file);
}
if (b_file) {
fclose(b_file);
}
free(a_real);
free(b_real);
return match;
}

+ 822
- 0
source/libs/lilv/lilv-0.14.4/src/world.c View File

@@ -0,0 +1,822 @@
/*
Copyright 2007-2011 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 <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "lv2/presets.h"

#include "lilv_internal.h"

LILV_API
LilvWorld*
lilv_world_new(void)
{
LilvWorld* world = (LilvWorld*)malloc(sizeof(LilvWorld));

world->world = sord_world_new();
if (!world->world)
goto fail;

world->model = sord_new(world->world, SORD_SPO|SORD_OPS, true);
if (!world->model)
goto fail;

world->specs = NULL;
world->plugin_classes = lilv_plugin_classes_new();
world->plugins = lilv_plugins_new();
world->loaded_files = zix_tree_new(
false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free);

#ifdef LILV_NEW_LV2
world->libs = zix_tree_new(
false, lilv_header_compare_by_uri, NULL, NULL);
#endif

#define NS_DCTERMS "http://purl.org/dc/terms/"
#define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#"

#define NEW_URI(uri) sord_new_uri(world->world, (const uint8_t*)uri)

world->uris.dc_replaces = NEW_URI(NS_DCTERMS "replaces");
world->uris.dman_DynManifest = NEW_URI(NS_DYNMAN "DynManifest");
world->uris.doap_name = NEW_URI(LILV_NS_DOAP "name");
world->uris.lv2_Plugin = NEW_URI(LV2_CORE__Plugin);
world->uris.lv2_Specification = NEW_URI(LV2_CORE__Specification);
world->uris.lv2_appliesTo = NEW_URI(LV2_CORE__appliesTo);
world->uris.lv2_binary = NEW_URI(LV2_CORE__binary);
world->uris.lv2_default = NEW_URI(LV2_CORE__default);
world->uris.lv2_designation = NEW_URI(LV2_CORE__designation);
world->uris.lv2_extensionData = NEW_URI(LV2_CORE__extensionData);
world->uris.lv2_index = NEW_URI(LV2_CORE__index);
world->uris.lv2_maximum = NEW_URI(LV2_CORE__maximum);
world->uris.lv2_minimum = NEW_URI(LV2_CORE__minimum);
world->uris.lv2_name = NEW_URI(LV2_CORE__name);
world->uris.lv2_optionalFeature = NEW_URI(LV2_CORE__optionalFeature);
world->uris.lv2_port = NEW_URI(LV2_CORE__port);
world->uris.lv2_portProperty = NEW_URI(LV2_CORE__portProperty);
world->uris.lv2_reportsLatency = NEW_URI(LV2_CORE__reportsLatency);
world->uris.lv2_requiredFeature = NEW_URI(LV2_CORE__requiredFeature);
world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol);
world->uris.pset_value = NEW_URI(LV2_PRESETS__value);
world->uris.rdf_a = NEW_URI(LILV_NS_RDF "type");
world->uris.rdf_value = NEW_URI(LILV_NS_RDF "value");
world->uris.rdfs_Class = NEW_URI(LILV_NS_RDFS "Class");
world->uris.rdfs_label = NEW_URI(LILV_NS_RDFS "label");
world->uris.rdfs_seeAlso = NEW_URI(LILV_NS_RDFS "seeAlso");
world->uris.rdfs_subClassOf = NEW_URI(LILV_NS_RDFS "subClassOf");
world->uris.xsd_base64Binary = NEW_URI(LILV_NS_XSD "base64Binary");
world->uris.xsd_boolean = NEW_URI(LILV_NS_XSD "boolean");
world->uris.xsd_decimal = NEW_URI(LILV_NS_XSD "decimal");
world->uris.xsd_double = NEW_URI(LILV_NS_XSD "double");
world->uris.xsd_integer = NEW_URI(LILV_NS_XSD "integer");
world->uris.null_uri = NULL;

world->lv2_plugin_class = lilv_plugin_class_new(
world, NULL, world->uris.lv2_Plugin, "Plugin");
assert(world->lv2_plugin_class);

world->n_read_files = 0;
world->opt.filter_language = true;
world->opt.dyn_manifest = true;

return world;

fail:
/* keep on rockin' in the */ free(world);
return NULL;
}

LILV_API
void
lilv_world_free(LilvWorld* world)
{
if (!world) {
return;
}

lilv_plugin_class_free(world->lv2_plugin_class);
world->lv2_plugin_class = NULL;

for (SordNode** n = (SordNode**)&world->uris; *n; ++n) {
sord_node_free(world->world, *n);
}

for (LilvSpec* spec = world->specs; spec;) {
LilvSpec* next = spec->next;
sord_node_free(world->world, spec->spec);
sord_node_free(world->world, spec->bundle);
lilv_nodes_free(spec->data_uris);
free(spec);
spec = next;
}
world->specs = NULL;

LILV_FOREACH(plugins, i, world->plugins) {
const LilvPlugin* p = lilv_plugins_get(world->plugins, i);
lilv_plugin_free((LilvPlugin*)p);
}
zix_tree_free((ZixTree*)world->plugins);
world->plugins = NULL;

zix_tree_free((ZixTree*)world->loaded_files);
world->loaded_files = NULL;

#ifdef LILV_NEW_LV2
zix_tree_free((ZixTree*)world->libs);
world->libs = NULL;
#endif

zix_tree_free((ZixTree*)world->plugin_classes);
world->plugin_classes = NULL;

sord_free(world->model);
world->model = NULL;

sord_world_free(world->world);
world->world = NULL;

free(world);
}

LILV_API
void
lilv_world_set_option(LilvWorld* world,
const char* option,
const LilvNode* value)
{
if (!strcmp(option, LILV_OPTION_DYN_MANIFEST)) {
if (lilv_node_is_bool(value)) {
world->opt.dyn_manifest = lilv_node_as_bool(value);
return;
}
} else if (!strcmp(option, LILV_OPTION_FILTER_LANG)) {
if (lilv_node_is_bool(value)) {
world->opt.filter_language = lilv_node_as_bool(value);
return;
}
}
LILV_WARNF("Unrecognized or invalid option `%s'\n", option);
}

LILV_API
LilvNodes*
lilv_world_find_nodes(LilvWorld* world,
const LilvNode* subject,
const LilvNode* predicate,
const LilvNode* object)
{
if (subject && !lilv_node_is_uri(subject) && !lilv_node_is_blank(subject)) {
LILV_ERRORF("Subject `%s' is not a resource\n",
sord_node_get_string(subject->node));
return NULL;
}
if (!lilv_node_is_uri(predicate)) {
LILV_ERRORF("Predicate `%s' is not a URI\n",
sord_node_get_string(predicate->node));
return NULL;
}
if (!subject && !object) {
LILV_ERROR("Both subject and object are NULL\n");
return NULL;
}

SordNode* const subject_node = subject
? sord_node_copy(subject->node)
: NULL;

SordNode* const object_node = object
? sord_node_copy(object->node)
: NULL;

LilvNodes* ret = lilv_world_query_values_internal(
world, subject_node, predicate->node, object_node);

sord_node_free(world->world, subject_node);
sord_node_free(world->world, object_node);
return ret;
}

SordIter*
lilv_world_query_internal(LilvWorld* world,
const SordNode* subject,
const SordNode* predicate,
const SordNode* object)
{
return sord_search(world->model, subject, predicate, object, NULL);
}

LilvNodes*
lilv_world_query_values_internal(LilvWorld* world,
const SordNode* subject,
const SordNode* predicate,
const SordNode* object)
{
return lilv_nodes_from_stream_objects(
world,
lilv_world_query_internal(world, subject, predicate, object),
(object == NULL) ? SORD_OBJECT : SORD_SUBJECT);
}

static SerdNode
lilv_new_uri_relative_to_base(const uint8_t* uri_str,
const uint8_t* base_uri_str)
{
SerdURI base_uri;
if (serd_uri_parse(base_uri_str, &base_uri)) {
return SERD_NODE_NULL;
}

SerdURI ignored;
return serd_node_new_uri_from_string(uri_str, &base_uri, &ignored);
}

const uint8_t*
lilv_world_blank_node_prefix(LilvWorld* world)
{
static char str[32];
snprintf(str, sizeof(str), "%d", world->n_read_files++);
return (const uint8_t*)str;
}

/** Comparator for sequences (e.g. world->plugins). */
int
lilv_header_compare_by_uri(const void* a, const void* b, void* user_data)
{
const struct LilvHeader* const header_a = (const struct LilvHeader*)a;
const struct LilvHeader* const header_b = (const struct LilvHeader*)b;
return strcmp(lilv_node_as_uri(header_a->uri),
lilv_node_as_uri(header_b->uri));
}

/** Get an element of a collection of any object with an LilvHeader by URI. */
struct LilvHeader*
lilv_collection_get_by_uri(const ZixTree* const_seq,
const LilvNode* uri)
{
if (!lilv_node_is_uri(uri)) {
return NULL;
}

ZixTree* seq = (ZixTree*)const_seq;
struct LilvHeader key = { NULL, (LilvNode*)uri };

ZixTreeIter* i = NULL;
ZixStatus st = zix_tree_find(seq, &key, &i);
if (!st) {
return (struct LilvHeader*)zix_tree_get(i);
}

return NULL;
}

static void
lilv_world_add_spec(LilvWorld* world,
const SordNode* specification_node,
const SordNode* bundle_node)
{
LilvSpec* spec = (LilvSpec*)malloc(sizeof(LilvSpec));
spec->spec = sord_node_copy(specification_node);
spec->bundle = sord_node_copy(bundle_node);
spec->data_uris = lilv_nodes_new();

// Add all plugin data files (rdfs:seeAlso)
SordIter* files = sord_search(
world->model,
specification_node,
world->uris.rdfs_seeAlso,
NULL,
NULL);
FOREACH_MATCH(files) {
const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT);
zix_tree_insert((ZixTree*)spec->data_uris,
lilv_node_new_from_node(world, file_node),
NULL);
}
sord_iter_free(files);

// Add specification to world specification list
spec->next = world->specs;
world->specs = spec;
}

static void
lilv_world_add_plugin(LilvWorld* world,
const SordNode* plugin_node,
SerdNode* manifest_uri,
void* dynmanifest,
const SordNode* bundle_node)
{
LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node);

const LilvPlugin* last = lilv_plugins_get_by_uri(world->plugins,
plugin_uri);
if (last) {
LILV_ERRORF("Duplicate plugin <%s>\n", lilv_node_as_uri(plugin_uri));
LILV_ERRORF("... found in %s\n", lilv_node_as_string(
lilv_plugin_get_bundle_uri(last)));
LILV_ERRORF("... and %s\n", sord_node_get_string(bundle_node));
lilv_node_free(plugin_uri);
return;
}

// Create LilvPlugin
LilvNode* bundle_uri = lilv_node_new_from_node(world, bundle_node);
LilvPlugin* plugin = lilv_plugin_new(world, plugin_uri, bundle_uri);

// Add manifest as plugin data file (as if it were rdfs:seeAlso)
zix_tree_insert((ZixTree*)plugin->data_uris,
lilv_new_uri(world, (const char*)manifest_uri->buf),
NULL);

#ifdef LILV_DYN_MANIFEST
// Set dynamic manifest library URI, if applicable
if (dynmanifest) {
plugin->dynmanifest = (LilvDynManifest*)dynmanifest;
++((LilvDynManifest*)dynmanifest)->refs;
}
#endif

// Add all plugin data files (rdfs:seeAlso)
SordIter* files = sord_search(
world->model,
plugin_node,
world->uris.rdfs_seeAlso,
NULL,
NULL);
FOREACH_MATCH(files) {
const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT);
zix_tree_insert((ZixTree*)plugin->data_uris,
lilv_node_new_from_node(world, file_node),
NULL);
}
sord_iter_free(files);

// Add plugin to world plugin sequence
zix_tree_insert((ZixTree*)world->plugins, plugin, NULL);
}

static void
lilv_world_load_dyn_manifest(LilvWorld* world,
SordNode* bundle_node,
SerdNode manifest_uri)
{
#ifdef LILV_DYN_MANIFEST
if (!world->opt.dyn_manifest) {
return;
}

typedef void* LV2_Dyn_Manifest_Handle;
LV2_Dyn_Manifest_Handle handle = NULL;

// ?dman a dynman:DynManifest
SordIter* dmanifests = sord_search(
world->model,
NULL,
world->uris.rdf_a,
world->uris.dman_DynManifest,
bundle_node);
FOREACH_MATCH(dmanifests) {
const SordNode* dmanifest = sord_iter_get_node(dmanifests, SORD_SUBJECT);

// ?dman lv2:binary ?binary
SordIter* binaries = sord_search(
world->model,
dmanifest,
world->uris.lv2_binary,
NULL,
bundle_node);
if (sord_iter_end(binaries)) {
sord_iter_free(binaries);
LILV_ERRORF("Dynamic manifest in <%s> has no binaries, ignored\n",
sord_node_get_string(bundle_node));
continue;
}

// Get binary path
const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT);
const uint8_t* lib_uri = sord_node_get_string(binary);
const char* lib_path = lilv_uri_to_path((const char*)lib_uri);
if (!lib_path) {
LILV_ERROR("No dynamic manifest library path\n");
sord_iter_free(binaries);
continue;
}

// Open library
void* lib = dlopen(lib_path, RTLD_LAZY);
if (!lib) {
LILV_ERRORF("Failed to open dynmanifest library `%s'\n", lib_path);
sord_iter_free(binaries);
continue;
}

// Open dynamic manifest
typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*,
const LV2_Feature *const *);
OpenFunc dmopen = (OpenFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_open");
if (!dmopen || dmopen(&handle, &dman_features)) {
LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path);
sord_iter_free(binaries);
dlclose(lib);
continue;
}

// Get subjects (the data that would be in manifest.ttl)
typedef int (*GetSubjectsFunc)(LV2_Dyn_Manifest_Handle, FILE*);
GetSubjectsFunc get_subjects_func = (GetSubjectsFunc)lilv_dlfunc(
lib, "lv2_dyn_manifest_get_subjects");
if (!get_subjects_func) {
LILV_ERRORF("No `lv2_dyn_manifest_get_subjects' in `%s'\n",
lib_path);
sord_iter_free(binaries);
dlclose(lib);
continue;
}

LilvDynManifest* desc = malloc(sizeof(LilvDynManifest));
desc->bundle = lilv_node_new_from_node(world, bundle_node);
desc->lib = lib;
desc->handle = handle;
desc->refs = 0;

// Generate data file
FILE* fd = tmpfile();
get_subjects_func(handle, fd);
rewind(fd);

// Parse generated data file
const SerdNode* base = sord_node_to_serd_node(dmanifest);
SerdEnv* env = serd_env_new(base);
SerdReader* reader = sord_new_reader(
world->model, env, SERD_TURTLE, sord_node_copy(dmanifest));
serd_reader_add_blank_prefix(reader,
lilv_world_blank_node_prefix(world));
serd_reader_read_file_handle(reader, fd,
(const uint8_t*)"(dyn-manifest)");
serd_reader_free(reader);
serd_env_free(env);

// Close (and automatically delete) temporary data file
fclose(fd);

// ?plugin a lv2:Plugin
SordIter* plug_results = sord_search(
world->model,
NULL,
world->uris.rdf_a,
world->uris.lv2_Plugin,
dmanifest);
FOREACH_MATCH(plug_results) {
const SordNode* plugin_node = sord_iter_get_node(plug_results, SORD_SUBJECT);
lilv_world_add_plugin(world, plugin_node,
&manifest_uri, desc, bundle_node);
}
sord_iter_free(plug_results);

sord_iter_free(binaries);
}
sord_iter_free(dmanifests);
#endif // LILV_DYN_MANIFEST
}

LILV_API
void
lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
{
if (!lilv_node_is_uri(bundle_uri)) {
LILV_ERRORF("Bundle URI `%s' is not a URI\n",
sord_node_get_string(bundle_uri->node));
return;
}

SordNode* bundle_node = bundle_uri->node;

SerdNode manifest_uri = lilv_new_uri_relative_to_base(
(const uint8_t*)"manifest.ttl",
(const uint8_t*)sord_node_get_string(bundle_node));

SerdEnv* env = serd_env_new(&manifest_uri);
SerdReader* reader = sord_new_reader(world->model, env, SERD_TURTLE,
bundle_node);
serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world));

SerdStatus st = serd_reader_read_file(reader, manifest_uri.buf);
serd_reader_free(reader);
serd_env_free(env);
if (st) {
LILV_ERRORF("Error reading %s\n", manifest_uri.buf);
return;
}

// ?plugin a lv2:Plugin
SordIter* plug_results = sord_search(
world->model,
NULL,
world->uris.rdf_a,
world->uris.lv2_Plugin,
bundle_node);
FOREACH_MATCH(plug_results) {
const SordNode* plugin_node = sord_iter_get_node(plug_results, SORD_SUBJECT);
lilv_world_add_plugin(world, plugin_node,
&manifest_uri, NULL, bundle_node);
}
sord_iter_free(plug_results);

lilv_world_load_dyn_manifest(world, bundle_node, manifest_uri);

// ?specification a lv2:Specification
SordIter* spec_results = sord_search(
world->model,
NULL,
world->uris.rdf_a,
world->uris.lv2_Specification,
bundle_node);
FOREACH_MATCH(spec_results) {
const SordNode* spec = sord_iter_get_node(spec_results, SORD_SUBJECT);
lilv_world_add_spec(world, spec, bundle_node);
}
sord_iter_free(spec_results);

serd_node_free(&manifest_uri);
}

static void
load_dir_entry(const char* dir, const char* name, void* data)
{
LilvWorld* world = (LilvWorld*)data;
if (!strcmp(name, ".") || !strcmp(name, ".."))
return;

const char* scheme = (dir[0] == '/') ? "file://" : "file:///";
char* uri = lilv_strjoin(scheme, dir, "/", name, "/", NULL);
LilvNode* uri_val = lilv_new_uri(world, uri);

lilv_world_load_bundle(world, uri_val);
lilv_node_free(uri_val);
free(uri);
}

/** Load all bundles in the directory at @a dir_path. */
static void
lilv_world_load_directory(LilvWorld* world, const char* dir_path)
{
char* path = lilv_expand(dir_path);
if (!path) {
LILV_WARNF("Empty path `%s'\n", path);
return;
}

lilv_dir_for_each(path, world, load_dir_entry);
free(path);
}

static bool
is_path_sep(char c)
{
return c == LILV_PATH_SEP[0];
}

static const char*
first_path_sep(const char* path)
{
for (const char* p = path; *p != '\0'; ++p) {
if (is_path_sep(*p)) {
return p;
}
}
return NULL;
}

/** Load all bundles found in @a lv2_path.
* @param lv2_path A colon-delimited list of directories. These directories
* should contain LV2 bundle directories (ie the search path is a list of
* parent directories of bundles, not a list of bundle directories).
*/
static void
lilv_world_load_path(LilvWorld* world,
const char* lv2_path)
{
while (lv2_path[0] != '\0') {
const char* const sep = first_path_sep(lv2_path);
if (sep) {
const size_t dir_len = sep - lv2_path;
char* const dir = (char*)malloc(dir_len + 1);
memcpy(dir, lv2_path, dir_len);
dir[dir_len] = '\0';
lilv_world_load_directory(world, dir);
free(dir);
lv2_path += dir_len + 1;
} else {
lilv_world_load_directory(world, lv2_path);
lv2_path = "\0";
}
}
}

static void
lilv_world_load_specifications(LilvWorld* world)
{
for (LilvSpec* spec = world->specs; spec; spec = spec->next) {
LILV_FOREACH(nodes, f, spec->data_uris) {
LilvNode* file = (LilvNode*)lilv_collection_get(spec->data_uris, f);

const SerdNode* node = sord_node_to_serd_node(file->node);
SerdEnv* env = serd_env_new(node);
SerdReader* reader = sord_new_reader(world->model, env,
SERD_TURTLE, NULL);
serd_reader_add_blank_prefix(reader,
lilv_world_blank_node_prefix(world));
serd_reader_read_file(reader, node->buf);
serd_reader_free(reader);
serd_env_free(env);
}
}
}

static void
lilv_world_load_plugin_classes(LilvWorld* world)
{
/* FIXME: This loads all classes, not just lv2:Plugin subclasses.
However, if the host gets all the classes via lilv_plugin_class_get_children
starting with lv2:Plugin as the root (which is e.g. how a host would build
a menu), they won't be seen anyway...
*/

SordIter* classes = sord_search(
world->model,
NULL,
world->uris.rdf_a,
world->uris.rdfs_Class,
NULL);
FOREACH_MATCH(classes) {
const SordNode* class_node = sord_iter_get_node(classes, SORD_SUBJECT);

// Get parents (superclasses)
SordIter* parents = sord_search(
world->model,
class_node,
world->uris.rdfs_subClassOf,
NULL,
NULL);

if (sord_iter_end(parents)) {
sord_iter_free(parents);
continue;
}

const SordNode* parent_node = sord_iter_get_node(parents, SORD_OBJECT);
sord_iter_free(parents);

if (!sord_node_get_type(parent_node) == SORD_URI) {
// Class parent is not a resource, ignore (e.g. owl restriction)
continue;
}

// Get labels
SordIter* labels = sord_search(
world->model,
class_node,
world->uris.rdfs_label,
NULL,
NULL);

if (sord_iter_end(labels)) {
sord_iter_free(labels);
continue;
}

const SordNode* label_node = sord_iter_get_node(labels, SORD_OBJECT);
const uint8_t* label = sord_node_get_string(label_node);
sord_iter_free(labels);

LilvPluginClass* pclass = lilv_plugin_class_new(
world, parent_node, class_node, (const char*)label);
if (pclass) {
zix_tree_insert((ZixTree*)world->plugin_classes, pclass, NULL);
}
}
sord_iter_free(classes);
}

LILV_API
void
lilv_world_load_all(LilvWorld* world)
{
const char* lv2_path = getenv("LV2_PATH");
if (!lv2_path)
lv2_path = LILV_DEFAULT_LV2_PATH;

// Discover bundles and read all manifest files into model
lilv_world_load_path(world, lv2_path);

LILV_FOREACH(plugins, p, world->plugins) {
const LilvPlugin* plugin = (const LilvPlugin*)lilv_collection_get(
(ZixTree*)world->plugins, p);

// ?new dc:replaces plugin
SordIter* replacement = sord_search(
world->model,
NULL,
world->uris.dc_replaces,
lilv_node_as_node(lilv_plugin_get_uri(plugin)),
NULL);
if (!sord_iter_end(replacement)) {
/* TODO: Check if replacement is actually a known plugin,
though this is expensive...
*/
((LilvPlugin*)plugin)->replaced = true;
}
sord_iter_free(replacement);
}

// Query out things to cache
lilv_world_load_specifications(world);
lilv_world_load_plugin_classes(world);
}

LILV_API
int
lilv_world_load_resource(LilvWorld* world,
const LilvNode* resource)
{
if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) {
LILV_ERRORF("Node `%s' is not a resource\n",
sord_node_get_string(resource->node));
return -1;
}

int n_read = 0;
SordIter* files = sord_search(world->model,
resource->node,
world->uris.rdfs_seeAlso,
NULL, NULL);
FOREACH_MATCH(files) {
const SordNode* file = sord_iter_get_node(files, SORD_OBJECT);
const uint8_t* str = sord_node_get_string(file);
LilvNode* file_node = lilv_node_new_from_node(world, file);
ZixTreeIter* iter;
if (zix_tree_find((ZixTree*)world->loaded_files, file_node, &iter)) {
if (sord_node_get_type(file) == SORD_URI) {
const SerdNode* base = sord_node_to_serd_node(file);
SerdEnv* env = serd_env_new(base);
SerdReader* reader = sord_new_reader(
world->model, env, SERD_TURTLE, (SordNode*)file);
serd_reader_add_blank_prefix(
reader, lilv_world_blank_node_prefix(world));
if (!serd_reader_read_file(reader, str)) {
++n_read;
zix_tree_insert(
(ZixTree*)world->loaded_files, file_node, NULL);
file_node = NULL; // prevent deletion...
} else {
LILV_ERRORF("Error loading resource `%s'\n", str);
}
serd_reader_free(reader);
serd_env_free(env);
} else {
LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", str);
}
}
lilv_node_free(file_node); // ...here
}
sord_iter_free(files);

return n_read;
}

LILV_API
const LilvPluginClass*
lilv_world_get_plugin_class(const LilvWorld* world)
{
return world->lv2_plugin_class;
}

LILV_API
const LilvPluginClasses*
lilv_world_get_plugin_classes(const LilvWorld* world)
{
return world->plugin_classes;
}

LILV_API
const LilvPlugins*
lilv_world_get_all_plugins(const LilvWorld* world)
{
return world->plugins;
}

+ 88
- 0
source/libs/lilv/lilv-0.14.4/src/zix/common.h View File

@@ -0,0 +1,88 @@
/*
Copyright 2011 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.
*/

#ifndef ZIX_COMMON_H
#define ZIX_COMMON_H

/**
@addtogroup zix
@{
*/

/** @cond */
#ifdef ZIX_SHARED
# ifdef _WIN32
# define ZIX_LIB_IMPORT __declspec(dllimport)
# define ZIX_LIB_EXPORT __declspec(dllexport)
# else
# define ZIX_LIB_IMPORT __attribute__((visibility("default")))
# define ZIX_LIB_EXPORT __attribute__((visibility("default")))
# endif
# ifdef ZIX_INTERNAL
# define ZIX_API ZIX_LIB_EXPORT
# else
# define ZIX_API ZIX_LIB_IMPORT
# endif
# define ZIX_PRIVATE static
#elif defined(ZIX_INLINE)
# define ZIX_API static inline
# define ZIX_PRIVATE static inline
#else
# define ZIX_API
# define ZIX_PRIVATE static
#endif
/** @endcond */

#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif

typedef enum {
ZIX_STATUS_SUCCESS,
ZIX_STATUS_ERROR,
ZIX_STATUS_NO_MEM,
ZIX_STATUS_NOT_FOUND,
ZIX_STATUS_EXISTS,
ZIX_STATUS_BAD_ARG,
ZIX_STATUS_BAD_PERMS,
} ZixStatus;

/**
Function for comparing two elements.
*/
typedef int (*ZixComparator)(const void* a, const void* b, void* user_data);

/**
Function for testing equality of two elements.
*/
typedef bool (*ZixEqualFunc)(const void* a, const void* b);

/**
Function to destroy an element.
*/
typedef void (*ZixDestroyFunc)(void* ptr);

/**
@}
*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* ZIX_COMMON_H */

+ 716
- 0
source/libs/lilv/lilv-0.14.4/src/zix/tree.c View File

@@ -0,0 +1,716 @@
/*
Copyright 2011 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 <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "zix/common.h"
#include "zix/tree.h"

typedef struct ZixTreeNodeImpl ZixTreeNode;

struct ZixTreeImpl {
ZixTreeNode* root;
ZixDestroyFunc destroy;
ZixComparator cmp;
void* cmp_data;
size_t size;
bool allow_duplicates;
};

struct ZixTreeNodeImpl {
void* data;
struct ZixTreeNodeImpl* left;
struct ZixTreeNodeImpl* right;
struct ZixTreeNodeImpl* parent;
int_fast8_t balance;
};

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

// Uncomment these for debugging features
// #define ZIX_TREE_DUMP 1
// #define ZIX_TREE_VERIFY 1
// #define ZIX_TREE_HYPER_VERIFY 1

#if defined(ZIX_TREE_VERIFY) || defined(ZIX_TREE_HYPER_VERIFY)
# include "tree_debug.h"
# define ASSERT_BALANCE(n) assert(verify_balance(n))
#else
# define ASSERT_BALANCE(n)
#endif

#ifdef ZIX_TREE_DUMP
# include "tree_debug.h"
# define DUMP(t) zix_tree_print(t->root, 0)
# define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
# define DUMP(t)
# define DEBUG_PRINTF(fmt, ...)
#endif

ZIX_API ZixTree*
zix_tree_new(bool allow_duplicates,
ZixComparator cmp,
void* cmp_data,
ZixDestroyFunc destroy)
{
ZixTree* t = (ZixTree*)malloc(sizeof(ZixTree));
t->root = NULL;
t->destroy = destroy;
t->cmp = cmp;
t->cmp_data = cmp_data;
t->size = 0;
t->allow_duplicates = allow_duplicates;
return t;
}

ZIX_PRIVATE void
zix_tree_free_rec(ZixTree* t, ZixTreeNode* n)
{
if (n) {
zix_tree_free_rec(t, n->left);
zix_tree_free_rec(t, n->right);
if (t->destroy) {
t->destroy(n->data);
}
free(n);
}
}

ZIX_API void
zix_tree_free(ZixTree* t)
{
if (t) {
zix_tree_free_rec(t, t->root);
free(t);
}
}

ZIX_API size_t
zix_tree_size(const ZixTree* t)
{
return t->size;
}

ZIX_PRIVATE void
rotate(ZixTreeNode* p, ZixTreeNode* q)
{
assert(q->parent == p);
assert(p->left == q || p->right == q);

q->parent = p->parent;
if (q->parent) {
if (q->parent->left == p) {
q->parent->left = q;
} else {
q->parent->right = q;
}
}

if (p->right == q) {
// Rotate left
p->right = q->left;
q->left = p;
if (p->right) {
p->right->parent = p;
}
} else {
// Rotate right
assert(p->left == q);
p->left = q->right;
q->right = p;
if (p->left) {
p->left->parent = p;
}
}

p->parent = q;
}

/**
* Rotate left about @a p.
*
* p q
* / \ / \
* A q => p C
* / \ / \
* B C A B
*/
ZIX_PRIVATE ZixTreeNode*
rotate_left(ZixTreeNode* p, int* height_change)
{
ZixTreeNode* const q = p->right;
*height_change = (q->balance == 0) ? 0 : -1;

DEBUG_PRINTF("LL %ld\n", (intptr_t)p->data);

assert(p->balance == 2);
assert(q->balance == 0 || q->balance == 1);

rotate(p, q);

// p->balance -= 1 + MAX(0, q->balance);
// q->balance -= 1 - MIN(0, p->balance);
--q->balance;
p->balance = -(q->balance);

ASSERT_BALANCE(p);
ASSERT_BALANCE(q);
return q;
}

/**
* Rotate right about @a p.
*
* p q
* / \ / \
* q C => A p
* / \ / \
* A B B C
*
*/
ZIX_PRIVATE ZixTreeNode*
rotate_right(ZixTreeNode* p, int* height_change)
{
ZixTreeNode* const q = p->left;
*height_change = (q->balance == 0) ? 0 : -1;

DEBUG_PRINTF("RR %ld\n", (intptr_t)p->data);

assert(p->balance == -2);
assert(q->balance == 0 || q->balance == -1);

rotate(p, q);

// p->balance += 1 - MIN(0, q->balance);
// q->balance += 1 + MAX(0, p->balance);
++q->balance;
p->balance = -(q->balance);

ASSERT_BALANCE(p);
ASSERT_BALANCE(q);
return q;
}

/**
* Rotate left about @a p->left then right about @a p.
*
* p r
* / \ / \
* q D => q p
* / \ / \ / \
* A r A B C D
* / \
* B C
*
*/
ZIX_PRIVATE ZixTreeNode*
rotate_left_right(ZixTreeNode* p, int* height_change)
{
ZixTreeNode* const q = p->left;
ZixTreeNode* const r = q->right;

assert(p->balance == -2);
assert(q->balance == 1);
assert(r->balance == -1 || r->balance == 0 || r->balance == 1);

DEBUG_PRINTF("LR %ld P: %2d Q: %2d R: %2d\n",
(intptr_t)p->data, p->balance, q->balance, r->balance);

rotate(q, r);
rotate(p, r);

q->balance -= 1 + MAX(0, r->balance);
p->balance += 1 - MIN(MIN(0, r->balance) - 1, r->balance + q->balance);
// r->balance += MAX(0, p->balance) + MIN(0, q->balance);

// p->balance = (p->left && p->right) ? -MIN(r->balance, 0) : 0;
// q->balance = - MAX(r->balance, 0);
r->balance = 0;

*height_change = -1;

ASSERT_BALANCE(p);
ASSERT_BALANCE(q);
ASSERT_BALANCE(r);
return r;
}

/**
* Rotate right about @a p->right then right about @a p.
*
* p r
* / \ / \
* A q => p q
* / \ / \ / \
* r D A B C D
* / \
* B C
*
*/
ZIX_PRIVATE ZixTreeNode*
rotate_right_left(ZixTreeNode* p, int* height_change)
{
ZixTreeNode* const q = p->right;
ZixTreeNode* const r = q->left;

assert(p->balance == 2);
assert(q->balance == -1);
assert(r->balance == -1 || r->balance == 0 || r->balance == 1);

DEBUG_PRINTF("RL %ld P: %2d Q: %2d R: %2d\n",
(intptr_t)p->data, p->balance, q->balance, r->balance);

rotate(q, r);
rotate(p, r);

q->balance += 1 - MIN(0, r->balance);
p->balance -= 1 + MAX(MAX(0, r->balance) + 1, r->balance + q->balance);
// r->balance += MAX(0, q->balance) + MIN(0, p->balance);

// p->balance = (p->left && p->right) ? -MAX(r->balance, 0) : 0;
// q->balance = - MIN(r->balance, 0);
r->balance = 0;
// assert(r->balance == 0);

*height_change = -1;

ASSERT_BALANCE(p);
ASSERT_BALANCE(q);
ASSERT_BALANCE(r);
return r;
}

ZIX_PRIVATE ZixTreeNode*
zix_tree_rebalance(ZixTree* t, ZixTreeNode* node, int* height_change)
{
#ifdef ZIX_TREE_HYPER_VERIFY
const size_t old_height = height(node);
#endif
DEBUG_PRINTF("REBALANCE %ld (%d)\n", (intptr_t)node->data, node->balance);
*height_change = 0;
const bool is_root = !node->parent;
assert((is_root && t->root == node) || (!is_root && t->root != node));
ZixTreeNode* replacement = node;
if (node->balance == -2) {
assert(node->left);
if (node->left->balance == 1) {
replacement = rotate_left_right(node, height_change);
} else {
replacement = rotate_right(node, height_change);
}
} else if (node->balance == 2) {
assert(node->right);
if (node->right->balance == -1) {
replacement = rotate_right_left(node, height_change);
} else {
replacement = rotate_left(node, height_change);
}
}
if (is_root) {
assert(!replacement->parent);
t->root = replacement;
}
DUMP(t);
#ifdef ZIX_TREE_HYPER_VERIFY
assert(old_height + *height_change == height(replacement));
#endif
return replacement;
}

ZIX_API ZixStatus
zix_tree_insert(ZixTree* t, void* e, ZixTreeIter** ti)
{
DEBUG_PRINTF("**** INSERT %ld\n", (intptr_t)e);
int cmp = 0;
ZixTreeNode* n = t->root;
ZixTreeNode* p = NULL;

// Find the parent p of e
while (n) {
p = n;
cmp = t->cmp(e, n->data, t->cmp_data);
if (cmp < 0) {
n = n->left;
} else if (cmp > 0) {
n = n->right;
} else if (t->allow_duplicates) {
n = n->right;
} else {
if (ti) {
*ti = n;
}
DEBUG_PRINTF("%ld EXISTS!\n", (intptr_t)e);
return ZIX_STATUS_EXISTS;
}
}

// Allocate a new node n
if (!(n = (ZixTreeNode*)malloc(sizeof(ZixTreeNode)))) {
return ZIX_STATUS_NO_MEM;
}
memset(n, '\0', sizeof(ZixTreeNode));
n->data = e;
n->balance = 0;
if (ti) {
*ti = n;
}

bool p_height_increased = false;

// Make p the parent of n
n->parent = p;
if (!p) {
t->root = n;
} else {
if (cmp < 0) {
assert(!p->left);
assert(p->balance == 0 || p->balance == 1);
p->left = n;
--p->balance;
p_height_increased = !p->right;
} else {
assert(!p->right);
assert(p->balance == 0 || p->balance == -1);
p->right = n;
++p->balance;
p_height_increased = !p->left;
}
}

DUMP(t);

// Rebalance if necessary (at most 1 rotation)
assert(!p || p->balance == -1 || p->balance == 0 || p->balance == 1);
if (p && p_height_increased) {
int height_change = 0;
for (ZixTreeNode* i = p; i && i->parent; i = i->parent) {
if (i == i->parent->left) {
if (--i->parent->balance == -2) {
zix_tree_rebalance(t, i->parent, &height_change);
break;
}
} else {
assert(i == i->parent->right);
if (++i->parent->balance == 2) {
zix_tree_rebalance(t, i->parent, &height_change);
break;
}
}

if (i->parent->balance == 0) {
break;
}
}
}

DUMP(t);

++t->size;

#ifdef ZIX_TREE_VERIFY
if (!verify(t, t->root)) {
return ZIX_STATUS_ERROR;
}
#endif

return ZIX_STATUS_SUCCESS;
}

ZIX_API ZixStatus
zix_tree_remove(ZixTree* t, ZixTreeIter* ti)
{
ZixTreeNode* const n = ti;
ZixTreeNode** pp = NULL; // parent pointer
ZixTreeNode* to_balance = n->parent; // lowest node to balance
int8_t d_balance = 0; // delta(balance) for n->parent

DEBUG_PRINTF("*** REMOVE %ld\n", (intptr_t)n->data);

if ((n == t->root) && !n->left && !n->right) {
t->root = NULL;
if (t->destroy) {
t->destroy(n->data);
}
free(n);
--t->size;
assert(t->size == 0);
return ZIX_STATUS_SUCCESS;
}

// Set pp to the parent pointer to n, if applicable
if (n->parent) {
assert(n->parent->left == n || n->parent->right == n);
if (n->parent->left == n) { // n is left child
pp = &n->parent->left;
d_balance = 1;
} else { // n is right child
assert(n->parent->right == n);
pp = &n->parent->right;
d_balance = -1;
}
}

assert(!pp || *pp == n);

int height_change = 0;
if (!n->left && !n->right) {
// n is a leaf, just remove it
if (pp) {
*pp = NULL;
to_balance = n->parent;
height_change = (!n->parent->left && !n->parent->right) ? -1 : 0;
}
} else if (!n->left) {
// Replace n with right (only) child
if (pp) {
*pp = n->right;
to_balance = n->parent;
} else {
t->root = n->right;
}
n->right->parent = n->parent;
height_change = -1;
} else if (!n->right) {
// Replace n with left (only) child
if (pp) {
*pp = n->left;
to_balance = n->parent;
} else {
t->root = n->left;
}
n->left->parent = n->parent;
height_change = -1;
} else {
// Replace n with in-order successor (leftmost child of right subtree)
ZixTreeNode* replace = n->right;
while (replace->left) {
assert(replace->left->parent == replace);
replace = replace->left;
}

// Remove replace from parent (replace_p)
if (replace->parent->left == replace) {
height_change = replace->parent->right ? 0 : -1;
d_balance = 1;
to_balance = replace->parent;
replace->parent->left = replace->right;
} else {
assert(replace->parent == n);
height_change = replace->parent->left ? 0 : -1;
d_balance = -1;
to_balance = replace->parent;
replace->parent->right = replace->right;
}

if (to_balance == n) {
to_balance = replace;
}

if (replace->right) {
replace->right->parent = replace->parent;
}

replace->balance = n->balance;

// Swap node to delete with replace
if (pp) {
*pp = replace;
} else {
assert(t->root == n);
t->root = replace;
}
replace->parent = n->parent;
replace->left = n->left;
n->left->parent = replace;
replace->right = n->right;
if (n->right) {
n->right->parent = replace;
}

assert(!replace->parent
|| replace->parent->left == replace
|| replace->parent->right == replace);
}

// Rebalance starting at to_balance upwards.
for (ZixTreeNode* i = to_balance; i; i = i->parent) {
i->balance += d_balance;
if (d_balance == 0 || i->balance == -1 || i->balance == 1) {
break;
}

assert(i != n);
i = zix_tree_rebalance(t, i, &height_change);
if (i->balance == 0) {
height_change = -1;
}

if (i->parent) {
if (i == i->parent->left) {
d_balance = height_change * -1;
} else {
assert(i == i->parent->right);
d_balance = height_change;
}
}
}

DUMP(t);

if (t->destroy) {
t->destroy(n->data);
}
free(n);

--t->size;

#ifdef ZIX_TREE_VERIFY
if (!verify(t, t->root)) {
return ZIX_STATUS_ERROR;
}
#endif

return ZIX_STATUS_SUCCESS;
}

ZIX_API ZixStatus
zix_tree_find(const ZixTree* t, const void* e, ZixTreeIter** ti)
{
ZixTreeNode* n = t->root;
while (n) {
const int cmp = t->cmp(e, n->data, t->cmp_data);
if (cmp == 0) {
break;
} else if (cmp < 0) {
n = n->left;
} else {
n = n->right;
}
}

*ti = n;
return (n) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_NOT_FOUND;
}

ZIX_API void*
zix_tree_get(ZixTreeIter* ti)
{
return ti ? ti->data : NULL;
}

ZIX_API ZixTreeIter*
zix_tree_begin(ZixTree* t)
{
if (!t->root) {
return NULL;
}

ZixTreeNode* n = t->root;
while (n->left) {
n = n->left;
}
return n;
}

ZIX_API ZixTreeIter*
zix_tree_end(ZixTree* t)
{
return NULL;
}

ZIX_API ZixTreeIter*
zix_tree_rbegin(ZixTree* t)
{
if (!t->root) {
return NULL;
}

ZixTreeNode* n = t->root;
while (n->right) {
n = n->right;
}
return n;
}

ZIX_API ZixTreeIter*
zix_tree_rend(ZixTree* t)
{
return NULL;
}

ZIX_API bool
zix_tree_iter_is_end(ZixTreeIter* i)
{
return !i;
}

ZIX_API bool
zix_tree_iter_is_rend(ZixTreeIter* i)
{
return !i;
}

ZIX_API ZixTreeIter*
zix_tree_iter_next(ZixTreeIter* i)
{
if (!i) {
return NULL;
}

if (i->right) {
i = i->right;
while (i->left) {
i = i->left;
}
} else {
while (i->parent && i->parent->right == i) { // i is a right child
i = i->parent;
}

i = i->parent;
}

return i;
}

ZIX_API ZixTreeIter*
zix_tree_iter_prev(ZixTreeIter* i)
{
if (!i) {
return NULL;
}

if (i->left) {
i = i->left;
while (i->right) {
i = i->right;
}
} else {
while (i->parent && i->parent->left == i) { // i is a left child
i = i->parent;
}

i = i->parent;
}

return i;
}

+ 148
- 0
source/libs/lilv/lilv-0.14.4/src/zix/tree.h View File

@@ -0,0 +1,148 @@
/*
Copyright 2011 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.
*/

#ifndef ZIX_TREE_H
#define ZIX_TREE_H

#include <stddef.h>

#include "zix/common.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
@addtogroup zix
@{
@name Tree
@{
*/

/**
A balanced binary search tree.
*/
typedef struct ZixTreeImpl ZixTree;

/**
An iterator over a @ref ZixTree.
*/
typedef struct ZixTreeNodeImpl ZixTreeIter;

/**
Create a new (empty) tree.
*/
ZIX_API ZixTree*
zix_tree_new(bool allow_duplicates,
ZixComparator cmp,
void* cmp_data,
ZixDestroyFunc destroy);

/**
Free @a t.
*/
ZIX_API void
zix_tree_free(ZixTree* t);

/**
Return the number of elements in @a t.
*/
ZIX_API size_t
zix_tree_size(const ZixTree* t);

/**
Insert the element @a e into @a t and point @a ti at the new element.
*/
ZIX_API ZixStatus
zix_tree_insert(ZixTree* t, void* e, ZixTreeIter** ti);

/**
Remove the item pointed at by @a ti from @a t.
*/
ZIX_API ZixStatus
zix_tree_remove(ZixTree* t, ZixTreeIter* ti);

/**
Set @a ti to an element equal to @a e in @a t.
If no such item exists, @a ti is set to NULL.
*/
ZIX_API ZixStatus
zix_tree_find(const ZixTree* t, const void* e, ZixTreeIter** ti);

/**
Return the data associated with the given tree item.
*/
ZIX_API void*
zix_tree_get(ZixTreeIter* ti);

/**
Return an iterator to the first (smallest) element in @a t.
*/
ZIX_API ZixTreeIter*
zix_tree_begin(ZixTree* t);

/**
Return an iterator the the element one past the last element in @a t.
*/
ZIX_API ZixTreeIter*
zix_tree_end(ZixTree* t);

/**
Return true iff @a i is an iterator to the end of its tree.
*/
ZIX_API bool
zix_tree_iter_is_end(ZixTreeIter* i);

/**
Return an iterator to the last (largest) element in @a t.
*/
ZIX_API ZixTreeIter*
zix_tree_rbegin(ZixTree* t);

/**
Return an iterator the the element one before the first element in @a t.
*/
ZIX_API ZixTreeIter*
zix_tree_rend(ZixTree* t);

/**
Return true iff @a i is an iterator to the reverse end of its tree.
*/
ZIX_API bool
zix_tree_iter_is_rend(ZixTreeIter* i);

/**
Return an iterator that points to the element one past @a i.
*/
ZIX_API ZixTreeIter*
zix_tree_iter_next(ZixTreeIter* i);

/**
Return an iterator that points to the element one before @a i.
*/
ZIX_API ZixTreeIter*
zix_tree_iter_prev(ZixTreeIter* i);

/**
@}
@}
*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* ZIX_TREE_H */

+ 1581
- 0
source/libs/lilv/lilv-0.14.4/test/lilv_test.c
File diff suppressed because it is too large
View File


+ 7
- 0
source/libs/lilv/lilv-0.14.4/test/manifest.ttl.in View File

@@ -0,0 +1,7 @@
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<http://example.org/lilv-test-plugin>
a lv2:Plugin ;
lv2:binary <test_plugin@SHLIB_EXT@> ;
rdfs:seeAlso <test_plugin.ttl> .

+ 384
- 0
source/libs/lilv/lilv-0.14.4/test/test_plugin.c View File

@@ -0,0 +1,384 @@
/*
Lilv Test Plugin
Copyright 2011 David Robillard <d@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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
#include "lv2/lv2plug.in/ns/ext/state/state.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"

#define TEST_URI "http://example.org/lilv-test-plugin"

enum {
TEST_INPUT = 0,
TEST_OUTPUT = 1
};

typedef struct {
LV2_URID_Map* map;

struct {
LV2_URID atom_Float;
} uris;

char* tmp_file_path;
char* rec_file_path;
FILE* rec_file;

float* input;
float* output;
unsigned num_runs;
} Test;

static void
cleanup(LV2_Handle instance)
{
Test* test = (Test*)instance;
if (test->rec_file) {
fclose(test->rec_file);
}
free(test->tmp_file_path);
free(test->rec_file_path);
free(instance);
}

static void
connect_port(LV2_Handle instance,
uint32_t port,
void* data)
{
Test* test = (Test*)instance;
switch (port) {
case TEST_INPUT:
test->input = (float*)data;
break;
case TEST_OUTPUT:
test->output = (float*)data;
break;
default:
break;
}
}

static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double rate,
const char* path,
const LV2_Feature* const* features)
{
Test* test = (Test*)malloc(sizeof(Test));
if (!test) {
return NULL;
}

test->map = NULL;
test->input = NULL;
test->output = NULL;
test->num_runs = 0;
test->tmp_file_path = (char*)malloc(L_tmpnam);
test->rec_file_path = NULL;
test->rec_file = NULL;

tmpnam(test->tmp_file_path);

LV2_State_Make_Path* make_path = NULL;

for (int i = 0; features[i]; ++i) {
if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) {
test->map = (LV2_URID_Map*)features[i]->data;
test->uris.atom_Float = test->map->map(
test->map->handle, LV2_ATOM__Float);
} else if (!strcmp(features[i]->URI, LV2_STATE__makePath)) {
make_path = (LV2_State_Make_Path*)features[i]->data;
}
}

if (!test->map) {
fprintf(stderr, "Host does not support urid:map\n");
free(test);
return NULL;
}

if (make_path) {
test->rec_file_path = make_path->path(make_path->handle, "recfile");
if (!(test->rec_file = fopen(test->rec_file_path, "w"))) {
fprintf(stderr, "ERROR: Failed to open rec file\n");
}
fprintf(test->rec_file, "instantiate\n");
}

return (LV2_Handle)test;
}

static void
run(LV2_Handle instance,
uint32_t sample_count)
{
Test* test = (Test*)instance;
*test->output = *test->input;
if (sample_count == 1) {
++test->num_runs;
} else if (sample_count == 2 && test->rec_file) {
// Append to rec file (changes size)
fprintf(test->rec_file, "run\n");
} else if (sample_count == 3 && test->rec_file) {
// Change the first byte of rec file (doesn't change size)
fseek(test->rec_file, 0, SEEK_SET);
fprintf(test->rec_file, "X");
fseek(test->rec_file, 0, SEEK_END);
}
}

static uint32_t
map_uri(Test* plugin, const char* uri)
{
return plugin->map->map(plugin->map->handle, uri);
}

static LV2_State_Status
save(LV2_Handle instance,
LV2_State_Store_Function store,
void* callback_data,
uint32_t flags,
const LV2_Feature* const* features)
{
Test* plugin = (Test*)instance;

LV2_State_Map_Path* map_path = NULL;
LV2_State_Make_Path* make_path = NULL;
for (int i = 0; features && features[i]; ++i) {
if (!strcmp(features[i]->URI, LV2_STATE__mapPath)) {
map_path = (LV2_State_Map_Path*)features[i]->data;
} else if (!strcmp(features[i]->URI, LV2_STATE__makePath)) {
make_path = (LV2_State_Make_Path*)features[i]->data;
}
}

store(callback_data,
map_uri(plugin, "http://example.org/greeting"),
"hello",
strlen("hello") + 1,
map_uri(plugin, LV2_ATOM__String),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

const uint32_t urid = map_uri(plugin, "http://example.org/urivalue");
store(callback_data,
map_uri(plugin, "http://example.org/uri"),
&urid,
sizeof(uint32_t),
map_uri(plugin, LV2_ATOM__URID),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

store(callback_data,
map_uri(plugin, "http://example.org/num-runs"),
&plugin->num_runs,
sizeof(plugin->num_runs),
map_uri(plugin, LV2_ATOM__Int),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

const float two = 2.0f;
store(callback_data,
map_uri(plugin, "http://example.org/two"),
&two,
sizeof(two),
map_uri(plugin, LV2_ATOM__Float),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

const uint32_t affirmative = 1;
store(callback_data,
map_uri(plugin, "http://example.org/true"),
&affirmative,
sizeof(affirmative),
map_uri(plugin, LV2_ATOM__Bool),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

const uint32_t negative = 0;
store(callback_data,
map_uri(plugin, "http://example.org/false"),
&negative,
sizeof(negative),
map_uri(plugin, LV2_ATOM__Bool),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

const uint8_t blob[] = "I am a blob of arbitrary data.";
store(callback_data,
map_uri(plugin, "http://example.org/blob"),
blob,
sizeof(blob),
map_uri(plugin, "http://example.org/SomeUnknownType"),
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

if (map_path) {
FILE* file = fopen(plugin->tmp_file_path, "w");
fprintf(file, "Hello\n");
fclose(file);
char* apath = map_path->abstract_path(map_path->handle,
plugin->tmp_file_path);
char* apath2 = map_path->abstract_path(map_path->handle,
plugin->tmp_file_path);
if (strcmp(apath, apath2)) {
fprintf(stderr, "ERROR: Path %s != %s\n", apath, apath2);
}

store(callback_data,
map_uri(plugin, "http://example.org/extfile"),
apath,
strlen(apath) + 1,
map_uri(plugin, LV2_ATOM__Path),
LV2_STATE_IS_PORTABLE);

free(apath);
free(apath2);

if (plugin->rec_file) {
fflush(plugin->rec_file);
apath = map_path->abstract_path(map_path->handle,
plugin->rec_file_path);

store(callback_data,
map_uri(plugin, "http://example.org/recfile"),
apath,
strlen(apath) + 1,
map_uri(plugin, LV2_ATOM__Path),
LV2_STATE_IS_PORTABLE);

free(apath);
}

if (make_path) {
char* spath = make_path->path(make_path->handle, "save");
FILE* sfile = fopen(spath, "w");
fprintf(sfile, "save");
fclose(sfile);

apath = map_path->abstract_path(map_path->handle, spath);
store(callback_data,
map_uri(plugin, "http://example.org/save-file"),
apath,
strlen(apath) + 1,
map_uri(plugin, LV2_ATOM__Path),
LV2_STATE_IS_PORTABLE);
free(apath);
free(spath);
}
}

return LV2_STATE_SUCCESS;
}

static LV2_State_Status
restore(LV2_Handle instance,
LV2_State_Retrieve_Function retrieve,
void* callback_data,
uint32_t flags,
const LV2_Feature* const* features)
{
Test* plugin = (Test*)instance;

LV2_State_Map_Path* map_path = NULL;
for (int i = 0; features && features[i]; ++i) {
if (!strcmp(features[i]->URI, LV2_STATE__mapPath)) {
map_path = (LV2_State_Map_Path*)features[i]->data;
}
}

size_t size;
uint32_t type;
uint32_t valflags;

plugin->num_runs = *(int32_t*)retrieve(
callback_data,
map_uri(plugin, "http://example.org/num-runs"),
&size, &type, &valflags);

if (!map_path) {
return LV2_STATE_ERR_NO_FEATURE;
}

char* apath = (char*)retrieve(
callback_data,
map_uri(plugin, "http://example.org/extfile"),
&size, &type, &valflags);

if (apath) {
char* path = map_path->absolute_path(map_path->handle, apath);
FILE* f = fopen(path, "r");
char str[8];
size_t n_read = fread(str, 1, sizeof(str), f);
fclose(f);
if (strncmp(str, "Hello\n", n_read)) {
fprintf(stderr, "error: Restored bad file contents `%s' != `Hello'\n",
str);
}
free(path);
}

apath = (char*)retrieve(
callback_data,
map_uri(plugin, "http://example.org/save-file"),
&size, &type, &valflags);
if (apath) {
char* spath = map_path->absolute_path(map_path->handle, apath);
FILE* sfile = fopen(spath, "r");
if (!sfile) {
fprintf(stderr, "error: Failed to open save file %s\n", spath);
} else {
fclose(sfile);
}
free(spath);
} else {
fprintf(stderr, "error: Failed to restore save file.\n");
}

return LV2_STATE_SUCCESS;
}

static const void*
extension_data(const char* uri)
{
static const LV2_State_Interface state = { save, restore };
if (!strcmp(uri, LV2_STATE__interface)) {
return &state;
}
return NULL;
}

static const LV2_Descriptor descriptor = {
TEST_URI,
instantiate,
connect_port,
NULL, // activate,
run,
NULL, // deactivate,
cleanup,
extension_data
};

LV2_SYMBOL_EXPORT
const LV2_Descriptor* lv2_descriptor(uint32_t index)
{
switch (index) {
case 0:
return &descriptor;
default:
return NULL;
}
}

+ 40
- 0
source/libs/lilv/lilv-0.14.4/test/test_plugin.ttl.in View File

@@ -0,0 +1,40 @@
# Lilv Test Plugin
# Copyright 2011 David Robillard <d@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.

@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .

<http://example.org/lilv-test-plugin>
a lv2:Plugin ;
doap:name "Lilv Test" ;
doap:license <http://opensource.org/licenses/isc> ;
lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#Mapper> ;
lv2:optionalFeature lv2:hardRTCapable ;
lv2:extensionData <http://lv2plug.in/ns/ext/state#Interface> ;
lv2:port [
a lv2:InputPort ,
lv2:ControlPort ;
lv2:index 0 ;
lv2:symbol "input" ;
lv2:name "Input"
] , [
a lv2:OutputPort ,
lv2:ControlPort ;
lv2:index 1 ;
lv2:symbol "output" ;
lv2:name "Output"
] .

+ 52
- 0
source/libs/lilv/lilv-0.14.4/utils/bench.h View File

@@ -0,0 +1,52 @@
/*
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.
*/

/**
@file bench.h A simple real-time benchmarking API.
*/

#ifndef BENCH_H
#define BENCH_H

#define _POSIX_C_SOURCE 199309L

#include <time.h>
#include <sys/time.h>

static inline double
bench_elapsed_s(const struct timespec* start, const struct timespec* end)
{
return ((end->tv_sec - start->tv_sec)
+ ((end->tv_nsec - start->tv_nsec) * 0.000000001));
}

static inline struct timespec
bench_start()
{
struct timespec start_t;
clock_gettime(CLOCK_REALTIME, &start_t);
return start_t;
}

static inline double
bench_end(const struct timespec* start_t)
{
struct timespec end_t;
clock_gettime(CLOCK_REALTIME, &end_t);
return bench_elapsed_s(start_t, &end_t);
}

#endif /* BENCH_H */

+ 38
- 0
source/libs/lilv/lilv-0.14.4/utils/lilv-bench.c View File

@@ -0,0 +1,38 @@
/*
Copyright 2007-2011 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 <stdio.h>

#include "lilv/lilv.h"

#include "lilv_config.h"

int
main(int argc, char** argv)
{
LilvWorld* world = lilv_world_new();
lilv_world_load_all(world);

const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
LILV_FOREACH(plugins, p, plugins) {
const LilvPlugin* plugin = lilv_plugins_get(plugins, p);
lilv_plugin_get_class(plugin);
}

lilv_world_free(world);

return 0;
}

+ 59
- 0
source/libs/lilv/lilv-0.14.4/utils/lilv.bash_completion View File

@@ -0,0 +1,59 @@
# Bash auto-completion script written for lv2info and lv2jack.
# Could be adapted to any other program that takes an
# LV2 plugin URI as parameter.

# Updated for Lilv by David Robillard <d@drobilla.net> on 2012-01-08.
# Written by Lars Luthman <lars.luthman@gmail.com> on 2009-10-12.
# No copyright claimed for this script. Do what you want with it.

# For some reason Bash splits the command line not only at whitespace
# but also at ':' signs before putting the parts into COMP_WORDS.
# Since ':' is used in all URIs, which are what we want to complete,
# we have to put the URI back together before we can complete it
# and then cut off the parts we prepended from the completions.
# It probably breaks in some special cases but for most common uses
# it should work fine.

function _lv2info() {
local uri cur opts w wn raw_reply len type
opts=`lv2ls | xargs -n1 echo -n " "`
# This is the last "word", as split by Bash.
cur="${COMP_WORDS[COMP_CWORD]}"
w="$cur"
# Add the previous word while it or this one is a word break character
for i in `seq $(( $COMP_CWORD - 1 )) -1 1`; do
wn="${COMP_WORDS[i]}"
if expr "$COMP_WORDBREAKS" : ".*$wn" > /dev/null; then
if expr "$COMP_WORDBREAKS" : ".*$w" > /dev/null; then
break
fi
fi
w="$wn"
uri="$w$uri"
done
# Check the length of the words we prepend
len=${#uri}
uri="$uri$cur"
raw_reply="$(compgen -W "${opts}" -- ${uri})"
# If we are listing alternatives, just print the full URIs.
type=`echo $COMP_TYPE | awk '{ printf "%c", $1 }'`
if expr "?!@%" : ".*$type" > /dev/null; then
COMPREPLY=( $raw_reply )
return 0
fi
# Otherwise, strip the prepended words from all completion suggestions.
COMPREPLY=()
for i in $raw_reply; do
COMPREPLY=( ${COMPREPLY[@]} ${i:len} )
done
}

complete -F _lv2info lv2info

# And the same for lv2jack.
complete -F _lv2info lv2jack

+ 226
- 0
source/libs/lilv/lilv-0.14.4/utils/lv2bench.c View File

@@ -0,0 +1,226 @@
/*
Copyright 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.
*/

#define _POSIX_C_SOURCE 199309L

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lilv/lilv.h"
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"

#include "lilv_config.h"
#include "bench.h"
#include "uri_table.h"

static LilvNode* atom_AtomPort = NULL;
static LilvNode* atom_Sequence = NULL;
static LilvNode* lv2_AudioPort = NULL;
static LilvNode* lv2_CVPort = NULL;
static LilvNode* lv2_ControlPort = NULL;
static LilvNode* lv2_InputPort = NULL;
static LilvNode* lv2_OutputPort = NULL;
static LilvNode* urid_map = NULL;

static bool full_output = false;

static void
print_version(void)
{
printf(
"lv2bench (lilv) " LILV_VERSION "\n"
"Copyright 2012 David Robillard <http://drobilla.net>\n"
"License: <http://www.opensource.org/licenses/isc-license>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n");
}

static void
print_usage(void)
{
printf("lv2bench - Benchmark all installed and supported LV2 plugins.\n");
printf("Usage: lv2bench [OPTIONS]\n");
printf("\n");
printf(" -b BLOCK_SIZE Specify block size, in audio frames.\n");
printf(" -f, --full Full plottable output.\n");
printf(" -h, --help Display this help and exit.\n");
printf(" -n FRAMES Total number of audio frames to process\n");
printf(" --version Display version information and exit\n");
}

static double
bench(const LilvPlugin* p, uint32_t sample_count, uint32_t block_size)
{
URITable uri_table;
uri_table_init(&uri_table);

LV2_URID_Map map = { &uri_table, uri_table_map };
LV2_Feature map_feature = { LV2_URID_MAP_URI, &map };
LV2_URID_Unmap unmap = { &uri_table, uri_table_unmap };
LV2_Feature unmap_feature = { LV2_URID_UNMAP_URI, &unmap };
const LV2_Feature* features[] = { &map_feature, &unmap_feature, NULL };

float* const buf = (float*)calloc(block_size * 2, sizeof(float));
float* const in = buf;
float* const out = buf + block_size;
if (!buf) {
fprintf(stderr, "Out of memory\n");
return 0.0;
}

LV2_Atom_Sequence seq = {
{ sizeof(LV2_Atom_Sequence_Body),
uri_table_map(&uri_table, LV2_ATOM__Sequence) },
{ 0, 0 } };

const char* uri = lilv_node_as_string(lilv_plugin_get_uri(p));
LilvNodes* required = lilv_plugin_get_required_features(p);
LILV_FOREACH(nodes, i, required) {
const LilvNode* feature = lilv_nodes_get(required, i);
if (!lilv_node_equals(feature, urid_map)) {
fprintf(stderr, "<%s> requires feature <%s>, skipping\n",
uri, lilv_node_as_uri(feature));
free(buf);
return 0.0;
}
}

LilvInstance* instance = lilv_plugin_instantiate(p, 48000.0, features);
if (!instance) {
fprintf(stderr, "Failed to instantiate <%s>\n",
lilv_node_as_uri(lilv_plugin_get_uri(p)));
free(buf);
return 0.0;
}

float* controls = (float*)calloc(
lilv_plugin_get_num_ports(p), sizeof(float));
lilv_plugin_get_port_ranges_float(p, NULL, NULL, controls);

const uint32_t n_ports = lilv_plugin_get_num_ports(p);
for (uint32_t index = 0; index < n_ports; ++index) {
const LilvPort* port = lilv_plugin_get_port_by_index(p, index);
if (lilv_port_is_a(p, port, lv2_ControlPort)) {
lilv_instance_connect_port(instance, index, &controls[index]);
} else if (lilv_port_is_a(p, port, lv2_AudioPort) ||
lilv_port_is_a(p, port, lv2_CVPort)) {
if (lilv_port_is_a(p, port, lv2_InputPort)) {
lilv_instance_connect_port(instance, index, in);
} else if (lilv_port_is_a(p, port, lv2_OutputPort)) {
lilv_instance_connect_port(instance, index, out);
} else {
fprintf(stderr, "<%s> port %d neither input nor output, skipping\n",
uri, index);
lilv_instance_free(instance);
free(buf);
free(controls);
return 0.0;
}
} else if (lilv_port_is_a(p, port, atom_AtomPort)) {
lilv_instance_connect_port(instance, index, &seq);
} else {
fprintf(stderr, "<%s> port %d has unknown type, skipping\n",
uri, index);
lilv_instance_free(instance);
free(buf);
free(controls);
return 0.0;
}
}

lilv_instance_activate(instance);

struct timespec ts = bench_start();
for (uint32_t i = 0; i < (sample_count / block_size); ++i) {
lilv_instance_run(instance, block_size);
}
const double elapsed = bench_end(&ts);

lilv_instance_deactivate(instance);
lilv_instance_free(instance);

uri_table_destroy(&uri_table);

if (full_output) {
printf("%d %d ", block_size, sample_count);
}
printf("%lf %s\n", elapsed, uri);

free(buf);
free(controls);
return elapsed;
}

int
main(int argc, char** argv)
{
uint32_t block_size = 512;
uint32_t sample_count = (1 << 19);

for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "--version")) {
print_version();
return 0;
} else if (!strcmp(argv[i], "--help")) {
print_usage();
return 0;
} else if (!strcmp(argv[i], "-f")) {
full_output = true;
} else if (!strcmp(argv[i], "-n") && (i + 1 < argc)) {
sample_count = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-b") && (i + 1 < argc)) {
block_size = atoi(argv[++i]);
} else {
print_usage();
return 1;
}
}

LilvWorld* world = lilv_world_new();
lilv_world_load_all(world);

atom_AtomPort = lilv_new_uri(world, LV2_ATOM__AtomPort);
atom_Sequence = lilv_new_uri(world, LV2_ATOM__Sequence);
lv2_AudioPort = lilv_new_uri(world, LV2_CORE__AudioPort);
lv2_CVPort = lilv_new_uri(world, LV2_CORE__CVPort);
lv2_ControlPort = lilv_new_uri(world, LV2_CORE__ControlPort);
lv2_InputPort = lilv_new_uri(world, LV2_CORE__InputPort);
lv2_OutputPort = lilv_new_uri(world, LV2_CORE__OutputPort);
urid_map = lilv_new_uri(world, LV2_URID__map);

if (full_output) {
printf("# Block Samples Time Plugin\n");
}

const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
LILV_FOREACH(plugins, i, plugins) {
bench(lilv_plugins_get(plugins, i), sample_count, block_size);
}

lilv_node_free(urid_map);
lilv_node_free(lv2_OutputPort);
lilv_node_free(lv2_InputPort);
lilv_node_free(lv2_ControlPort);
lilv_node_free(lv2_CVPort);
lilv_node_free(lv2_AudioPort);
lilv_node_free(atom_Sequence);
lilv_node_free(atom_AtomPort);

lilv_world_free(world);

return 0;
}

+ 437
- 0
source/libs/lilv/lilv-0.14.4/utils/lv2info.c View File

@@ -0,0 +1,437 @@
/*
Copyright 2007-2011 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 <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lv2/lv2plug.in/ns/ext/port-groups/port-groups.h"
#include "lv2/lv2plug.in/ns/ext/presets/presets.h"
#include "lv2/lv2plug.in/ns/ext/event/event.h"

#include "lilv/lilv.h"

#include "lilv_config.h"

#ifdef _MSC_VER
# define isnan _isnan
#endif

LilvNode* applies_to_pred = NULL;
LilvNode* control_class = NULL;
LilvNode* event_class = NULL;
LilvNode* group_pred = NULL;
LilvNode* label_pred = NULL;
LilvNode* preset_class = NULL;
LilvNode* designation_pred = NULL;
LilvNode* supports_event_pred = NULL;

static void
print_port(const LilvPlugin* p,
uint32_t index,
float* mins,
float* maxes,
float* defaults)
{
const LilvPort* port = lilv_plugin_get_port_by_index(p, index);

printf("\n\tPort %d:\n", index);

if (!port) {
printf("\t\tERROR: Illegal/nonexistent port\n");
return;
}

bool first = true;

const LilvNodes* classes = lilv_port_get_classes(p, port);
printf("\t\tType: ");
LILV_FOREACH(nodes, i, classes) {
const LilvNode* value = lilv_nodes_get(classes, i);
if (!first) {
printf("\n\t\t ");
}
printf("%s", lilv_node_as_uri(value));
first = false;
}

if (lilv_port_is_a(p, port, event_class)) {
LilvNodes* supported = lilv_port_get_value(
p, port, supports_event_pred);
if (lilv_nodes_size(supported) > 0) {
printf("\n\t\tSupported events:\n");
LILV_FOREACH(nodes, i, supported) {
const LilvNode* value = lilv_nodes_get(supported, i);
printf("\t\t\t%s\n", lilv_node_as_uri(value));
}
}
lilv_nodes_free(supported);
}

LilvScalePoints* points = lilv_port_get_scale_points(p, port);
if (points)
printf("\n\t\tScale Points:\n");
LILV_FOREACH(scale_points, i, points) {
const LilvScalePoint* point = lilv_scale_points_get(points, i);
printf("\t\t\t%s = \"%s\"\n",
lilv_node_as_string(lilv_scale_point_get_value(point)),
lilv_node_as_string(lilv_scale_point_get_label(point)));
}
lilv_scale_points_free(points);

const LilvNode* sym = lilv_port_get_symbol(p, port);
printf("\n\t\tSymbol: %s\n", lilv_node_as_string(sym));

LilvNode* name = lilv_port_get_name(p, port);
printf("\t\tName: %s\n", lilv_node_as_string(name));
lilv_node_free(name);

LilvNodes* groups = lilv_port_get_value(p, port, group_pred);
if (lilv_nodes_size(groups) > 0) {
printf("\t\tGroup: %s\n",
lilv_node_as_string(lilv_nodes_get_first(groups)));
}
lilv_nodes_free(groups);

LilvNodes* designations = lilv_port_get_value(p, port, designation_pred);
if (lilv_nodes_size(designations) > 0) {
printf("\t\tDesignation: %s\n",
lilv_node_as_string(lilv_nodes_get_first(designations)));
}
lilv_nodes_free(designations);

if (lilv_port_is_a(p, port, control_class)) {
if (!isnan(mins[index]))
printf("\t\tMinimum: %f\n", mins[index]);
if (!isnan(mins[index]))
printf("\t\tMaximum: %f\n", maxes[index]);
if (!isnan(mins[index]))
printf("\t\tDefault: %f\n", defaults[index]);
}

LilvNodes* properties = lilv_port_get_properties(p, port);
if (lilv_nodes_size(properties) > 0)
printf("\t\tProperties: ");
first = true;
LILV_FOREACH(nodes, i, properties) {
if (!first) {
printf("\t\t ");
}
printf("%s\n", lilv_node_as_uri(lilv_nodes_get(properties, i)));
first = false;
}
if (lilv_nodes_size(properties) > 0)
printf("\n");
lilv_nodes_free(properties);
}

static void
print_plugin(LilvWorld* world,
const LilvPlugin* p)
{
LilvNode* val = NULL;

printf("%s\n\n", lilv_node_as_uri(lilv_plugin_get_uri(p)));

val = lilv_plugin_get_name(p);
if (val) {
printf("\tName: %s\n", lilv_node_as_string(val));
lilv_node_free(val);
}

const LilvPluginClass* pclass = lilv_plugin_get_class(p);
const LilvNode* class_label = lilv_plugin_class_get_label(pclass);
if (class_label) {
printf("\tClass: %s\n", lilv_node_as_string(class_label));
}

val = lilv_plugin_get_author_name(p);
if (val) {
printf("\tAuthor: %s\n", lilv_node_as_string(val));
lilv_node_free(val);
}

val = lilv_plugin_get_author_email(p);
if (val) {
printf("\tAuthor Email: %s\n", lilv_node_as_uri(val));
lilv_node_free(val);
}

val = lilv_plugin_get_author_homepage(p);
if (val) {
printf("\tAuthor Homepage: %s\n", lilv_node_as_uri(val));
lilv_node_free(val);
}

if (lilv_plugin_has_latency(p)) {
uint32_t latency_port = lilv_plugin_get_latency_port_index(p);
printf("\tHas latency: yes, reported by port %d\n", latency_port);
} else {
printf("\tHas latency: no\n");
}

printf("\tBundle: %s\n",
lilv_node_as_uri(lilv_plugin_get_bundle_uri(p)));

const LilvNode* binary_uri = lilv_plugin_get_library_uri(p);
if (binary_uri) {
printf("\tBinary: %s\n",
lilv_node_as_uri(lilv_plugin_get_library_uri(p)));
}

LilvUIs* uis = lilv_plugin_get_uis(p);
if (lilv_nodes_size(uis) > 0) {
printf("\tUIs:\n");
LILV_FOREACH(uis, i, uis) {
const LilvUI* ui = lilv_uis_get(uis, i);
printf("\t\t%s\n", lilv_node_as_uri(lilv_ui_get_uri(ui)));

const char* binary = lilv_node_as_uri(lilv_ui_get_binary_uri(ui));

const LilvNodes* types = lilv_ui_get_classes(ui);
LILV_FOREACH(nodes, t, types) {
printf("\t\t\tClass: %s\n",
lilv_node_as_uri(lilv_nodes_get(types, t)));
}

if (binary)
printf("\t\t\tBinary: %s\n", binary);

printf("\t\t\tBundle: %s\n",
lilv_node_as_uri(lilv_ui_get_bundle_uri(ui)));
}
}
lilv_uis_free(uis);

printf("\tData URIs: ");
const LilvNodes* data_uris = lilv_plugin_get_data_uris(p);
bool first = true;
LILV_FOREACH(nodes, i, data_uris) {
if (!first) {
printf("\n\t ");
}
printf("%s", lilv_node_as_uri(lilv_nodes_get(data_uris, i)));
first = false;
}
printf("\n");

/* Required Features */

LilvNodes* features = lilv_plugin_get_required_features(p);
if (features)
printf("\tRequired Features: ");
first = true;
LILV_FOREACH(nodes, i, features) {
if (!first) {
printf("\n\t ");
}
printf("%s", lilv_node_as_uri(lilv_nodes_get(features, i)));
first = false;
}
if (features)
printf("\n");
lilv_nodes_free(features);

/* Optional Features */

features = lilv_plugin_get_optional_features(p);
if (features)
printf("\tOptional Features: ");
first = true;
LILV_FOREACH(nodes, i, features) {
if (!first) {
printf("\n\t ");
}
printf("%s", lilv_node_as_uri(lilv_nodes_get(features, i)));
first = false;
}
if (features)
printf("\n");
lilv_nodes_free(features);

/* Extension Data */

LilvNodes* data = lilv_plugin_get_extension_data(p);
if (data)
printf("\tExtension Data: ");
first = true;
LILV_FOREACH(nodes, i, data) {
if (!first) {
printf("\n\t ");
}
printf("%s", lilv_node_as_uri(lilv_nodes_get(data, i)));
first = false;
}
if (data)
printf("\n");
lilv_nodes_free(data);

/* Presets */

LilvNodes* presets = lilv_plugin_get_related(p, preset_class);
if (presets)
printf("\tPresets: \n");
LILV_FOREACH(nodes, i, presets) {
const LilvNode* preset = lilv_nodes_get(presets, i);
lilv_world_load_resource(world, preset);
LilvNodes* titles = lilv_world_find_nodes(
world, preset, label_pred, NULL);
if (titles) {
const LilvNode* title = lilv_nodes_get_first(titles);
printf("\t %s\n", lilv_node_as_string(title));
lilv_nodes_free(titles);
} else {
fprintf(stderr, "Preset <%s> has no rdfs:label\n",
lilv_node_as_string(lilv_nodes_get(presets, i)));
}
}
lilv_nodes_free(presets);

/* Ports */

const uint32_t num_ports = lilv_plugin_get_num_ports(p);
float* mins = (float*)calloc(num_ports, sizeof(float));
float* maxes = (float*)calloc(num_ports, sizeof(float));
float* defaults = (float*)calloc(num_ports, sizeof(float));
lilv_plugin_get_port_ranges_float(p, mins, maxes, defaults);

for (uint32_t i = 0; i < num_ports; ++i)
print_port(p, i, mins, maxes, defaults);

free(mins);
free(maxes);
free(defaults);
}

static void
print_version(void)
{
printf(
"lv2info (lilv) " LILV_VERSION "\n"
"Copyright 2007-2011 David Robillard <http://drobilla.net>\n"
"License: <http://www.opensource.org/licenses/isc-license>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n");
}

static void
print_usage(void)
{
printf(
"Usage: lv2info [OPTION]... PLUGIN_URI\n"
"Print information about an installed LV2 plugin.\n\n"
" -p FILE Write Turtle description of plugin to FILE\n"
" -m FILE Add record of plugin to manifest FILE\n"
" --help Display this help and exit\n"
" --version Display version information and exit\n\n"
"For -p and -m, Turtle files are appended to (not overwritten),\n"
"and @prefix directives are only written if the file was empty.\n"
"This allows several plugins to be added to a single file.\n");
}

int
main(int argc, char** argv)
{
if (argc == 1) {
print_usage();
return 1;
}

const char* plugin_file = NULL;
const char* manifest_file = NULL;
const char* plugin_uri = NULL;
for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "--version")) {
print_version();
return 0;
} else if (!strcmp(argv[i], "--help")) {
print_usage();
return 0;
} else if (!strcmp(argv[i], "-p")) {
plugin_file = argv[++i];
} else if (!strcmp(argv[i], "-m")) {
manifest_file = argv[++i];
} else if (argv[i][0] == '-') {
print_usage();
return 1;
} else if (i == argc - 1) {
plugin_uri = argv[i];
}
}

int ret = 0;

LilvWorld* world = lilv_world_new();
lilv_world_load_all(world);

LilvNode* uri = lilv_new_uri(world, plugin_uri);
if (!uri) {
fprintf(stderr, "Invalid plugin URI\n");
lilv_world_free(world);
return 1;
}

applies_to_pred = lilv_new_uri(world, LV2_CORE__appliesTo);
control_class = lilv_new_uri(world, LILV_URI_CONTROL_PORT);
event_class = lilv_new_uri(world, LILV_URI_EVENT_PORT);
group_pred = lilv_new_uri(world, LV2_PORT_GROUPS__group);
label_pred = lilv_new_uri(world, LILV_NS_RDFS "label");
preset_class = lilv_new_uri(world, LV2_PRESETS__Preset);
designation_pred = lilv_new_uri(world, LV2_CORE__designation);
supports_event_pred = lilv_new_uri(world, LV2_EVENT__supportsEvent);

const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
const LilvPlugin* p = lilv_plugins_get_by_uri(plugins, uri);

if (p && plugin_file) {
LilvNode* base = lilv_new_uri(world, plugin_file);

FILE* plugin_fd = fopen(plugin_file, "a");
lilv_plugin_write_description(world, p, base, plugin_fd);
fclose(plugin_fd);

if (manifest_file) {
FILE* manifest_fd = fopen(manifest_file, "a");
lilv_plugin_write_manifest_entry(
world, p, base, manifest_fd, plugin_file);
fclose(manifest_fd);
}
lilv_node_free(base);
} else if (p) {
print_plugin(world, p);
} else {
fprintf(stderr, "Plugin not found.\n");
}

ret = (p != NULL ? 0 : -1);

lilv_node_free(uri);

lilv_node_free(supports_event_pred);
lilv_node_free(designation_pred);
lilv_node_free(preset_class);
lilv_node_free(label_pred);
lilv_node_free(group_pred);
lilv_node_free(event_class);
lilv_node_free(control_class);
lilv_node_free(applies_to_pred);

lilv_world_free(world);
return ret;
}


+ 93
- 0
source/libs/lilv/lilv-0.14.4/utils/lv2ls.c View File

@@ -0,0 +1,93 @@
/*
Copyright 2007-2011 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 <stdio.h>
#include <string.h>

#include "lilv/lilv.h"

#include "lilv_config.h"

static void
list_plugins(const LilvPlugins* list, bool show_names)
{
LILV_FOREACH(plugins, i, list) {
const LilvPlugin* p = lilv_plugins_get(list, i);
if (show_names) {
LilvNode* n = lilv_plugin_get_name(p);
printf("%s\n", lilv_node_as_string(n));
lilv_node_free(n);
} else {
printf("%s\n", lilv_node_as_uri(lilv_plugin_get_uri(p)));
}
}
}

static void
print_version(void)
{
printf(
"lv2ls (lilv) " LILV_VERSION "\n"
"Copyright 2007-2011 David Robillard <http://drobilla.net>\n"
"License: <http://www.opensource.org/licenses/isc-license>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n");
}

static void
print_usage(void)
{
printf("Usage: lv2ls [OPTION]...\n");
printf("List all installed LV2 plugins.\n");
printf("\n");
printf(" -n, --names Show names instead of URIs\n");
printf(" --help Display this help and exit\n");
printf(" --version Display version information and exit\n");
printf("\n");
printf("The environment variable LV2_PATH can be used to control where\n");
printf("this (and all other lilv based LV2 hosts) will search for plugins.\n");
}

int
main(int argc, char** argv)
{
bool show_names = false;
for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "--names") || !strcmp(argv[i], "-n")) {
show_names = true;
} else if (!strcmp(argv[i], "--version")) {
print_version();
return 0;
} else if (!strcmp(argv[i], "--help")) {
print_usage();
return 0;
} else {
print_usage();
return 1;
}
}

LilvWorld* world = lilv_world_new();
lilv_world_load_all(world);

const LilvPlugins* plugins = lilv_world_get_all_plugins(world);

list_plugins(plugins, show_names);

lilv_world_free(world);

return 0;
}

+ 73
- 0
source/libs/lilv/lilv-0.14.4/utils/uri_table.h View File

@@ -0,0 +1,73 @@
/*
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.
*/

/**
@file uri_table.h A toy URI map/unmap implementation.

This file contains function definitions and must only be included once.
*/

#ifndef URI_TABLE_H
#define URI_TABLE_H

typedef struct {
char** uris;
size_t n_uris;
} URITable;

static void
uri_table_init(URITable* table)
{
table->uris = NULL;
table->n_uris = 0;
}

static void
uri_table_destroy(URITable* table)
{
free(table->uris);
}

static LV2_URID
uri_table_map(LV2_URID_Map_Handle handle,
const char* uri)
{
URITable* table = (URITable*)handle;
for (size_t i = 0; i < table->n_uris; ++i) {
if (!strcmp(table->uris[i], uri)) {
return i + 1;
}
}

const size_t len = strlen(uri);
table->uris = (char**)realloc(table->uris, ++table->n_uris * sizeof(char*));
table->uris[table->n_uris - 1] = malloc(len + 1);
memcpy(table->uris[table->n_uris - 1], uri, len + 1);
return table->n_uris;
}

static const char*
uri_table_unmap(LV2_URID_Map_Handle handle,
LV2_URID urid)
{
URITable* table = (URITable*)handle;
if (urid > 0 && urid <= table->n_uris) {
return table->uris[urid - 1];
}
return NULL;
}

#endif /* URI_TABLE_H */

BIN
source/libs/lilv/lilv-0.14.4/waf View File


+ 378
- 0
source/libs/lilv/lilv-0.14.4/wscript View File

@@ -0,0 +1,378 @@
#!/usr/bin/env python
import os
import sys
import subprocess

from waflib.extras import autowaf as autowaf
import waflib.Options as Options

# Version of this package (even if built as a child)
LILV_VERSION = '0.14.4'
LILV_MAJOR_VERSION = '0'

# Library version (UNIX style major, minor, micro)
# major increment <=> incompatible changes
# minor increment <=> compatible changes (additions)
# micro increment <=> no interface changes
# Lilv uses the same version number for both library and package
LILV_LIB_VERSION = LILV_VERSION

# Variables for 'waf dist'
APPNAME = 'lilv'
VERSION = LILV_VERSION

# Mandatory variables
top = '.'
out = 'build'

def options(opt):
opt.load('compiler_c')
opt.load('compiler_cxx')
opt.load('python')
autowaf.set_options(opt)
opt.add_option('--no-utils', action='store_true', dest='no_utils',
help='Do not build command line utilities')
opt.add_option('--bindings', action='store_true', dest='bindings',
help='Build python bindings')
opt.add_option('--dyn-manifest', action='store_true', dest='dyn_manifest',
help='Build support for dynamic manifests')
opt.add_option('--test', action='store_true', dest='build_tests',
help='Build unit tests')
opt.add_option('--no-bash-completion', action='store_true',
dest='no_bash_completion',
help='Do not install bash completion script in CONFIGDIR')
opt.add_option('--static', action='store_true', dest='static',
help='Build static library')
opt.add_option('--no-shared', action='store_true', dest='no_shared',
help='Do not build shared library')
opt.add_option('--static-progs', action='store_true', dest='static_progs',
help='Build programs as static binaries')
opt.add_option('--default-lv2-path', type='string', default='',
dest='default_lv2_path',
help='Default LV2 path to use if LV2_PATH is unset')

def configure(conf):
conf.load('compiler_c')

if Options.options.bindings:
try:
conf.load('swig')
conf.load('python')
conf.load('compiler_cxx')
conf.check_python_headers()
autowaf.define(conf, 'LILV_PYTHON', 1);
except:
pass

autowaf.configure(conf)
autowaf.set_c99_mode(conf)
autowaf.display_header('Lilv Configuration')

conf.env.BASH_COMPLETION = not Options.options.no_bash_completion
conf.env.BUILD_TESTS = Options.options.build_tests
conf.env.BUILD_UTILS = not Options.options.no_utils
conf.env.BUILD_SHARED = not Options.options.no_shared
conf.env.STATIC_PROGS = Options.options.static_progs
conf.env.BUILD_STATIC = (Options.options.static or
Options.options.static_progs)

if not conf.env.BUILD_SHARED and not conf.env.BUILD_STATIC:
conf.fatal('Neither a shared nor a static build requested')

autowaf.check_pkg(conf, 'lv2', uselib_store='LV2',
atleast_version='1.0.0', mandatory=True)
autowaf.check_pkg(conf, 'serd-0', uselib_store='SERD',
atleast_version='0.14.0', mandatory=True)
autowaf.check_pkg(conf, 'sord-0', uselib_store='SORD',
atleast_version='0.8.0', mandatory=True)
autowaf.check_pkg(conf, 'sratom-0', uselib_store='SRATOM',
atleast_version='0.2.0', mandatory=True)

autowaf.define(conf, 'LILV_NEW_LV2', 1) # New LV2 discovery API

defines = ['_POSIX_C_SOURCE', '_BSD_SOURCE']
if Options.platform == 'darwin':
defines += ['_DARWIN_C_SOURCE']

# Check for gcov library (for test coverage)
if conf.env.BUILD_TESTS:
conf.check_cc(lib='gcov',
define_name='HAVE_GCOV',
mandatory=False)

conf.check_cc(function_name='flock',
header_name='sys/file.h',
defines=defines,
define_name='HAVE_FLOCK',
mandatory=False)

conf.check_cc(function_name='fileno',
header_name='stdio.h',
defines=defines,
define_name='HAVE_FILENO',
mandatory=False)

conf.check_cc(function_name='clock_gettime',
header_name=['sys/time.h','time.h'],
defines=['_POSIX_C_SOURCE=199309L'],
define_name='HAVE_CLOCK_GETTIME',
uselib_store='CLOCK_GETTIME',
lib=['rt'],
mandatory=False)

autowaf.define(conf, 'LILV_VERSION', LILV_VERSION)
if Options.options.dyn_manifest:
autowaf.define(conf, 'LILV_DYN_MANIFEST', 1)

lilv_path_sep = ':'
lilv_dir_sep = '/'
if sys.platform == 'win32':
lilv_path_sep = ';'
lilv_dir_sep = '\\\\'

autowaf.define(conf, 'LILV_PATH_SEP', lilv_path_sep)
autowaf.define(conf, 'LILV_DIR_SEP', lilv_dir_sep)

# Set default LV2 path
lv2_path = Options.options.default_lv2_path
if lv2_path == '':
if Options.platform == 'darwin':
lv2_path = lilv_path_sep.join(['~/Library/Audio/Plug-Ins/LV2',
'~/.lv2',
'/usr/local/lib/lv2',
'/usr/lib/lv2',
'/Library/Audio/Plug-Ins/LV2'])
elif Options.platform == 'haiku':
lv2_path = lilv_path_sep.join(['~/.lv2',
'/boot/common/add-ons/lv2'])
elif Options.platform == 'win32':
lv2_path = lilv_path_sep.join(['%APPDATA%\\\\LV2',
'%COMMONPROGRAMFILES%\\\\LV2'])
else:
libdirname = os.path.basename(conf.env.LIBDIR)
lv2_path = lilv_path_sep.join(['~/.lv2',
'/usr/%s/lv2' % libdirname,
'/usr/local/%s/lv2' % libdirname])
autowaf.define(conf, 'LILV_DEFAULT_LV2_PATH', lv2_path)

conf.env.LIB_LILV = ['lilv-%s' % LILV_MAJOR_VERSION]

conf.write_config_header('lilv_config.h', remove=False)

autowaf.display_msg(conf, 'Default LV2_PATH',
conf.env.LILV_DEFAULT_LV2_PATH)
autowaf.display_msg(conf, 'Utilities',
bool(conf.env.BUILD_UTILS))
autowaf.display_msg(conf, 'Unit tests',
bool(conf.env.BUILD_TESTS))
autowaf.display_msg(conf, 'Dynamic manifest support',
bool(conf.env.LILV_DYN_MANIFEST))
autowaf.display_msg(conf, 'Python bindings',
conf.is_defined('LILV_PYTHON'))

conf.undefine('LILV_DEFAULT_LV2_PATH') # Cmd line errors with VC++
print('')

def build_util(bld, name, defines):
obj = bld(features = 'c cprogram',
source = name + '.c',
includes = ['.', './src', './utils'],
use = 'liblilv',
target = name,
defines = defines,
install_path = '${BINDIR}')
if not bld.env.BUILD_SHARED or bld.env.STATIC_PROGS:
obj.use = 'liblilv_static'
if bld.env.STATIC_PROGS:
if not bld.env.MSVC_COMPILER:
obj.lib = ['m']
obj.env.SHLIB_MARKER = obj.env.STLIB_MARKER
obj.linkflags = ['-static', '-Wl,--start-group']
return obj

def build(bld):
# C/C++ Headers
includedir = '${INCLUDEDIR}/lilv-%s/lilv' % LILV_MAJOR_VERSION
bld.install_files(includedir, bld.path.ant_glob('lilv/*.h'))
bld.install_files(includedir, bld.path.ant_glob('lilv/*.hpp'))

# Pkgconfig file
autowaf.build_pc(bld, 'LILV', LILV_VERSION, LILV_MAJOR_VERSION, [],
{'LILV_MAJOR_VERSION' : LILV_MAJOR_VERSION,
'LILV_PKG_DEPS' : 'lv2 serd-0 sord-0 sratom-0'})

lib_source = '''
src/collections.c
src/instance.c
src/lib.c
src/node.c
src/plugin.c
src/pluginclass.c
src/port.c
src/query.c
src/scalepoint.c
src/state.c
src/ui.c
src/util.c
src/world.c
src/zix/tree.c
'''.split()

lib = ['dl']
libflags = ['-fvisibility=hidden']
defines = []
if sys.platform == 'win32':
lib = []
if bld.env.MSVC_COMPILER:
libflags = []
defines = ['snprintf=_snprintf']
elif sys.platform.find('bsd') > 0:
lib = []

# Shared Library
if bld.env.BUILD_SHARED:
obj = bld(features = 'c cshlib',
export_includes = ['.'],
source = lib_source,
includes = ['.', './src'],
name = 'liblilv',
target = 'lilv-%s' % LILV_MAJOR_VERSION,
vnum = LILV_LIB_VERSION,
install_path = '${LIBDIR}',
defines = ['LILV_SHARED', 'LILV_INTERNAL'],
cflags = libflags,
lib = lib)
autowaf.use_lib(bld, obj, 'SORD SRATOM LV2')

# Static library
if bld.env.BUILD_STATIC:
obj = bld(features = 'c cstlib',
export_includes = ['.'],
source = lib_source,
includes = ['.', './src'],
name = 'liblilv_static',
target = 'lilv-%s' % LILV_MAJOR_VERSION,
vnum = LILV_LIB_VERSION,
install_path = '${LIBDIR}',
defines = defines + ['LILV_INTERNAL'])
autowaf.use_lib(bld, obj, 'SORD SRATOM LV2')

if bld.env.BUILD_TESTS:
test_libs = lib
test_cflags = ['']
if bld.is_defined('HAVE_GCOV'):
test_libs += ['gcov']
test_cflags += ['-fprofile-arcs', '-ftest-coverage']

# Test plugin library
penv = bld.env.derive()
shlib_pattern = penv.cshlib_PATTERN
if shlib_pattern.startswith('lib'):
shlib_pattern = shlib_pattern[3:]
penv.cshlib_PATTERN = shlib_pattern
shlib_ext = shlib_pattern[shlib_pattern.rfind('.'):]

obj = bld(features = 'c cshlib',
env = penv,
source = 'test/test_plugin.c',
name = 'test_plugin',
target = 'test/test_plugin.lv2/test_plugin',
install_path = None,
defines = defines,
cflags = test_cflags,
lib = test_libs,
uselib = 'LV2')

# Test plugin data files
for i in [ 'manifest.ttl.in', 'test_plugin.ttl.in' ]:
bld(features = 'subst',
source = 'test/' + i,
target = 'test/test_plugin.lv2/' + i.replace('.in', ''),
install_path = None,
SHLIB_EXT = shlib_ext)

# Static profiled library (for unit test code coverage)
obj = bld(features = 'c cstlib',
source = lib_source,
includes = ['.', './src'],
name = 'liblilv_profiled',
target = 'lilv_profiled',
install_path = None,
defines = defines + ['LILV_INTERNAL'],
cflags = test_cflags,
lib = test_libs)
autowaf.use_lib(bld, obj, 'SORD SRATOM LV2')

# Unit test program
bpath = os.path.abspath(os.path.join(out, 'test', 'test_plugin.lv2'))
bpath = bpath.replace('\\', '/')
obj = bld(features = 'c cprogram',
source = 'test/lilv_test.c',
includes = ['.', './src'],
use = 'liblilv_profiled',
uselib = 'SORD LV2',
lib = test_libs,
target = 'test/lilv_test',
install_path = None,
defines = defines + ['LILV_TEST_BUNDLE=\"%s/\"' % bpath],
cflags = test_cflags)
autowaf.use_lib(bld, obj, 'SORD SRATOM LV2')

# Utilities
if bld.env.BUILD_UTILS:
utils = '''
utils/lilv-bench
utils/lv2info
utils/lv2ls
'''
for i in utils.split():
build_util(bld, i, defines)

# lv2bench (less portable than other utilities)
if bld.is_defined('HAVE_CLOCK_GETTIME'):
obj = build_util(bld, 'utils/lv2bench', defines)
if not bld.env.MSVC_COMPILER:
obj.lib = ['rt']

# Documentation
autowaf.build_dox(bld, 'LILV', LILV_VERSION, top, out)

# Man pages
bld.install_files('${MANDIR}/man1', bld.path.ant_glob('doc/*.1'))

# Bash completion
if bld.env.BASH_COMPLETION:
bld.install_as(
'${SYSCONFDIR}/bash_completion.d/lilv', 'utils/lilv.bash_completion')

if bld.is_defined('LILV_PYTHON'):
# Python Wrapper
obj = bld(features = 'cxx cxxshlib pyext',
source = 'bindings/lilv.i',
target = 'bindings/_lilv',
includes = ['..'],
swig_flags = '-c++ -python -Wall -I.. -llilv -features autodoc=1',
use = 'liblilv')
autowaf.use_lib(bld, obj, 'LILV')

bld.install_files('${PYTHONDIR}', 'bindings/lilv.py')

bld.add_post_fun(autowaf.run_ldconfig)
if bld.env.DOCS:
bld.add_post_fun(fix_docs)

def fix_docs(ctx):
if ctx.cmd == 'build':
autowaf.make_simple_dox(APPNAME)

def upload_docs(ctx):
os.system('rsync -ravz --delete -e ssh build/doc/html/ drobilla@drobilla.net:~/drobilla.net/docs/lilv/')

def test(ctx):
autowaf.pre_test(ctx, APPNAME)
os.environ['PATH'] = 'test' + os.pathsep + os.getenv('PATH')
autowaf.run_tests(ctx, APPNAME, ['lilv_test'], dirs=['./src','./test'])
autowaf.post_test(ctx, APPNAME)

def lint(ctx):
subprocess.call('cpplint.py --filter=+whitespace/comments,-whitespace/tab,-whitespace/braces,-whitespace/labels,-build/header_guard,-readability/casting,-readability/todo,-build/include,-runtime/sizeof src/* lilv/*', shell=True)

+ 31
- 0
source/libs/lilv/lilv.c View File

@@ -0,0 +1,31 @@
/*
* Carla static lilv code
* Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "src/collections.c"
#include "src/instance.c"
#include "src/lib.c"
#include "src/node.c"
#include "src/plugin.c"
#include "src/pluginclass.c"
#include "src/port.c"
#include "src/query.c"
#include "src/scalepoint.c"
#include "src/state.c"
#include "src/ui.c"
#include "src/util.c"
#include "src/world.c"
#include "src/zix/tree.c"

+ 1
- 0
source/libs/lilv/serd-0.18.2/AUTHORS View File

@@ -0,0 +1 @@
David Robillard <d@drobilla.net>

+ 13
- 0
source/libs/lilv/serd-0.18.2/COPYING View File

@@ -0,0 +1,13 @@
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.

+ 59
- 0
source/libs/lilv/serd-0.18.2/INSTALL View File

@@ -0,0 +1,59 @@
Installation Instructions
=========================

Basic Installation
------------------

Building this software requires only Python. To install with default options:

./waf configure
./waf
./waf install

You may need to become root for the install stage, for example:

sudo ./waf install

Configuration Options
---------------------

All supported options can be viewed using the command:

./waf --help

Most options only need to be passed during the configure stage, for example:

./waf configure --prefix=/usr
./waf
./waf install

Compiler Configuration
----------------------

Several standard environment variables can be used to control how compilers are
invoked:

* CC: Path to C compiler
* CFLAGS: C compiler options
* CXX: Path to C++ compiler
* CXXFLAGS: C++ compiler options
* CPPFLAGS: C preprocessor options
* LINKFLAGS: Linker options

Installation Directories
------------------------

The --prefix option (or the PREFIX environment variable) can be used to change
the prefix which all files are installed under. There are also several options
allowing for more fine-tuned control, see the --help output for details.

Packaging
---------

Everything can be installed to a specific root directory by passing a --destdir
option to the install stage (or setting the DESTDIR environment variable),
which adds a prefix to all install paths. For example:

./waf configure --prefix=/usr
./waf
./waf install --destdir=/tmp/package

+ 98
- 0
source/libs/lilv/serd-0.18.2/NEWS View File

@@ -0,0 +1,98 @@
serd (0.18.2) stable;

* Fix crash when serd_node_new_decimal is called with infinity or NaN
* Fix crash when resolving against non-standard base URIs
* Fix bug that caused "a" abbreviation in non-predicate position
* Disable timestamps in HTML documentation for reproducible build
* Fix clashing symbol "error" in amalgamation build
* Update to waf 1.7.8 and autowaf r90 (install docs to versioned directory)

-- David Robillard <d@drobilla.net> Sat, 22 Dec 2012 21:32:15 -0500

serd (0.18.0) stable;

* Support digits at start of local names as per new Turtle grammar
* Add incremental read interface suitable for reading from infinite streams
* Add -e option to serdi to use incremental reading
* Add error callback to reader and writer for custom error reporting
* Add -q option to serdi to suppress all non-data output, e.g. errors
* Reset indent when finishing a write
* Report write size correctly when invalid UTF-8 is encountered and a
replacement character is written
* Strip down API documentation to a single clean page
* Fix various hyper-strict warnings
* Do not require a C++ compiler to build
* Add option to build utilities as static binaries
* Upgrade to waf 1.7.2

-- David Robillard <d@drobilla.net> Thu, 23 Aug 2012 00:18:34 -0400

serd (0.14.0) stable;

* Use path variables in pkgconfig files
* Install man page to DATADIR (e.g. PREFIX/share/man, not PREFIX/man)
* Tolerate invalid characters in string literals by replacing with the
Unicode replacement character
* Report reason for failure to open file in serdi
* Improve write performance by doing bulk writes for unescaped substrings
* Add SerdBulkSink for writing bulk output and corresponding serdi -B option
* Add serdi -f option to prevent URI qualification
* Remove use of multi-byte peek (readahead) and use exactly 1 page for
read buffer (instead of 2)
* Handle a quote as the last character of a long string literal in the
writer (by escaping it) rather than the reader, to avoid writing Turtle
other tools fail to parse.
* Add serd_strtod(), serd_node_new_decimal(), and serd_node_new_integer()
for locale-independent numeric node parsing/serialising.
* Add serd_file_sink for easy writing to a FILE* stream.
* Add serd_chunk_sink for easy writing to a string.
* Escape ASCII control characters in output (e.g. fix problems with string
literals that start with a backspace)
* Improve URI resolution to cover most of the abnormal cases from RFC3986
* Support file://localhost/foo URIs in serd_uri_to_path()
* Support Windows file://c:/foo URIs in serd_uri_to_path() on all platforms
* Add serd_node_new_blob and serd_base64_decode for handling arbitrary
binary data via base64 encoding.
* Support compilation as C++ under MSVC++.
* Implement pretty-printing for collections.
* Parse collections iteratively in O(1) space.
* Report read error if both "genid" and "docid" IDs are found in the same
document, to prevent silent merging of distinct blank nodes.
* Handle files and strings that start with a UTF-8 Byte Order Mark.
* Add serd_writer_get_env().
* Add serd_node_new_file_uri() and serd_file_uri_parse() and implement
proper URI to/from path hex escaping, etc.
* Add serd_uri_serialise_relative() for making URIs relative to a base
where possible (by chopping a common prefix and adding dot segments).
* Make URIs serialised by the writer properly escape characters.
* Add serd_writer_set_root_uri() and corresponding -r option to serdi to
enable writing URIs with up references (../).
* Resolve dot segments in serd_uri_resolve() instead of at write time.
* Add serd_reader_set_default_graph() for reading a file as a named graph.

-- David Robillard <d@drobilla.net> Tue, 17 Apr 2012 18:23:53 -0400

serd (0.5.0) stable;

* Fix pretty printing of successive blank descriptions, i.e. "] , ["
* Avoid writing illegal Turtle names as a result of URI qualifying
* Gracefully handle NULL reader sinks
* Add serd_strerror
* Add serd_env_set_prefix_from_strings for convenience
* Fix erroneously equal SERD_ERR_BAD_SYNTAX and SERD_ERR_BAD_ARG
* Add ability to build static library

-- David Robillard <d@drobilla.net> Thu, 29 Sep 2011 00:00:00 -0400

serd (0.4.2) stable;

* Fix compilation issues on some systems
* Fix build system Python 3 compatibility

-- David Robillard <d@drobilla.net> Wed, 25 May 2011 19:00:00 -0400

serd (0.4.0) stable;

* Initial release

-- David Robillard <d@drobilla.net> Tue, 24 May 2011 23:00:00 -0400

+ 29
- 0
source/libs/lilv/serd-0.18.2/PACKAGING View File

@@ -0,0 +1,29 @@
This library is designed to allow parallel installation of different major
versions. To facilitate this, the shared library name, include directory, and
pkg-config file are suffixed with the major version number of the library.

For example, if this library was named "foo" and at version 1.x.y:

/usr/include/foo-1/foo/foo.h
/usr/lib/foo-1.so.1.x.y
/usr/lib/pkgconfig/foo-1.pc

Dependencies check for pkg-config name "foo-1" and will build
against a compatible version 1, regardless any other installed versions.

*** IMPORTANT GUIDELINES FOR PACKAGERS ***

Packages should follow the same conventions as above, i.e. include the major
version (and only the major version) in the name of the package. Continuing the
example above, the package(s) would be named foo-1 and foo-1-dev. This way,
if/when version 2 comes out, it may be installed at the same time as version 1
without breaking anything.

Please do not create packages of this library that do not follow these
guidelines, you will break things and cause unnecessary headaches. Please do
not use any number as a suffix other than the actual major version number of the
upstream source package.

Because program and documentation names are not versioned, these should be
included in separate packages which may replace previous versions, since
there is little use in having parallel installations of them.

+ 10
- 0
source/libs/lilv/serd-0.18.2/README View File

@@ -0,0 +1,10 @@
Serd
----

Serd is a lightweight C library for RDF syntax which supports reading and
writing Turtle and NTriples.

For more information, see <http://drobilla.net/software/serd>.

-- David Robillard <d@drobilla.net>


+ 187
- 0
source/libs/lilv/serd-0.18.2/doc/layout.xml View File

@@ -0,0 +1,187 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>

<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>

<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>

<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>

<!-- Layout definition for a group page -->
<group>
<briefdescription visible="no"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>

<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

+ 1792
- 0
source/libs/lilv/serd-0.18.2/doc/reference.doxygen.in
File diff suppressed because it is too large
View File


+ 72
- 0
source/libs/lilv/serd-0.18.2/doc/serdi.1 View File

@@ -0,0 +1,72 @@
.TH SERDI 1 "08 May 2012"

.SH NAME
.B serdi \- Read and write RDF syntax

.SH SYNOPSIS
serdi [OPTION]... INPUT BASE_URI

.SH OPTIONS

.TP
\fB\-b\fR
Fast bulk output for large serialisations.

.TP
\fB\-c PREFIX\fR
Chop PREFIX from matching blank node IDs.

.TP
\fB\-e\fR
Eat input one character at a time, rather than a page at a time which is the
default. This is useful when reading from a pipe since output will be
generated immediately as input arrives, rather than waiting until an entire
page of input has arrived. With this option serdi uses one page less memory,
but will likely be significantly slower.

.TP
\fB\-f\fR
Keep full URIs in input (don't qualify).

.TP
\fB\-h\fR
Print the command line options.

.TP
\fB\-i SYNTAX\fR
Read input in SYNTAX (`turtle' or `ntriples').

.TP
\fB\-o SYNTAX\fR
Write output in SYNTAX (`turtle' or `ntriples').

.TP
\fB\-p PREFIX\fR
Add PREFIX to blank node IDs.

.TP
\fB\-r ROOT_URI\fR
Keep relative URIs within ROOT_URI.

.TP
\fB\-s INPUT\fR
Parse INPUT as a string (terminates options).

.TP
\fB\-v\fR
Display version information and exit.

.SH AUTHOR
Serdi was written by David Robillard <d@drobilla.net>

.SH COPYRIGHT
Copyright \(co 2011-2012 David Robillard.
.br
License: <http://www.opensource.org/licenses/isc>
.br
This is free software; you are free to change and redistribute it.
.br
There is NO WARRANTY, to the extent permitted by law.

.SH "SEE ALSO"
<http://drobilla.net/software/serd>

+ 563
- 0
source/libs/lilv/serd-0.18.2/doc/style.css View File

@@ -0,0 +1,563 @@
body {
font-size: medium;
font-family: sans-serif;
}

#top {
background-color: #F3F3F3;
margin: 0;
padding: 0;
border-bottom: 1px solid #DDD;
margin-bottom: 1ex;
font-size: xx-large;
font-weight: bold;
}

div.header {
display: none;
}

.tabs {
display: none;
}

h1 h2 h3 h4 h5 h6 {
font-weight: bold;
}

h1 {
font-size: 164%;
}

h2 {
font-size: 132%;
}

h3 {
font-size: 124%;
}

h4 {
font-size: 116%;
}

h5 {
font-size: 108%;
}

h6 {
font-size: 100%;
}

p {
margin: 0 0 1ex 0;
}

br {
display: none;
}

dt {
font-weight: 700;
}

div.multicol {
}

p.startli,p.startdd,p.starttd {
margin-top: 2px;
}

p.endli {
margin-bottom: 0;
}

p.enddd {
margin-bottom: 4px;
}

p.endtd {
margin-bottom: 2px;
}

caption {
font-weight: 700;
}

span.legend {
font-size: 70%;
text-align: center;
}

h3.version {
font-size: 90%;
text-align: center;
}

div.qindex,div.navtab {
background-color: #EBEFF6;
border: 1px solid #A3B4D7;
text-align: center;
margin: 2px;
padding: 2px;
}

div.qindex,div.navpath {
width: 100%;
line-height: 140%;
}

div.navtab {
margin-right: 15px;
}

/* @group Link Styling */
a {
color: #3D8C57;
text-decoration: none;
}

.contents a:visited {
color: #50755E;
}

a:hover {
text-decoration: underline;
}

a.qindexHL {
background-color: #9CAFD4;
color: #FFF;
border: 1px double #869DCA;
}

a.code {
color: #4665A2;
}

a.codeRef {
color: #4665A2;
}

/* @end */
dl.el {
margin-left: -1cm;
}

.fragment {
font-family: monospace, fixed;
font-size: 105%;
}

pre.fragment {
border: 1px solid #C4C4C4;
background-color: #F9F9F9;
padding: 4px 6px;
margin: 4px 8px 4px 2px;
overflow: auto;
font-size: 9pt;
line-height: 125%;
}

div.ah {
background-color: #000;
font-weight: 700;
color: #FFF;
margin-bottom: 3px;
margin-top: 3px;
padding: .2em;
border: thin solid #333;
}

div.groupHeader {
margin-left: 16px;
margin-top: 12px;
margin-bottom: 6px;
font-weight: 700;
}

div.groupText {
margin-left: 16px;
font-style: italic;
}

body {
background: #FFF;
color: #000;
margin: 0;
}

div.contents {
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
}

td.indexkey {
background-color: #EBEFF6;
font-weight: 700;
border: 1px solid #C4CFE5;
margin: 2px 0;
padding: 2px 10px;
}

td.indexvalue {
background-color: #EBEFF6;
border: 1px solid #C4CFE5;
padding: 2px 10px;
margin: 2px 0;
}

tr.memlist {
background-color: #EEF1F7;
}

p.formulaDsp {
text-align: center;
}

img.formulaDsp {
}

img.formulaInl {
vertical-align: middle;
}

div.center {
text-align: center;
margin-top: 0;
margin-bottom: 0;
padding: 0;
}

div.center img {
border: 0;
}

address.footer {
text-align: right;
padding: 0 0.25em 0.25em 0;
}

img.footer {
border: 0;
vertical-align: middle;
}

/* @group Code Colorization */
span.keyword {
color: green;
}

span.keywordtype {
color: #604020;
}

span.keywordflow {
color: #e08000;
}

span.comment {
color: maroon;
}

span.preprocessor {
color: #806020;
}

span.stringliteral {
color: #002080;
}

span.charliteral {
color: teal;
}

span.vhdldigit {
color: #F0F;
}

span.vhdlkeyword {
color: #700070;
}

span.vhdllogic {
color: red;
}

/* @end */
td.tiny {
font-size: 75%;
}

.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #A3B4D7;
}

th.dirtab {
background: #EBEFF6;
font-weight: 700;
}

hr {
height: 0;
border: none;
border-top: 1px solid #DDD;
margin: 2em 0 1em;
}

hr.footer {
height: 1px;
}

/* @group Member Descriptions */
table.memberdecls {
border-spacing: 0;
font-size: small;
}

.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams {
background-color: #FBFBFB;
margin: 0;
padding: 0.25ex;
}

.mdescLeft,.mdescRight {
color: #555;
}

.memItemLeft,.memItemRight,.memTemplParams {
border-top: 1px solid #DDD;
}

.memItemLeft,.memTemplItemLeft {
white-space: nowrap;
padding-left: 2em;
}

.memTemplParams {
color: #464646;
white-space: nowrap;
}

/* @end */
/* @group Member Details */
/* Styles for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #4665A2;
font-weight: bold;
}

.memnav {
background-color: #EBEFF6;
border: 1px solid #A3B4D7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}

.memitem {
padding: 0;
margin: 1ex 0 2ex 0;
border: 1px solid #CCC;
}

.memname {
white-space: nowrap;
font-weight: bold;
}

.memproto {
border-bottom: 1px solid #DDD;
padding: 0.5ex;
font-weight: bold;
background-color: #F3F3F3;
}

.memdoc {
padding: 1ex;
background-color: #FBFBFB;
border-top-width: 0;
}

.paramkey {
text-align: right;
}

.paramtype {
white-space: nowrap;
}

.paramname {
color: #602020;
white-space: nowrap;
}

.paramname em {
font-style: normal;
}

/* @end */
/* @group Directory (tree) */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin: 0;
}

/* these are for tree view when used as main index */
.directory {
font-size: 9pt;
font-weight: bold;
margin: 5px;
}

.directory h3 {
margin: 0;
margin-top: 1em;
font-size: 11pt;
}

.directory > h3 {
margin-top: 0;
}

.directory p {
margin: 0;
white-space: nowrap;
}

.directory div {
display: none;
margin: 0;
}

.directory img {
vertical-align: -30%;
}

/* these are for tree view when not used as main index */
.directory-alt {
font-size: 100%;
font-weight: bold;
}

.directory-alt h3 {
margin: 0;
margin-top: 1em;
font-size: 11pt;
}

.directory-alt > h3 {
margin-top: 0;
}

.directory-alt p {
margin: 0;
white-space: nowrap;
}

.directory-alt div {
display: none;
margin: 0;
}

.directory-alt img {
vertical-align: -30%;
}

/* @end */
div.dynheader {
margin-top: 8px;
}

address {
font-style: normal;
color: #2A3D61;
}

table.doxtable {
border-collapse: collapse;
margin: 0.5ex;
}

table.doxtable td,table.doxtable th {
border: 1px solid #DDD;
padding: 3px 7px 2px;
}

table.doxtable th {
background-color: #F3F3F3;
color: #000;
padding-bottom: 4px;
padding-top: 5px;
text-align: left;
font-weight: bold;
}

.tabsearch {
top: 0;
left: 10px;
height: 36px;
z-index: 101;
overflow: hidden;
font-size: 13px;
}

.navpath ul {
font-size: 11px;
height: 30px;
line-height: 30px;
color: #8AA0CC;
border: 1px solid #C2CDE4;
overflow: hidden;
margin: 0;
padding: 0;
}

.navpath li {
list-style-type: none;
float: left;
padding-left: 10px;
padding-right: 15px;
color: #364D7C;
}

.navpath a {
height: 32px;
display: block;
text-decoration: none;
outline: none;
}

.navpath a:hover {
color: #6884BD;
}

div.summary {
float: right;
font-size: 8pt;
padding-right: 5px;
width: 50%;
text-align: right;
}

div.summary a {
white-space: nowrap;
}

div.header {
background-color: #F3F3F3;
margin: 0;
border-bottom: 1px solid #DDD;
}

div.headertitle {
padding: 5px 5px 5px 10px;
font-size: 180%;
font-weight: bold;
}

+ 10
- 0
source/libs/lilv/serd-0.18.2/serd.pc.in View File

@@ -0,0 +1,10 @@
prefix=@PREFIX@
exec_prefix=@EXEC_PREFIX@
libdir=@LIBDIR@
includedir=@INCLUDEDIR@

Name: Serd
Version: @SERD_VERSION@
Description: Lightweight RDF syntax library
Libs: -L${libdir} -l@LIB_SERD@
Cflags: -I${includedir}/serd-@SERD_MAJOR_VERSION@

+ 963
- 0
source/libs/lilv/serd-0.18.2/serd/serd.h View File

@@ -0,0 +1,963 @@
/*
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.
*/

/**
@file serd.h API for Serd, a lightweight RDF syntax library.
*/

#ifndef SERD_SERD_H
#define SERD_SERD_H

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#ifdef SERD_SHARED
# ifdef _WIN32
# define SERD_LIB_IMPORT __declspec(dllimport)
# define SERD_LIB_EXPORT __declspec(dllexport)
# else
# define SERD_LIB_IMPORT __attribute__((visibility("default")))
# define SERD_LIB_EXPORT __attribute__((visibility("default")))
# endif
# ifdef SERD_INTERNAL
# define SERD_API SERD_LIB_EXPORT
# else
# define SERD_API SERD_LIB_IMPORT
# endif
#else
# define SERD_API
#endif

#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif

/**
@defgroup serd Serd
A lightweight RDF syntax library.
@{
*/

/**
Environment.

Represents the state required to resolve a CURIE or relative URI, e.g. the
base URI and set of namespace prefixes at a particular point.
*/
typedef struct SerdEnvImpl SerdEnv;

/**
RDF reader.

Parses RDF by calling user-provided sink functions as input is consumed
(much like an XML SAX parser).
*/
typedef struct SerdReaderImpl SerdReader;

/**
RDF writer.

Provides a number of functions to allow writing RDF syntax out to some
stream. These functions are deliberately compatible with the sink functions
used by SerdReader, so a reader can be directly connected to a writer to
re-serialise a document with minimal overhead.
*/
typedef struct SerdWriterImpl SerdWriter;

/**
Return status code.
*/
typedef enum {
SERD_SUCCESS, /**< No error */
SERD_FAILURE, /**< Non-fatal failure */
SERD_ERR_UNKNOWN, /**< Unknown error */
SERD_ERR_BAD_SYNTAX, /**< Invalid syntax */
SERD_ERR_BAD_ARG, /**< Invalid argument */
SERD_ERR_NOT_FOUND, /**< Not found */
SERD_ERR_ID_CLASH, /**< Encountered clashing blank node IDs */
SERD_ERR_BAD_CURIE, /**< Invalid CURIE (e.g. prefix does not exist) */
SERD_ERR_INTERNAL /**< Unexpected internal error (should not happen) */
} SerdStatus;

/**
RDF syntax type.
*/
typedef enum {
/**
Turtle - Terse RDF Triple Language (UTF-8).
@see <a href="http://www.w3.org/TeamSubmission/turtle/">Turtle</a>
*/
SERD_TURTLE = 1,

/**
NTriples - Line-based RDF triples (ASCII).
@see <a href="http://www.w3.org/TR/rdf-testcases#ntriples">NTriples</a>
*/
SERD_NTRIPLES = 2
} SerdSyntax;

/**
Flags indication inline abbreviation information for a statement.
*/
typedef enum {
SERD_EMPTY_S = 1 << 1, /**< Empty blank node subject */
SERD_EMPTY_O = 1 << 2, /**< Empty blank node object */
SERD_ANON_S_BEGIN = 1 << 3, /**< Start of anonymous subject */
SERD_ANON_O_BEGIN = 1 << 4, /**< Start of anonymous object */
SERD_ANON_CONT = 1 << 5, /**< Continuation of anonymous node */
SERD_LIST_S_BEGIN = 1 << 6, /**< Start of list subject */
SERD_LIST_O_BEGIN = 1 << 7, /**< Start of list object */
SERD_LIST_CONT = 1 << 8 /**< Continuation of list */
} SerdStatementFlag;

/**
Bitwise OR of SerdNodeFlag values.
*/
typedef uint32_t SerdStatementFlags;

/**
Type of a syntactic RDF node.

This is more precise than the type of an abstract RDF node. An abstract
node is either a resource, literal, or blank. In syntax there are two ways
to refer to a resource (by URI or CURIE) and two ways to refer to a blank
(by ID or anonymously). Anonymous (inline) blank nodes are expressed using
SerdStatementFlags rather than this type.
*/
typedef enum {
/**
The type of a nonexistent node.

This type is useful as a sentinel, but is never emitted by the reader.
*/
SERD_NOTHING = 0,

/**
Literal value.

A literal optionally has either a language, or a datatype (not both).
*/
SERD_LITERAL = 1,

/**
URI (absolute or relative).

Value is an unquoted URI string, which is either a relative reference
with respect to the current base URI (e.g. "foo/bar"), or an absolute
URI (e.g. "http://example.org/foo").
@see <a href="http://tools.ietf.org/html/rfc3986">RFC3986</a>.
*/
SERD_URI = 2,

/**
CURIE, a shortened URI.

Value is an unquoted CURIE string relative to the current environment,
e.g. "rdf:type".
@see <a href="http://www.w3.org/TR/curie">CURIE Syntax 1.0</a>
*/
SERD_CURIE = 3,

/**
A blank node.

Value is a blank node ID, e.g. "id3", which is meaningful only within
this serialisation.
@see <a href="http://www.w3.org/TeamSubmission/turtle#nodeID">Turtle
<tt>nodeID</tt></a>
*/
SERD_BLANK = 4,

} SerdType;

/**
Flags indicating certain string properties relevant to serialisation.
*/
typedef enum {
SERD_HAS_NEWLINE = 1, /**< Contains line breaks ('\\n' or '\\r') */
SERD_HAS_QUOTE = 1 << 1 /**< Contains quotes ('"') */
} SerdNodeFlag;

/**
Bitwise OR of SerdNodeFlag values.
*/
typedef uint32_t SerdNodeFlags;

/**
A syntactic RDF node.
*/
typedef struct {
const uint8_t* buf; /**< Value string */
size_t n_bytes; /**< Size in bytes (not including null) */
size_t n_chars; /**< Length in characters (not including null)*/
SerdNodeFlags flags; /**< Node flags (e.g. string properties) */
SerdType type; /**< Node type */
} SerdNode;

/**
An unterminated string fragment.
*/
typedef struct {
const uint8_t* buf; /**< Start of chunk */
size_t len; /**< Length of chunk in bytes */
} SerdChunk;

/**
An error description.
*/
typedef struct {
SerdStatus status; /**< Error code */
const uint8_t* filename; /**< File where error was encountered, or NULL */
unsigned line; /**< Line where error was encountered, or 0 */
unsigned col; /**< Column where error was encountered */
const char* fmt; /**< Message format string (printf style) */
va_list* args; /**< Arguments for fmt */
} SerdError;

/**
A parsed URI.

This struct directly refers to chunks in other strings, it does not own any
memory itself. Thus, URIs can be parsed and/or resolved against a base URI
in-place without allocating memory.
*/
typedef struct {
SerdChunk scheme; /**< Scheme */
SerdChunk authority; /**< Authority */
SerdChunk path_base; /**< Path prefix if relative */
SerdChunk path; /**< Path suffix */
SerdChunk query; /**< Query */
SerdChunk fragment; /**< Fragment */
} SerdURI;

/**
Syntax style options.

The style of the writer output can be controlled by ORing together
values from this enumeration. Note that some options are only supported
for some syntaxes (e.g. NTriples does not support abbreviation and is
always ASCII).
*/
typedef enum {
SERD_STYLE_ABBREVIATED = 1, /**< Abbreviate triples when possible. */
SERD_STYLE_ASCII = 1 << 1, /**< Escape all non-ASCII characters. */
SERD_STYLE_RESOLVED = 1 << 2, /**< Resolve URIs against base URI. */
SERD_STYLE_CURIED = 1 << 3, /**< Shorten URIs into CURIEs. */
SERD_STYLE_BULK = 1 << 4 /**< Write output in pages. */
} SerdStyle;

/**
@name String Utilities
@{
*/

/**
Return a string describing a status code.
*/
SERD_API
const uint8_t*
serd_strerror(SerdStatus status);

/**
Measure a UTF-8 string.
@return Length of @c str in characters (except NULL).
@param str A null-terminated UTF-8 string.
@param n_bytes (Output) Set to the size of @c str in bytes (except NULL).
@param flags (Output) Set to the applicable flags.
*/
SERD_API
size_t
serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags);

/**
Parse a string to a double.

The API of this function is identical to the standard C strtod function,
except this function is locale-independent and always matches the lexical
format used in the Turtle grammar (the decimal point is always ".").
*/
SERD_API
double
serd_strtod(const char* str, char** endptr);

/**
Decode a base64 string.
This function can be used to deserialise a blob node created with
serd_node_new_blob().

@param str Base64 string to decode.
@param len The length of @c str.
@param size Set to the size of the returned blob in bytes.
@return A newly allocated blob which must be freed with free().
*/
SERD_API
void*
serd_base64_decode(const uint8_t* str, size_t len, size_t* size);

/**
@}
@name URI
@{
*/

static const SerdURI SERD_URI_NULL = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};

/**
Return the local path for @c uri, or NULL if @c uri is not a file URI.
Note this (inappropriately named) function only removes the file scheme if
necessary, and returns @c uri unmodified if it is an absolute path. Percent
encoding and other issues are not handled, to properly convert a file URI to
a path, use serd_file_uri_parse().
*/
SERD_API
const uint8_t*
serd_uri_to_path(const uint8_t* uri);

/**
Get the unescaped path and hostname from a file URI.
@param uri A file URI.
@param hostname If non-NULL, set to the hostname, if present.
@return The path component of the URI.

Both the returned path and @c hostname (if applicable) are owned by the
caller and must be freed with free().
*/
SERD_API
uint8_t*
serd_file_uri_parse(const uint8_t* uri, uint8_t** hostname);

/**
Return true iff @c utf8 starts with a valid URI scheme.
*/
SERD_API
bool
serd_uri_string_has_scheme(const uint8_t* utf8);

/**
Parse @c utf8, writing result to @c out.
*/
SERD_API
SerdStatus
serd_uri_parse(const uint8_t* utf8, SerdURI* out);

/**
Set @c out to @c uri resolved against @c base.
*/
SERD_API
void
serd_uri_resolve(const SerdURI* uri, const SerdURI* base, SerdURI* out);

/**
Sink function for raw string output.
*/
typedef size_t (*SerdSink)(const void* buf, size_t len, void* stream);

/**
Serialise @c uri with a series of calls to @c sink.
*/
SERD_API
size_t
serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream);

/**
Serialise @c uri relative to @c base with a series of calls to @c sink.

The @c uri is written as a relative URI iff if it a child of @c base and @c
root. The optional @c root parameter must be a prefix of @c base and can be
used keep up-references ("../") within a certain namespace.
*/
SERD_API
size_t
serd_uri_serialise_relative(const SerdURI* uri,
const SerdURI* base,
const SerdURI* root,
SerdSink sink,
void* stream);

/**
@}
@name Node
@{
*/

static const SerdNode SERD_NODE_NULL = { 0, 0, 0, 0, SERD_NOTHING };

/**
Make a (shallow) node from @c str.

This measures, but does not copy, @c str. No memory is allocated.
*/
SERD_API
SerdNode
serd_node_from_string(SerdType type, const uint8_t* str);

/**
Make a deep copy of @c node.

@return a node that the caller must free with @ref serd_node_free.
*/
SERD_API
SerdNode
serd_node_copy(const SerdNode* node);

/**
Return true iff @c a is equal to @c b.
*/
SERD_API
bool
serd_node_equals(const SerdNode* a, const SerdNode* b);

/**
Simple wrapper for serd_node_new_uri to resolve a URI node.
*/
SERD_API
SerdNode
serd_node_new_uri_from_node(const SerdNode* uri_node,
const SerdURI* base,
SerdURI* out);

/**
Simple wrapper for serd_node_new_uri to resolve a URI string.
*/
SERD_API
SerdNode
serd_node_new_uri_from_string(const uint8_t* str,
const SerdURI* base,
SerdURI* out);

/**
Create a new file URI node from a file system path and optional hostname.

Backslashes in Windows paths will be converted and '%' will always be
percent encoded. If @c escape is true, all other invalid characters will be
percent encoded as well.

If @c path is relative, @c hostname is ignored.
If @c out is not NULL, it will be set to the parsed URI.
*/
SERD_API
SerdNode
serd_node_new_file_uri(const uint8_t* path,
const uint8_t* hostname,
SerdURI* out,
bool escape);

/**
Create a new node by serialising @c uri into a new string.

@param uri The URI to parse and serialise.

@param base Base URI to resolve @c uri against (or NULL for no resolution).

@param out Set to the parsing of the new URI (i.e. points only to
memory owned by the new returned node).
*/
SERD_API
SerdNode
serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out);

/**
Create a new node by serialising @c d into an xsd:decimal string.

The resulting node will always contain a `.', start with a digit, and end
with a digit (i.e. will have a leading and/or trailing `0' if necessary).
It will never be in scientific notation. A maximum of @c frac_digits digits
will be written after the decimal point, but trailing zeros will
automatically be omitted (except one if @c d is a round integer).

Note that about 16 and 8 fractional digits are required to precisely
represent a double and float, respectively.

@param d The value for the new node.
@param frac_digits The maximum number of digits after the decimal place.
*/
SERD_API
SerdNode
serd_node_new_decimal(double d, unsigned frac_digits);

/**
Create a new node by serialising @c i into an xsd:integer string.
*/
SERD_API
SerdNode
serd_node_new_integer(int64_t i);

/**
Create a node by serialising @c buf into an xsd:base64Binary string.
This function can be used to make a serialisable node out of arbitrary
binary data, which can be decoded using serd_base64_decode().

@param buf Raw binary input data.
@param size Size of @c buf.
@param wrap_lines Wrap lines at 76 characters to conform to RFC 2045.
*/
SERD_API
SerdNode
serd_node_new_blob(const void* buf, size_t size, bool wrap_lines);

/**
Free any data owned by @c node.

Note that if @c node is itself dynamically allocated (which is not the case
for nodes created internally by serd), it will not be freed.
*/
SERD_API
void
serd_node_free(SerdNode* node);

/**
@}
@name Event Handlers
@{
*/

/**
Sink (callback) for errors.

@param handle Handle for user data.
@param error Error description.
*/
typedef SerdStatus (*SerdErrorSink)(void* handle,
const SerdError* error);

/**
Sink (callback) for base URI changes.

Called whenever the base URI of the serialisation changes.
*/
typedef SerdStatus (*SerdBaseSink)(void* handle,
const SerdNode* uri);

/**
Sink (callback) for namespace definitions.

Called whenever a prefix is defined in the serialisation.
*/
typedef SerdStatus (*SerdPrefixSink)(void* handle,
const SerdNode* name,
const SerdNode* uri);

/**
Sink (callback) for statements.

Called for every RDF statement in the serialisation.
*/
typedef SerdStatus (*SerdStatementSink)(void* handle,
SerdStatementFlags flags,
const SerdNode* graph,
const SerdNode* subject,
const SerdNode* predicate,
const SerdNode* object,
const SerdNode* object_datatype,
const SerdNode* object_lang);

/**
Sink (callback) for anonymous node end markers.

This is called to indicate that the anonymous node with the given
@c value will no longer be referred to by any future statements
(i.e. the anonymous serialisation of the node is finished).
*/
typedef SerdStatus (*SerdEndSink)(void* handle,
const SerdNode* node);

/**
@}
@name Environment
@{
*/

/**
Create a new environment.
*/
SERD_API
SerdEnv*
serd_env_new(const SerdNode* base_uri);

/**
Free @c ns.
*/
SERD_API
void
serd_env_free(SerdEnv* env);

/**
Get the current base URI.
*/
SERD_API
const SerdNode*
serd_env_get_base_uri(const SerdEnv* env,
SerdURI* out);

/**
Set the current base URI.
*/
SERD_API
SerdStatus
serd_env_set_base_uri(SerdEnv* env,
const SerdNode* uri);

/**
Set a namespace prefix.
*/
SERD_API
SerdStatus
serd_env_set_prefix(SerdEnv* env,
const SerdNode* name,
const SerdNode* uri);

/**
Set a namespace prefix.
*/
SERD_API
SerdStatus
serd_env_set_prefix_from_strings(SerdEnv* env,
const uint8_t* name,
const uint8_t* uri);

/**
Qualify @c uri into a CURIE if possible.
*/
SERD_API
bool
serd_env_qualify(const SerdEnv* env,
const SerdNode* uri,
SerdNode* prefix,
SerdChunk* suffix);

/**
Expand @c curie.
*/
SERD_API
SerdStatus
serd_env_expand(const SerdEnv* env,
const SerdNode* curie,
SerdChunk* uri_prefix,
SerdChunk* uri_suffix);

/**
Expand @c node, which must be a CURIE or URI, to a full URI.
*/
SERD_API
SerdNode
serd_env_expand_node(const SerdEnv* env,
const SerdNode* node);

/**
Call @c func for each prefix defined in @c env.
*/
SERD_API
void
serd_env_foreach(const SerdEnv* env,
SerdPrefixSink func,
void* handle);

/**
@}
@name Reader
@{
*/

/**
Create a new RDF reader.
*/
SERD_API
SerdReader*
serd_reader_new(SerdSyntax syntax,
void* handle,
void (*free_handle)(void*),
SerdBaseSink base_sink,
SerdPrefixSink prefix_sink,
SerdStatementSink statement_sink,
SerdEndSink end_sink);

/**
Set a function to be called when errors occur during reading.

The @p error_sink will be called with @p handle as its first argument. If
no error function is set, errors are printed to stderr in GCC style.
*/
SERD_API
void
serd_reader_set_error_sink(SerdReader* reader,
SerdErrorSink error_sink,
void* handle);

/**
Return the @c handle passed to @ref serd_reader_new.
*/
SERD_API
void*
serd_reader_get_handle(const SerdReader* reader);

/**
Set a prefix to be added to all blank node identifiers.

This is useful when multiple files are to be parsed into the same output
(e.g. a store, or other files). Since Serd preserves blank node IDs, this
could cause conflicts where two non-equivalent blank nodes are merged,
resulting in corrupt data. By setting a unique blank node prefix for each
parsed file, this can be avoided, while preserving blank node names.
*/
SERD_API
void
serd_reader_add_blank_prefix(SerdReader* reader,
const uint8_t* prefix);

/**
Set the URI of the default graph.

If this is set, the reader will emit quads with the graph set to the given
node for any statements that are not in a named graph (which is currently
all of them since Serd currently does not support any graph syntaxes).
*/
SERD_API
void
serd_reader_set_default_graph(SerdReader* reader,
const SerdNode* graph);

/**
Read a file at a given @c uri.
*/
SERD_API
SerdStatus
serd_reader_read_file(SerdReader* reader,
const uint8_t* uri);

/**
Start an incremental read from a file handle.

Iff @p bulk is true, @p file will be read a page at a time. This is more
efficient, but uses a page of memory and means that an entire page of input
must be ready before any callbacks will fire. To react as soon as input
arrives, set @p bulk to false.
*/
SERD_API
SerdStatus
serd_reader_start_stream(SerdReader* me,
FILE* file,
const uint8_t* name,
bool bulk);

/**
Read a single "chunk" of data during an incremental read.

This function will read a single top level description, and return. This
may be a directive, statement, or several statements; essentially it reads
until a '.' is encountered. This is particularly useful for reading
directly from a pipe or socket.
*/
SERD_API
SerdStatus
serd_reader_read_chunk(SerdReader* me);

/**
Finish an incremental read from a file handle.
*/
SERD_API
SerdStatus
serd_reader_end_stream(SerdReader* me);

/**
Read @c file.
*/
SERD_API
SerdStatus
serd_reader_read_file_handle(SerdReader* reader,
FILE* file,
const uint8_t* name);

/**
Read @c utf8.
*/
SERD_API
SerdStatus
serd_reader_read_string(SerdReader* me, const uint8_t* utf8);

/**
Free @c reader.
*/
SERD_API
void
serd_reader_free(SerdReader* reader);

/**
@}
@name Writer
@{
*/

/**
Create a new RDF writer.
*/
SERD_API
SerdWriter*
serd_writer_new(SerdSyntax syntax,
SerdStyle style,
SerdEnv* env,
const SerdURI* base_uri,
SerdSink sink,
void* stream);

/**
Free @c writer.
*/
SERD_API
void
serd_writer_free(SerdWriter* writer);

/**
Return the env used by @c writer.
*/
SERD_API
SerdEnv*
serd_writer_get_env(SerdWriter* writer);

/**
A convenience sink function for writing to a FILE*.

This function can be used as a SerdSink when writing to a FILE*. The
@c stream parameter must be a FILE* opened for writing.
*/
SERD_API
size_t
serd_file_sink(const void* buf, size_t len, void* stream);

/**
A convenience sink function for writing to a string.

This function can be used as a SerdSink to write to a SerdChunk which is
resized as necessary with realloc(). The @c stream parameter must point to
an initialized SerdChunk. When the write is finished, the string should be
retrieved with serd_chunk_sink_finish().
*/
SERD_API
size_t
serd_chunk_sink(const void* buf, size_t len, void* stream);

/**
Finish a serialisation to a chunk with serd_chunk_sink().

The returned string is the result of the serialisation, which is NULL
terminated (by this function) and owned by the caller.
*/
SERD_API
uint8_t*
serd_chunk_sink_finish(SerdChunk* stream);

/**
Set a function to be called when errors occur during writing.

The @p error_sink will be called with @p handle as its first argument. If
no error function is set, errors are printed to stderr.
*/
SERD_API
void
serd_writer_set_error_sink(SerdWriter* writer,
SerdErrorSink error_sink,
void* handle);

/**
Set a prefix to be removed from matching blank node identifiers.
*/
SERD_API
void
serd_writer_chop_blank_prefix(SerdWriter* writer,
const uint8_t* prefix);

/**
Set the current output base URI (and emit directive if applicable).

Note this function can be safely casted to SerdBaseSink.
*/
SERD_API
SerdStatus
serd_writer_set_base_uri(SerdWriter* writer,
const SerdNode* uri);

/**
Set the current root URI.

The root URI should be a prefix of the base URI. The path of the root URI
is the highest path any relative up-reference can refer to. For example,
with root <file:///foo/root> and base <file:///foo/root/base>,
<file:///foo/root> will be written as <../>, but <file:///foo> will be
written non-relatively as <file:///foo>. If the root is not explicitly set,
it defaults to the base URI, so no up-references will be created at all.
*/
SERD_API
SerdStatus
serd_writer_set_root_uri(SerdWriter* writer,
const SerdNode* uri);

/**
Set a namespace prefix (and emit directive if applicable).

Note this function can be safely casted to SerdPrefixSink.
*/
SERD_API
SerdStatus
serd_writer_set_prefix(SerdWriter* writer,
const SerdNode* name,
const SerdNode* uri);

/**
Write a statement.

Note this function can be safely casted to SerdStatementSink.
*/
SERD_API
SerdStatus
serd_writer_write_statement(SerdWriter* writer,
SerdStatementFlags flags,
const SerdNode* graph,
const SerdNode* subject,
const SerdNode* predicate,
const SerdNode* object,
const SerdNode* object_datatype,
const SerdNode* object_lang);

/**
Mark the end of an anonymous node's description.

Note this function can be safely casted to SerdEndSink.
*/
SERD_API
SerdStatus
serd_writer_end_anon(SerdWriter* writer,
const SerdNode* node);

/**
Finish a write.
*/
SERD_API
SerdStatus
serd_writer_finish(SerdWriter* writer);

/**
@}
@}
*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* SERD_SERD_H */

+ 271
- 0
source/libs/lilv/serd-0.18.2/src/env.c View File

@@ -0,0 +1,271 @@
/*
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 <assert.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
SerdNode name;
SerdNode uri;
} SerdPrefix;

struct SerdEnvImpl {
SerdPrefix* prefixes;
size_t n_prefixes;
SerdNode base_uri_node;
SerdURI base_uri;
};

SERD_API
SerdEnv*
serd_env_new(const SerdNode* base_uri)
{
SerdEnv* env = (SerdEnv*)malloc(sizeof(struct SerdEnvImpl));
env->prefixes = NULL;
env->n_prefixes = 0;
env->base_uri_node = SERD_NODE_NULL;
env->base_uri = SERD_URI_NULL;
if (base_uri) {
serd_env_set_base_uri(env, base_uri);
}
return env;
}

SERD_API
void
serd_env_free(SerdEnv* env)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
serd_node_free(&env->prefixes[i].name);
serd_node_free(&env->prefixes[i].uri);
}
free(env->prefixes);
serd_node_free(&env->base_uri_node);
free(env);
}

SERD_API
const SerdNode*
serd_env_get_base_uri(const SerdEnv* env,
SerdURI* out)
{
if (out) {
*out = env->base_uri;
}
return &env->base_uri_node;
}

SERD_API
SerdStatus
serd_env_set_base_uri(SerdEnv* env,
const SerdNode* uri_node)
{
// Resolve base URI and create a new node and URI for it
SerdURI base_uri;
SerdNode base_uri_node = serd_node_new_uri_from_node(
uri_node, &env->base_uri, &base_uri);

if (base_uri_node.buf) {
// Replace the current base URI
serd_node_free(&env->base_uri_node);
env->base_uri_node = base_uri_node;
env->base_uri = base_uri;
return SERD_SUCCESS;
}
return SERD_ERR_BAD_ARG;
}

static inline SerdPrefix*
serd_env_find(const SerdEnv* env,
const uint8_t* name,
size_t name_len)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
const SerdNode* const prefix_name = &env->prefixes[i].name;
if (prefix_name->n_bytes == name_len) {
if (!memcmp(prefix_name->buf, name, name_len)) {
return &env->prefixes[i];
}
}
}
return NULL;
}

static void
serd_env_add(SerdEnv* env,
const SerdNode* name,
const SerdNode* uri)
{
SerdPrefix* const prefix = serd_env_find(env, name->buf, name->n_bytes);
if (prefix) {
SerdNode old_prefix_uri = prefix->uri;
prefix->uri = serd_node_copy(uri);
serd_node_free(&old_prefix_uri);
} else {
env->prefixes = (SerdPrefix*)realloc(
env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix));
env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name);
env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri);
}
}

SERD_API
SerdStatus
serd_env_set_prefix(SerdEnv* env,
const SerdNode* name,
const SerdNode* uri_node)
{
if (!name->buf || uri_node->type != SERD_URI) {
return SERD_ERR_BAD_ARG;
} else if (serd_uri_string_has_scheme(uri_node->buf)) {
// Set prefix to absolute URI
serd_env_add(env, name, uri_node);
} else {
// Resolve relative URI and create a new node and URI for it
SerdURI abs_uri;
SerdNode abs_uri_node = serd_node_new_uri_from_node(
uri_node, &env->base_uri, &abs_uri);

// Set prefix to resolved (absolute) URI
serd_env_add(env, name, &abs_uri_node);
serd_node_free(&abs_uri_node);
}
return SERD_SUCCESS;
}

SERD_API
SerdStatus
serd_env_set_prefix_from_strings(SerdEnv* env,
const uint8_t* name,
const uint8_t* uri)
{
const SerdNode name_node = serd_node_from_string(SERD_LITERAL, name);
const SerdNode uri_node = serd_node_from_string(SERD_URI, uri);

return serd_env_set_prefix(env, &name_node, &uri_node);
}

static inline bool
is_nameChar(const uint8_t c)
{
return is_alpha(c) || is_digit(c) || c == '_';
}

/**
Return true iff @c buf is a valid prefixed name suffix.
TODO: This is more strict than it should be.
*/
static inline bool
is_name(const uint8_t* buf, size_t len)
{
for (size_t i = 0; i < len; ++i) {
if (!is_nameChar(buf[i])) {
return false;
}
}
return true;
}

SERD_API
bool
serd_env_qualify(const SerdEnv* env,
const SerdNode* uri,
SerdNode* prefix_name,
SerdChunk* suffix)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
const SerdNode* const prefix_uri = &env->prefixes[i].uri;
if (uri->n_bytes >= prefix_uri->n_bytes) {
if (!strncmp((const char*)uri->buf,
(const char*)prefix_uri->buf,
prefix_uri->n_bytes)) {
*prefix_name = env->prefixes[i].name;
suffix->buf = uri->buf + prefix_uri->n_bytes;
suffix->len = uri->n_bytes - prefix_uri->n_bytes;
if (is_name(suffix->buf, suffix->len)) {
return true;
}
}
}
}
return false;
}

SERD_API
SerdStatus
serd_env_expand(const SerdEnv* env,
const SerdNode* qname,
SerdChunk* uri_prefix,
SerdChunk* uri_suffix)
{
const uint8_t* const colon = (const uint8_t*)memchr(
qname->buf, ':', qname->n_bytes + 1);
if (!colon) {
return SERD_ERR_BAD_ARG; // Invalid qname
}

const size_t name_len = colon - qname->buf;
const SerdPrefix* const prefix = serd_env_find(env, qname->buf, name_len);
if (prefix) {
uri_prefix->buf = prefix->uri.buf;
uri_prefix->len = prefix->uri.n_bytes;
uri_suffix->buf = colon + 1;
uri_suffix->len = qname->n_bytes - (colon - qname->buf) - 1;
return SERD_SUCCESS;
}
return SERD_ERR_NOT_FOUND;
}

SERD_API
SerdNode
serd_env_expand_node(const SerdEnv* env,
const SerdNode* node)
{
switch (node->type) {
case SERD_CURIE: {
SerdChunk prefix;
SerdChunk suffix;
if (serd_env_expand(env, node, &prefix, &suffix)) {
return SERD_NODE_NULL;
}
const size_t len = prefix.len + suffix.len; // FIXME: UTF-8?
uint8_t* buf = (uint8_t*)malloc(len + 1);
SerdNode ret = { buf, len, len, 0, SERD_URI };
snprintf((char*)buf, ret.n_bytes + 1, "%s%s", prefix.buf, suffix.buf);
return ret;
}
case SERD_URI: {
SerdURI ignored;
return serd_node_new_uri_from_node(node, &env->base_uri, &ignored);
}
default:
return SERD_NODE_NULL;
}
}

SERD_API
void
serd_env_foreach(const SerdEnv* env,
SerdPrefixSink func,
void* handle)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
func(handle, &env->prefixes[i].name, &env->prefixes[i].uri);
}
}

+ 347
- 0
source/libs/lilv/serd-0.18.2/src/node.c View 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;
}
}

+ 1585
- 0
source/libs/lilv/serd-0.18.2/src/reader.c
File diff suppressed because it is too large
View File


+ 306
- 0
source/libs/lilv/serd-0.18.2/src/serd_internal.h View File

@@ -0,0 +1,306 @@
/*
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.
*/

#ifndef SERD_INTERNAL_H
#define SERD_INTERNAL_H

#define _POSIX_C_SOURCE 201112L /* for posix_memalign and posix_fadvise */

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "serd/serd.h"
#include "serd_config.h"

#if defined(HAVE_POSIX_FADVISE) && defined(HAVE_FILENO)
# include <fcntl.h>
#endif

#define SERD_PAGE_SIZE 4096

#ifndef MIN
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif

#ifndef HAVE_FMAX
static inline double
fmax(double a, double b)
{
return (a < b) ? b : a;
}
#endif

/* File and Buffer Utilities */

static inline FILE*
serd_fopen(const char* path, const char* mode)
{
FILE* fd = fopen((const char*)path, mode);
if (!fd) {
fprintf(stderr, "Error opening file %s (%s)\n", path, strerror(errno));
return NULL;
}
#if defined(HAVE_POSIX_FADVISE) && defined(HAVE_FILENO)
posix_fadvise(fileno(fd), 0, 0, POSIX_FADV_SEQUENTIAL);
#endif
return fd;
}

static inline void*
serd_bufalloc(size_t size)
{
#ifdef HAVE_POSIX_MEMALIGN
void* ptr;
posix_memalign(&ptr, SERD_PAGE_SIZE, size);
return ptr;
#else
return malloc(size);
#endif
}

/* Stack */

/** A dynamic stack in memory. */
typedef struct {
uint8_t* buf; ///< Stack memory
size_t buf_size; ///< Allocated size of buf (>= size)
size_t size; ///< Conceptual size of stack in buf
} SerdStack;

/** An offset to start the stack at. Note 0 is reserved for NULL. */
#define SERD_STACK_BOTTOM sizeof(void*)

static inline SerdStack
serd_stack_new(size_t size)
{
SerdStack stack;
stack.buf = (uint8_t*)malloc(size);
stack.buf_size = size;
stack.size = SERD_STACK_BOTTOM;
return stack;
}

static inline bool
serd_stack_is_empty(SerdStack* stack)
{
return stack->size <= SERD_STACK_BOTTOM;
}

static inline void
serd_stack_free(SerdStack* stack)
{
free(stack->buf);
stack->buf = NULL;
stack->buf_size = 0;
stack->size = 0;
}

static inline uint8_t*
serd_stack_push(SerdStack* stack, size_t n_bytes)
{
const size_t new_size = stack->size + n_bytes;
if (stack->buf_size < new_size) {
stack->buf_size *= 2;
stack->buf = (uint8_t*)realloc(stack->buf, stack->buf_size);
}
uint8_t* const ret = (stack->buf + stack->size);
stack->size = new_size;
return ret;
}

static inline void
serd_stack_pop(SerdStack* stack, size_t n_bytes)
{
assert(stack->size >= n_bytes);
stack->size -= n_bytes;
}

/* Bulk Sink */

typedef struct SerdBulkSinkImpl {
SerdSink sink;
void* stream;
uint8_t* buf;
size_t size;
size_t block_size;
} SerdBulkSink;

static inline SerdBulkSink
serd_bulk_sink_new(SerdSink sink, void* stream, size_t block_size)
{
SerdBulkSink bsink;
bsink.sink = sink;
bsink.stream = stream;
bsink.size = 0;
bsink.block_size = block_size;
bsink.buf = (uint8_t*)serd_bufalloc(block_size);
return bsink;
}

static inline void
serd_bulk_sink_flush(SerdBulkSink* bsink)
{
if (bsink->size > 0) {
bsink->sink(bsink->buf, bsink->size, bsink->stream);
}
bsink->size = 0;
}

static inline void
serd_bulk_sink_free(SerdBulkSink* bsink)
{
serd_bulk_sink_flush(bsink);
free(bsink->buf);
bsink->buf = NULL;
}

static inline size_t
serd_bulk_sink_write(const void* buf, size_t len, SerdBulkSink* bsink)
{
const size_t orig_len = len;
while (len) {
const size_t space = bsink->block_size - bsink->size;
const size_t n = MIN(space, len);

// Write as much as possible into the remaining buffer space
memcpy(bsink->buf + bsink->size, buf, n);
bsink->size += n;
buf = (const uint8_t*)buf + n;
len -= n;

// Flush page if buffer is full
if (bsink->size == bsink->block_size) {
bsink->sink(bsink->buf, bsink->block_size, bsink->stream);
bsink->size = 0;
}
}
return orig_len;
}

/* Character utilities */

/** Return true if @a c lies within [min...max] (inclusive) */
static inline bool
in_range(const uint8_t c, const uint8_t min, const uint8_t max)
{
return (c >= min && c <= max);
}

/** RFC2234: ALPHA := %x41-5A / %x61-7A ; A-Z / a-z */
static inline bool
is_alpha(const uint8_t c)
{
return in_range(c, 'A', 'Z') || in_range(c, 'a', 'z');
}

/** RFC2234: DIGIT ::= %x30-39 ; 0-9 */
static inline bool
is_digit(const uint8_t c)
{
return in_range(c, '0', '9');
}

static inline bool
is_space(const char c)
{
switch (c) {
case ' ': case '\f': case '\n': case '\r': case '\t': case '\v':
return true;
default:
return false;
}
}

static inline bool
is_base64(const uint8_t c)
{
return is_alpha(c) || is_digit(c) || c == '+' || c == '/' || c == '=';
}

static inline bool
is_windows_path(const uint8_t* path)
{
return is_alpha(path[0]) && (path[1] == ':' || path[1] == '|')
&& (path[2] == '/' || path[2] == '\\');
}

/* URI utilities */

static inline bool
chunk_equals(const SerdChunk* a, const SerdChunk* b)
{
return a->len == b->len
&& !strncmp((const char*)a->buf, (const char*)b->buf, a->len);
}

static inline size_t
uri_path_len(const SerdURI* uri)
{
return uri->path_base.len + uri->path.len;
}

static inline uint8_t
uri_path_at(const SerdURI* uri, size_t i)
{
if (i < uri->path_base.len) {
return uri->path_base.buf[i];
} else {
return uri->path.buf[i - uri->path_base.len];
}
}

/** Return true iff @p uri is within the base of @p root */
static inline bool
uri_is_under(const SerdURI* uri, const SerdURI* root)
{
if (!root || !uri || !root->scheme.len ||
!chunk_equals(&root->scheme, &uri->scheme) ||
!chunk_equals(&root->authority, &uri->authority)) {
return false;
}

bool differ = false;
const size_t path_len = uri_path_len(uri);
const size_t root_len = uri_path_len(root);
for (size_t i = 0; i < path_len && i < root_len; ++i) {
if (uri_path_at(uri, i) != uri_path_at(root, i)) {
differ = true;
}
if (differ && uri_path_at(root, i) == '/') {
return false;
}
}

return true;
}

/* Error reporting */

static inline void
serd_error(SerdErrorSink error_sink, void* handle, const SerdError* e)
{
if (error_sink) {
error_sink(handle, e);
} else {
fprintf(stderr, "error: %s:%u:%u: ", e->filename, e->line, e->col);
vfprintf(stderr, e->fmt, *e->args);
}
}

#endif // SERD_INTERNAL_H

+ 253
- 0
source/libs/lilv/serd-0.18.2/src/serdi.c View File

@@ -0,0 +1,253 @@
/*
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 <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
SerdEnv* env;
SerdWriter* writer;
} State;

static int
print_version(void)
{
printf("serdi " SERD_VERSION " <http://drobilla.net/software/serd>\n");
printf("Copyright 2011-2012 David Robillard <http://drobilla.net>.\n"
"License: <http://www.opensource.org/licenses/isc>\n"
"This is free software; you are free to change and redistribute it."
"\nThere is NO WARRANTY, to the extent permitted by law.\n");
return 0;
}

static int
print_usage(const char* name, bool error)
{
FILE* const os = error ? stderr : stdout;
fprintf(os, "Usage: %s [OPTION]... INPUT [BASE_URI]\n", name);
fprintf(os, "Read and write RDF syntax.\n");
fprintf(os, "Use - for INPUT to read from standard input.\n\n");
fprintf(os, " -b Fast bulk output for large serialisations.\n");
fprintf(os, " -c PREFIX Chop PREFIX from matching blank node IDs.\n");
fprintf(os, " -e Eat input one character at a time.\n");
fprintf(os, " -f Keep full URIs in input (don't qualify).\n");
fprintf(os, " -h Display this help and exit.\n");
fprintf(os, " -i SYNTAX Input syntax (`turtle' or `ntriples').\n");
fprintf(os, " -o SYNTAX Output syntax (`turtle' or `ntriples').\n");
fprintf(os, " -p PREFIX Add PREFIX to blank node IDs.\n");
fprintf(os, " -q Suppress all output except data.\n");
fprintf(os, " -r ROOT_URI Keep relative URIs within ROOT_URI.\n");
fprintf(os, " -s INPUT Parse INPUT as string (terminates options).\n");
fprintf(os, " -v Display version information and exit.\n");
return error ? 1 : 0;
}

static bool
set_syntax(SerdSyntax* syntax, const char* name)
{
if (!strcmp(name, "turtle")) {
*syntax = SERD_TURTLE;
} else if (!strcmp(name, "ntriples")) {
*syntax = SERD_NTRIPLES;
} else {
fprintf(stderr, "Unknown input format `%s'\n", name);
return false;
}
return true;
}

static int
bad_arg(const char* name, char opt)
{
fprintf(stderr, "%s: Bad or missing value for -%c\n", name, opt);
return 1;
}

static SerdStatus
quiet_error_sink(void* handle, const SerdError* e)
{
return SERD_SUCCESS;
}

int
main(int argc, char** argv)
{
if (argc < 2) {
return print_usage(argv[0], true);
}

FILE* in_fd = NULL;
SerdSyntax input_syntax = SERD_TURTLE;
SerdSyntax output_syntax = SERD_NTRIPLES;
bool from_file = true;
bool bulk_read = true;
bool bulk_write = false;
bool full_uris = false;
bool quiet = false;
const uint8_t* in_name = NULL;
const uint8_t* add_prefix = NULL;
const uint8_t* chop_prefix = NULL;
const uint8_t* root_uri = NULL;
int a = 1;
for (; a < argc && argv[a][0] == '-'; ++a) {
if (argv[a][1] == '\0') {
in_name = (const uint8_t*)"(stdin)";
in_fd = stdin;
break;
} else if (argv[a][1] == 'b') {
bulk_write = true;
} else if (argv[a][1] == 'e') {
bulk_read = false;
} else if (argv[a][1] == 'f') {
full_uris = true;
} else if (argv[a][1] == 'h') {
return print_usage(argv[0], false);
} else if (argv[a][1] == 'q') {
quiet = true;
} else if (argv[a][1] == 'v') {
return print_version();
} else if (argv[a][1] == 's') {
in_name = (const uint8_t*)"(string)";
from_file = false;
++a;
break;
} else if (argv[a][1] == 'i') {
if (++a == argc || !set_syntax(&input_syntax, argv[a])) {
return bad_arg(argv[0], 'i');
}
} else if (argv[a][1] == 'o') {
if (++a == argc || !set_syntax(&output_syntax, argv[a])) {
return bad_arg(argv[0], 'o');
}
} else if (argv[a][1] == 'p') {
if (++a == argc) {
return bad_arg(argv[0], 'p');
}
add_prefix = (const uint8_t*)argv[a];
} else if (argv[a][1] == 'c') {
if (++a == argc) {
return bad_arg(argv[0], 'c');
}
chop_prefix = (const uint8_t*)argv[a];
} else if (argv[a][1] == 'r') {
if (++a == argc) {
return bad_arg(argv[0], 'r');
}
root_uri = (const uint8_t*)argv[a];
} else {
fprintf(stderr, "%s: Unknown option `%s'\n", argv[0], argv[a]);
return print_usage(argv[0], true);
}
}

if (a == argc) {
fprintf(stderr, "%s: Missing input\n", argv[0]);
return 1;
}

const uint8_t* input = (const uint8_t*)argv[a++];
if (from_file) {
in_name = in_name ? in_name : input;
if (!in_fd) {
input = serd_uri_to_path(in_name);
if (!input || !(in_fd = serd_fopen((const char*)input, "r"))) {
return 1;
}
}
}

SerdURI base_uri = SERD_URI_NULL;
SerdNode base = SERD_NODE_NULL;
if (a < argc) { // Base URI given on command line
base = serd_node_new_uri_from_string(
(const uint8_t*)argv[a], NULL, &base_uri);
} else if (from_file && in_fd != stdin) { // Use input file URI
base = serd_node_new_file_uri(input, NULL, &base_uri, false);
}

FILE* out_fd = stdout;
SerdEnv* env = serd_env_new(&base);

int output_style = 0;
if (output_syntax == SERD_NTRIPLES) {
output_style |= SERD_STYLE_ASCII;
} else {
output_style |= SERD_STYLE_ABBREVIATED;
if (!full_uris) {
output_style |= SERD_STYLE_CURIED;
}
}

if (input_syntax != SERD_NTRIPLES // Base URI may change (@base)
|| (output_syntax == SERD_TURTLE)) {
output_style |= SERD_STYLE_RESOLVED;
}

if (bulk_write) {
output_style |= SERD_STYLE_BULK;
}

SerdWriter* writer = serd_writer_new(
output_syntax, (SerdStyle)output_style,
env, &base_uri, serd_file_sink, out_fd);

SerdReader* reader = serd_reader_new(
input_syntax, writer, NULL,
(SerdBaseSink)serd_writer_set_base_uri,
(SerdPrefixSink)serd_writer_set_prefix,
(SerdStatementSink)serd_writer_write_statement,
(SerdEndSink)serd_writer_end_anon);

if (quiet) {
serd_reader_set_error_sink(reader, quiet_error_sink, NULL);
serd_writer_set_error_sink(writer, quiet_error_sink, NULL);
}

SerdNode root = serd_node_from_string(SERD_URI, root_uri);
serd_writer_set_root_uri(writer, &root);
serd_writer_chop_blank_prefix(writer, chop_prefix);
serd_reader_add_blank_prefix(reader, add_prefix);

SerdStatus status = SERD_SUCCESS;
if (!from_file) {
status = serd_reader_read_string(reader, input);
} else if (bulk_read) {
status = serd_reader_read_file_handle(reader, in_fd, in_name);
} else {
status = serd_reader_start_stream(reader, in_fd, in_name, false);
while (!status) {
status = serd_reader_read_chunk(reader);
}
serd_reader_end_stream(reader);
}

serd_reader_free(reader);

if (from_file) {
fclose(in_fd);
}

serd_writer_finish(writer);
serd_writer_free(writer);
serd_env_free(env);
serd_node_free(&base);

return (status > SERD_FAILURE) ? 1 : 0;
}

+ 165
- 0
source/libs/lilv/serd-0.18.2/src/string.c View File

@@ -0,0 +1,165 @@
/*
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 <math.h>

SERD_API
const uint8_t*
serd_strerror(SerdStatus st)
{
switch (st) {
case SERD_SUCCESS: return (const uint8_t*)"Success";
case SERD_FAILURE: return (const uint8_t*)"Non-fatal failure";
case SERD_ERR_UNKNOWN: return (const uint8_t*)"Unknown error";
case SERD_ERR_BAD_SYNTAX: return (const uint8_t*)"Invalid syntax";
case SERD_ERR_BAD_ARG: return (const uint8_t*)"Invalid argument";
case SERD_ERR_NOT_FOUND: return (const uint8_t*)"Not found";
case SERD_ERR_ID_CLASH: return (const uint8_t*)"Blank node ID clash";
case SERD_ERR_BAD_CURIE: return (const uint8_t*)"Invalid CURIE";
case SERD_ERR_INTERNAL: return (const uint8_t*)"Internal error";
}
return (const uint8_t*)"Unknown error"; // never reached
}

SERD_API
size_t
serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags)
{
size_t n_chars = 0;
size_t i = 0;
*flags = 0;
for (; str[i]; ++i) {
if ((str[i] & 0xC0) != 0x80) {
// Does not start with `10', start of a new character
++n_chars;
switch (str[i]) {
case '\r': case '\n':
*flags |= SERD_HAS_NEWLINE;
break;
case '"':
*flags |= SERD_HAS_QUOTE;
}
}
}
if (n_bytes) {
*n_bytes = i;
}
return n_chars;
}

static inline double
read_sign(const char** sptr)
{
double sign = 1.0;
switch (**sptr) {
case '-': sign = -1.0;
case '+': ++(*sptr);
default: return sign;
}
}

SERD_API
double
serd_strtod(const char* str, char** endptr)
{
double result = 0.0;

// Point s at the first non-whitespace character
const char* s = str;
while (is_space(*s)) { ++s; }

// Read leading sign if necessary
const double sign = read_sign(&s);

// Parse integer part
for (; is_digit(*s); ++s) {
result = (result * 10.0) + (*s - '0');
}

// Parse fractional part
if (*s == '.') {
double denom = 10.0;
for (++s; is_digit(*s); ++s) {
result += (*s - '0') / denom;
denom *= 10.0;
}
}

// Parse exponent
if (*s == 'e' || *s == 'E') {
++s;
double expt = 0.0;
double expt_sign = read_sign(&s);
for (; is_digit(*s); ++s) {
expt = (expt * 10.0) + (*s - '0');
}
result *= pow(10, expt * expt_sign);
}

if (endptr) {
*endptr = (char*)s;
}

return result * sign;
}

/**
Base64 decoding table.
This is indexed by encoded characters and returns the numeric value used
for decoding, shifted up by 47 to be in the range of printable ASCII.
A '$' is a placeholder for characters not in the base64 alphabet.
*/
static const char b64_unmap[] =
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$"
"$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$"
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";

static inline uint8_t unmap(const uint8_t in) { return b64_unmap[in] - 47; }

/**
Decode 4 base64 characters to 3 raw bytes.
*/
static inline size_t
decode_chunk(const uint8_t in[4], uint8_t out[3])
{
out[0] = (uint8_t)(((unmap(in[0]) << 2)) | unmap(in[1]) >> 4);
out[1] = (uint8_t)(((unmap(in[1]) << 4) & 0xF0) | unmap(in[2]) >> 2);
out[2] = (uint8_t)(((unmap(in[2]) << 6) & 0xC0) | unmap(in[3]));
return 1 + (in[2] != '=') + ((in[2] != '=') && (in[3] != '='));
}

SERD_API
void*
serd_base64_decode(const uint8_t* str, size_t len, size_t* size)
{
void* buf = malloc((len * 3) / 4 + 2);
*size = 0;
for (size_t i = 0, j = 0; i < len; j += 3) {
uint8_t in[] = "====";
size_t n_in = 0;
for (; i < len && n_in < 4; ++n_in) {
for (; i < len && !is_base64(str[i]); ++i) {} // Skip junk
in[n_in] = str[i++];
}
if (n_in > 1) {
*size += decode_chunk(in, (uint8_t*)buf + j);
}
}
return buf;
}

+ 504
- 0
source/libs/lilv/serd-0.18.2/src/uri.c View File

@@ -0,0 +1,504 @@
/*
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>

// #define URI_DEBUG 1

SERD_API
const uint8_t*
serd_uri_to_path(const uint8_t* uri)
{
const uint8_t* path = uri;
if (!is_windows_path(uri) && serd_uri_string_has_scheme(uri)) {
if (strncmp((const char*)uri, "file:", 5)) {
fprintf(stderr, "Non-file URI `%s'\n", uri);
return NULL;
} else if (!strncmp((const char*)uri, "file://localhost/", 17)) {
path = uri + 16;
} else if (!strncmp((const char*)uri, "file://", 7)) {
path = uri + 7;
} else {
fprintf(stderr, "Invalid file URI `%s'\n", uri);
return NULL;
}
if (is_windows_path(path + 1)) {
++path; // Special case for terrible Windows file URIs
}
}
return path;
}

SERD_API
uint8_t*
serd_file_uri_parse(const uint8_t* uri, uint8_t** hostname)
{
const uint8_t* path = uri;
if (hostname) {
*hostname = NULL;
}
if (!strncmp((const char*)uri, "file://", 7)) {
const uint8_t* auth = uri + 7;
if (*auth == '/') { // No hostname
path = auth;
} else { // Has hostname
if (!(path = (const uint8_t*)strchr((const char*)auth, '/'))) {
return NULL;
}
if (hostname) {
*hostname = (uint8_t*)calloc(1, path - auth + 1);
memcpy(*hostname, auth, path - auth);
}
}
}

if (is_windows_path(path + 1)) {
++path;
}

SerdChunk chunk = { NULL, 0 };
for (const uint8_t* s = path; *s; ++s) {
if (*s == '%') {
if (*(s + 1) == '%') {
serd_chunk_sink("%", 1, &chunk);
++s;
} else if (is_digit(*(s + 1)) && is_digit(*(s + 2))) {
const uint8_t code[3] = { *(s + 1), *(s + 2), 0 };
uint32_t num;
sscanf((const char*)code, "%X", &num);
const uint8_t c = num;
serd_chunk_sink(&c, 1, &chunk);
s += 2;
} else {
s += 2; // Junk escape, ignore
}
} else {
serd_chunk_sink(s, 1, &chunk);
}
}
return serd_chunk_sink_finish(&chunk);
}

SERD_API
bool
serd_uri_string_has_scheme(const uint8_t* utf8)
{
// RFC3986: scheme ::= ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
if (!is_alpha(utf8[0])) {
return false; // Invalid scheme initial character, URI is relative
}
for (uint8_t c; (c = *++utf8) != '\0';) {
switch (c) {
case ':':
return true; // End of scheme
case '+': case '-': case '.':
break; // Valid scheme character, continue
default:
if (!is_alpha(c) && !is_digit(c)) {
return false; // Invalid scheme character
}
}
}

return false;
}

#ifdef URI_DEBUG
static void
serd_uri_dump(const SerdURI* uri, FILE* file)
{
#define PRINT_PART(range, name) \
if (range.buf) { \
fprintf(stderr, " " name " = "); \
fwrite((range).buf, 1, (range).len, stderr); \
fprintf(stderr, "\n"); \
}

PRINT_PART(uri->scheme, "scheme ");
PRINT_PART(uri->authority, "authority");
PRINT_PART(uri->path_base, "path_base");
PRINT_PART(uri->path, "path ");
PRINT_PART(uri->query, "query ");
PRINT_PART(uri->fragment, "fragment ");
}
#endif

SERD_API
SerdStatus
serd_uri_parse(const uint8_t* utf8, SerdURI* uri)
{
*uri = SERD_URI_NULL;

const uint8_t* ptr = utf8;

/* See http://tools.ietf.org/html/rfc3986#section-3
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
*/

/* S3.1: scheme ::= ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
if (is_alpha(*ptr)) {
for (uint8_t c = *++ptr; true; c = *++ptr) {
switch (c) {
case '\0': case '/': case '?': case '#':
ptr = utf8;
goto path; // Relative URI (starts with path by definition)
case ':':
uri->scheme.buf = utf8;
uri->scheme.len = (ptr++) - utf8;
goto maybe_authority; // URI with scheme
case '+': case '-': case '.':
continue;
default:
if (is_alpha(c) || is_digit(c)) {
continue;
}
}
}
}

/* S3.2: The authority component is preceded by a double slash ("//")
and is terminated by the next slash ("/"), question mark ("?"),
or number sign ("#") character, or by the end of the URI.
*/
maybe_authority:
if (*ptr == '/' && *(ptr + 1) == '/') {
ptr += 2;
uri->authority.buf = ptr;
for (uint8_t c; (c = *ptr) != '\0'; ++ptr) {
switch (c) {
case '/': goto path;
case '?': goto query;
case '#': goto fragment;
default:
++uri->authority.len;
}
}
}

/* RFC3986 S3.3: The path is terminated by the first question mark ("?")
or number sign ("#") character, or by the end of the URI.
*/
path:
switch (*ptr) {
case '?': goto query;
case '#': goto fragment;
case '\0': goto end;
default: break;
}
uri->path.buf = ptr;
uri->path.len = 0;
for (uint8_t c; (c = *ptr) != '\0'; ++ptr) {
switch (c) {
case '?': goto query;
case '#': goto fragment;
default:
++uri->path.len;
}
}

/* RFC3986 S3.4: The query component is indicated by the first question
mark ("?") character and terminated by a number sign ("#") character
or by the end of the URI.
*/
query:
if (*ptr == '?') {
uri->query.buf = ++ptr;
for (uint8_t c; (c = *ptr) != '\0'; ++ptr) {
switch (c) {
case '#':
goto fragment;
default:
++uri->query.len;
}
}
}

/* RFC3986 S3.5: A fragment identifier component is indicated by the
presence of a number sign ("#") character and terminated by the end
of the URI.
*/
fragment:
if (*ptr == '#') {
uri->fragment.buf = ptr;
while (*ptr++ != '\0') {
++uri->fragment.len;
}
}

end:
#ifdef URI_DEBUG
fprintf(stderr, "PARSE URI <%s>\n", utf8);
serd_uri_dump(uri, stderr);
fprintf(stderr, "\n");
#endif

return SERD_SUCCESS;
}

/**
Remove leading dot components from @c path.
See http://tools.ietf.org/html/rfc3986#section-5.2.3
@param up Set to the number of up-references (e.g. "../") trimmed
@return A pointer to the new start of @path
*/
static const uint8_t*
remove_dot_segments(const uint8_t* path, size_t len, size_t* up)
{
const uint8_t* begin = path;
const uint8_t* const end = path + len;

*up = 0;
while (begin < end) {
switch (begin[0]) {
case '.':
switch (begin[1]) {
case '/':
begin += 2; // Chop leading "./"
break;
case '.':
switch (begin[2]) {
case '\0':
++*up;
begin += 2; // Chop input ".."
break;
case '/':
++*up;
begin += 3; // Chop leading "../"
break;
default:
return begin;
}
break;
case '\0':
++begin; // Chop input "." (and fall-through)
default:
return begin;
}
break;
case '/':
switch (begin[1]) {
case '.':
switch (begin[2]) {
case '/':
begin += 2; // Leading "/./" => "/"
break;
case '.':
switch (begin[3]) {
case '/':
++*up;
begin += 3; // Leading "/../" => "/"
}
break;
default:
return begin;
}
} // else fall through
default:
return begin; // Finished chopping dot components
}
}

return begin;
}

/// Merge @p base and @p path in-place
static void
merge(SerdChunk* base, SerdChunk* path)
{
size_t up;
const uint8_t* begin = remove_dot_segments(path->buf, path->len, &up);
const uint8_t* end = path->buf + path->len;

if (base->buf && base->len > 0) {
// Find the up'th last slash
const uint8_t* base_last = (base->buf + base->len - 1);
++up;
do {
if (*base_last == '/') {
--up;
}
} while (up > 0 && (--base_last > base->buf));

// Set path prefix
base->len = base_last - base->buf + 1;
}

// Set path suffix
path->buf = begin;
path->len = end - begin;
}

/// See http://tools.ietf.org/html/rfc3986#section-5.2.2
SERD_API
void
serd_uri_resolve(const SerdURI* r, const SerdURI* base, SerdURI* t)
{
if (!base->scheme.len) {
*t = *r; // Don't resolve against non-absolute URIs
return;
}

t->path_base.buf = NULL;
t->path_base.len = 0;
if (r->scheme.len) {
*t = *r;
} else {
if (r->authority.len) {
t->authority = r->authority;
t->path = r->path;
t->query = r->query;
} else {
t->path = r->path;
if (!r->path.len) {
t->path_base = base->path;
if (r->query.len) {
t->query = r->query;
} else {
t->query = base->query;
}
} else {
if (r->path.buf[0] != '/') {
t->path_base = base->path;
}
merge(&t->path_base, &t->path);
t->query = r->query;
}
t->authority = base->authority;
}
t->scheme = base->scheme;
t->fragment = r->fragment;
}

#ifdef URI_DEBUG
fprintf(stderr, "## RESOLVE URI\n# BASE\n");
serd_uri_dump(base, stderr);
fprintf(stderr, "# URI\n");
serd_uri_dump(r, stderr);
fprintf(stderr, "# RESULT\n");
serd_uri_dump(t, stderr);
fprintf(stderr, "\n");
#endif
}

/** Write the path of @p uri starting at index @p i */
static size_t
write_path_tail(SerdSink sink, void* stream, const SerdURI* uri, size_t i)
{
size_t len = 0;
if (i < uri->path_base.len) {
len += sink(uri->path_base.buf + i, uri->path_base.len - i, stream);
}
if (uri->path.buf) {
if (i < uri->path_base.len) {
len += sink(uri->path.buf, uri->path.len, stream);
} else {
const size_t j = (i - uri->path_base.len);
len += sink(uri->path.buf + j, uri->path.len - j, stream);
}
}
return len;
}

/** Write the path of @p uri relative to the path of @p base. */
static size_t
write_rel_path(SerdSink sink,
void* stream,
const SerdURI* uri,
const SerdURI* base)
{
const size_t path_len = uri_path_len(uri);
const size_t base_len = uri_path_len(base);
const size_t min_len = (path_len < base_len) ? path_len : base_len;

// Find the last separator common to both paths
size_t last_shared_sep = 0;
size_t i = 0;
for (; i < min_len && uri_path_at(uri, i) == uri_path_at(base, i); ++i) {
if (uri_path_at(uri, i) == '/') {
last_shared_sep = i;
}
}

if (i == path_len && i == base_len) { // Paths are identical
return 0;
} else if (last_shared_sep == 0) { // No common components
return write_path_tail(sink, stream, uri, 0);
}

// Find the number of up references ("..") required
size_t up = 0;
for (size_t s = last_shared_sep + 1; s < base_len; ++s) {
if (uri_path_at(base, s) == '/') {
++up;
}
}

// Write up references
size_t len = 0;
for (size_t u = 0; u < up; ++u) {
len += sink("../", 3, stream);
}

// Write suffix
return len += write_path_tail(sink, stream, uri, last_shared_sep + 1);
}

/// See http://tools.ietf.org/html/rfc3986#section-5.3
SERD_API
size_t
serd_uri_serialise_relative(const SerdURI* uri,
const SerdURI* base,
const SerdURI* root,
SerdSink sink,
void* stream)
{
size_t len = 0;
const bool relative = uri_is_under(uri, root ? root : base);
if (relative) {
len = write_rel_path(sink, stream, uri, base);
}
if (!relative || (!len && base->query.buf)) {
if (uri->scheme.buf) {
len += sink(uri->scheme.buf, uri->scheme.len, stream);
len += sink(":", 1, stream);
}
if (uri->authority.buf) {
len += sink("//", 2, stream);
len += sink(uri->authority.buf, uri->authority.len, stream);
}
len += write_path_tail(sink, stream, uri, 0);
}
if (uri->query.buf) {
len += sink("?", 1, stream);
len += sink(uri->query.buf, uri->query.len, stream);
}
if (uri->fragment.buf) {
// Note uri->fragment.buf includes the leading `#'
len += sink(uri->fragment.buf, uri->fragment.len, stream);
}
return len;
}

/// See http://tools.ietf.org/html/rfc3986#section-5.3
SERD_API
size_t
serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream)
{
return serd_uri_serialise_relative(uri, NULL, NULL, sink, stream);
}

+ 807
- 0
source/libs/lilv/serd-0.18.2/src/writer.c View File

@@ -0,0 +1,807 @@
/*
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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_XSD "http://www.w3.org/2001/XMLSchema#"

typedef struct {
SerdNode graph;
SerdNode subject;
SerdNode predicate;
} WriteContext;

static const WriteContext WRITE_CONTEXT_NULL = {
{ 0, 0, 0, 0, SERD_NOTHING },
{ 0, 0, 0, 0, SERD_NOTHING },
{ 0, 0, 0, 0, SERD_NOTHING }
};

typedef enum {
SEP_NONE,
SEP_END_S, ///< End of a subject ('.')
SEP_END_P, ///< End of a predicate (';')
SEP_END_O, ///< End of an object (',')
SEP_S_P, ///< Between a subject and predicate (whitespace)
SEP_P_O, ///< Between a predicate and object (whitespace)
SEP_ANON_BEGIN, ///< Start of anonymous node ('[')
SEP_ANON_END, ///< End of anonymous node (']')
SEP_LIST_BEGIN, ///< Start of list ('(')
SEP_LIST_SEP, ///< List separator (whitespace)
SEP_LIST_END ///< End of list (')')
} Sep;

typedef struct {
const char* str; ///< Sep string
uint8_t len; ///< Length of sep string
uint8_t space_before; ///< Newline before sep
uint8_t space_after_node; ///< Newline after sep if after node
uint8_t space_after_sep; ///< Newline after sep if after sep
} SepRule;

static const SepRule rules[] = {
{ NULL, 0, 0, 0, 0 },
{ " .\n\n", 4, 0, 0, 0 },
{ " ;", 2, 0, 1, 1 },
{ " ,", 2, 0, 1, 0 },
{ NULL, 0, 0, 1, 0 },
{ " ", 1, 0, 0, 0 },
{ "[", 1, 0, 1, 1 },
{ "]", 1, 1, 0, 0 },
{ "(", 1, 0, 0, 0 },
{ NULL, 1, 0, 1, 0 },
{ ")", 1, 1, 0, 0 },
{ "\n", 1, 0, 1, 0 }
};

struct SerdWriterImpl {
SerdSyntax syntax;
SerdStyle style;
SerdEnv* env;
SerdNode root_node;
SerdURI root_uri;
SerdURI base_uri;
SerdStack anon_stack;
SerdBulkSink bulk_sink;
SerdSink sink;
void* stream;
SerdErrorSink error_sink;
void* error_handle;
WriteContext context;
SerdNode list_subj;
unsigned list_depth;
uint8_t* bprefix;
size_t bprefix_len;
unsigned indent;
Sep last_sep;
bool empty;
};

typedef enum {
WRITE_URI,
WRITE_STRING,
WRITE_LONG_STRING
} TextContext;

static void
w_err(SerdWriter* writer, SerdStatus st, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
const SerdError e = { st, NULL, 0, 0, fmt, &args };
serd_error(writer->error_sink, writer->error_handle, &e);
va_end(args);
}

static inline WriteContext*
anon_stack_top(SerdWriter* writer)
{
assert(!serd_stack_is_empty(&writer->anon_stack));
return (WriteContext*)(writer->anon_stack.buf
+ writer->anon_stack.size - sizeof(WriteContext));
}

static void
copy_node(SerdNode* dst, const SerdNode* src)
{
if (src) {
dst->buf = (uint8_t*)realloc((char*)dst->buf, src->n_bytes + 1);
dst->n_bytes = src->n_bytes;
dst->n_chars = src->n_chars;
dst->flags = src->flags;
dst->type = src->type;
memcpy((char*)dst->buf, src->buf, src->n_bytes + 1);
} else {
dst->type = SERD_NOTHING;
}
}

static inline size_t
sink(const void* buf, size_t len, SerdWriter* writer)
{
if (writer->style & SERD_STYLE_BULK) {
return serd_bulk_sink_write(buf, len, &writer->bulk_sink);
} else {
return writer->sink(buf, len, writer->stream);
}
}

static size_t
write_text(SerdWriter* writer, TextContext ctx,
const uint8_t* utf8, size_t n_bytes)
{
size_t len = 0;
char escape[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (size_t i = 0; i < n_bytes;) {
// Fast bulk write for long strings of printable ASCII
size_t j = i;
for (; j < n_bytes; ++j) {
if (utf8[j] == '>' || utf8[j] == '\\' || utf8[j] == '"'
|| (!in_range(utf8[j], 0x20, 0x7E))) {
break;
}
}

if (j > i) {
len += sink(&utf8[i], j - i, writer);
i = j;
continue;
}

uint8_t in = utf8[i++];
if (ctx == WRITE_LONG_STRING) {
if (in == '\\') {
len += sink("\\\\", 2, writer); continue;
} else if (in == '\"' && i == n_bytes) {
len += sink("\\\"", 2, writer); continue; // '"' at string end
}
} else {
switch (in) {
case '\\': len += sink("\\\\", 2, writer); continue;
case '\n': len += sink("\\n", 2, writer); continue;
case '\r': len += sink("\\r", 2, writer); continue;
case '\t': len += sink("\\t", 2, writer); continue;
case '"':
if (ctx == WRITE_STRING) {
len += sink("\\\"", 2, writer);
continue;
} // else fall-through
default: break;
}

if ((ctx == WRITE_STRING && in == '"') ||
(ctx == WRITE_URI && in == '>')) {
snprintf(escape, sizeof(escape), "\\u%04X",
ctx == WRITE_STRING ? '"' : '>');
len += sink(escape, 6, writer);
continue;
}
}

uint32_t c = 0;
size_t size = 0;
if ((in & 0x80) == 0) { // Starts with `0'
c = in & 0x7F;
if (in_range(c, 0x20, 0x7E)
|| (is_space(c) && ctx == WRITE_LONG_STRING)) {
len += sink(&in, 1, writer); // Print ASCII character
} else {
snprintf(escape, sizeof(escape), "\\u%04X", c);
len += sink(escape, 6, writer); // ASCII control character
}
continue;
} else if ((in & 0xE0) == 0xC0) { // Starts with `110'
size = 2;
c = in & 0x1F;
} else if ((in & 0xF0) == 0xE0) { // Starts with `1110'
size = 3;
c = in & 0x0F;
} else if ((in & 0xF8) == 0xF0) { // Starts with `11110'
size = 4;
c = in & 0x07;
} else {
w_err(writer, SERD_ERR_BAD_ARG, "invalid UTF-8: %X\n", in);
const uint8_t replacement_char[] = { 0xEF, 0xBF, 0xBD };
len += sink(replacement_char, sizeof(replacement_char), writer);
return len;
}

if (ctx != WRITE_URI && !(writer->style & SERD_STYLE_ASCII)) {
// Write UTF-8 character directly to UTF-8 output
// TODO: Always parse and validate character?
len += sink(utf8 + i - 1, size, writer);
i += size - 1;
continue;
}

#define READ_BYTE() \
in = utf8[i++] & 0x3f; \
c = (c << 6) | in;

switch (size) {
case 4: READ_BYTE();
case 3: READ_BYTE();
case 2: READ_BYTE();
}

if (c < 0xFFFF) {
snprintf(escape, sizeof(escape), "\\u%04X", c);
len += sink(escape, 6, writer);
} else {
snprintf(escape, sizeof(escape), "\\U%08X", c);
len += sink(escape, 10, writer);
}
}
return len;
}

static size_t
uri_sink(const void* buf, size_t len, void* stream)
{
return write_text((SerdWriter*)stream, WRITE_URI,
(const uint8_t*)buf, len);
}

static void
write_newline(SerdWriter* writer)
{
sink("\n", 1, writer);
for (unsigned i = 0; i < writer->indent; ++i) {
sink("\t", 1, writer);
}
}

static void
write_sep(SerdWriter* writer, const Sep sep)
{
const SepRule* rule = &rules[sep];
if (rule->space_before) {
write_newline(writer);
}
if (rule->str) {
sink(rule->str, rule->len, writer);
}
if ( (writer->last_sep && rule->space_after_sep)
|| (!writer->last_sep && rule->space_after_node)) {
write_newline(writer);
} else if (writer->last_sep && rule->space_after_node) {
sink(" ", 1, writer);
}
writer->last_sep = sep;
}

static SerdStatus
reset_context(SerdWriter* writer, bool del)
{
if (del) {
serd_node_free(&writer->context.graph);
serd_node_free(&writer->context.subject);
serd_node_free(&writer->context.predicate);
writer->context = WRITE_CONTEXT_NULL;
} else {
writer->context.graph.type = SERD_NOTHING;
writer->context.subject.type = SERD_NOTHING;
writer->context.predicate.type = SERD_NOTHING;
}
writer->empty = false;
return SERD_SUCCESS;
}

typedef enum {
FIELD_NONE,
FIELD_SUBJECT,
FIELD_PREDICATE,
FIELD_OBJECT
} Field;

static bool
write_node(SerdWriter* writer,
const SerdNode* node,
const SerdNode* datatype,
const SerdNode* lang,
Field field,
SerdStatementFlags flags)
{
SerdChunk uri_prefix;
SerdChunk uri_suffix;
bool has_scheme;
switch (node->type) {
case SERD_BLANK:
if (writer->syntax != SERD_NTRIPLES
&& ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN))
|| (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) {
++writer->indent;
write_sep(writer, SEP_ANON_BEGIN);
} else if (writer->syntax != SERD_NTRIPLES
&& (field == FIELD_SUBJECT && (flags & SERD_LIST_S_BEGIN))) {
assert(writer->list_depth == 0);
copy_node(&writer->list_subj, node);
++writer->list_depth;
++writer->indent;
write_sep(writer, SEP_LIST_BEGIN);
} else if (writer->syntax != SERD_NTRIPLES
&& (field == FIELD_OBJECT && (flags & SERD_LIST_O_BEGIN))) {
++writer->indent;
++writer->list_depth;
write_sep(writer, SEP_LIST_BEGIN);
} else if (writer->syntax != SERD_NTRIPLES
&& ((field == FIELD_SUBJECT && (flags & SERD_EMPTY_S))
|| (field == FIELD_OBJECT && (flags & SERD_EMPTY_O)))) {
sink("[]", 2, writer);
} else {
sink("_:", 2, writer);
if (writer->bprefix && !strncmp((const char*)node->buf,
(const char*)writer->bprefix,
writer->bprefix_len)) {
sink(node->buf + writer->bprefix_len,
node->n_bytes - writer->bprefix_len,
writer);
} else {
sink(node->buf, node->n_bytes, writer);
}
}
break;
case SERD_CURIE:
switch (writer->syntax) {
case SERD_NTRIPLES:
if (serd_env_expand(writer->env, node, &uri_prefix, &uri_suffix)) {
w_err(writer, SERD_ERR_BAD_CURIE,
"undefined namespace prefix `%s'\n", node->buf);
return false;
}
sink("<", 1, writer);
write_text(writer, WRITE_URI, uri_prefix.buf, uri_prefix.len);
write_text(writer, WRITE_URI, uri_suffix.buf, uri_suffix.len);
sink(">", 1, writer);
break;
case SERD_TURTLE:
sink(node->buf, node->n_bytes, writer);
}
break;
case SERD_LITERAL:
if (writer->syntax == SERD_TURTLE && datatype && datatype->buf) {
const char* type_uri = (const char*)datatype->buf;
if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) && (
!strcmp(type_uri + sizeof(NS_XSD) - 1, "boolean") ||
!strcmp(type_uri + sizeof(NS_XSD) - 1, "decimal") ||
!strcmp(type_uri + sizeof(NS_XSD) - 1, "integer"))) {
sink(node->buf, node->n_bytes, writer);
break;
}
}
if (writer->syntax != SERD_NTRIPLES
&& (node->flags & (SERD_HAS_NEWLINE|SERD_HAS_QUOTE))) {
sink("\"\"\"", 3, writer);
write_text(writer, WRITE_LONG_STRING, node->buf, node->n_bytes);
sink("\"\"\"", 3, writer);
} else {
sink("\"", 1, writer);
write_text(writer, WRITE_STRING, node->buf, node->n_bytes);
sink("\"", 1, writer);
}
if (lang && lang->buf) {
sink("@", 1, writer);
sink(lang->buf, lang->n_bytes, writer);
} else if (datatype && datatype->buf) {
sink("^^", 2, writer);
write_node(writer, datatype, NULL, NULL, FIELD_NONE, flags);
}
break;
case SERD_URI:
has_scheme = serd_uri_string_has_scheme(node->buf);
if (field == FIELD_PREDICATE && (writer->syntax == SERD_TURTLE)
&& !strcmp((const char*)node->buf, NS_RDF "type")) {
sink("a", 1, writer);
break;
} else if ((writer->syntax == SERD_TURTLE)
&& !strcmp((const char*)node->buf, NS_RDF "nil")) {
sink("()", 2, writer);
break;
} else if (has_scheme && (writer->style & SERD_STYLE_CURIED)) {
SerdNode prefix;
SerdChunk suffix;
if (serd_env_qualify(writer->env, node, &prefix, &suffix)) {
write_text(writer, WRITE_URI, prefix.buf, prefix.n_bytes);
sink(":", 1, writer);
write_text(writer, WRITE_URI, suffix.buf, suffix.len);
break;
}
}
sink("<", 1, writer);
if (writer->style & SERD_STYLE_RESOLVED) {
SerdURI in_base_uri, uri, abs_uri;
serd_env_get_base_uri(writer->env, &in_base_uri);
serd_uri_parse(node->buf, &uri);
serd_uri_resolve(&uri, &in_base_uri, &abs_uri);
bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri);
SerdURI* root = rooted ? &writer->root_uri : & writer->base_uri;
if (!uri_is_under(&abs_uri, root) ||
writer->syntax == SERD_NTRIPLES) {
serd_uri_serialise(&abs_uri, uri_sink, writer);
} else {
serd_uri_serialise_relative(
&uri, &writer->base_uri, root, uri_sink, writer);
}
} else {
write_text(writer, WRITE_URI, node->buf, node->n_bytes);
}
sink(">", 1, writer);
default:
break;
}
writer->last_sep = SEP_NONE;
return true;
}

static inline bool
is_resource(const SerdNode* node)
{
return node->type > SERD_LITERAL;
}

static void
write_pred(SerdWriter* writer, SerdStatementFlags flags, const SerdNode* pred)
{
write_node(writer, pred, NULL, NULL, FIELD_PREDICATE, flags);
write_sep(writer, SEP_P_O);
copy_node(&writer->context.predicate, pred);
}

static bool
write_list_obj(SerdWriter* writer,
SerdStatementFlags flags,
const SerdNode* predicate,
const SerdNode* object,
const SerdNode* datatype,
const SerdNode* lang)
{
if (!strcmp((const char*)object->buf, NS_RDF "nil")) {
--writer->indent;
write_sep(writer, SEP_LIST_END);
return true;
} else if (!strcmp((const char*)predicate->buf, NS_RDF "first")) {
write_sep(writer, SEP_LIST_SEP);
write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
}
return false;
}

SERD_API
SerdStatus
serd_writer_write_statement(SerdWriter* writer,
SerdStatementFlags flags,
const SerdNode* graph,
const SerdNode* subject,
const SerdNode* predicate,
const SerdNode* object,
const SerdNode* datatype,
const SerdNode* lang)
{
if (!subject || !predicate || !object
|| !subject->buf || !predicate->buf || !object->buf
|| !is_resource(subject) || !is_resource(predicate)) {
return SERD_ERR_BAD_ARG;
}

switch (writer->syntax) {
case SERD_NTRIPLES:
write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags);
sink(" ", 1, writer);
write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags);
sink(" ", 1, writer);
if (!write_node(writer, object, datatype, lang, FIELD_OBJECT, flags)) {
return SERD_ERR_UNKNOWN;
}
sink(" .\n", 3, writer);
return SERD_SUCCESS;
default:
break;
}

if ((flags & SERD_LIST_CONT)) {
if (write_list_obj(writer, flags, predicate, object, datatype, lang)) {
// Reached end of list
if (--writer->list_depth == 0 && writer->list_subj.type) {
reset_context(writer, true);
writer->context.subject = writer->list_subj;
writer->list_subj = SERD_NODE_NULL;
}
return SERD_SUCCESS;
}
} else if (serd_node_equals(subject, &writer->context.subject)) {
if (serd_node_equals(predicate, &writer->context.predicate)) {
// Abbreviate S P
if (!(flags & SERD_ANON_O_BEGIN)) {
++writer->indent;
}
write_sep(writer, SEP_END_O);
write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
if (!(flags & SERD_ANON_O_BEGIN)) {
--writer->indent;
}
} else {
// Abbreviate S
Sep sep = writer->context.predicate.type ? SEP_END_P : SEP_S_P;
write_sep(writer, sep);
write_pred(writer, flags, predicate);
write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
}
} else {
// No abbreviation
if (writer->context.subject.type) {
assert(writer->indent > 0);
--writer->indent;
if (serd_stack_is_empty(&writer->anon_stack)) {
write_sep(writer, SEP_END_S);
}
} else if (!writer->empty) {
write_sep(writer, SEP_S_P);
}

if (!(flags & SERD_ANON_CONT)) {
write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags);
++writer->indent;
write_sep(writer, SEP_S_P);
} else {
++writer->indent;
}

reset_context(writer, true);
copy_node(&writer->context.subject, subject);

if (!(flags & SERD_LIST_S_BEGIN)) {
write_pred(writer, flags, predicate);
}

write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
}

if (flags & (SERD_ANON_S_BEGIN|SERD_ANON_O_BEGIN)) {
WriteContext* ctx = (WriteContext*)serd_stack_push(
&writer->anon_stack, sizeof(WriteContext));
*ctx = writer->context;
WriteContext new_context = {
serd_node_copy(graph), serd_node_copy(subject), SERD_NODE_NULL };
if ((flags & SERD_ANON_S_BEGIN)) {
new_context.predicate = serd_node_copy(predicate);
}
writer->context = new_context;
} else {
copy_node(&writer->context.graph, graph);
copy_node(&writer->context.subject, subject);
copy_node(&writer->context.predicate, predicate);
}

return SERD_SUCCESS;
}

SERD_API
SerdStatus
serd_writer_end_anon(SerdWriter* writer,
const SerdNode* node)
{
if (writer->syntax == SERD_NTRIPLES) {
return SERD_SUCCESS;
}
if (serd_stack_is_empty(&writer->anon_stack)) {
w_err(writer, SERD_ERR_UNKNOWN,
"unexpected end of anonymous node\n");
return SERD_ERR_UNKNOWN;
}
assert(writer->indent > 0);
--writer->indent;
write_sep(writer, SEP_ANON_END);
reset_context(writer, true);
writer->context = *anon_stack_top(writer);
serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
const bool is_subject = serd_node_equals(node, &writer->context.subject);
if (is_subject) {
copy_node(&writer->context.subject, node);
writer->context.predicate.type = SERD_NOTHING;
}
return SERD_SUCCESS;
}

SERD_API
SerdStatus
serd_writer_finish(SerdWriter* writer)
{
if (writer->context.subject.type) {
sink(" .\n", 3, writer);
}
if (writer->style & SERD_STYLE_BULK) {
serd_bulk_sink_flush(&writer->bulk_sink);
}
writer->indent = 0;
return reset_context(writer, true);
}

SERD_API
SerdWriter*
serd_writer_new(SerdSyntax syntax,
SerdStyle style,
SerdEnv* env,
const SerdURI* base_uri,
SerdSink ssink,
void* stream)
{
const WriteContext context = WRITE_CONTEXT_NULL;
SerdWriter* writer = (SerdWriter*)malloc(sizeof(SerdWriter));
writer->syntax = syntax;
writer->style = style;
writer->env = env;
writer->root_node = SERD_NODE_NULL;
writer->root_uri = SERD_URI_NULL;
writer->base_uri = base_uri ? *base_uri : SERD_URI_NULL;
writer->anon_stack = serd_stack_new(sizeof(WriteContext));
writer->sink = ssink;
writer->stream = stream;
writer->error_sink = NULL;
writer->error_handle = NULL;
writer->context = context;
writer->list_subj = SERD_NODE_NULL;
writer->list_depth = 0;
writer->bprefix = NULL;
writer->bprefix_len = 0;
writer->indent = 0;
writer->last_sep = SEP_NONE;
writer->empty = true;
if (style & SERD_STYLE_BULK) {
writer->bulk_sink = serd_bulk_sink_new(ssink, stream, SERD_PAGE_SIZE);
}
return writer;
}

SERD_API
void
serd_writer_set_error_sink(SerdWriter* writer,
SerdErrorSink error_sink,
void* error_handle)
{
writer->error_sink = error_sink;
writer->error_handle = error_handle;
}

SERD_API
void
serd_writer_chop_blank_prefix(SerdWriter* writer,
const uint8_t* prefix)
{
free(writer->bprefix);
writer->bprefix_len = 0;
writer->bprefix = NULL;
if (prefix) {
writer->bprefix_len = strlen((const char*)prefix);
writer->bprefix = (uint8_t*)malloc(writer->bprefix_len + 1);
memcpy(writer->bprefix, prefix, writer->bprefix_len + 1);
}
}

SERD_API
SerdStatus
serd_writer_set_base_uri(SerdWriter* writer,
const SerdNode* uri)
{
if (!serd_env_set_base_uri(writer->env, uri)) {
serd_env_get_base_uri(writer->env, &writer->base_uri);

if (writer->syntax != SERD_NTRIPLES) {
if (writer->context.graph.type || writer->context.subject.type) {
sink(" .\n\n", 4, writer);
reset_context(writer, false);
}
sink("@base <", 7, writer);
sink(uri->buf, uri->n_bytes, writer);
sink("> .\n", 4, writer);
}
writer->indent = 0;
return reset_context(writer, false);
}
return SERD_ERR_UNKNOWN;
}

SERD_API
SerdStatus
serd_writer_set_root_uri(SerdWriter* writer,
const SerdNode* uri)
{
serd_node_free(&writer->root_node);
if (uri && uri->buf) {
writer->root_node = serd_node_copy(uri);
serd_uri_parse(uri->buf, &writer->root_uri);
} else {
writer->root_node = SERD_NODE_NULL;
writer->root_uri = SERD_URI_NULL;
}
return SERD_SUCCESS;
}

SERD_API
SerdStatus
serd_writer_set_prefix(SerdWriter* writer,
const SerdNode* name,
const SerdNode* uri)
{
if (!serd_env_set_prefix(writer->env, name, uri)) {
if (writer->syntax != SERD_NTRIPLES) {
if (writer->context.graph.type || writer->context.subject.type) {
sink(" .\n\n", 4, writer);
reset_context(writer, false);
}
sink("@prefix ", 8, writer);
sink(name->buf, name->n_bytes, writer);
sink(": <", 3, writer);
write_text(writer, WRITE_URI, uri->buf, uri->n_bytes);
sink("> .\n", 4, writer);
}
writer->indent = 0;
return reset_context(writer, false);
}
return SERD_ERR_UNKNOWN;
}

SERD_API
void
serd_writer_free(SerdWriter* writer)
{
serd_writer_finish(writer);
serd_stack_free(&writer->anon_stack);
free(writer->bprefix);
if (writer->style & SERD_STYLE_BULK) {
serd_bulk_sink_free(&writer->bulk_sink);
}
serd_node_free(&writer->root_node);
free(writer);
}

SERD_API
SerdEnv*
serd_writer_get_env(SerdWriter* writer)
{
return writer->env;
}

SERD_API
size_t
serd_file_sink(const void* buf, size_t len, void* stream)
{
return fwrite(buf, 1, len, (FILE*)stream);
}

SERD_API
size_t
serd_chunk_sink(const void* buf, size_t len, void* stream)
{
SerdChunk* chunk = (SerdChunk*)stream;
chunk->buf = (uint8_t*)realloc((uint8_t*)chunk->buf, chunk->len + len);
memcpy((uint8_t*)chunk->buf + chunk->len, buf, len);
chunk->len += len;
return len;
}

SERD_API
uint8_t*
serd_chunk_sink_finish(SerdChunk* stream)
{
serd_chunk_sink("", 1, stream);
return (uint8_t*)stream->buf;
}

+ 20
- 0
source/libs/lilv/serd-0.18.2/tests/README.txt View File

@@ -0,0 +1,20 @@
These are the tests for the Turtle Terse RDF Triple Language
that must be passed by conformant systems. See
http://www.dajobe.org/2004/01/turtle/
for the full conformance information.

The format is a set of good tests and bad tests.

Good tests are a pair of files:
abc.ttl abc.out
which are the input Turtle file and the expected output RDF triples,
written in N-Triples.

bad tests are of the form
bad-XX.ttl
which must fail.

The tests should be performed with an assumed base URI
of http://www.w3.org/2001/sw/DataAccess/df1/tests/

Dave

+ 219
- 0
source/libs/lilv/serd-0.18.2/tests/UTF-8.ttl View File

@@ -0,0 +1,219 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<> rdfs:comment """
UTF-8 encoded sample plain-text file
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25


The ASCII compatible UTF-8 encoding used in this plain-text file
is defined in Unicode, ISO 10646-1, and RFC 2279.


Using Unicode/UTF-8, you can write in emails and source code things such as

Mathematics and sciences:

∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
⎪⎢⎜│a²+b³ ⎟⎥⎪
∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
⎪⎢⎜⎷ c₈ ⎟⎥⎪
ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
⎪⎢⎜ ∞ ⎟⎥⎪
⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭

Linguistics and dictionaries:

ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]

APL:

((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈

Nicer typography in plain text files:

╔══════════════════════════════════════════╗
║ ║
║ • ‘single’ and “double” quotes ║
║ ║
║ • Curly apostrophes: “We’ve been here” ║
║ ║
║ • Latin-1 apostrophe and accents: '´` ║
║ ║
║ • ‚deutsche‘ „Anführungszeichen“ ║
║ ║
║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
║ ║
║ • ASCII safety test: 1lI|, 0OD, 8B ║
║ ╭─────────╮ ║
║ • the euro symbol: │ 14.95 € │ ║
║ ╰─────────╯ ║
╚══════════════════════════════════════════╝

Combining characters:

STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑

Greek (in Polytonic):

The Greek anthem:

Σὲ γνωρίζω ἀπὸ τὴν κόψη
τοῦ σπαθιοῦ τὴν τρομερή,
σὲ γνωρίζω ἀπὸ τὴν ὄψη
ποὺ μὲ βία μετράει τὴ γῆ.

᾿Απ᾿ τὰ κόκκαλα βγαλμένη
τῶν ῾Ελλήνων τὰ ἱερά
καὶ σὰν πρῶτα ἀνδρειωμένη
χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!

From a speech of Demosthenes in the 4th century BC:

Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.

Δημοσθένους, Γ´ ᾿Ολυνθιακὸς

Georgian:

From a Unicode conference invitation:

გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.

Russian:

From a Unicode conference invitation:

Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
Конференция соберет широкий круг экспертов по вопросам глобального
Интернета и Unicode, локализации и интернационализации, воплощению и
применению Unicode в различных операционных системах и программных
приложениях, шрифтах, верстке и многоязычных компьютерных системах.

Thai (UCS Level 2):

Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
classic 'San Gua'):

[----------------------------|------------------------]
๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ

(The above is a two-column text. If combining characters are handled
correctly, the lines of the second column should be aligned with the
| character above.)

Ethiopian:

Proverbs in the Amharic language:

ሰማይ አይታረስ ንጉሥ አይከሰስ።
ብላ ካለኝ እንደአባቴ በቆመጠኝ።
ጌጥ ያለቤቱ ቁምጥና ነው።
ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
የአፍ ወለምታ በቅቤ አይታሽም።
አይጥ በበላ ዳዋ ተመታ።
ሲተረጉሙ ይደረግሙ።
ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
ድር ቢያብር አንበሳ ያስር።
ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
ሥራ ከመፍታት ልጄን ላፋታት።
ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
ተንጋሎ ቢተፉ ተመልሶ ባፉ።
ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
እግርህን በፍራሽህ ልክ ዘርጋ።

Runes:

ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ

(Old English, which transcribed into Latin reads 'He cwaeth that he
bude thaem lande northweardum with tha Westsae.' and means 'He said
that he lived in the northern land near the Western Sea.')

Braille:

⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌

⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲

⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲

⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲

(The first couple of paragraphs of "A Christmas Carol" by Dickens)

Compact font selection example text:

ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა

Greetings in various languages:

Hello world, Καλημέρα κόσμε, コンニチハ

Box drawing alignment tests: █
╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
▝▀▘▙▄▟
""" .
<> rdfs:comment """
Two byte Unicode escape: \u00E0
Largest Unicode escape in Turtle: \U0010FFFF
""" .

+ 2
- 0
source/libs/lilv/serd-0.18.2/tests/bad-00.ttl View File

@@ -0,0 +1,2 @@
# prefix name must end in a :
@prefix a <#> .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-01.ttl View File

@@ -0,0 +1,3 @@
# Forbidden by RDF - predicate cannot be blank
@prefix : <http://example.org/base#> .
:a [ :b :c ] :d .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-02.ttl View File

@@ -0,0 +1,3 @@
# Forbidden by RDF - predicate cannot be blank
@prefix : <http://example.org/base#> .
:a [] :b .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-03.ttl View File

@@ -0,0 +1,3 @@
# 'a' only allowed as a predicate
@prefix : <http://example.org/base#> .
a :a :b .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-04.ttl View File

@@ -0,0 +1,3 @@
# No comma is allowed in collections
@prefix : <http://example.org/stuff/1.0/> .
:a :b ( "apple", "banana" ) .

+ 4
- 0
source/libs/lilv/serd-0.18.2/tests/bad-05.ttl View File

@@ -0,0 +1,4 @@
# N3 {}s are not in Turtle
@prefix : <http://example.org/stuff/1.0/> .
{ :a :b :c . } :d :e .


+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-06.ttl View File

@@ -0,0 +1,3 @@
# is and of are not in turtle
@prefix : <http://example.org/stuff/1.0/> .
:a is :b of :c .

+ 4
- 0
source/libs/lilv/serd-0.18.2/tests/bad-07.ttl View File

@@ -0,0 +1,4 @@
# paths are not in turtle
@prefix : <http://example.org/stuff/1.0/> .
:a.:b.:c .
:a^:b^:c .

+ 2
- 0
source/libs/lilv/serd-0.18.2/tests/bad-08.ttl View File

@@ -0,0 +1,2 @@
@keywords something.
# @keywords is not in turtle

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-09.ttl View File

@@ -0,0 +1,3 @@
# implies is not in turtle
@prefix : <http://example.org/stuff/1.0/> .
:a => :b .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-10.ttl View File

@@ -0,0 +1,3 @@
# equivalence is not in turtle
@prefix : <http://example.org/stuff/1.0/> .
:a = :b .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-11.ttl View File

@@ -0,0 +1,3 @@
# @forAll is not in turtle
@prefix : <http://example.org/stuff/1.0/> .
@forAll :x .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-12.ttl View File

@@ -0,0 +1,3 @@
# @forSome is not in turtle
@prefix : <http://example.org/stuff/1.0/> .
@forSome :x .

+ 3
- 0
source/libs/lilv/serd-0.18.2/tests/bad-13.ttl View File

@@ -0,0 +1,3 @@
# <= is not in turtle
@prefix : <http://example.org/stuff/1.0/> .
:a <= :b .

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save