summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy46
-rw-r--r--.gitignore11
-rw-r--r--.gitmodules3
-rw-r--r--.reuse/dep518
-rw-r--r--COPYING16
-rw-r--r--INSTALL66
-rw-r--r--INSTALL.md77
-rw-r--r--LICENSES/0BSD.txt12
l---------LICENSES/ISC.txt1
-rw-r--r--NEWS95
-rw-r--r--README.md3
-rw-r--r--bindings/python/Makefile2
-rw-r--r--bindings/python/conf.py8
-rw-r--r--bindings/python/index.rst4
-rw-r--r--bindings/python/lilv.py7
-rwxr-xr-xbindings/python/lv2_apply.py3
-rwxr-xr-xbindings/python/lv2_list.py3
-rwxr-xr-xbindings/python/lv2_list_presets.py3
-rw-r--r--bindings/python/meson.build9
-rw-r--r--bindings/test/bindings_test_plugin.c26
-rw-r--r--bindings/test/python/test_api.py13
-rw-r--r--doc/Doxyfile.in (renamed from doc/c/Doxyfile)9
-rw-r--r--doc/api/meson.build9
-rw-r--r--doc/c/index.rst10
-rw-r--r--doc/c/wscript43
-rw-r--r--doc/conf.py.in124
-rw-r--r--doc/html/meson.build39
-rw-r--r--doc/index.rst (renamed from doc/summary.rst)14
-rw-r--r--doc/lv2apply.1100
-rw-r--r--doc/lv2bench.155
-rw-r--r--doc/lv2info.198
-rw-r--r--doc/lv2ls.189
-rw-r--r--doc/meson.build71
-rw-r--r--doc/overview.rst (renamed from doc/c/overview.rst)4
-rw-r--r--doc/plugins.rst (renamed from doc/c/plugins.rst)4
-rw-r--r--doc/singlehtml/meson.build33
-rw-r--r--doc/uis.rst (renamed from doc/c/uis.rst)4
-rw-r--r--doc/world.rst (renamed from doc/c/world.rst)4
-rw-r--r--doc/xml/meson.build36
-rw-r--r--include/lilv/lilv.h77
-rw-r--r--include/lilv/lilvmm.hpp279
-rw-r--r--lilv.pc.in11
-rw-r--r--lilv.ttl48
-rw-r--r--meson.build265
-rw-r--r--meson/suppressions/meson.build141
-rw-r--r--meson_options.txt29
-rwxr-xr-xscripts/dox_to_sphinx.py655
-rw-r--r--src/.clang-tidy21
-rw-r--r--src/collections.c52
-rw-r--r--src/filesystem.c564
-rw-r--r--src/filesystem.h182
-rw-r--r--src/instance.c17
-rw-r--r--src/lib.c17
-rw-r--r--src/lilv_config.h115
-rw-r--r--src/lilv_internal.h40
-rw-r--r--src/node.c41
-rw-r--r--src/plugin.c27
-rw-r--r--src/pluginclass.c22
-rw-r--r--src/port.c26
-rw-r--r--src/query.c24
-rw-r--r--src/scalepoint.c17
-rw-r--r--src/state.c339
-rw-r--r--src/ui.c17
-rw-r--r--src/util.c53
-rw-r--r--src/world.c86
-rw-r--r--src/zix/common.h138
-rw-r--r--src/zix/tree.c727
-rw-r--r--src/zix/tree.h164
-rw-r--r--subprojects/sphinxygen.wrap14
-rw-r--r--test/.clang-tidy39
-rw-r--r--test/bad_syntax.lv2/bad_syntax.c18
-rw-r--r--test/bad_syntax.lv2/meson.build36
-rw-r--r--test/bad_syntax.lv2/test_bad_syntax.c15
-rw-r--r--test/cpp/.clang-tidy19
-rw-r--r--test/cpp/meson.build37
-rw-r--r--test/cpp/test_lilv_hpp.cpp12
-rw-r--r--test/failed_instantiation.lv2/failed_instantiation.c18
-rw-r--r--test/failed_instantiation.lv2/meson.build36
-rw-r--r--test/failed_instantiation.lv2/test_failed_instantiation.c15
-rw-r--r--test/failed_lib_descriptor.lv2/failed_lib_descriptor.c18
-rw-r--r--test/failed_lib_descriptor.lv2/meson.build36
-rw-r--r--test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c15
-rw-r--r--test/lib_descriptor.lv2/lib_descriptor.c25
-rw-r--r--test/lib_descriptor.lv2/meson.build36
-rw-r--r--test/lib_descriptor.lv2/test_lib_descriptor.c15
-rw-r--r--test/lilv_cxx_test.cpp25
-rw-r--r--test/lilv_test_uri_map.h26
-rw-r--r--test/lilv_test_utils.c85
-rw-r--r--test/lilv_test_utils.h21
-rw-r--r--test/lv2/core.lv2/lv2core.ttl (renamed from test/core.lv2/lv2core.ttl)0
-rw-r--r--test/lv2/core.lv2/manifest.ttl (renamed from test/core.lv2/manifest.ttl)0
-rw-r--r--test/lv2/core.lv2/meson.build11
-rw-r--r--test/meson.build115
-rw-r--r--test/missing_descriptor.lv2/meson.build36
-rw-r--r--test/missing_descriptor.lv2/missing_descriptor.c18
-rw-r--r--test/missing_descriptor.lv2/test_missing_descriptor.c15
-rw-r--r--test/missing_name.lv2/meson.build36
-rw-r--r--test/missing_name.lv2/missing_name.c18
-rw-r--r--test/missing_name.lv2/test_missing_name.c15
-rw-r--r--test/missing_plugin.lv2/meson.build36
-rw-r--r--test/missing_plugin.lv2/missing_plugin.c18
-rw-r--r--test/missing_plugin.lv2/test_missing_plugin.c15
-rw-r--r--test/missing_port.lv2/meson.build36
-rw-r--r--test/missing_port.lv2/missing_port.c18
-rw-r--r--test/missing_port.lv2/test_missing_port.c15
-rw-r--r--test/missing_port_name.lv2/meson.build36
-rw-r--r--test/missing_port_name.lv2/missing_port_name.c18
-rw-r--r--test/missing_port_name.lv2/test_missing_port_name.c15
-rw-r--r--test/new_version.lv2/meson.build24
-rw-r--r--test/new_version.lv2/new_version.c18
-rw-r--r--test/old_version.lv2/meson.build24
-rw-r--r--test/old_version.lv2/old_version.c18
-rw-r--r--test/test_bad_port_index.c17
-rw-r--r--test/test_bad_port_symbol.c17
-rw-r--r--test/test_classes.c17
-rw-r--r--test/test_discovery.c17
-rw-r--r--test/test_filesystem.c553
-rw-r--r--test/test_get_symbol.c17
-rw-r--r--test/test_no_author.c17
-rw-r--r--test/test_no_verify.c17
-rw-r--r--test/test_plugin.c17
-rw-r--r--test/test_plugin.lv2/manifest.ttl.in (renamed from test/test.lv2/manifest.ttl.in)4
-rw-r--r--test/test_plugin.lv2/meson.build24
-rw-r--r--test/test_plugin.lv2/test_plugin.c (renamed from test/test.lv2/test.c)72
-rw-r--r--test/test_plugin.lv2/test_plugin.ttl.in (renamed from test/test.lv2/test.ttl.in)0
-rw-r--r--test/test_port.c17
-rw-r--r--test/test_preset.c17
-rw-r--r--test/test_project.c17
-rw-r--r--test/test_project_no_author.c17
-rw-r--r--test/test_prototype.c17
-rw-r--r--test/test_reload_bundle.c17
-rw-r--r--test/test_replace_version.c17
-rw-r--r--test/test_state.c234
-rw-r--r--test/test_string.c43
-rw-r--r--test/test_ui.c17
-rw-r--r--test/test_util.c65
-rw-r--r--test/test_value.c17
-rw-r--r--test/test_verify.c17
-rw-r--r--test/test_world.c17
-rw-r--r--tools/.clang-tidy16
-rw-r--r--tools/bench.h38
-rw-r--r--tools/lilv.bash_completion (renamed from utils/lilv.bash_completion)14
-rw-r--r--tools/lv2apply.c (renamed from utils/lv2apply.c)31
-rw-r--r--tools/lv2bench.c (renamed from utils/lv2bench.c)27
-rw-r--r--tools/lv2info.c (renamed from utils/lv2info.c)29
-rw-r--r--tools/lv2ls.c (renamed from utils/lv2ls.c)25
-rw-r--r--tools/meson.build91
-rw-r--r--tools/uri_table.h (renamed from utils/uri_table.h)17
-rw-r--r--utils/bench.h53
-rw-r--r--utils/lilv-bench.c34
-rwxr-xr-xwaf27
m---------waflib0
-rw-r--r--wscript633
153 files changed, 2979 insertions, 5856 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 9accc2c..aa54c19 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,32 +1,24 @@
+# Copyright 2020-2023 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
Checks: >
*,
- -*-magic-numbers,
- -*-uppercase-literal-suffix,
- -android-cloexec-fopen,
- -bugprone-branch-clone,
+ -*-vararg,
+ -altera-*,
+ -bugprone-assignment-in-if-condition,
+ -bugprone-easily-swappable-parameters,
-bugprone-macro-parentheses,
- -bugprone-narrowing-conversions,
- -bugprone-not-null-terminated-result,
- -bugprone-reserved-identifier,
- -bugprone-suspicious-string-compare,
- -cert-dcl37-c,
- -cert-dcl51-cpp,
- -cert-err34-c,
- -clang-analyzer-alpha.*,
- -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
- -cppcoreguidelines-avoid-non-const-global-variables,
- -cppcoreguidelines-macro-usage,
- -cppcoreguidelines-narrowing-conversions,
- -google-readability-todo,
- -hicpp-multiway-paths-covered,
- -hicpp-signed-bitwise,
- -llvm-header-guard,
+ -bugprone-suspicious-realloc-usage,
+ -clang-diagnostic-unused-function,
+ -clang-diagnostic-unused-macros,
-llvmlibc-*,
- -misc-no-recursion,
- -misc-non-private-member-variables-in-classes,
- -misc-unused-parameters,
- -modernize-use-trailing-return-type,
- -readability-implicit-bool-conversion,
-WarningsAsErrors: '*'
-HeaderFilterRegex: '.*'
+ -modernize-macro-to-enum,
+ -readability-identifier-length,
+CheckOptions:
+ - key: hicpp-uppercase-literal-suffix.NewSuffixes
+ value: 'L;U;UL;ULL'
+ - key: readability-uppercase-literal-suffix.NewSuffixes
+ value: 'L;U;UL;ULL'
FormatStyle: file
+HeaderFilterRegex: '.*/lilv/[^/]+.h'
+WarningsAsErrors: '*'
diff --git a/.gitignore b/.gitignore
index 204c242..7bc1d37 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,9 @@
-build/**
-.waf-*
-.lock-waf*
+# Copyright 2018-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+.meson-subproject-wrap-hash.txt
__pycache__
+build/**
+subprojects/packagecache/
+subprojects/sphinxygen-1.0.4/
+subprojects/sphinxygen/
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index cc8b569..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "waflib"]
- path = waflib
- url = ../../drobilla/autowaf.git
diff --git a/.reuse/dep5 b/.reuse/dep5
new file mode 100644
index 0000000..f9693c0
--- /dev/null
+++ b/.reuse/dep5
@@ -0,0 +1,18 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: lilv
+Upstream-Contact: David Robillard <d@drobilla.net>
+Source: https://gitlab.com/drobilla/lilv
+
+Files: AUTHORS NEWS lilv.ttl
+Copyright: 2006-2022 David Robillard <d@drobilla.net>
+Comment: Contributed to the Commons as a representation of simple facts
+License: 0BSD OR ISC
+
+Files: .clant.json
+Copyright: 2020 David Robillard <d@drobilla.net>
+Comment: Contributed to the Commons as a tool configuration
+License: 0BSD OR ISC
+
+Files: bindings/test/*.ttl.in test/*/*.ttl.in test/lv2/core.lv2/*.ttl
+Copyright: 2015-2022 David Robillard <d@drobilla.net>
+License: ISC
diff --git a/COPYING b/COPYING
index 9748bb9..977d7b6 100644
--- a/COPYING
+++ b/COPYING
@@ -1,13 +1,13 @@
-Copyright 2011-2021 David Robillard <d@drobilla.net>
+Copyright 2011-2022 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. \ No newline at end of file
+THE 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.
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 9b54f51..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,66 +0,0 @@
-Installation Instructions
-=========================
-
-Basic Installation
-------------------
-
-Building this software requires only Python. To install with default options:
-
- ./waf configure
- ./waf
- ./waf install # or 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
-
-Library Versioning
-------------------
-
-This library uses semantic versioning <http://semver.org/>.
-
-Several major versions can be installed in parallel. The shared library name,
-include directory, and pkg-config file are suffixed with the major version
-number. For example, a library named "foo" at version 1.x.y might install:
-
- /usr/include/foo-1/foo/foo.h
- /usr/lib/foo-1.so.1.x.y
- /usr/lib/pkgconfig/foo-1.pc
-
-Dependencies can check for the package "foo-1" with pkg-config.
-
-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
-
-Packages should allow parallel installation of several major versions. For
-example, the above would be packaged as "foo-1". \ No newline at end of file
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 0000000..2adecf0
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,77 @@
+<!-- Copyright 2022 David Robillard <d@drobilla.net> -->
+<!-- SPDX-License-Identifier: ISC -->
+
+Installation Instructions
+=========================
+
+Prerequisites
+-------------
+
+To build from source, you will need:
+
+ * A relatively modern C compiler (GCC, Clang, and MSVC are known to work).
+
+ * [Meson](http://mesonbuild.com/), which depends on
+ [Python](http://python.org/).
+
+This is a brief overview of building this project with meson. See the meson
+documentation for more detailed information.
+
+Configuration
+-------------
+
+The build is configured with the `setup` command, which creates a new build
+directory with the given name:
+
+ meson setup build
+
+Some environment variables are read during `setup` and stored with the
+configuration:
+
+ * `CC`: Path to C compiler.
+ * `CFLAGS`: C compiler options.
+ * `LDFLAGS`: Linker options.
+
+However, it is better to use meson options for configuration. All options can
+be inspected with the `configure` command from within the build directory:
+
+ cd build
+ meson configure
+
+Options can be set by passing C-style "define" options to `configure`:
+
+ meson configure -Dc_args="-march=native" -Dprefix="/opt/mypackage/"
+
+Note that some options, such as `strict` and `werror` are for
+developer/maintainer use only. Please don't file issues about anything that
+happens when they are enabled.
+
+Building
+--------
+
+From within a configured build directory, everything can be built with the
+`compile` command:
+
+ meson compile
+
+Similarly, tests can be run with the `test` command:
+
+ meson test
+
+Meson can also generate a project for several popular IDEs, see the `backend`
+option for details.
+
+Installation
+------------
+
+A compiled project can be installed with the `install` command:
+
+ meson install
+
+You may need to acquire root permissions to install to a system-wide prefix.
+For packaging, the installation may be staged to a directory using the
+`DESTDIR` environment variable or the `--destdir` option:
+
+ DESTDIR=/tmp/mypackage/ meson install
+
+ meson install --destdir=/tmp/mypackage/
diff --git a/LICENSES/0BSD.txt b/LICENSES/0BSD.txt
new file mode 100644
index 0000000..b3e8cfd
--- /dev/null
+++ b/LICENSES/0BSD.txt
@@ -0,0 +1,12 @@
+Copyright 2011-2022 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.
+
+THE 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.
diff --git a/LICENSES/ISC.txt b/LICENSES/ISC.txt
new file mode 120000
index 0000000..012065c
--- /dev/null
+++ b/LICENSES/ISC.txt
@@ -0,0 +1 @@
+../COPYING \ No newline at end of file
diff --git a/NEWS b/NEWS
index c911422..92b4030 100644
--- a/NEWS
+++ b/NEWS
@@ -1,11 +1,66 @@
-lilv (0.24.13) unstable;
+lilv (0.24.25) unstable; urgency=medium
+ * Fix C++ test build on MacOS
+ * Fix library current_version on MacOS
+ * Fix test suite when TMPDIR has no trailing slash
+
+ -- David Robillard <d@drobilla.net> Sat, 16 Mar 2024 13:51:02 +0000
+
+lilv (0.24.24) stable; urgency=medium
+
+ * Avoid overriding state features passed by the host
+ * Fix null dereference when trying to load state from a missing file
+ * Fix potential null dereferences and conversion warnings
+
+ -- David Robillard <d@drobilla.net> Tue, 23 Jan 2024 19:39:29 +0000
+
+lilv (0.24.22) stable; urgency=medium
+
+ * Allow LILV_API to be defined by the user
+ * Clean up code
+ * Clean up inconsistent tool command line interfaces
+ * Convert man pages to mdoc
+ * Fix crash when plugins pass NULL to the LV2_State_Retrieve_Function
+ * Fix dependencies in pkg-config file
+ * Fix potential crash when writing state files fails
+ * Order plugin classes by URI
+ * Override pkg-config dependency within meson
+ * Remove junk files from documentation install
+ * Replace duplicated dox_to_sphinx script with sphinxygen dependency
+ * Switch to external zix dependency
+
+ -- David Robillard <d@drobilla.net> Sun, 22 Oct 2023 20:14:02 +0000
+
+lilv (0.24.20) stable; urgency=medium
+
+ * Adopt REUSE machine-readable licensing standard
+ * Update project metadata
+
+ -- David Robillard <d@drobilla.net> Fri, 09 Sep 2022 17:28:30 +0000
+
+lilv (0.24.18) stable; urgency=medium
+
+ * Allow programs to be used from subproject
+ * Fix default LV2_PATH
+
+ -- David Robillard <d@drobilla.net> Fri, 12 Aug 2022 22:15:29 +0000
+
+lilv (0.24.16) stable; urgency=medium
+
+ * Fix fallback flock() detection on MacOS
+ * Switch to meson build system
+
+ -- David Robillard <d@drobilla.net> Tue, 19 Jul 2022 01:16:26 +0000
+
+lilv (0.24.14) stable; urgency=medium
+
+ * Fix build issues with newer toolchains
* Fix unused parameter warnings
* Update zix tree
- -- David Robillard <d@drobilla.net> Mon, 11 Jan 2021 11:20:41 +0000
+ -- David Robillard <d@drobilla.net> Fri, 27 May 2022 01:38:26 +0000
-lilv (0.24.12) stable;
+lilv (0.24.12) stable; urgency=medium
* Allow connecting ports to structures in Python
* Fix potential memory error when joining filesystem paths
@@ -16,7 +71,7 @@ lilv (0.24.12) stable;
-- David Robillard <d@drobilla.net> Thu, 07 Jan 2021 21:46:06 +0000
-lilv (0.24.10) stable;
+lilv (0.24.10) stable; urgency=medium
* Fix memory leaks in lv2bench
* Fix various minor warnings and other code quality issues
@@ -25,7 +80,7 @@ lilv (0.24.10) stable;
-- David Robillard <d@drobilla.net> Sun, 27 Sep 2020 12:17:02 +0000
-lilv (0.24.8) stable;
+lilv (0.24.8) stable; urgency=medium
* Allow passing strings for URIs in Python API when unambiguous
* Fix cases where incorrect translation is used
@@ -35,7 +90,7 @@ lilv (0.24.8) stable;
-- David Robillard <d@drobilla.net> Sun, 26 Apr 2020 15:55:26 +0000
-lilv (0.24.6) stable;
+lilv (0.24.6) stable; urgency=medium
* Add more strict error detection when storing plugin state properties
* Add option to override LV2_PATH in applications
@@ -49,7 +104,7 @@ lilv (0.24.6) stable;
-- David Robillard <d@drobilla.net> Sun, 10 Nov 2019 21:39:37 +0000
-lilv (0.24.4) stable;
+lilv (0.24.4) stable; urgency=medium
* Don't attempt to load remote or non-Turtle files
* Fix saving state when broken links are encountered
@@ -64,14 +119,14 @@ lilv (0.24.4) stable;
-- David Robillard <d@drobilla.net> Sun, 22 Jul 2018 18:42:00 +0000
-lilv (0.24.2) stable;
+lilv (0.24.2) stable; urgency=medium
* Fix comparison of restored states with paths
* Fix saving state to paths that contain URI delimiters (#, ?, etc)
-- David Robillard <d@drobilla.net> Wed, 04 Jan 2017 16:48:08 +0000
-lilv (0.24.0) stable;
+lilv (0.24.0) stable; urgency=medium
* Add LILV_URI_ATOM_PORT and LILV_URI_CV_PORT defines
* Add lilv_state_set_metadata() for adding state banks/comments/etc (based
@@ -94,7 +149,7 @@ lilv (0.24.0) stable;
-- David Robillard <d@drobilla.net> Tue, 20 Sep 2016 02:24:57 +0000
-lilv (0.22.0) stable;
+lilv (0.22.0) stable; urgency=medium
* Add lilv_file_uri_parse() for correct URI to path conversion
* Add lilv_free() for systems picky about such things
@@ -121,7 +176,7 @@ lilv (0.22.0) stable;
-- David Robillard <d@drobilla.net> Thu, 08 Oct 2015 19:39:29 +0000
-lilv (0.20.0) stable;
+lilv (0.20.0) stable; urgency=medium
* Add convenient lilv_new_file_uri for creating file URIs
* Add lilv_world_unload_bundle() and lilv_world_unload_resource()
@@ -142,7 +197,7 @@ lilv (0.20.0) stable;
-- David Robillard <d@drobilla.net> Fri, 08 Aug 2014 22:21:32 +0000
-lilv (0.18.0) stable;
+lilv (0.18.0) stable; urgency=medium
* Add lilv_port_get_node() for using world query functions with ports
* Add support for running plugins from Python by Kaspar Emanuel
@@ -159,7 +214,7 @@ lilv (0.18.0) stable;
-- David Robillard <d@drobilla.net> Sat, 04 Jan 2014 21:06:42 +0000
-lilv (0.16.0) stable;
+lilv (0.16.0) stable; urgency=medium
* Add lilv_nodes_merge()
* Add lilv_world_ask() for easily checking if a statement exists
@@ -181,7 +236,7 @@ lilv (0.16.0) stable;
-- David Robillard <d@drobilla.net> Mon, 18 Feb 2013 21:43:10 +0000
-lilv (0.14.4) stable;
+lilv (0.14.4) stable; urgency=medium
* Add lv2bench utility
* Add option to build utilities as static binaries
@@ -201,13 +256,13 @@ lilv (0.14.4) stable;
-- David Robillard <d@drobilla.net> Thu, 23 Aug 2012 05:38:29 +0000
-lilv (0.14.2) stable;
+lilv (0.14.2) stable; urgency=medium
* Fix dynmanifest support
-- David Robillard <d@drobilla.net> Thu, 19 Apr 2012 20:11:31 +0000
-lilv (0.14.0) stable;
+lilv (0.14.0) stable; urgency=medium
* 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
@@ -238,7 +293,7 @@ lilv (0.14.0) stable;
-- David Robillard <d@drobilla.net> Thu, 19 Apr 2012 00:06:28 +0000
-lilv (0.5.0) stable;
+lilv (0.5.0) stable; urgency=medium
* Add ability to build static library
* Add lv2core as a pkg-config dependency (for lv2.h header include)
@@ -249,7 +304,7 @@ lilv (0.5.0) stable;
-- David Robillard <d@drobilla.net> Thu, 29 Sep 2011 04:00:00 +0000
-lilv (0.4.4) stable;
+lilv (0.4.4) stable; urgency=medium
* Fix building python bindings
* Fix lilv_ui_is_supported when Lilv is built independently
@@ -259,14 +314,14 @@ lilv (0.4.4) stable;
-- David Robillard <d@drobilla.net> Sat, 11 Jun 2011 15:20:11 +0000
-lilv (0.4.2) stable;
+lilv (0.4.2) stable; urgency=medium
* Fix build system Python 3 compatibility
* Fix compilation issues on some systems
-- David Robillard <d@drobilla.net> Wed, 25 May 2011 23:00:00 +0000
-lilv (0.4.0) stable;
+lilv (0.4.0) stable; urgency=medium
* Initial version (forked from SLV2)
diff --git a/README.md b/README.md
index 807fc2b..6d3ff88 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
+<!-- Copyright 2006-2019 David Robillard <d@drobilla.net> -->
+<!-- SPDX-License-Identifier: ISC -->
+
Lilv
====
diff --git a/bindings/python/Makefile b/bindings/python/Makefile
index e63c124..32f199d 100644
--- a/bindings/python/Makefile
+++ b/bindings/python/Makefile
@@ -1,5 +1,7 @@
# Makefile for Sphinx documentation
#
+# Copyright 2016 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
# You can set these variables from the command line.
SPHINXOPTS =
diff --git a/bindings/python/conf.py b/bindings/python/conf.py
index 005e03a..52d514a 100644
--- a/bindings/python/conf.py
+++ b/bindings/python/conf.py
@@ -1,4 +1,8 @@
# -*- coding: utf-8 -*-
+
+# Copyright 2016-2024 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
#
# Lilv documentation build configuration file, created by
# sphinx-quickstart on Sun Sep 4 18:25:58 2016.
@@ -56,9 +60,9 @@ copyright = u'2016, David Robillard'
# built documents.
#
# The short X.Y version.
-version = '0.24.12'
+version = '0.24.25'
# The full version, including alpha/beta/rc tags.
-release = '0.24.12'
+release = '0.24.25'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/bindings/python/index.rst b/bindings/python/index.rst
index 4616054..b44fa08 100644
--- a/bindings/python/index.rst
+++ b/bindings/python/index.rst
@@ -1,3 +1,7 @@
+..
+ Copyright 2016 David Robillard <d@drobilla.net>
+ SPDX-License-Identifier: ISC
+
Lilv Python Documentation
=========================
diff --git a/bindings/python/lilv.py b/bindings/python/lilv.py
index 98da72f..69f6e7d 100644
--- a/bindings/python/lilv.py
+++ b/bindings/python/lilv.py
@@ -1,9 +1,12 @@
"""Lilv Python interface"""
+# Copyright 2016-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
__author__ = "David Robillard"
-__copyright__ = "Copyright 2016-2020 David Robillard"
+__copyright__ = "Copyright 2016-2024 David Robillard"
__license__ = "ISC"
-__version__ = "0.24.12"
+__version__ = "0.24.25"
__maintainer__ = "David Robillard"
__email__ = "d@drobilla.net"
__status__ = "Production"
diff --git a/bindings/python/lv2_apply.py b/bindings/python/lv2_apply.py
index 4c7d9b4..bb95682 100755
--- a/bindings/python/lv2_apply.py
+++ b/bindings/python/lv2_apply.py
@@ -1,6 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# Copyright 2011-2016 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
import math
import lilv
import sys
diff --git a/bindings/python/lv2_list.py b/bindings/python/lv2_list.py
index babe1b4..1bb233c 100755
--- a/bindings/python/lv2_list.py
+++ b/bindings/python/lv2_list.py
@@ -1,5 +1,8 @@
#!/usr/bin/env python
+# Copyright 2007-2011 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
import lilv
world = lilv.World()
diff --git a/bindings/python/lv2_list_presets.py b/bindings/python/lv2_list_presets.py
index 4e0c9b1..a6439d6 100755
--- a/bindings/python/lv2_list_presets.py
+++ b/bindings/python/lv2_list_presets.py
@@ -1,6 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# Copyright 2019-2020 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
import sys
import lilv
diff --git a/bindings/python/meson.build b/bindings/python/meson.build
new file mode 100644
index 0000000..1cffd71
--- /dev/null
+++ b/bindings/python/meson.build
@@ -0,0 +1,9 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+pymod = import('python')
+py = pymod.find_installation('python3', required: get_option('bindings_py'))
+
+if py.found()
+ py.install_sources(files('lilv.py'))
+endif
diff --git a/bindings/test/bindings_test_plugin.c b/bindings/test/bindings_test_plugin.c
index 2df64ea..18907d5 100644
--- a/bindings/test/bindings_test_plugin.c
+++ b/bindings/test/bindings_test_plugin.c
@@ -1,19 +1,6 @@
-/*
- Copyright 2006-2019 David Robillard <d@drobilla.net>
- Copyright 2006 Steve Harris <steve@plugin.org.uk>
-
- 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.
-*/
+// Copyright 2006-2019 David Robillard <d@drobilla.net>
+// Copyright 2006 Steve Harris <steve@plugin.org.uk>
+// SPDX-License-Identifier: ISC
/**
LV2 headers are based on the URI of the specification they come from, so a
@@ -197,10 +184,5 @@ LV2_SYMBOL_EXPORT
const LV2_Descriptor*
lv2_descriptor(uint32_t index)
{
- switch (index) {
- case 0:
- return &descriptor;
- default:
- return NULL;
- }
+ return index ? NULL : &descriptor;
}
diff --git a/bindings/test/python/test_api.py b/bindings/test/python/test_api.py
index 8d3a94a..d70dbe6 100644
--- a/bindings/test/python/test_api.py
+++ b/bindings/test/python/test_api.py
@@ -1,17 +1,6 @@
# Copyright 2016-2020 David Robillard <d@drobilla.net>
# Copyright 2013 Kaspar Emanuel <kaspar.emanuel@gmail.com>
-#
-# 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.
+# SPDX-License-Identifier: ISC
import lilv
import os
diff --git a/doc/c/Doxyfile b/doc/Doxyfile.in
index ce10524..2ca5694 100644
--- a/doc/c/Doxyfile
+++ b/doc/Doxyfile.in
@@ -1,3 +1,6 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
PROJECT_NAME = Lilv
PROJECT_BRIEF = "A library for simple use of LV2 plugins"
@@ -21,6 +24,8 @@ SHOW_FILES = NO
MACRO_EXPANSION = YES
PREDEFINED = LILV_API LILV_DEPRECATED
-INPUT = ../../include/lilv/lilv.h
+RECURSIVE = YES
+STRIP_FROM_PATH = @LILV_SRCDIR@
+INPUT = @LILV_SRCDIR@/include/lilv/lilv.h
-OUTPUT_DIRECTORY = .
+OUTPUT_DIRECTORY = @DOX_OUTPUT@
diff --git a/doc/api/meson.build b/doc/api/meson.build
new file mode 100644
index 0000000..a470564
--- /dev/null
+++ b/doc/api/meson.build
@@ -0,0 +1,9 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+api_lilv_rst = custom_target(
+ 'lilv.rst',
+ command: [sphinxygen, '-f', '@INPUT0@', '@OUTDIR@'],
+ input: doxygen_xml,
+ output: 'lilv.rst',
+)
diff --git a/doc/c/index.rst b/doc/c/index.rst
deleted file mode 100644
index 6968981..0000000
--- a/doc/c/index.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-####
-Lilv
-####
-
-.. include:: summary.rst
-
-.. toctree::
-
- overview
- api/lilv
diff --git a/doc/c/wscript b/doc/c/wscript
deleted file mode 100644
index d515ddf..0000000
--- a/doc/c/wscript
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-
-def build(bld):
- dox_to_sphinx = bld.path.find_node("../../scripts/dox_to_sphinx.py")
- index_xml = bld.path.get_bld().make_node("xml/index.xml")
-
- files = [
- ("../summary.rst", "sphinx/summary.rst"),
- ("index.rst", "sphinx/index.rst"),
- ("overview.rst", "sphinx/overview.rst"),
- ("plugins.rst", "sphinx/plugins.rst"),
- ("uis.rst", "sphinx/uis.rst"),
- ("world.rst", "sphinx/world.rst"),
- ]
-
- # Run Doxygen to generate XML documentation
- bld(features="doxygen", doxyfile="Doxyfile")
-
- # Substitute variables to make Sphinx configuration file
- bld(features="subst",
- source="../conf.py.in",
- target="sphinx/conf.py",
- LILV_VERSION=bld.env.LILV_VERSION)
-
- # Copy static documentation files to Sphinx build directory
- for f in files:
- bld(features="subst", is_copy=True, source=f[0], target=f[1])
-
- # Generate Sphinx markup from Doxygen XML
- bld.add_group()
- bld(rule="${PYTHON} " + dox_to_sphinx.abspath() + " -f ${SRC} ${TGT}",
- source=index_xml,
- target="sphinx/api/")
-
- doc_dir = bld.env.DOCDIR + "/lilv-%s/" % bld.env.LILV_MAJOR_VERSION
-
- # Run Sphinx to generate HTML documentation
- for builder in ["html", "singlehtml"]:
- bld(features="sphinx",
- sphinx_source=bld.path.get_bld().make_node("sphinx"),
- sphinx_output_format=builder,
- sphinx_options=["-E", "-q", "-t", builder],
- install_path=doc_dir + "c/%s/" % builder)
diff --git a/doc/conf.py.in b/doc/conf.py.in
index e62eaff..444b70a 100644
--- a/doc/conf.py.in
+++ b/doc/conf.py.in
@@ -1,9 +1,14 @@
+# Copyright 2020-2021 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
# Project information
-project = "Lilv"
-copyright = "2020, David Robillard"
+project = "@LILV_TITLE@"
+copyright = "2020-2023, David Robillard"
author = "David Robillard"
release = "@LILV_VERSION@"
+version = "@LILV_VERSION@"
+desc = "A library for loading LV2 plugins"
# General configuration
@@ -12,6 +17,13 @@ language = "en"
nitpicky = True
pygments_style = "friendly"
+try:
+ import sphinx_lv2_theme
+
+ have_lv2_theme = True
+except ModuleNotFoundError:
+ have_lv2_theme = False
+
# Ignore everything opaque or external for nitpicky mode
_opaque = [
"FILE",
@@ -38,42 +50,78 @@ nitpick_ignore = list(map(lambda x: ("c:identifier", x), _opaque))
# HTML output
-html_theme = "sphinx_lv2_theme"
html_copy_source = False
-html_short_title = "Lilv"
-
-if tags.has('singlehtml'):
- html_sidebars = {
- "**": [
- "globaltoc.html",
- ]
- }
-
- html_theme_options = {
- "body_max_width": "65em",
- "body_min_width": "50em",
- "description": "A library for loading LV2 plugins",
- "show_footer_version": True,
- "show_logo_version": False,
- "logo_name": True,
- "nosidebar": False,
- "page_width": "80em",
- "sidebar_width": "11em",
- "globaltoc_maxdepth": 3,
- "globaltoc_collapse": False,
- }
+html_secnumber_suffix = " "
+html_short_title = "@LILV_TITLE@"
+
+html_theme_options = {
+ "description": desc,
+ "logo_name": True,
+ "logo_width": "8em",
+}
+
+if tags.has("singlehtml"):
+ html_sidebars = {"**": ["globaltoc.html"]}
+ html_theme_options.update(
+ {
+ "globaltoc_collapse": False,
+ "globaltoc_maxdepth": 3,
+ "nosidebar": False,
+ "page_width": "80em",
+ }
+ )
+else:
+ html_theme_options.update(
+ {
+ "globaltoc_collapse": True,
+ "globaltoc_maxdepth": 1,
+ "nosidebar": True,
+ "page_width": "60em",
+ }
+ )
+
+if have_lv2_theme:
+ html_theme = "sphinx_lv2_theme"
+
+ html_theme_options.update(
+ {
+ "show_footer_version": True,
+ "show_logo_version": True,
+ }
+ )
+
+ if tags.has("singlehtml"):
+ html_theme_options.update(
+ {
+ "body_max_width": "64em",
+ "body_min_width": "64em",
+ "nosidebar": False,
+ "sidebar_width": "12em",
+ }
+ )
+
+ else:
+ html_theme_options.update(
+ {
+ "body_max_width": "60em",
+ "body_min_width": "40em",
+ }
+ )
else:
- html_theme_options = {
- "body_max_width": "60em",
- "body_min_width": "40em",
- "description": "A library for loading LV2 plugins",
- "show_footer_version": True,
- "show_logo_version": False,
- "logo_name": True,
- "nosidebar": True,
- "page_width": "60em",
- "sidebar_width": "14em",
- "globaltoc_maxdepth": 1,
- "globaltoc_collapse": True,
- }
+ html_theme = "alabaster"
+
+ if tags.has("singlehtml"):
+ html_theme_options = {
+ "body_max_width": "58em",
+ "body_min_width": "40em",
+ "sidebar_width": "16em",
+ }
+
+ else:
+ html_theme_options = {
+ "body_max_width": "60em",
+ "body_min_width": "40em",
+ "nosidebar": True,
+ "show_relbars": True,
+ }
diff --git a/doc/html/meson.build b/doc/html/meson.build
new file mode 100644
index 0000000..59da474
--- /dev/null
+++ b/doc/html/meson.build
@@ -0,0 +1,39 @@
+# Copyright 2021-2023 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+html_dir = docdir / versioned_name / 'html'
+
+# TODO: Add install_tag: 'doc' after requiring meson 0.60.0
+
+custom_target(
+ 'html',
+ build_by_default: true,
+ command: sphinx_build_command + [
+ '-b', 'html',
+ '-t', 'html',
+ sphinx_in_dir,
+ '@OUTDIR@',
+ ],
+ input: [api_lilv_rst, conf_py, sphinx_input],
+ install: true,
+ install_dir: html_dir,
+ output: [
+ 'index.html',
+
+ '_static',
+ 'api',
+ 'genindex.html',
+ 'overview.html',
+ 'plugins.html',
+ 'uis.html',
+ 'world.html',
+ ],
+)
+
+if not meson.is_subproject()
+ summary(
+ 'HTML',
+ get_option('prefix') / html_dir,
+ section: 'Directories',
+ )
+endif
diff --git a/doc/summary.rst b/doc/index.rst
index 313ffa8..46a9026 100644
--- a/doc/summary.rst
+++ b/doc/index.rst
@@ -1,3 +1,11 @@
+..
+ Copyright 2020-2022 David Robillard <d@drobilla.net>
+ SPDX-License-Identifier: ISC
+
+####
+Lilv
+####
+
Lilv is a library for working with LV2_ plugins.
It provides several types and functions that can be used to discover plugins,
investigate their data, load and run them, and save and restore their state.
@@ -6,4 +14,10 @@ Lilv is the standard implementation used by nearly all LV2 hosts.
It implements the details of the LV2 specification on POSIX, MacOS, and Windows,
and provides a simpler portable API for applications.
+.. toctree::
+
+ overview
+ api/lilv
+
.. _LV2: http://lv2plug.in/
+
diff --git a/doc/lv2apply.1 b/doc/lv2apply.1
index 4877aba..3bb0218 100644
--- a/doc/lv2apply.1
+++ b/doc/lv2apply.1
@@ -1,34 +1,66 @@
-.TH LV2APPLY 1 "05 Sep 2016"
-
-.SH NAME
-.B lv2apply \- apply an LV2 plugin to an audio file
-.SH SYNOPSIS
-.B lv2apply [OPTION]... PLUGIN_URI
-
-.SH OPTIONS
-.TP
-\fB\-i IN_FILE\fR
-Input file
-
-.TP
-\fB\-o OUT_FILE\fR
-Output file
-
-.TP
-\fB\-c SYM VAL\fR
-Set control port SYM to VAL
-
-.TP
-\fB\-\-help\fR
-Display help and exit
-
-.TP
-\fB\-\-version\fR
-Display version information and exit
-
-.SH "SEE ALSO"
-.BR lv2ls(1)
-.BR lv2info(1)
-
-.SH AUTHOR
-lv2apply was written by David Robillard <d@drobilla.net>
+.\" # Copyright 2010-2024 David Robillard <d@drobilla.net>
+.\" # SPDX-License-Identifier: ISC
+.Dd Nov 29, 2022
+.Dt LV2APPLY 1
+.Os Lilv 0.24.25
+.Sh NAME
+.Nm lv2apply
+.Nd apply an LV2 plugin to an audio file
+.Sh SYNOPSIS
+.Nm lv2apply
+.Op Fl Vh
+.Op Fl c Ar symbol value
+.Op Fl i Ar in_file
+.Op Fl o Ar out_file
+.Op Fl Fl help
+.Op Fl Fl version
+.Ar plugin_uri
+.Sh DESCRIPTION
+.Nm
+runs an LV2 plugin on an audio file and writes the processed output to another.
+.Pp
+The options are as follows:
+.Pp
+.Bl -tag -compact -width 3n
+.It Fl V , Fl Fl version
+Display version information and exit.
+.Pp
+.It Fl c Ar symbol value
+Set control port
+.Ar symbol
+to
+.Ar value.
+.Pp
+.It Fl h , Fl Fl help
+Print the command line options.
+.Pp
+.It Fl i Ar in_file
+Input file path.
+.Pp
+.It Fl o Ar out_file
+Output file path.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width LV2_PATH -compact
+.It Ev LV2_PATH
+List of directories to search for LV2 plugin bundles,
+in the style of
+.Ev PATH .
+.El
+.Sh EXIT STATUS
+.Nm
+exits with a status of 0, or non-zero if an error occurred.
+.Sh SEE ALSO
+.Bl -item -compact
+.It
+.Xr lv2bench 1
+.It
+.Xr lv2info 1
+.It
+.Xr lv2ls 1
+.El
+.Sh AUTHORS
+.Nm
+is a part of lilv, by
+.An David Robillard
+.Mt d@drobilla.net .
diff --git a/doc/lv2bench.1 b/doc/lv2bench.1
new file mode 100644
index 0000000..e70c47d
--- /dev/null
+++ b/doc/lv2bench.1
@@ -0,0 +1,55 @@
+.\" # Copyright 2024 David Robillard <d@drobilla.net>
+.\" # SPDX-License-Identifier: ISC
+.Dd Nov 29, 2022
+.Dt LV2BENCH 1
+.Os Lilv 0.24.25
+.Sh NAME
+.Nm lv2bench
+.Nd benchmark all installed and supported LV2 plugins
+.Sh SYNOPSIS
+.Nm lv2bench
+.Op Fl fhV
+.Op Fl b Ar block_size
+.Op Fl n Ar frames
+.Op Fl Fl full
+.Op Fl Fl help
+.Op Fl Fl version
+.Sh DESCRIPTION
+.Nm
+is a simple utility for running basic benchmarks of installed LV2 plugins.
+.Pp
+The options are as follows:
+.Pp
+.Bl -tag -compact -width 3n
+.It Fl V , Fl Fl version
+Display version information and exit.
+.Pp
+.It Fl b Ar block_size
+Block size, in audio frames.
+.Pp
+.It Fl f , Fl Fl full
+Emit full plottable output with values for every block.
+.Pp
+.It Fl h , Fl Fl help
+Print the command line options.
+.Pp
+.It Fl n Ar frames
+Total number of audio frames to process.
+.El
+.Sh EXIT STATUS
+.Nm
+exits with a status of 0, or non-zero if an error occurred.
+.Sh SEE ALSO
+.Bl -item -compact
+.It
+.Xr lv2apply 1
+.It
+.Xr lv2info 1
+.It
+.Xr lv2ls 1
+.El
+.Sh AUTHORS
+.Nm
+is a part of lilv, by
+.An David Robillard
+.Mt d@drobilla.net .
diff --git a/doc/lv2info.1 b/doc/lv2info.1
index 32a3bec..43cde63 100644
--- a/doc/lv2info.1
+++ b/doc/lv2info.1
@@ -1,33 +1,65 @@
-.TH LV2INFO 1 "05 Sep 2016"
-
-.SH NAME
-.B lv2info \- print information about an installed LV2 plugin
-.SH SYNOPSIS
-.B lv2info PLUGIN_URI
-
-.SH OPTIONS
-.TP
-\fB\-p FILE\fR
-Write Turtle description of plugin to FILE
-
-.TP
-\fB\-m FILE\fR
-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>
+.\" # Copyright 2009-2024 David Robillard <d@drobilla.net>
+.\" # SPDX-License-Identifier: ISC
+.Dd Nov 29, 2022
+.Dt LV2INFO 1
+.Os Lilv 0.24.25
+.Sh NAME
+.Nm lv2info
+.Nd print information about an installed LV2 plugin
+.Sh SYNOPSIS
+.Nm lv2info
+.Op Fl hV
+.Op Fl m Ar file
+.Op Fl p Ar file
+.Ar plugin_uri
+.Sh DESCRIPTION
+.Nm
+prints a human-readable summary of information about an LV2 plugin.
+.Pp
+The plugin must be installed;
+.Nm
+will search for one with the given
+.Ar plugin_uri
+in the LV2 path.
+.Pp
+The options are as follows:
+.Pp
+.Bl -tag -compact -width 3n
+.It Fl V , Fl Fl version
+Display version information and exit.
+.Pp
+.It Fl h , Fl Fl help
+Print the command line options.
+.Pp
+.It Fl m Ar file
+Add record of plugin to Turtle manifest
+.Ar file .
+.Pp
+.It Fl p Ar file
+Write description of plugin to Turtle
+.Ar file .
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width LV2_PATH -compact
+.It Ev LV2_PATH
+List of directories to search for LV2 plugin bundles,
+in the style of
+.Ev PATH .
+.El
+.Sh EXIT STATUS
+.Nm
+exits with a status of 0, or non-zero if an error occurred.
+.Sh SEE ALSO
+.Bl -item -compact
+.It
+.Xr lv2apply 1
+.It
+.Xr lv2bench 1
+.It
+.Xr lv2ls 1
+.El
+.Sh AUTHORS
+.Nm
+is a part of lilv, by
+.An David Robillard
+.Mt d@drobilla.net .
diff --git a/doc/lv2ls.1 b/doc/lv2ls.1
index 320b71c..3b96370 100644
--- a/doc/lv2ls.1
+++ b/doc/lv2ls.1
@@ -1,30 +1,59 @@
-.TH LV2LS 1 "26 Aug 2016"
-
-.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>
+.\" # Copyright 2010-2024 David Robillard <d@drobilla.net>
+.\" # SPDX-License-Identifier: ISC
+.Dd Nov 29, 2022
+.Dt LV2LS 1
+.Os Lilv 0.24.25
+.Sh NAME
+.Nm lv2ls
+.Nd list all installed LV2 plugins
+.Sh SYNOPSIS
+.Nm lv2ls
+.Op Fl Vhn
+.Op Fl Fl help
+.Op Fl Fl names
+.Op Fl Fl version
+.Sh DESCRIPTION
+.Nm
+prints the URI of every installed LV2 plugin to stdout.
+.Pp
+Plugins are discovered with the same mechanism used by most hosts.
+The default path can be overridden by setting the
+.Ev LV2_PATH
+environment variable.
+.Pp
+The options are as follows:
+.Pp
+.Bl -tag -compact -width 3n
+.It Fl V , Fl Fl version
+Display version information and exit.
+.Pp
+.It Fl h , Fl Fl help
+Print the command line options.
+.Pp
+.It Fl n , Fl Fl names
+Show names instead of URIs.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width LV2_PATH -compact
+.It Ev LV2_PATH
+List of directories to search for LV2 plugin bundles,
+in the style of
+.Ev PATH .
+.El
+.Sh EXIT STATUS
+.Nm
+exits with a status of 0, or non-zero if an error occurred.
+.Sh SEE ALSO
+.Bl -item -compact
+.It
+.Xr lv2apply 1
+.It
+.Xr lv2bench 1
+.It
+.Xr lv2info 1
+.El
+.Sh AUTHORS
+.Nm
+is a part of lilv, by
+.An David Robillard
+.Mt d@drobilla.net .
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000..32a885b
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,71 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+docdir = get_option('datadir') / 'doc'
+
+# Find required programs
+doxygen = find_program('doxygen', required: get_option('docs'))
+sphinx_build = find_program('sphinx-build', required: get_option('docs'))
+
+# Find sphinxygen or fall back to subproject
+sphinxygen = disabler()
+if doxygen.found() and sphinx_build.found()
+ sphinxygen = find_program('sphinxygen', required: false)
+ if not sphinxygen.found()
+ subproject('sphinxygen')
+ sphinxygen = find_program('sphinxygen', required: get_option('docs'))
+ endif
+endif
+
+# Build documentation if all required tools are found
+build_docs = doxygen.found() and sphinxygen.found() and sphinx_build.found()
+if build_docs
+ # Configure conf.py for Sphinx
+ conf_config = configuration_data()
+ conf_config.set('LILV_SRCDIR', lilv_src_root)
+ conf_config.set('LILV_TITLE', get_option('title'))
+ conf_config.set('LILV_VERSION', meson.project_version())
+ conf_py = configure_file(
+ configuration: conf_config,
+ input: files('conf.py.in'),
+ output: 'conf.py',
+ )
+
+ # Copy hand-written documentation files
+ rst_sources = files(
+ 'index.rst',
+ 'overview.rst',
+ 'plugins.rst',
+ 'uis.rst',
+ 'world.rst',
+ )
+ sphinx_input = []
+ foreach f : rst_sources
+ sphinx_input += [
+ configure_file(copy: true, input: f, output: '@PLAINNAME@'),
+ ]
+ endforeach
+
+ # Generate reference documentation input with Doxygen and Sphinxygen
+ subdir('xml')
+ subdir('api')
+
+ # Build strict Sphinx flags, with termination on warnings if werror=true
+ sphinx_in_dir = meson.current_build_dir()
+ sphinx_flags = ['-E', '-a', '-q']
+ if get_option('werror')
+ sphinx_flags += ['-W']
+ endif
+
+ # Run Sphinx to generate final documentation for each format
+ sphinx_build_command = [sphinx_build] + sphinx_flags
+ foreach format : ['html', 'singlehtml']
+ if not get_option(format).disabled()
+ subdir(format)
+ endif
+ endforeach
+endif
+
+if not meson.is_subproject()
+ summary('Documentation', build_docs, bool_yn: true, section: 'Components')
+endif
diff --git a/doc/c/overview.rst b/doc/overview.rst
index 6abc123..17ebec9 100644
--- a/doc/c/overview.rst
+++ b/doc/overview.rst
@@ -1,3 +1,7 @@
+..
+ Copyright 2020-2022 David Robillard <d@drobilla.net>
+ SPDX-License-Identifier: ISC
+
.. default-domain:: c
.. highlight:: c
diff --git a/doc/c/plugins.rst b/doc/plugins.rst
index c86431e..c7ad547 100644
--- a/doc/c/plugins.rst
+++ b/doc/plugins.rst
@@ -1,3 +1,7 @@
+..
+ Copyright 2020-2022 David Robillard <d@drobilla.net>
+ SPDX-License-Identifier: ISC
+
.. default-domain:: c
.. highlight:: c
diff --git a/doc/singlehtml/meson.build b/doc/singlehtml/meson.build
new file mode 100644
index 0000000..ed4bb71
--- /dev/null
+++ b/doc/singlehtml/meson.build
@@ -0,0 +1,33 @@
+# Copyright 2021-2023 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+singlehtml_dir = docdir / versioned_name / 'singlehtml'
+
+# TODO: Add install_tag: 'doc' after requiring meson 0.60.0
+
+custom_target(
+ 'singlehtml',
+ build_by_default: true,
+ command: sphinx_build_command + [
+ '-b', 'singlehtml',
+ '-t', 'singlehtml',
+ sphinx_in_dir,
+ '@OUTDIR@',
+ ],
+ input: [api_lilv_rst, conf_py, sphinx_input],
+ install: true,
+ install_dir: singlehtml_dir,
+ output: [
+ 'index.html',
+
+ '_static',
+ ],
+)
+
+if not meson.is_subproject()
+ summary(
+ 'Single HTML',
+ get_option('prefix') / singlehtml_dir,
+ section: 'Directories',
+ )
+endif
diff --git a/doc/c/uis.rst b/doc/uis.rst
index 5abaa2c..1169060 100644
--- a/doc/c/uis.rst
+++ b/doc/uis.rst
@@ -1,3 +1,7 @@
+..
+ Copyright 2020-2022 David Robillard <d@drobilla.net>
+ SPDX-License-Identifier: ISC
+
.. default-domain:: c
.. highlight:: c
diff --git a/doc/c/world.rst b/doc/world.rst
index 4128f77..8b71165 100644
--- a/doc/c/world.rst
+++ b/doc/world.rst
@@ -1,3 +1,7 @@
+..
+ Copyright 2020-2022 David Robillard <d@drobilla.net>
+ SPDX-License-Identifier: ISC
+
.. default-domain:: c
.. highlight:: c
diff --git a/doc/xml/meson.build b/doc/xml/meson.build
new file mode 100644
index 0000000..eb66325
--- /dev/null
+++ b/doc/xml/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+doxygen = find_program('doxygen')
+
+config = configuration_data()
+config.set('LILV_SRCDIR', lilv_src_root)
+config.set('DOX_OUTPUT', meson.current_build_dir() / '..')
+
+doxyfile = configure_file(
+ configuration: config,
+ input: files('../Doxyfile.in'),
+ output: 'Doxyfile',
+)
+
+doxygen_xml = custom_target(
+ 'index.xml',
+ command: [doxygen, '@INPUT0@'],
+ input: [doxyfile] + c_headers,
+ output: [
+ 'index.xml',
+
+ 'group__lilv.xml',
+ 'group__lilv__class.xml',
+ 'group__lilv__collections.xml',
+ 'group__lilv__instance.xml',
+ 'group__lilv__node.xml',
+ 'group__lilv__plugin.xml',
+ 'group__lilv__port.xml',
+ 'group__lilv__scalepoint.xml',
+ 'group__lilv__state.xml',
+ 'group__lilv__ui.xml',
+ 'group__lilv__world.xml',
+ 'lilv_8h.xml',
+ ],
+)
diff --git a/include/lilv/lilv.h b/include/lilv/lilv.h
index 5fd7a9f..9f52925 100644
--- a/include/lilv/lilv.h
+++ b/include/lilv/lilv.h
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
/// @file lilv.h API for Lilv, a lightweight LV2 host library.
@@ -22,19 +9,22 @@
#include "lv2/core/lv2.h"
#include "lv2/urid/urid.h"
-#include <stdarg.h>
+#include <stdarg.h> // IWYU pragma: keep
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
-#if defined(_WIN32) && !defined(LILV_STATIC) && defined(LILV_INTERNAL)
-# define LILV_API __declspec(dllexport)
-#elif defined(_WIN32) && !defined(LILV_STATIC)
-# define LILV_API __declspec(dllimport)
-#elif defined(__GNUC__)
-# define LILV_API __attribute__((visibility("default")))
-#else
-# define LILV_API
+// LILV_API must be used to decorate things in the public API
+#ifndef LILV_API
+# if defined(_WIN32) && !defined(LILV_STATIC) && defined(LILV_INTERNAL)
+# define LILV_API __declspec(dllexport)
+# elif defined(_WIN32) && !defined(LILV_STATIC)
+# define LILV_API __declspec(dllimport)
+# elif defined(__GNUC__)
+# define LILV_API __attribute__((visibility("default")))
+# else
+# define LILV_API
+# endif
#endif
#if defined(__GNUC__) && \
@@ -396,6 +386,7 @@ lilv_node_as_bool(const LilvNode* value);
@endcode
*/
#define LILV_FOREACH(colltype, iter, collection) \
+ /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
for (LilvIter* iter = lilv_##colltype##_begin(collection); \
!lilv_##colltype##_is_end(collection, iter); \
(iter) = lilv_##colltype##_next(collection, iter))
@@ -1875,6 +1866,9 @@ struct LilvInstanceImpl {
`features` is a NULL-terminated array of features the host supports.
NULL may be passed if the host supports no additional features.
+ This function is in the "discovery" threading class: it isn't real-time
+ safe, and may not be called concurrently with itself for the same plugin.
+
@return NULL if instantiation failed.
*/
LILV_API
@@ -1886,8 +1880,12 @@ lilv_plugin_instantiate(const LilvPlugin* plugin,
/**
Free a plugin instance.
- It is safe to call this function on NULL.
- `instance` is invalid after this call.
+ It is safe to call this function on NULL. The `instance` is invalid after
+ this call.
+
+ This function is in the "discovery" threading class: it isn't real-time
+ safe, and may not be called concurrently with any other function for the
+ same instance, or with lilv_plugin_instantiate() for the same plugin.
*/
LILV_API
void
@@ -1898,7 +1896,8 @@ lilv_instance_free(LilvInstance* instance);
/**
Get the URI of the plugin which `instance` is an instance of.
- Returned string is shared and must not be modified or deleted.
+ This function is a simple accessor and may be called at any time. The
+ returned string is shared and must not be modified or deleted.
*/
static inline const char*
lilv_instance_get_uri(const LilvInstance* instance)
@@ -1911,6 +1910,10 @@ lilv_instance_get_uri(const LilvInstance* instance)
This may be called regardless of whether the plugin is activated,
activation and deactivation does not destroy port connections.
+
+ This function is in the "audio" threading class: it's real-time safe if the
+ plugin is <http://lv2plug.in/ns/lv2core#hardRTCapable>, but may not be
+ called concurrently with any other function for the same instance.
*/
static inline void
lilv_instance_connect_port(LilvInstance* instance,
@@ -1927,6 +1930,10 @@ lilv_instance_connect_port(LilvInstance* instance,
This resets all state information in the plugin, except for port data
locations (as set by lilv_instance_connect_port()). This MUST be called
before calling lilv_instance_run().
+
+ This function is in the "instantiation" threading class: it isn't real-time
+ safe, and may not be called concurrently with any other function for the
+ same instance.
*/
static inline void
lilv_instance_activate(LilvInstance* instance)
@@ -1941,6 +1948,10 @@ lilv_instance_activate(LilvInstance* instance)
If the hint lv2:hardRTCapable is set for this plugin, this function is
guaranteed not to block.
+
+ This function is in the "audio" threading class: it's real-time safe if the
+ plugin is <http://lv2plug.in/ns/lv2core#hardRTCapable>, but may not be
+ called concurrently with any other function for the same instance.
*/
static inline void
lilv_instance_run(LilvInstance* instance, uint32_t sample_count)
@@ -1953,6 +1964,10 @@ lilv_instance_run(LilvInstance* instance, uint32_t sample_count)
Note that to run the plugin after this you must activate it, which will
reset all state information (except port connections).
+
+ This function is in the "instantiation" threading class: it isn't real-time
+ safe and may not be called concurrently with any other function for the same
+ instance.
*/
static inline void
lilv_instance_deactivate(LilvInstance* instance)
@@ -1967,6 +1982,10 @@ lilv_instance_deactivate(LilvInstance* instance)
The type and semantics of the data returned is specific to the particular
extension, though in all cases it is shared and must not be deleted.
+
+ This function is in the "discovery" threading class: it isn't real-time safe
+ and may not be called concurrently with any other function for the same
+ instance.
*/
static inline const void*
lilv_instance_get_extension_data(const LilvInstance* instance, const char* uri)
@@ -1985,6 +2004,8 @@ lilv_instance_get_extension_data(const LilvInstance* instance, const char* uri)
use the lilv_instance_* functions.
The returned descriptor is shared and must not be deleted.
+
+ This function is a simple accessor and may be called at any time.
*/
static inline const LV2_Descriptor*
lilv_instance_get_descriptor(const LilvInstance* instance)
@@ -1999,6 +2020,8 @@ lilv_instance_get_descriptor(const LilvInstance* instance)
use the lilv_instance_* functions.
The returned handle is shared and must not be deleted.
+
+ This function is a simple accessor and may be called at any time.
*/
static inline LV2_Handle
lilv_instance_get_handle(const LilvInstance* instance)
diff --git a/include/lilv/lilvmm.hpp b/include/lilv/lilvmm.hpp
index 0ac802d..6e270df 100644
--- a/include/lilv/lilvmm.hpp
+++ b/include/lilv/lilvmm.hpp
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2017 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.
-*/
+// Copyright 2007-2017 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#ifndef LILV_LILVMM_HPP
#define LILV_LILVMM_HPP
@@ -60,20 +47,35 @@ uri_to_path(const char* uri)
# pragma GCC diagnostic pop
#endif
-#define LILV_WRAP0(RT, prefix, name) \
- inline RT name() { return lilv_##prefix##_##name(me); }
+#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); }
+ 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); }
+ 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); }
+ 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); }
+ inline RT name(T1 a1, T2 a2) \
+ { \
+ return lilv_##prefix##_##name(me, a1, a2); \
+ }
#define LILV_WRAP3(RT, prefix, name, T1, a1, T2, a2, T3, a3) \
inline RT name(T1 a1, T2 a2, T3 a3) \
@@ -82,11 +84,17 @@ uri_to_path(const char* uri)
}
#define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \
- inline void name(T1 a1, T2 a2) { lilv_##prefix##_##name(me, a1, 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; }
+ inline operator CT*() const \
+ { \
+ return me; \
+ }
#else
# define LILV_WRAP_CONVERSION(CT)
#endif
@@ -133,22 +141,22 @@ struct Node {
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);
+ 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;
};
@@ -158,10 +166,10 @@ struct ScalePoint {
: me(c_obj)
{}
- LILV_WRAP_CONVERSION(const LilvScalePoint);
+ LILV_WRAP_CONVERSION(const LilvScalePoint)
- LILV_WRAP0(const LilvNode*, scale_point, get_label);
- LILV_WRAP0(const LilvNode*, scale_point, get_value);
+ LILV_WRAP0(const LilvNode*, scale_point, get_label)
+ LILV_WRAP0(const LilvNode*, scale_point, get_value)
const LilvScalePoint* me;
};
@@ -171,41 +179,41 @@ struct PluginClass {
: me(c_obj)
{}
- LILV_WRAP_CONVERSION(const LilvPluginClass);
+ 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);
+ 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(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); \
+#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(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(PluginClass, plugin_classes, get_by_uri, const LilvNode*, uri);
+ LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes)
+ LILV_WRAP1(PluginClass, plugin_classes, get_by_uri, const LilvNode*, uri)
};
struct ScalePoints {
- LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points);
+ 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);
+ LILV_WRAP_COLL(Nodes, Node, nodes)
+ LILV_WRAP1(bool, nodes, contains, const Node&, node)
+ LILV_WRAP0(Node, nodes, get_first)
};
struct UI {
@@ -213,23 +221,23 @@ struct UI {
: me(c_obj)
{}
- LILV_WRAP_CONVERSION(const LilvUI);
+ LILV_WRAP_CONVERSION(const LilvUI)
- LILV_WRAP0(const LilvNode*, ui, get_uri);
- LILV_WRAP0(const LilvNode*, ui, get_bundle_uri);
- LILV_WRAP0(const LilvNode*, ui, get_binary_uri);
- LILV_WRAP0(const LilvNodes*, ui, get_classes);
+ LILV_WRAP0(const LilvNode*, ui, get_uri)
+ LILV_WRAP0(const LilvNode*, ui, get_bundle_uri)
+ LILV_WRAP0(const LilvNode*, ui, get_binary_uri)
+ LILV_WRAP0(const LilvNodes*, ui, get_classes)
/*LILV_WRAP3(bool, ui, is_supported,
LilvUISupportedFunc, supported_func,
const LilvNode*, container_type,
const LilvNode**, ui_type);*/
- LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri);
+ LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri)
const LilvUI* me;
};
struct UIs {
- LILV_WRAP_COLL(UIs, UI, uis);
+ LILV_WRAP_COLL(UIs, UI, uis)
};
struct Port {
@@ -238,23 +246,29 @@ struct Port {
, me(c_obj)
{}
- LILV_WRAP_CONVERSION(const LilvPort);
+ LILV_WRAP_CONVERSION(const LilvPort)
-#define LILV_PORT_WRAP0(RT, name) \
- inline RT name() { return lilv_port_##name(parent, me); }
+#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); }
+#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_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);
+ 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)
@@ -267,30 +281,30 @@ struct Plugin {
: 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, const Node&, pred);
- LILV_WRAP1(bool, plugin, has_feature, const 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);
- LILV_WRAP1(Nodes, plugin, get_related, const Node&, type);
+ 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, const Node&, pred)
+ LILV_WRAP1(bool, plugin, has_feature, const 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)
+ LILV_WRAP1(Nodes, plugin, get_related, const Node&, type)
inline Port get_port_by_index(unsigned index) const
{
@@ -312,7 +326,7 @@ struct Plugin {
inline unsigned get_num_ports_of_class(LilvNode* class_1, ...) const
{
- va_list args;
+ va_list args; // NOLINT(cppcoreguidelines-init-variables)
va_start(args, class_1);
const uint32_t count =
@@ -326,8 +340,8 @@ struct Plugin {
};
struct Plugins {
- LILV_WRAP_COLL(Plugins, Plugin, plugins);
- LILV_WRAP1(Plugin, plugins, get_by_uri, const LilvNode*, uri);
+ LILV_WRAP_COLL(Plugins, Plugin, plugins)
+ LILV_WRAP1(Plugin, plugins, get_by_uri, const LilvNode*, uri)
};
struct Instance {
@@ -337,16 +351,15 @@ struct Instance {
LILV_DEPRECATED
inline Instance(Plugin plugin, double sample_rate)
- {
- me = lilv_plugin_instantiate(plugin, sample_rate, nullptr);
- }
+ : me(lilv_plugin_instantiate(plugin, sample_rate, nullptr))
+ {}
- LILV_DEPRECATED inline Instance(Plugin plugin,
- double sample_rate,
- LV2_Feature* const* features)
- {
- me = lilv_plugin_instantiate(plugin, sample_rate, features);
- }
+ 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,
@@ -357,18 +370,18 @@ struct Instance {
return me ? new Instance(me) : nullptr;
}
- LILV_WRAP_CONVERSION(LilvInstance);
+ LILV_WRAP_CONVERSION(LilvInstance)
LILV_WRAP2_VOID(instance,
connect_port,
unsigned,
port_index,
void*,
- data_location);
+ data_location)
- LILV_WRAP0_VOID(instance, activate);
- LILV_WRAP1_VOID(instance, run, unsigned, sample_count);
- LILV_WRAP0_VOID(instance, deactivate);
+ 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) const
{
@@ -392,10 +405,10 @@ struct World {
inline ~World() { lilv_world_free(me); }
- World(const World&) = delete;
+ World(const World&) = delete;
World& operator=(const World&) = delete;
- World(World&&) = delete;
+ World(World&&) = delete;
World& operator=(World&&) = delete;
inline LilvNode* new_uri(const char* uri) const
@@ -424,13 +437,13 @@ struct World {
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(Plugins, world, get_all_plugins);
- LILV_WRAP1(int, world, load_resource, const LilvNode*, resource);
+ 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(Plugins, world, get_all_plugins)
+ LILV_WRAP1(int, world, load_resource, const LilvNode*, resource)
LilvWorld* me;
};
diff --git a/lilv.pc.in b/lilv.pc.in
deleted file mode 100644
index 97f4f8c..0000000
--- a/lilv.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=@EXEC_PREFIX@
-libdir=@LIBDIR@
-includedir=@INCLUDEDIR@
-
-Name: Lilv
-Version: @LILV_VERSION@
-Description: Simple C library for hosting LV2 plugins
-Requires: @LILV_PKG_DEPS@
-Libs: -L${libdir} -l@LIB_LILV@ @LILV_PKG_LIBS@
-Cflags: -I${includedir}/lilv-@LILV_MAJOR_VERSION@
diff --git a/lilv.ttl b/lilv.ttl
index edfb0e5..9bdd56d 100644
--- a/lilv.ttl
+++ b/lilv.ttl
@@ -1,29 +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 doap: <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" .
-
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ foaf:name "David Robillard" ;
+ foaf:nick "drobilla" .
+<http://drobilla.net/software/lilv>
+ a doap:Project ;
+ doap:blog <https://drobilla.net/category/lilv/> ;
+ doap:bug-database <https://gitlab.com/lv2/lilv/issues> ;
+ doap:description "C library for hosting LV2 plugins" ;
+ doap:developer <http://drobilla.net/drobilla#me> ;
+ doap:download-page <http://download.drobilla.net/> ;
+ doap:homepage <http://drobilla.net/software/lilv> ;
+ doap:implements <http://lv2plug.in/ns/lv2core> ;
+ doap:license <http://opensource.org/licenses/isc> ;
+ doap:maintainer <http://drobilla.net/drobilla#me> ;
+ doap:name "Lilv" ;
+ doap:programming-language "C" ;
+ doap:repository [
+ a doap:GitBranch ;
+ doap:location <https://gitlab.com/lv2/lilv.git>
+ ] .
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..6a9b52a
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,265 @@
+# Copyright 2021-2024 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+project(
+ 'lilv',
+ ['c'],
+ default_options: [
+ 'b_ndebug=if-release',
+ 'buildtype=release',
+ 'c_std=c99',
+ 'cpp_std=c++11',
+ ],
+ license: 'ISC',
+ meson_version: '>= 0.56.0',
+ version: '0.24.25',
+)
+
+lilv_src_root = meson.current_source_dir()
+major_version = meson.project_version().split('.')[0]
+version_suffix = '-@0@'.format(major_version)
+versioned_name = 'lilv' + version_suffix
+
+#######################
+# Compilers and Flags #
+#######################
+
+# Required tools
+pkg = import('pkgconfig')
+cc = meson.get_compiler('c')
+
+# Enable C++ support if bindings aren't disabled
+if not get_option('bindings_cpp').disabled()
+ if add_languages(['cpp'], native: false, required: false)
+ cpp = meson.get_compiler('cpp')
+ endif
+endif
+
+# Set global warning flags
+subdir('meson/suppressions')
+
+##########################
+# Platform Configuration #
+##########################
+
+platform_defines = ['-DLILV_VERSION="@0@"'.format(meson.project_version())]
+if host_machine.system() in ['gnu', 'linux']
+ platform_defines += [
+ '-D_POSIX_C_SOURCE=200809L',
+ ]
+endif
+
+default_lv2_path = get_option('default_lv2_path')
+if default_lv2_path == ''
+ if host_machine.system() == 'darwin'
+ lv2_dirs = [
+ '~/.lv2',
+ '~/Library/Audio/Plug-Ins/LV2',
+ '/usr/local/lib/lv2',
+ '/usr/lib/lv2',
+ '/Library/Audio/Plug-Ins/LV2',
+ ]
+
+ default_lv2_path = ':'.join(lv2_dirs)
+
+ elif host_machine.system() == 'haiku'
+ default_lv2_path = ':'.join(['~/.lv2', '/boot/common/add-ons/lv2'])
+
+ elif host_machine.system() == 'windows'
+ lv2_dirs = ['%%APPDATA%%\\\\LV2', '%%COMMONPROGRAMFILES%%\\\\LV2']
+ default_lv2_path = ';'.join(lv2_dirs)
+
+ else
+ lv2_dirs = [
+ '~' / '.lv2',
+ '/usr/local' / get_option('libdir') / 'lv2',
+ '/usr' / get_option('libdir') / 'lv2',
+ ]
+
+ default_lv2_path = ':'.join(lv2_dirs)
+ endif
+endif
+
+platform_defines += ['-DLILV_DEFAULT_LV2_PATH="@0@"'.format(default_lv2_path)]
+
+# Use versioned name everywhere to support parallel major version installations
+if host_machine.system() == 'windows'
+ if get_option('default_library') == 'both'
+ error('default_library=both is not supported on Windows')
+ endif
+ soversion = ''
+else
+ soversion = meson.project_version().split('.')[0]
+endif
+
+add_project_arguments(platform_defines, language: ['c'])
+
+################
+# Dependencies #
+################
+
+m_dep = cc.find_library('m', required: false)
+dl_dep = cc.find_library('dl', required: false)
+
+zix_dep = dependency('zix-0', fallback: 'zix', version: '>= 0.4.0')
+serd_dep = dependency('serd-0', fallback: 'serd', version: '>= 0.30.10')
+sord_dep = dependency('sord-0', fallback: 'sord', version: '>= 0.16.15')
+lv2_dep = dependency('lv2', fallback: 'lv2', version: '>= 1.18.2')
+sratom_dep = dependency('sratom-0', fallback: 'sratom', version: '>= 0.6.10')
+
+###########
+# Library #
+###########
+
+c_headers = files('include/lilv/lilv.h')
+cpp_headers = files('include/lilv/lilvmm.hpp')
+
+sources = files(
+ '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',
+)
+
+common_dependencies = [
+ dl_dep,
+ lv2_dep,
+ m_dep,
+ serd_dep,
+ sord_dep,
+ sratom_dep,
+ zix_dep,
+]
+
+# Set appropriate arguments for building against the library type
+extra_c_args = []
+if get_option('default_library') == 'static'
+ extra_c_args = ['-DLILV_STATIC']
+endif
+
+# Build main shared and/or static library
+liblilv = library(
+ versioned_name,
+ sources,
+ c_args: c_suppressions + extra_c_args + ['-DLILV_INTERNAL'],
+ darwin_versions: [major_version + '.0.0', meson.project_version()],
+ dependencies: common_dependencies,
+ gnu_symbol_visibility: 'hidden',
+ include_directories: include_directories('include', 'src'),
+ install: true,
+ soversion: soversion,
+ version: meson.project_version(),
+)
+
+# Declare dependency for internal meson dependants
+lilv_dep = declare_dependency(
+ compile_args: extra_c_args,
+ dependencies: common_dependencies,
+ include_directories: include_directories('include'),
+ link_with: liblilv,
+)
+
+# Generage pkg-config file for external dependants
+pkg.generate(
+ liblilv,
+ description: 'Library for hosting LV2 plugins',
+ extra_cflags: extra_c_args,
+ filebase: versioned_name,
+ name: 'Lilv',
+ requires: ['lv2'],
+ subdirs: [versioned_name],
+ version: meson.project_version(),
+)
+
+# Override pkg-config dependency for internal meson dependants
+meson.override_dependency(versioned_name, lilv_dep)
+
+# Install headers to a versioned include directory
+install_headers(c_headers, subdir: versioned_name / 'lilv')
+install_headers(cpp_headers, subdir: versioned_name / 'lilv')
+
+# Display top-level summary (before subdirectories to appear first)
+if not meson.is_subproject()
+ summary(
+ {
+ 'Tests': not get_option('tests').disabled(),
+ 'Tools': not get_option('tools').disabled(),
+ },
+ bool_yn: true,
+ section: 'Components',
+ )
+
+ summary('Default LV2_PATH', default_lv2_path, section: 'Configuration')
+
+ summary(
+ {
+ 'Install prefix': get_option('prefix'),
+ 'Headers': get_option('prefix') / get_option('includedir'),
+ 'Libraries': get_option('prefix') / get_option('libdir'),
+ 'Executables': get_option('prefix') / get_option('bindir'),
+ 'Man pages': get_option('prefix') / get_option('mandir'),
+ },
+ section: 'Directories',
+ )
+endif
+
+#########
+# Tools #
+#########
+
+if not get_option('tools').disabled()
+ subdir('tools')
+endif
+
+############
+# Bindings #
+############
+
+if not get_option('bindings_py').disabled()
+ subdir('bindings/python')
+endif
+
+###########
+# Support #
+###########
+
+if not get_option('docs').disabled()
+ subdir('doc')
+endif
+
+if not get_option('tests').disabled()
+ # Get or build a static library for linking internal tests
+ if get_option('default_library') == 'both'
+ liblilv_static = liblilv.get_static_lib()
+ elif get_option('default_library') == 'shared'
+ liblilv_static = static_library(
+ versioned_name,
+ sources,
+ include_directories: include_directories('include', 'src'),
+ c_args: c_suppressions + ['-DLILV_INTERNAL', '-DLILV_STATIC'],
+ dependencies: common_dependencies,
+ gnu_symbol_visibility: 'default',
+ )
+ else
+ liblilv_static = liblilv
+ endif
+
+ lilv_static_dep = declare_dependency(
+ compile_args: extra_c_args,
+ dependencies: common_dependencies,
+ include_directories: include_directories('include'),
+ link_with: liblilv_static,
+ )
+
+ # Build and run tests against static library
+ subdir('test')
+endif
diff --git a/meson/suppressions/meson.build b/meson/suppressions/meson.build
new file mode 100644
index 0000000..d05af9e
--- /dev/null
+++ b/meson/suppressions/meson.build
@@ -0,0 +1,141 @@
+# Copyright 2020-2023 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+# Project-specific warning suppressions
+
+warning_level = get_option('warning_level')
+
+#####
+# C #
+#####
+
+c_suppressions = []
+
+if cc.get_id() in ['clang', 'emscripten']
+ if warning_level == 'everything'
+ c_suppressions += [
+ '-Wno-cast-align',
+ '-Wno-cast-function-type-strict',
+ '-Wno-cast-qual',
+ '-Wno-declaration-after-statement',
+ '-Wno-documentation-unknown-command',
+ '-Wno-double-promotion',
+ '-Wno-float-equal',
+ '-Wno-format-nonliteral',
+ '-Wno-implicit-float-conversion',
+ '-Wno-implicit-int-conversion',
+ '-Wno-padded',
+ '-Wno-reserved-id-macro',
+ '-Wno-shorten-64-to-32',
+ '-Wno-sign-conversion',
+ '-Wno-switch-enum',
+ '-Wno-unsafe-buffer-usage',
+ '-Wno-vla',
+ ]
+
+ if not meson.is_cross_build()
+ c_suppressions += [
+ '-Wno-poison-system-directories',
+ ]
+ endif
+ endif
+
+ if warning_level in ['everything', '3']
+ c_suppressions += [
+ '-Wno-nullability-extension',
+ ]
+
+ if host_machine.system() == 'freebsd'
+ c_suppressions += [
+ '-Wno-c11-extensions',
+ ]
+ elif host_machine.system() == 'darwin'
+ c_suppressions += [
+ '-Wno-unused-macros',
+ ]
+ elif host_machine.system() == 'windows'
+ c_suppressions += [
+ '-Wno-deprecated-declarations',
+ '-Wno-nonportable-system-include-path',
+ '-Wno-unused-macros',
+ ]
+ endif
+ endif
+
+elif cc.get_id() == 'gcc'
+ if warning_level == 'everything'
+ c_suppressions += [
+ '-Wno-cast-align',
+ '-Wno-cast-qual',
+ '-Wno-conversion',
+ '-Wno-double-promotion',
+ '-Wno-float-equal',
+ '-Wno-format-nonliteral',
+ '-Wno-format-truncation',
+ '-Wno-inline',
+ '-Wno-padded',
+ '-Wno-stack-protector',
+ '-Wno-strict-overflow',
+ '-Wno-suggest-attribute=const',
+ '-Wno-suggest-attribute=pure',
+ '-Wno-switch-default',
+ '-Wno-switch-enum',
+ '-Wno-unsuffixed-float-constants',
+ '-Wno-unused-const-variable',
+ '-Wno-unused-parameter',
+ '-Wno-vla',
+ ]
+ endif
+
+ if warning_level in ['everything', '3']
+ c_suppressions += [
+ '-Wno-pedantic',
+ ]
+ endif
+
+ if host_machine.system() == 'windows'
+ c_suppressions += [
+ '-Wno-bad-function-cast',
+ '-Wno-unused-macros',
+ ]
+ endif
+
+elif cc.get_id() == 'msvc'
+ c_suppressions += [
+ '/experimental:external',
+ '/external:W0',
+ '/external:anglebrackets',
+ ]
+
+ if warning_level == 'everything'
+ c_suppressions += [
+ '/wd4061', # enumerator in switch is not explicitly handled
+ '/wd4191', # unsafe conversion from FARPROC
+ '/wd4365', # signed/unsigned mismatch
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4710', # function not inlined
+ '/wd4711', # function selected for automatic inline expansion
+ '/wd4774', # format string is not a string literal
+ '/wd4800', # implicit conversion to bool
+ '/wd4820', # padding added after construct
+ '/wd5045', # will insert Spectre mitigation for memory load
+ ]
+ endif
+
+ if warning_level in ['everything', '3']
+ c_suppressions += [
+ '/wd4090', # different const qualifiers
+ '/wd4706', # assignment within conditional expression
+ ]
+ endif
+
+ if warning_level in ['everything', '3', '2']
+ c_suppressions += [
+ '/wd4244', # conversion from floating point, possible loss of data
+ '/wd4267', # conversion from size_t, possible loss of data
+ '/wd4996', # POSIX name for this item is deprecated
+ ]
+ endif
+endif
+
+c_suppressions = cc.get_supported_arguments(c_suppressions)
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..4419e9d
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,29 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+option('bindings_py', type: 'feature', value: 'auto', yield: true,
+ description: 'Build Python bindings')
+
+option('bindings_cpp', type: 'feature', value: 'auto', yield: true,
+ description: 'Build C++ bindings')
+
+option('default_lv2_path', type: 'string', value: '', yield: true,
+ description: 'Default LV2_PATH to use if it is unset')
+
+option('docs', type: 'feature', value: 'auto', yield: true,
+ description: 'Build documentation')
+
+option('html', type: 'feature', value: 'auto', yield: true,
+ description: 'Build paginated HTML documentation')
+
+option('singlehtml', type: 'feature', value: 'auto', yield: true,
+ description: 'Build single-page HTML documentation')
+
+option('tests', type: 'feature', value: 'auto', yield: true,
+ description: 'Build tests')
+
+option('title', type: 'string', value: 'Lilv',
+ description: 'Project title')
+
+option('tools', type: 'feature', value: 'auto', yield: true,
+ description: 'Build command line utilities')
diff --git a/scripts/dox_to_sphinx.py b/scripts/dox_to_sphinx.py
deleted file mode 100755
index 024f125..0000000
--- a/scripts/dox_to_sphinx.py
+++ /dev/null
@@ -1,655 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2020 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.
-
-"""
-Write Sphinx markup from Doxygen XML.
-
-Takes a path to a directory of XML generated by Doxygen, and emits a directory
-with a reStructuredText file for every documented symbol.
-"""
-
-import argparse
-import os
-import sys
-import textwrap
-import xml.etree.ElementTree
-
-__author__ = "David Robillard"
-__date__ = "2020-11-18"
-__email__ = "d@drobilla.net"
-__license__ = "ISC"
-__version__ = __date__.replace("-", ".")
-
-
-def load_index(index_path):
- """
- Load the index from XML.
-
- :returns: A dictionary from ID to skeleton records with basic information
- for every documented entity. Some records have an ``xml_filename`` key
- with the filename of a definition file. These files will be loaded later
- to flesh out the records in the index.
- """
-
- root = xml.etree.ElementTree.parse(index_path).getroot()
- index = {}
-
- for compound in root:
- compound_id = compound.get("refid")
- compound_kind = compound.get("kind")
- compound_name = compound.find("name").text
- if compound_kind in ["dir", "file", "page"]:
- continue
-
- # Add record for compound (compounds appear only once in the index)
- assert compound_id not in index
- index[compound_id] = {
- "kind": compound_kind,
- "name": compound_name,
- "xml_filename": compound_id + ".xml",
- "children": [],
- }
-
- name_prefix = (
- ("%s::" % compound_name) if compound_kind == "namespace" else ""
- )
-
- for child in compound.findall("member"):
- if child.get("refid") in index:
- assert compound_kind == "group"
- continue
-
- # Everything has a kind and a name
- child_record = {
- "kind": child.get("kind"),
- "name": name_prefix + child.find("name").text,
- }
-
- if child.get("kind") == "enum":
- # Enums are not compounds, but we want to resolve the parent of
- # their values so they are not written as top level documents
- child_record["children"] = []
-
- if child.get("kind") == "enumvalue":
- # Remove namespace prefix
- child_record["name"] = child.find("name").text
-
- index[child.get("refid")] = child_record
-
- return index
-
-
-def resolve_index(index, root):
- """
- Walk a definition document and extend the index for linking.
-
- This does two things: sets the "parent" and "children" fields of all
- applicable records, and sets the "strong" field of enums so that the
- correct Sphinx role can be used when referring to them.
- """
-
- def add_child(index, parent_id, child_id):
- parent = index[parent_id]
- child = index[child_id]
-
- if child["kind"] == "enumvalue":
- assert parent["kind"] == "enum"
- assert "parent" not in child or child["parent"] == parent_id
- child["parent"] = parent_id
-
- else:
- if parent["kind"] in ["class", "struct", "union"]:
- assert "parent" not in child or child["parent"] == parent_id
- child["parent"] = parent_id
-
- if child_id not in parent["children"]:
- parent["children"] += [child_id]
-
- compound = root.find("compounddef")
- compound_kind = compound.get("kind")
-
- if compound_kind == "group":
- for subgroup in compound.findall("innergroup"):
- add_child(index, compound.get("id"), subgroup.get("refid"))
-
- for klass in compound.findall("innerclass"):
- add_child(index, compound.get("id"), klass.get("refid"))
-
- for section in compound.findall("sectiondef"):
- if section.get("kind").startswith("private"):
- for member in section.findall("memberdef"):
- if member.get("id") in index:
- del index[member.get("id")]
- else:
- for member in section.findall("memberdef"):
- member_id = member.get("id")
- add_child(index, compound.get("id"), member_id)
-
- if member.get("kind") == "enum":
- index[member_id]["strong"] = member.get("strong") == "yes"
- for value in member.findall("enumvalue"):
- add_child(index, member_id, value.get("id"))
-
-
-def sphinx_role(record, lang):
- """
- Return the Sphinx role used for a record.
-
- This is used for the description directive like ".. c:function::", and
- links like ":c:func:`foo`.
- """
-
- kind = record["kind"]
-
- if kind in ["class", "function", "namespace", "struct", "union"]:
- return lang + ":" + kind
-
- if kind == "define":
- return "c:macro"
-
- if kind == "enum":
- return lang + (":enum-class" if record["strong"] else ":enum")
-
- if kind == "typedef":
- return lang + ":type"
-
- if kind == "enumvalue":
- return lang + ":enumerator"
-
- if kind == "variable":
- return lang + (":member" if "parent" in record else ":var")
-
- raise RuntimeError("No known role for kind '%s'" % kind)
-
-
-def child_identifier(lang, parent_name, child_name):
- """
- Return the identifier for an enum value or struct member.
-
- Sphinx, for some reason, uses a different syntax for this in C and C++.
- """
-
- separator = "::" if lang == "cpp" else "."
-
- return "%s%s%s" % (parent_name, separator, child_name)
-
-
-def link_markup(index, lang, refid):
- """Return a Sphinx link for a Doxygen reference."""
-
- record = index[refid]
- kind, name = record["kind"], record["name"]
- role = sphinx_role(record, lang)
-
- if kind in ["class", "enum", "struct", "typedef", "union"]:
- return ":%s:`%s`" % (role, name)
-
- if kind == "function":
- return ":%s:func:`%s`" % (lang, name)
-
- if kind == "enumvalue":
- parent_name = index[record["parent"]]["name"]
- return ":%s:`%s`" % (role, child_identifier(lang, parent_name, name))
-
- if kind == "variable":
- if "parent" not in record:
- return ":%s:var:`%s`" % (lang, name)
-
- parent_name = index[record["parent"]]["name"]
- return ":%s:`%s`" % (role, child_identifier(lang, parent_name, name))
-
- if kind == "define":
- return ":%s:macro:`%s`" % (lang, name)
-
- raise RuntimeError("Unknown link target kind: %s" % kind)
-
-
-def indent(markup, depth):
- """
- Indent markup to a depth level.
-
- Like textwrap.indent() but takes an integer and works in reST indentation
- levels for clarity."
- """
-
- return textwrap.indent(markup, " " * depth)
-
-
-def heading(text, level):
- """
- Return a ReST heading at a given level.
-
- Follows the style in the Python documentation guide, see
- <https://devguide.python.org/documenting/#sections>.
- """
-
- assert 1 <= level <= 6
-
- chars = ("#", "*", "=", "-", "^", '"')
- line = chars[level] * len(text)
-
- return "%s%s\n%s\n\n" % (line + "\n" if level < 3 else "", text, line)
-
-
-def dox_to_rst(index, lang, node):
- """
- Convert documentation commands (docCmdGroup) to Sphinx markup.
-
- This is used to convert the content of descriptions in the documentation.
- It recursively parses all children tags and raises a RuntimeError if any
- unknown tag is encountered.
- """
-
- def field_value(markup):
- """Return a value for a field as a single line or indented block."""
- if "\n" in markup.strip():
- return "\n" + indent(markup, 1)
-
- return " " + markup.strip()
-
- if node.tag == "lsquo":
- return "‘"
-
- if node.tag == "rsquo":
- return "’"
-
- if node.tag == "computeroutput":
- assert len(node) == 0
- return "``%s``" % node.text
-
- if node.tag == "itemizedlist":
- markup = ""
- for item in node.findall("listitem"):
- assert len(item) == 1
- markup += "\n- %s" % dox_to_rst(index, lang, item[0])
-
- return markup
-
- if node.tag == "para":
- markup = node.text if node.text is not None else ""
- for child in node:
- markup += dox_to_rst(index, lang, child)
- markup += child.tail if child.tail is not None else ""
-
- return markup.strip() + "\n\n"
-
- if node.tag == "parameterlist":
- markup = ""
- for item in node.findall("parameteritem"):
- name = item.find("parameternamelist/parametername")
- description = item.find("parameterdescription")
- assert len(description) == 1
- markup += "\n\n:param %s:%s" % (
- name.text,
- field_value(dox_to_rst(index, lang, description[0])),
- )
-
- return markup + "\n"
-
- if node.tag == "programlisting":
- return "\n.. code-block:: %s\n\n%s" % (
- lang,
- indent(plain_text(node), 1),
- )
-
- if node.tag == "ref":
- refid = node.get("refid")
- if refid not in index:
- sys.stderr.write("warning: Unresolved link: %s\n" % refid)
- return node.text
-
- assert len(node) == 0
- assert len(link_markup(index, lang, refid)) > 0
- return link_markup(index, lang, refid)
-
- if node.tag == "simplesect":
- assert len(node) == 1
-
- if node.get("kind") == "return":
- return "\n:returns:" + field_value(
- dox_to_rst(index, lang, node[0])
- ) + "\n"
-
- if node.get("kind") == "see":
- return dox_to_rst(index, lang, node[0])
-
- raise RuntimeError("Unknown simplesect kind: %s" % node.get("kind"))
-
- if node.tag == "ulink":
- return "`%s <%s>`_" % (node.text, node.get("url"))
-
- raise RuntimeError("Unknown documentation command: %s" % node.tag)
-
-
-def description_markup(index, lang, node):
- """Return the markup for a brief or detailed description."""
-
- assert node.tag == "briefdescription" or node.tag == "detaileddescription"
- assert not (node.tag == "briefdescription" and len(node) > 1)
- assert len(node.text.strip()) == 0
-
- return "".join([dox_to_rst(index, lang, child) for child in node]).strip()
-
-
-def set_descriptions(index, lang, definition, record):
- """Set a record's brief/detailed descriptions from the XML definition."""
-
- for tag in ["briefdescription", "detaileddescription"]:
- node = definition.find(tag)
- if node is not None:
- record[tag] = description_markup(index, lang, node)
-
-
-def set_template_params(node, record):
- """Set a record's template_params from the XML definition."""
-
- template_param_list = node.find("templateparamlist")
- if template_param_list is not None:
- params = []
- for param in template_param_list.findall("param"):
- if param.find("declname") is not None:
- # Value parameter
- type_text = plain_text(param.find("type"))
- name_text = plain_text(param.find("declname"))
-
- params += ["%s %s" % (type_text, name_text)]
- else:
- # Type parameter
- params += ["%s" % (plain_text(param.find("type")))]
-
- record["template_params"] = "%s" % ", ".join(params)
-
-
-def plain_text(node):
- """
- Return the plain text of a node with all tags ignored.
-
- This is needed where Doxygen may include refs but Sphinx needs plain text
- because it parses things itself to generate links.
- """
-
- if node.tag == "sp":
- markup = " "
- elif node.text is not None:
- markup = node.text
- else:
- markup = ""
-
- for child in node:
- markup += plain_text(child)
- markup += child.tail if child.tail is not None else ""
-
- return markup
-
-
-def local_name(name):
- """Return a name with all namespace prefixes stripped."""
-
- return name[name.rindex("::") + 2 :] if "::" in name else name
-
-
-def read_definition_doc(index, lang, root):
- """Walk a definition document and update described records in the index."""
-
- # Set descriptions for the compound itself
- compound = root.find("compounddef")
- compound_record = index[compound.get("id")]
- set_descriptions(index, lang, compound, compound_record)
- set_template_params(compound, compound_record)
-
- if compound.find("title") is not None:
- compound_record["title"] = compound.find("title").text.strip()
-
- # Set documentation for all children
- for section in compound.findall("sectiondef"):
- if section.get("kind").startswith("private"):
- continue
-
- for member in section.findall("memberdef"):
- kind = member.get("kind")
- record = index[member.get("id")]
- set_descriptions(index, lang, member, record)
- set_template_params(member, record)
-
- if compound.get("kind") in ["class", "struct", "union"]:
- assert kind in ["function", "typedef", "variable"]
- record["type"] = plain_text(member.find("type"))
-
- if kind == "enum":
- for value in member.findall("enumvalue"):
- set_descriptions(
- index, lang, value, index[value.get("id")]
- )
-
- elif kind == "function":
- record["prototype"] = "%s %s%s" % (
- plain_text(member.find("type")),
- member.find("name").text,
- member.find("argsstring").text,
- )
-
- elif kind == "typedef":
- name = local_name(record["name"])
- args_text = member.find("argsstring").text
- target_text = plain_text(member.find("type"))
- if args_text is not None: # Function pointer
- assert target_text[-2:] == "(*" and args_text[0] == ")"
- record["type"] = target_text + args_text
- record["definition"] = target_text + name + args_text
- else: # Normal named typedef
- assert target_text is not None
- record["type"] = target_text
- if member.find("definition").text.startswith("using"):
- record["definition"] = "%s = %s" % (
- name,
- target_text,
- )
- else:
- record["definition"] = "%s %s" % (
- target_text,
- name,
- )
-
- elif kind == "variable":
- record["definition"] = member.find("definition").text
-
-
-def declaration_string(record):
- """
- Return the string that describes a declaration.
-
- This is what follows the directive, and is in C/C++ syntax, except without
- keywords like "typedef" and "using" as expected by Sphinx. For example,
- "struct ThingImpl Thing" or "void run(int value)".
- """
-
- kind = record["kind"]
- result = ""
-
- if "template_params" in record:
- result = "template <%s> " % record["template_params"]
-
- if kind == "function":
- result += record["prototype"]
- elif kind == "typedef":
- result += record["definition"]
- elif kind == "variable":
- if "parent" in record:
- result += "%s %s" % (record["type"], local_name(record["name"]))
- else:
- result += record["definition"]
- elif "type" in record:
- result += "%s %s" % (record["type"], local_name(record["name"]))
- else:
- result += local_name(record["name"])
-
- return result
-
-
-def document_markup(index, lang, record):
- """Return the complete document that describes some documented entity."""
-
- kind = record["kind"]
- role = sphinx_role(record, lang)
- name = record["name"]
- markup = ""
-
- if name != local_name(name):
- markup += ".. cpp:namespace:: %s\n\n" % name[0 : name.rindex("::")]
-
- # Write top-level directive
- markup += ".. %s:: %s\n" % (role, declaration_string(record))
-
- # Write main description blurb
- markup += "\n" + indent(record["briefdescription"] + "\n", 1)
- if len(record["detaileddescription"]) > 0:
- markup += "\n" + indent(record["detaileddescription"], 1) + "\n"
-
- assert (
- kind in ["class", "enum", "namespace", "struct", "union"]
- or "children" not in record
- )
-
- # Sphinx C++ namespaces work by setting a scope, they have no content
- child_indent = 0 if kind == "namespace" else 1
-
- # Write inline children if applicable
- markup += "\n" if "children" in record else ""
- for child_id in record.get("children", []):
- child_record = index[child_id]
- child_role = sphinx_role(child_record, lang)
-
- child_header = ".. %s:: %s\n\n" % (
- child_role,
- declaration_string(child_record),
- )
-
- markup += "\n"
- markup += indent(child_header, child_indent)
- markup += indent(child_record["briefdescription"], child_indent + 1)
- markup += indent(child_record["detaileddescription"], child_indent + 1)
-
- return markup
-
-
-def symbol_filename(name):
- """Adapt the name of a symbol to be suitable for use as a filename."""
-
- return name.replace("::", "__")
-
-
-def emit_groups(index, lang, output_dir, force):
- """Write a description file for every group documented in the index."""
-
- for record in index.values():
- if record["kind"] != "group":
- continue
-
- name = record["name"]
- filename = os.path.join(output_dir, "%s.rst" % name)
- if not force and os.path.exists(filename):
- raise FileExistsError("File already exists: '%s'" % filename)
-
- with open(filename, "w") as rst:
- rst.write(heading(record["title"], 1))
-
- # Get all child group and symbol names
- child_groups = {}
- child_symbols = {}
- for child_id in record["children"]:
- child = index[child_id]
- if child["kind"] == "group":
- child_groups[child["name"]] = child
- else:
- child_symbols[child["name"]] = child
-
- # Emit description (document body)
- if len(record["briefdescription"]) > 0:
- rst.write(record["briefdescription"] + "\n\n")
- if len(record["detaileddescription"]) > 0:
- rst.write(record["detaileddescription"] + "\n\n")
-
- if len(child_groups) > 0:
- # Emit TOC for child groups
- rst.write(".. toctree::\n\n")
- for name, group in child_groups.items():
- rst.write(indent(group["name"], 1) + "\n")
-
- # Emit symbols in sorted order
- for name, symbol in child_symbols.items():
- rst.write("\n")
- rst.write(document_markup(index, lang, symbol))
- rst.write("\n")
-
-
-def run(index_xml_path, output_dir, language, force):
- """Write a directory of Sphinx files from a Doxygen XML directory."""
-
- # Build skeleton index from index.xml
- xml_dir = os.path.dirname(index_xml_path)
- index = load_index(index_xml_path)
-
- # Load all definition documents
- definition_docs = []
- for record in index.values():
- if "xml_filename" in record:
- xml_path = os.path.join(xml_dir, record["xml_filename"])
- definition_docs += [xml.etree.ElementTree.parse(xml_path)]
-
- # Do an initial pass of the definition documents to resolve the index
- for root in definition_docs:
- resolve_index(index, root)
-
- # Finally read the documentation from definition documents
- for root in definition_docs:
- read_definition_doc(index, language, root)
-
- # Create output directory
- try:
- os.makedirs(output_dir)
- except OSError:
- pass
-
- # Emit output files
- emit_groups(index, language, output_dir, force)
-
-
-if __name__ == "__main__":
- ap = argparse.ArgumentParser(
- usage="%(prog)s [OPTION]... XML_DIR OUTPUT_DIR",
- description=__doc__,
- formatter_class=argparse.RawDescriptionHelpFormatter,
- )
-
- ap.add_argument(
- "-f",
- "--force",
- action="store_true",
- help="overwrite files",
- )
-
- ap.add_argument(
- "-l",
- "--language",
- default="c",
- choices=["c", "cpp"],
- help="language domain for output",
- )
-
- ap.add_argument("index_xml_path", help="path index.xml from Doxygen")
- ap.add_argument("output_dir", help="output directory")
-
- run(**vars(ap.parse_args(sys.argv[1:])))
diff --git a/src/.clang-tidy b/src/.clang-tidy
new file mode 100644
index 0000000..0673649
--- /dev/null
+++ b/src/.clang-tidy
@@ -0,0 +1,21 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+Checks: >
+ -*-magic-numbers,
+ -android-cloexec-fopen,
+ -bugprone-narrowing-conversions,
+ -cert-err33-c,
+ -cert-err34-c,
+ -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
+ -clang-analyzer-valist.Uninitialized,
+ -concurrency-mt-unsafe,
+ -cppcoreguidelines-narrowing-conversions,
+ -google-readability-todo,
+ -hicpp-multiway-paths-covered,
+ -hicpp-signed-bitwise,
+ -llvm-header-guard,
+ -performance-no-int-to-ptr,
+ -readability-function-cognitive-complexity,
+ -readability-suspicious-call-argument,
+InheritParentConfig: true
diff --git a/src/collections.c b/src/collections.c
index c2c752a..a7b6923 100644
--- a/src/collections.c
+++ b/src/collections.c
@@ -1,36 +1,23 @@
-/*
- Copyright 2008-2019 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.
-*/
+// Copyright 2008-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
#include "lilv/lilv.h"
#include "sord/sord.h"
-#include "zix/common.h"
#include "zix/tree.h"
#include <stdbool.h>
#include <stddef.h>
-#include <stdint.h>
+
+typedef void (*LilvFreeFunc)(void* ptr);
int
lilv_ptr_cmp(const void* a, const void* b, const void* user_data)
{
(void)user_data;
- return (intptr_t)a - (intptr_t)b;
+ return a < b ? -1 : b < a ? 1 : 0;
}
int
@@ -41,18 +28,26 @@ lilv_resource_node_cmp(const void* a, const void* b, const void* user_data)
const SordNode* an = ((const LilvNode*)a)->node;
const SordNode* bn = ((const LilvNode*)b)->node;
- return (intptr_t)an - (intptr_t)bn;
+ return an < bn ? -1 : bn < an ? 1 : 0;
}
/* Generic collection functions */
+static void
+destroy(void* const ptr, const void* const user_data)
+{
+ if (user_data) {
+ ((LilvFreeFunc)user_data)(ptr);
+ }
+}
+
static inline LilvCollection*
-lilv_collection_new(ZixComparator cmp, ZixDestroyFunc destructor)
+lilv_collection_new(ZixTreeCompareFunc cmp, LilvFreeFunc free_func)
{
- return zix_tree_new(false, cmp, NULL, destructor);
+ return zix_tree_new(NULL, false, cmp, NULL, destroy, (const void*)free_func);
}
-void
+static void
lilv_collection_free(LilvCollection* collection)
{
if (collection) {
@@ -60,13 +55,13 @@ lilv_collection_free(LilvCollection* collection)
}
}
-unsigned
+static unsigned
lilv_collection_size(const LilvCollection* collection)
{
return (collection ? zix_tree_size((const ZixTree*)collection) : 0);
}
-LilvIter*
+static LilvIter*
lilv_collection_begin(const LilvCollection* collection)
{
return collection ? (LilvIter*)zix_tree_begin((ZixTree*)collection) : NULL;
@@ -85,28 +80,27 @@ lilv_collection_get(const LilvCollection* collection, const LilvIter* i)
LilvScalePoints*
lilv_scale_points_new(void)
{
- return lilv_collection_new(lilv_ptr_cmp,
- (ZixDestroyFunc)lilv_scale_point_free);
+ return lilv_collection_new(lilv_ptr_cmp, (LilvFreeFunc)lilv_scale_point_free);
}
LilvNodes*
lilv_nodes_new(void)
{
- return lilv_collection_new(lilv_ptr_cmp, (ZixDestroyFunc)lilv_node_free);
+ return lilv_collection_new(lilv_ptr_cmp, (LilvFreeFunc)lilv_node_free);
}
LilvUIs*
lilv_uis_new(void)
{
return lilv_collection_new(lilv_header_compare_by_uri,
- (ZixDestroyFunc)lilv_ui_free);
+ (LilvFreeFunc)lilv_ui_free);
}
LilvPluginClasses*
lilv_plugin_classes_new(void)
{
return lilv_collection_new(lilv_header_compare_by_uri,
- (ZixDestroyFunc)lilv_plugin_class_free);
+ (LilvFreeFunc)lilv_plugin_class_free);
}
/* URI based accessors (for collections of things with URIs) */
diff --git a/src/filesystem.c b/src/filesystem.c
deleted file mode 100644
index 03614ce..0000000
--- a/src/filesystem.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- Copyright 2007-2021 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.
-*/
-
-#define _POSIX_C_SOURCE 200809L /* for fileno */
-#define _BSD_SOURCE 1 /* for realpath, symlink */
-#define _DEFAULT_SOURCE 1 /* for realpath, symlink */
-
-#ifdef __APPLE__
-# define _DARWIN_C_SOURCE 1 /* for flock */
-#endif
-
-#include "filesystem.h"
-#include "lilv_config.h"
-#include "lilv_internal.h"
-
-#ifdef _WIN32
-# include <direct.h>
-# include <io.h>
-# include <windows.h>
-# define F_OK 0
-# define mkdir(path, flags) _mkdir(path)
-# define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
-#else
-# include <dirent.h>
-# include <unistd.h>
-#endif
-
-#if USE_FLOCK && USE_FILENO
-# include <sys/file.h>
-#endif
-
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE 4096
-#endif
-
-static bool
-lilv_is_dir_sep(const char c)
-{
- return c == '/' || c == LILV_DIR_SEP[0];
-}
-
-#ifdef _WIN32
-static inline bool
-is_windows_path(const char* path)
-{
- return (isalpha(path[0]) && (path[1] == ':' || path[1] == '|') &&
- (path[2] == '/' || path[2] == '\\'));
-}
-#endif
-
-char*
-lilv_temp_directory_path(void)
-{
-#ifdef _WIN32
- DWORD len = GetTempPath(0, NULL);
- char* buf = (char*)calloc(len, 1);
- if (GetTempPath(len, buf) == 0) {
- free(buf);
- return NULL;
- }
-
- return buf;
-#else
- const char* const tmpdir = getenv("TMPDIR");
-
- return tmpdir ? lilv_strdup(tmpdir) : lilv_strdup("/tmp");
-#endif
-}
-
-bool
-lilv_path_is_absolute(const char* path)
-{
- if (lilv_is_dir_sep(path[0])) {
- return true;
- }
-
-#ifdef _WIN32
- if (is_windows_path(path)) {
- return true;
- }
-#endif
-
- return false;
-}
-
-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;
-}
-
-char*
-lilv_path_current(void)
-{
- return getcwd(NULL, 0);
-}
-
-char*
-lilv_path_absolute(const char* path)
-{
- if (lilv_path_is_absolute(path)) {
- return lilv_strdup(path);
- }
-
- char* cwd = getcwd(NULL, 0);
- char* abs_path = lilv_path_join(cwd, path);
- free(cwd);
- return abs_path;
-}
-
-char*
-lilv_path_absolute_child(const char* path, const char* parent)
-{
- if (lilv_path_is_absolute(path)) {
- return lilv_strdup(path);
- }
-
- return lilv_path_join(parent, path);
-}
-
-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;
- }
- }
-
-#ifdef _WIN32
- const bool use_slash = strchr(path, '/');
-#else
- static const bool use_slash = true;
-#endif
-
- // 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) {
- if (use_slash) {
- memcpy(rel + (i * 3), "../", 3);
- } else {
- memcpy(rel + (i * 3), "..\\", 3);
- }
- }
-
- // Write suffix
- memcpy(rel + (up * 3), path + last_shared_sep + 1, suffix_len);
- return rel;
-}
-
-char*
-lilv_path_parent(const char* path)
-{
- const char* s = path + strlen(path) - 1; // Last character
-
- // 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
- for (; s > path && lilv_is_dir_sep(*s); --s) {
- }
-
- if (s == path) { // Hit beginning
- return lilv_is_dir_sep(*s) ? lilv_strdup("/") : lilv_strdup(".");
- }
-
- // 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;
-}
-
-char*
-lilv_path_filename(const char* path)
-{
- const size_t path_len = strlen(path);
- size_t last_sep = path_len;
- for (size_t i = 0; i < path_len; ++i) {
- if (lilv_is_dir_sep(path[i])) {
- last_sep = i;
- }
- }
-
- if (last_sep >= path_len) {
- return lilv_strdup(path);
- }
-
- const size_t ret_len = path_len - last_sep;
- char* const ret = (char*)calloc(ret_len + 1, 1);
-
- strncpy(ret, path + last_sep + 1, ret_len);
- return ret;
-}
-
-char*
-lilv_path_join(const char* a, const char* b)
-{
- if (!a) {
- return (b && b[0]) ? lilv_strdup(b) : NULL;
- }
-
- const size_t a_len = strlen(a);
- const size_t b_len = b ? strlen(b) : 0;
- const bool a_end_is_sep = a_len > 0 && lilv_is_dir_sep(a[a_len - 1]);
- const size_t pre_len = a_len - (a_end_is_sep ? 1 : 0);
- char* path = (char*)calloc(1, a_len + b_len + 2);
- memcpy(path, a, pre_len);
-
-#ifdef _WIN32
- // Use forward slash if it seems that the input paths do
- const bool a_has_slash = strchr(a, '/');
- const bool b_has_slash = b && strchr(b, '/');
- if (a_has_slash || b_has_slash) {
- path[pre_len] = '/';
- } else {
- path[pre_len] = '\\';
- }
-#else
- path[pre_len] = '/';
-#endif
-
- 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;
-}
-
-char*
-lilv_path_canonical(const char* path)
-{
- if (!path) {
- return NULL;
- }
-
-#if defined(_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
-}
-
-bool
-lilv_path_exists(const char* path)
-{
-#if USE_LSTAT
- struct stat st;
- return !lstat(path, &st);
-#else
- return !access(path, F_OK);
-#endif
-}
-
-bool
-lilv_is_directory(const char* path)
-{
- struct stat st;
- return !stat(path, &st) && S_ISDIR(st.st_mode);
-}
-
-int
-lilv_copy_file(const char* src, const char* dst)
-{
- FILE* in = fopen(src, "r");
- if (!in) {
- return errno;
- }
-
- FILE* out = fopen(dst, "w");
- if (!out) {
- fclose(in);
- return errno;
- }
-
- char* page = (char*)malloc(PAGE_SIZE);
- size_t n_read = 0;
- int st = 0;
- while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) {
- if (fwrite(page, 1, n_read, out) != n_read) {
- st = errno;
- break;
- }
- }
-
- if (!st && fflush(out)) {
- st = errno;
- }
-
- if (!st && (ferror(in) || ferror(out))) {
- st = EBADF;
- }
-
- free(page);
- fclose(in);
- fclose(out);
-
- return st;
-}
-
-int
-lilv_symlink(const char* oldpath, const char* newpath)
-{
- int ret = 0;
- if (strcmp(oldpath, newpath)) {
-#ifdef _WIN32
- ret = !CreateHardLink(newpath, oldpath, 0);
-#else
- char* target = lilv_path_relative_to(oldpath, newpath);
-
- ret = symlink(target, newpath);
-
- free(target);
-#endif
- }
- return ret;
-}
-
-int
-lilv_flock(FILE* file, bool lock, bool block)
-{
-#ifdef _WIN32
- HANDLE handle = (HANDLE)_get_osfhandle(fileno(file));
- OVERLAPPED overlapped = {0};
-
- if (lock) {
- const DWORD flags =
- (LOCKFILE_EXCLUSIVE_LOCK | (block ? 0 : LOCKFILE_FAIL_IMMEDIATELY));
-
- return !LockFileEx(handle, flags, 0, UINT32_MAX, UINT32_MAX, &overlapped);
- } else {
- return !UnlockFileEx(handle, 0, UINT32_MAX, UINT32_MAX, &overlapped);
- }
-#elif USE_FLOCK && USE_FILENO
- return flock(fileno(file),
- (lock ? LOCK_EX : LOCK_UN) | (block ? 0 : LOCK_NB));
-#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 {
- if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) {
- f(path, fd.cFileName, data);
- }
- } while (FindNextFile(fh, &fd));
- }
- FindClose(fh);
- free(pat);
-#else
- DIR* dir = opendir(path);
- if (dir) {
- for (struct dirent* entry = NULL; (entry = readdir(dir));) {
- if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) {
- f(path, entry->d_name, data);
- }
- }
- closedir(dir);
- }
-#endif
-}
-
-char*
-lilv_create_temporary_directory_in(const char* pattern, const char* parent)
-{
-#ifdef _WIN32
- static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- static const int n_chars = sizeof(chars) - 1;
-
- const size_t pattern_len = strlen(pattern);
- if (pattern_len < 7 || strcmp(pattern + pattern_len - 6, "XXXXXX")) {
- errno = EINVAL;
- return NULL;
- }
-
- char* const path_pattern = lilv_path_join(parent, pattern);
- const size_t path_pattern_len = strlen(path_pattern);
- char* const suffix = path_pattern + path_pattern_len - 6;
-
- for (unsigned attempt = 0; attempt < 128; ++attempt) {
- for (unsigned i = 0; i < 6; ++i) {
- suffix[i] = chars[rand() % n_chars];
- }
-
- if (!mkdir(path_pattern, 0700)) {
- return path_pattern;
- }
- }
-
- return NULL;
-#else
- char* const path_pattern = lilv_path_join(parent, pattern);
-
- return mkdtemp(path_pattern); // NOLINT (not a leak)
-#endif
-}
-
-char*
-lilv_create_temporary_directory(const char* pattern)
-{
- char* const tmpdir = lilv_temp_directory_path();
- char* const result = lilv_create_temporary_directory_in(pattern, tmpdir);
-
- free(tmpdir);
-
- return result;
-}
-
-int
-lilv_create_directories(const char* dir_path)
-{
- char* path = lilv_strdup(dir_path);
- const size_t path_len = strlen(path);
- size_t i = 1;
-
-#ifdef _WIN32
- if (is_windows_path(dir_path)) {
- i = 3;
- }
-#endif
-
- for (; i <= path_len; ++i) {
- const char c = path[i];
- if (c == LILV_DIR_SEP[0] || c == '/' || c == '\0') {
- path[i] = '\0';
- if (mkdir(path, 0755) && (errno != EEXIST || !lilv_is_directory(path))) {
- free(path);
- return errno;
- }
- path[i] = c;
- }
- }
-
- free(path);
- return 0;
-}
-
-static off_t
-lilv_file_size(const char* path)
-{
- struct stat buf;
- if (stat(path, &buf)) {
- return 0;
- }
- return buf.st_size;
-}
-
-int
-lilv_remove(const char* path)
-{
-#ifdef _WIN32
- if (lilv_is_directory(path)) {
- return !RemoveDirectory(path);
- }
-#endif
-
- return remove(path);
-}
-
-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_path_canonical(a_path);
- char* const b_real = lilv_path_canonical(b_path);
- 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")) ||
- !(b_file = fopen(b_real, "rb"))) {
- match = false; // Missing file matches nothing
- } else {
- // TODO: Improve performance by reading chunks
- match = true;
- 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;
-}
diff --git a/src/filesystem.h b/src/filesystem.h
deleted file mode 100644
index 1a8dc68..0000000
--- a/src/filesystem.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- Copyright 2007-2020 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 <stdbool.h>
-#include <stdio.h>
-
-/// Return the path to a directory suitable for making temporary files
-char*
-lilv_temp_directory_path(void);
-
-/// Return true iff `path` is an absolute path
-bool
-lilv_path_is_absolute(const char* path);
-
-/// Return true iff `path` is a child of `dir`
-bool
-lilv_path_is_child(const char* path, const char* dir);
-
-/// Return the current working directory
-char*
-lilv_path_current(void);
-
-/**
- Return `path` as an absolute path.
-
- If `path` is absolute, an identical copy of it is returned. Otherwise, the
- returned path is relative to the current working directory.
-*/
-char*
-lilv_path_absolute(const char* path);
-
-/**
- Return `path` as an absolute path relative to `parent`.
-
- If `path` is absolute, an identical copy of it is returned. Otherwise, the
- returned path is relative to `parent`.
-*/
-char*
-lilv_path_absolute_child(const char* path, const char* parent);
-
-/**
- Return `path` relative to `base` if possible.
-
- If `path` is not within `base`, a copy is returned. Otherwise, an
- equivalent path relative to `base` is returned (which may contain
- up-references).
-*/
-char*
-lilv_path_relative_to(const char* path, const char* base);
-
-/**
- Return the path to the directory that contains `path`.
-
- Returns the root path if `path` is the root path.
-*/
-char*
-lilv_path_parent(const char* path);
-
-/**
- Return the filename component of `path` without any directories.
-
- Returns the empty string if `path` is the root path.
-*/
-char*
-lilv_path_filename(const char* path);
-
-/// Join path `a` and path `b` with a single directory separator between them
-char*
-lilv_path_join(const char* a, const char* b);
-
-/**
- Return `path` as a canonicalized absolute path.
-
- This expands all symbolic links, relative references, and removes extra
- directory separators.
-*/
-char*
-lilv_path_canonical(const char* path);
-
-/// Return true iff `path` points to an existing file system entry
-bool
-lilv_path_exists(const char* path);
-
-/// Return true iff `path` points to an existing directory
-bool
-lilv_is_directory(const char* path);
-
-/**
- Copy the file at path `src` to path `dst`.
-
- @return Zero on success, or a standard `errno` error code.
-*/
-int
-lilv_copy_file(const char* src, const char* dst);
-
-/**
- Create a symlink at `newpath` that points to `oldpath`.
-
- @return Zero on success, otherwise non-zero and `errno` is set.
-*/
-int
-lilv_symlink(const char* oldpath, const char* newpath);
-
-/**
- Set or remove an advisory exclusive lock on `file`.
-
- If the `lock` is true and the file is already locked by another process, or
- by this process via a different file handle, then this will not succeed and
- non-zero will be returned.
-
- @param file Handle for open file to lock.
- @param lock True to set lock, false to release lock.
- @param block If true, then this call will block until the lock is acquired.
- @return Zero on success.
-*/
-int
-lilv_flock(FILE* file, bool lock, bool block);
-
-/**
- Visit every file in the directory at `path`.
-
- @param path A path to a directory.
-
- @param data Opaque user data that is passed to `f`.
-
- @param f A function called on every entry in the directory. The `path`
- parameter is always the directory path passed to this function, the `name`
- parameter is the name of the directory entry (not its full path).
-*/
-void
-lilv_dir_for_each(const char* path,
- void* data,
- void (*f)(const char* path, const char* name, void* data));
-
-/**
- Create a unique temporary directory in a specific directory.
-
- The last six characters of `pattern` must be `XXXXXX` and will be replaced
- with random characters. This works roughly like mkdtemp, except the pattern
- should only be a directory name, not a full path. The created path will be
- a child of the given parent directory.
-*/
-char*
-lilv_create_temporary_directory_in(const char* pattern, const char* parent);
-
-/**
- Create a unique temporary directory.
-
- This is like lilv_create_temporary_directory_in(), except it creates the
- directory in the system temporary directory.
-*/
-char*
-lilv_create_temporary_directory(const char* pattern);
-
-/**
- Create the directory `dir_path` and any parent directories if necessary.
-
- @return Zero on success, or an `errno` error code.
-*/
-int
-lilv_create_directories(const char* dir_path);
-
-/// Remove the file or empty directory at `path`
-int
-lilv_remove(const char* path);
-
-/// Return true iff the given paths point to files with identical contents
-bool
-lilv_file_equals(const char* a_path, const char* b_path);
diff --git a/src/instance.c b/src/instance.c
index 6a2b856..379fe24 100644
--- a/src/instance.c
+++ b/src/instance.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
diff --git a/src/lib.c b/src/lib.c
index adba732..5f7a456 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2012-2019 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.
-*/
+// Copyright 2012-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
diff --git a/src/lilv_config.h b/src/lilv_config.h
index 10231c5..2f7c498 100644
--- a/src/lilv_config.h
+++ b/src/lilv_config.h
@@ -1,102 +1,11 @@
-/*
- Copyright 2021 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.
-*/
-
-/*
- Configuration header that defines reasonable defaults at compile time.
-
- This allows compile-time configuration from the command line (typically via
- the build system) while still allowing the source to be built without any
- configuration. The build system can define LILV_NO_DEFAULT_CONFIG to disable
- defaults, in which case it must define things like HAVE_FEATURE to enable
- features. The design here ensures that compiler warnings or
- include-what-you-use will catch any mistakes.
-*/
+// Copyright 2021-2024 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#ifndef LILV_CONFIG_H
#define LILV_CONFIG_H
// Define version unconditionally so a warning will catch a mismatch
-#define LILV_VERSION "0.24.13"
-
-#if !defined(LILV_NO_DEFAULT_CONFIG)
-
-// We need unistd.h to check _POSIX_VERSION
-# ifndef LILV_NO_POSIX
-# ifdef __has_include
-# if __has_include(<unistd.h>)
-# include <unistd.h>
-# endif
-# elif defined(__unix__)
-# include <unistd.h>
-# endif
-# endif
-
-// POSIX.1-2001: fileno()
-# ifndef HAVE_FILENO
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
-# define HAVE_FILENO
-# endif
-# endif
-
-// Classic UNIX: flock()
-# ifndef HAVE_FLOCK
-# if defined(__unix__)
-# define HAVE_FLOCK
-# endif
-# endif
-
-// POSIX.1-2001: lstat()
-# ifndef HAVE_LSTAT
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
-# define HAVE_LSTAT
-# endif
-# endif
-
-#endif // !defined(LILV_NO_DEFAULT_CONFIG)
-
-/*
- Make corresponding USE_FEATURE defines based on the HAVE_FEATURE defines from
- above or the command line. The code checks for these using #if (not #ifdef),
- so there will be an undefined warning if it checks for an unknown feature,
- and this header is always required by any code that checks for features, even
- if the build system defines them all.
-*/
-
-#ifdef HAVE_FILENO
-# define USE_FILENO 1
-#else
-# define USE_FILENO 0
-#endif
-
-#ifdef HAVE_FLOCK
-# define USE_FLOCK 1
-#else
-# define USE_FLOCK 0
-#endif
-
-#ifdef HAVE_LSTAT
-# define USE_LSTAT 1
-#else
-# define USE_LSTAT 0
-#endif
-
-/*
- Define required values. These are always used as a fallback, even with
- LILV_NO_DEFAULT_CONFIG, since they must be defined for the build to work.
-*/
+#define LILV_VERSION "0.24.25"
// Separator between entries in variables like PATH
#ifndef LILV_PATH_SEP
@@ -107,21 +16,17 @@
# endif
#endif
-// Separator between directories in a path
-#ifndef LILV_DIR_SEP
-# ifdef _WIN32
-# define LILV_DIR_SEP "\\"
-# else
-# define LILV_DIR_SEP "/"
-# endif
-#endif
-
// Default value for LV2_PATH environment variable
#ifndef LILV_DEFAULT_LV2_PATH
-# ifdef _WIN32
+# if defined(__APPLE__)
+# define LILV_DEFAULT_LV2_PATH \
+ "~/.lv2:~/Library/Audio/Plug-Ins/LV2:" \
+ "/usr/local/lib/lv2:/usr/lib/lv2:" \
+ "/Library/Audio/Plug-Ins/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"
+# define LILV_DEFAULT_LV2_PATH "~/.lv2:/usr/local/lib/lv2:/usr/lib/lv2"
# endif
#endif
diff --git a/src/lilv_internal.h b/src/lilv_internal.h
index 12b56de..f1bca25 100644
--- a/src/lilv_internal.h
+++ b/src/lilv_internal.h
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#ifndef LILV_INTERNAL_H
#define LILV_INTERNAL_H
@@ -35,22 +22,14 @@ extern "C" {
#ifdef _WIN32
# include <direct.h>
-# include <stdio.h>
# include <windows.h>
# define dlopen(path, flags) LoadLibrary(path)
# define dlclose(lib) FreeLibrary((HMODULE)lib)
# ifdef _MSC_VER
-# define __func__ __FUNCTION__
# ifndef snprintf
# define snprintf _snprintf
# endif
# endif
-# ifndef INFINITY
-# define INFINITY DBL_MAX + DBL_MAX
-# endif
-# ifndef NAN
-# define NAN INFINITY - INFINITY
-# endif
static inline const char*
dlerror(void)
{
@@ -275,15 +254,6 @@ lilv_plugin_get_unique(const LilvPlugin* plugin,
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);
@@ -332,9 +302,6 @@ lilv_world_blank_node_prefix(LilvWorld* world);
SerdStatus
lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri);
-SerdStatus
-lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri);
-
LilvUI*
lilv_ui_new(LilvWorld* world,
LilvNode* uri,
@@ -354,9 +321,6 @@ int
lilv_header_compare_by_uri(const void* a, const void* b, const void* user_data);
int
-lilv_lib_compare(const void* a, const void* b, const void* user_data);
-
-int
lilv_ptr_cmp(const void* a, const void* b, const void* user_data);
int
diff --git a/src/node.c b/src/node.c
index ac47e80..a10ac86 100644
--- a/src/node.c
+++ b/src/node.c
@@ -1,25 +1,14 @@
-/*
- Copyright 2007-2019 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 "filesystem.h"
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
#include "lilv_internal.h"
#include "lilv/lilv.h"
#include "serd/serd.h"
#include "sord/sord.h"
+#include "zix/allocator.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
#include <math.h>
#include <stdbool.h>
@@ -160,13 +149,23 @@ lilv_new_uri(LilvWorld* world, const char* uri)
LilvNode*
lilv_new_file_uri(LilvWorld* world, const char* host, const char* path)
{
- char* abs_path = lilv_path_absolute(path);
- SerdNode s = serd_node_new_file_uri(
- (const uint8_t*)abs_path, (const uint8_t*)host, NULL, true);
+ SerdNode s = SERD_NODE_NULL;
+ if (zix_path_root_directory(path).length) {
+ s = serd_node_new_file_uri(
+ (const uint8_t*)path, (const uint8_t*)host, NULL, true);
+ } else {
+ char* const cwd = zix_current_path(NULL);
+ char* const abs_path = zix_path_join(NULL, cwd, path);
+
+ s = serd_node_new_file_uri(
+ (const uint8_t*)abs_path, (const uint8_t*)host, NULL, true);
+
+ zix_free(NULL, abs_path);
+ zix_free(NULL, cwd);
+ }
LilvNode* ret = lilv_node_new(world, LILV_VALUE_URI, (const char*)s.buf);
serd_node_free(&s);
- free(abs_path);
return ret;
}
diff --git a/src/plugin.c b/src/plugin.c
index 9c7cbfd..f191eda 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
@@ -580,9 +567,11 @@ lilv_plugin_get_port_ranges_float(const LilvPlugin* plugin,
}
uint32_t
-lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* plugin,
- const LilvNode* class_1,
- va_list args)
+lilv_plugin_get_num_ports_of_class_va(
+ const LilvPlugin* plugin,
+ const LilvNode* class_1,
+ va_list args // NOLINT(readability-non-const-parameter)
+)
{
lilv_plugin_load_ports_if_necessary(plugin);
@@ -624,7 +613,7 @@ lilv_plugin_get_num_ports_of_class(const LilvPlugin* plugin,
const LilvNode* class_1,
...)
{
- va_list args;
+ va_list args; // NOLINT(cppcoreguidelines-init-variables)
va_start(args, class_1);
uint32_t count = lilv_plugin_get_num_ports_of_class_va(plugin, class_1, args);
diff --git a/src/pluginclass.c b/src/pluginclass.c
index 2f0afe7..18109f3 100644
--- a/src/pluginclass.c
+++ b/src/pluginclass.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
@@ -73,8 +60,9 @@ 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);
+ LilvPluginClasses* all = plugin_class->world->plugin_classes;
+ LilvPluginClasses* result =
+ zix_tree_new(NULL, false, lilv_header_compare_by_uri, NULL, NULL, NULL);
for (ZixTreeIter* i = zix_tree_begin((ZixTree*)all);
i != zix_tree_end((ZixTree*)all);
diff --git a/src/port.c b/src/port.c
index 71edaf1..55641e7 100644
--- a/src/port.c
+++ b/src/port.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
@@ -237,11 +224,12 @@ lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port)
sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__scalePoint),
NULL);
- LilvScalePoints* ret = NULL;
- if (!sord_iter_end(points)) {
- ret = lilv_scale_points_new();
+ if (sord_iter_end(points)) {
+ return NULL;
}
+ LilvScalePoints* ret = lilv_scale_points_new();
+
FOREACH_MATCH (points) {
const SordNode* point = sord_iter_get_node(points, SORD_OBJECT);
@@ -257,7 +245,7 @@ lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port)
}
sord_iter_free(points);
- assert(!ret || lilv_nodes_size(ret) > 0);
+ assert(lilv_nodes_size(ret) > 0);
return ret;
}
diff --git a/src/query.c b/src/query.c
index eb179f2..3dd8eca 100644
--- a/src/query.c
+++ b/src/query.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
@@ -96,12 +83,7 @@ lilv_nodes_from_stream_objects_i18n(LilvWorld* world,
}
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
+ if ((syslang && partial) || !best) {
best = partial;
}
diff --git a/src/scalepoint.c b/src/scalepoint.c
index e2db948..60cc905 100644
--- a/src/scalepoint.c
+++ b/src/scalepoint.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
diff --git a/src/state.c b/src/state.c
index a4a50a9..0ed5715 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1,26 +1,17 @@
-/*
- Copyright 2007-2019 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 "filesystem.h"
+// Copyright 2007-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
#include "lilv_internal.h"
#include "lilv/lilv.h"
#include "serd/serd.h"
#include "sord/sord.h"
#include "sratom/sratom.h"
+#include "zix/allocator.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
+#include "zix/status.h"
+#include "zix/string_view.h"
#include "zix/tree.h"
#include "lv2/atom/atom.h"
@@ -120,8 +111,9 @@ value_cmp(const void* a, const void* b)
}
static void
-path_rel_free(void* ptr)
+map_free(void* ptr, const void* user_data)
{
+ (void)user_data;
free(((PathMap*)ptr)->abs);
free(((PathMap*)ptr)->rel);
free(ptr);
@@ -234,9 +226,15 @@ retrieve_callback(LV2_State_Handle handle,
const Property* const prop = find_property((const LilvState*)handle, key);
if (prop) {
- *size = prop->size;
- *type = prop->type;
- *flags = prop->flags;
+ if (size) {
+ *size = prop->size;
+ }
+ if (type) {
+ *type = prop->type;
+ }
+ if (flags) {
+ *flags = prop->flags;
+ }
return prop->value;
}
return NULL;
@@ -247,7 +245,7 @@ path_exists(const char* path, const void* ignored)
{
(void)ignored;
- return lilv_path_exists(path);
+ return zix_file_type(path) != ZIX_FILE_TYPE_NONE;
}
static bool
@@ -260,19 +258,34 @@ static char*
make_path(LV2_State_Make_Path_Handle handle, const char* path)
{
LilvState* state = (LilvState*)handle;
- lilv_create_directories(state->dir);
+ zix_create_directories(NULL, state->dir);
- return lilv_path_join(state->dir, path);
+ return zix_path_join(NULL, state->dir, path);
+}
+
+static bool
+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;
}
static char*
abstract_path(LV2_State_Map_Path_Handle handle, const char* abs_path)
{
- LilvState* state = (LilvState*)handle;
- char* path = NULL;
- char* real_path = lilv_path_canonical(abs_path);
- const PathMap key = {real_path, NULL};
- ZixTreeIter* iter = NULL;
+ LilvState* state = (LilvState*)handle;
+ char* path = NULL;
+ char* real_path = zix_canonical_path(NULL, abs_path);
+ if (!real_path) {
+ real_path = zix_path_lexically_normal(NULL, abs_path);
+ }
+
+ const PathMap key = {real_path, NULL};
+ ZixTreeIter* iter = NULL;
if (abs_path[0] == '\0') {
return lilv_strdup(abs_path);
@@ -281,47 +294,47 @@ abstract_path(LV2_State_Map_Path_Handle handle, const char* abs_path)
if (!zix_tree_find(state->abs2rel, &key, &iter)) {
// Already mapped path in a previous call
PathMap* pm = (PathMap*)zix_tree_get(iter);
- free(real_path);
+ zix_free(NULL, real_path);
return lilv_strdup(pm->rel);
}
- if (lilv_path_is_child(real_path, state->dir)) {
+ if (path_is_child(real_path, state->dir)) {
// File in state directory (loaded, or created by plugin during save)
- path = lilv_path_relative_to(real_path, state->dir);
- } else if (lilv_path_is_child(real_path, state->scratch_dir)) {
+ path = zix_path_lexically_relative(NULL, real_path, state->dir);
+ } else if (path_is_child(real_path, state->scratch_dir)) {
// File created by plugin earlier
- path = lilv_path_relative_to(real_path, state->scratch_dir);
+ path = zix_path_lexically_relative(NULL, real_path, state->scratch_dir);
if (state->copy_dir) {
- int st = lilv_create_directories(state->copy_dir);
+ ZixStatus st = zix_create_directories(NULL, state->copy_dir);
if (st) {
- LILV_ERRORF(
- "Error creating directory %s (%s)\n", state->copy_dir, strerror(st));
+ LILV_ERRORF("Error creating directory %s (%s)\n",
+ state->copy_dir,
+ zix_strerror(st));
}
- char* cpath = lilv_path_join(state->copy_dir, path);
+ char* cpath = zix_path_join(NULL, state->copy_dir, path);
char* copy = lilv_get_latest_copy(real_path, cpath);
- if (!copy || !lilv_file_equals(real_path, copy)) {
+ if (!copy || !zix_file_equals(NULL, real_path, copy)) {
// No recent enough copy, make a new one
free(copy);
copy = lilv_find_free_path(cpath, path_exists, NULL);
- if ((st = lilv_copy_file(real_path, copy))) {
- LILV_ERRORF("Error copying state file %s (%s)\n", copy, strerror(st));
+ if ((st = zix_copy_file(NULL, real_path, copy, 0U))) {
+ LILV_ERRORF(
+ "Error copying state file %s (%s)\n", copy, zix_strerror(st));
}
}
- free(real_path);
- free(cpath);
+ zix_free(NULL, real_path);
+ zix_free(NULL, cpath);
// Refer to the latest copy in plugin state
real_path = copy;
}
} else if (state->link_dir) {
// New path outside state directory, make a link
- char* const name = lilv_path_filename(real_path);
+ const ZixStringView name = zix_path_filename(real_path);
// Find a free name in the (virtual) state directory
- path = lilv_find_free_path(name, lilv_state_has_path, state);
-
- free(name);
+ path = lilv_find_free_path(name.data, lilv_state_has_path, state);
} else {
// No link directory, preserve absolute path
path = lilv_strdup(abs_path);
@@ -342,12 +355,12 @@ absolute_path(LV2_State_Map_Path_Handle handle, const char* state_path)
{
LilvState* state = (LilvState*)handle;
char* path = NULL;
- if (lilv_path_is_absolute(state_path)) {
+ if (zix_path_is_absolute(state_path)) {
// Absolute path, return identical path
path = lilv_strdup(state_path);
} else if (state->dir) {
// Relative path inside state directory
- path = lilv_path_join(state->dir, state_path);
+ path = zix_path_join(NULL, state->dir, state_path);
} else {
// State has not been saved, unmap
path = lilv_strdup(lilv_state_rel2abs(state, state_path));
@@ -365,6 +378,15 @@ add_features(const LV2_Feature* const* features,
{
size_t n_features = 0;
for (; features && features[n_features]; ++n_features) {
+ if (!strcmp(features[n_features]->URI, LV2_STATE__mapPath)) {
+ map = NULL;
+ }
+ if (!strcmp(features[n_features]->URI, LV2_STATE__makePath)) {
+ make = NULL;
+ }
+ if (!strcmp(features[n_features]->URI, LV2_STATE__freePath)) {
+ free = NULL;
+ }
}
const LV2_Feature** ret =
@@ -388,14 +410,15 @@ add_features(const LV2_Feature* const* features,
return ret;
}
-/// Return the canonical path for a directory with a trailing separator
+/// Return a normal path for a directory with a trailing separator
static char*
-real_dir(const char* path)
+normal_dir(const char* path)
{
- char* abs_path = lilv_path_canonical(path);
- char* base = lilv_path_join(abs_path, NULL);
- free(abs_path);
- return base;
+ char* const normal_path = zix_path_lexically_normal(NULL, path);
+ char* const base_path = zix_path_join(NULL, normal_path, NULL);
+
+ zix_free(NULL, normal_path);
+ return base_path;
}
static const char*
@@ -442,12 +465,12 @@ lilv_state_new_from_instance(const LilvPlugin* plugin,
LilvWorld* const world = plugin->world;
LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState));
state->plugin_uri = lilv_node_duplicate(lilv_plugin_get_uri(plugin));
- state->abs2rel = zix_tree_new(false, abs_cmp, NULL, path_rel_free);
- state->rel2abs = zix_tree_new(false, rel_cmp, NULL, NULL);
- state->scratch_dir = scratch_dir ? real_dir(scratch_dir) : NULL;
- state->copy_dir = copy_dir ? real_dir(copy_dir) : NULL;
- state->link_dir = link_dir ? real_dir(link_dir) : NULL;
- state->dir = save_dir ? real_dir(save_dir) : NULL;
+ state->abs2rel = zix_tree_new(NULL, false, abs_cmp, NULL, map_free, NULL);
+ state->rel2abs = zix_tree_new(NULL, false, rel_cmp, NULL, NULL, NULL);
+ state->scratch_dir = scratch_dir ? normal_dir(scratch_dir) : NULL;
+ state->copy_dir = copy_dir ? normal_dir(copy_dir) : NULL;
+ state->link_dir = link_dir ? normal_dir(link_dir) : NULL;
+ state->dir = save_dir ? normal_dir(save_dir) : NULL;
state->atom_Path = map->map(map->handle, LV2_ATOM__Path);
LV2_State_Map_Path pmap = {state, abstract_path, absolute_path};
@@ -571,10 +594,10 @@ set_state_dir_from_model(LilvState* state, const SordNode* graph)
const char* uri = (const char*)sord_node_get_string(graph);
char* path = lilv_file_uri_parse(uri, NULL);
- state->dir = lilv_path_join(path, NULL);
+ state->dir = zix_path_join(NULL, path, NULL);
free(path);
}
- assert(!state->dir || lilv_path_is_absolute(state->dir));
+ assert(!state->dir || zix_path_is_absolute(state->dir));
}
static LilvState*
@@ -591,7 +614,7 @@ new_state_from_model(LilvWorld* world,
// Allocate state
LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState));
- state->dir = lilv_path_join(dir, NULL);
+ state->dir = dir ? zix_path_join(NULL, dir, NULL) : NULL;
state->atom_Path = map->map(map->handle, LV2_ATOM__Path);
state->uri = lilv_node_new_from_node(world, node);
@@ -742,29 +765,34 @@ lilv_state_new_from_file(LilvWorld* world,
return NULL;
}
- uint8_t* abs_path = (uint8_t*)lilv_path_absolute(path);
- SerdNode node = serd_node_new_file_uri(abs_path, NULL, NULL, true);
- SerdEnv* env = serd_env_new(&node);
- SordModel* model = sord_new(world->world, SORD_SPO, false);
- SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL);
+ uint8_t* const abs_path = (uint8_t*)zix_canonical_path(NULL, path);
+ if (!abs_path) {
+ return NULL;
+ }
+
+ SerdNode node = serd_node_new_file_uri(abs_path, NULL, NULL, true);
+ SerdEnv* env = serd_env_new(&node);
+ SordModel* model = sord_new(world->world, SORD_SPO, false);
+ SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL);
- serd_reader_read_file(reader, node.buf);
+ serd_reader_read_file(reader, (const uint8_t*)node.buf);
SordNode* subject_node =
(subject) ? subject->node
: sord_node_from_serd_node(world->world, env, &node, NULL, NULL);
- char* dirname = lilv_path_parent(path);
- char* real_path = lilv_path_canonical(dirname);
- char* dir_path = lilv_path_join(real_path, NULL);
- LilvState* state =
+ const ZixStringView dirname = zix_path_parent_path(path);
+ char* const real_path = zix_canonical_path(NULL, dirname.data);
+ char* const dir_path = zix_path_join(NULL, real_path, NULL);
+
+ LilvState* const state =
new_state_from_model(world, map, model, subject_node, dir_path);
- free(dir_path);
- free(real_path);
- free(dirname);
+
+ zix_free(NULL, dir_path);
+ zix_free(NULL, real_path);
serd_node_free(&node);
- free(abs_path);
+ zix_free(NULL, abs_path);
serd_reader_free(reader);
sord_free(model);
serd_env_free(env);
@@ -818,7 +846,7 @@ ttl_writer(SerdSink sink, void* stream, const SerdNode* base, SerdEnv** new_env)
{
SerdURI base_uri = SERD_URI_NULL;
if (base && base->buf) {
- serd_uri_parse(base->buf, &base_uri);
+ serd_uri_parse((const uint8_t*)base->buf, &base_uri);
}
SerdEnv* env = *new_env ? *new_env : serd_env_new(base);
@@ -895,11 +923,12 @@ write_manifest(LilvWorld* world,
{
(void)world;
- char* const path = (char*)serd_file_uri_parse(file_uri->buf, NULL);
- FILE* const wfd = fopen(path, "w");
+ char* const path =
+ (char*)serd_file_uri_parse((const uint8_t*)file_uri->buf, NULL);
+
+ FILE* const wfd = path ? fopen(path, "w") : NULL;
if (!wfd) {
LILV_ERRORF("Failed to open %s for writing (%s)\n", path, strerror(errno));
-
serd_free(path);
return 1;
}
@@ -925,10 +954,11 @@ add_state_to_manifest(LilvWorld* lworld,
SerdEnv* env = serd_env_new(&manifest);
SordModel* model = sord_new(world, SORD_SPO, false);
- if (lilv_path_exists(manifest_path)) {
+ const uint8_t* const manifest_uri = manifest.buf;
+ if (manifest_uri && zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR) {
// Read manifest into model
SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL);
- SerdStatus st = serd_reader_read_file(reader, manifest.buf);
+ SerdStatus st = serd_reader_read_file(reader, manifest_uri);
if (st) {
LILV_WARNF("Failed to read manifest (%s)\n", serd_strerror(st));
}
@@ -988,15 +1018,15 @@ add_state_to_manifest(LilvWorld* lworld,
LILV_ERRORF(
"Failed to open %s for writing (%s)\n", manifest_path, strerror(errno));
r = 1;
+ } else {
+ SerdWriter* writer = ttl_file_writer(wfd, &manifest, &env);
+ zix_file_lock(wfd, ZIX_FILE_LOCK_BLOCK);
+ sord_write(model, writer, NULL);
+ zix_file_unlock(wfd, ZIX_FILE_LOCK_BLOCK);
+ serd_writer_free(writer);
+ fclose(wfd);
}
- SerdWriter* writer = ttl_file_writer(wfd, &manifest, &env);
- lilv_flock(wfd, true, true);
- sord_write(model, writer, NULL);
- lilv_flock(wfd, false, true);
- serd_writer_free(writer);
- fclose(wfd);
-
sord_free(model);
serd_node_free(&file);
serd_node_free(&manifest);
@@ -1009,31 +1039,44 @@ static bool
link_exists(const char* path, const void* data)
{
const char* target = (const char*)data;
- if (!lilv_path_exists(path)) {
+ if (zix_file_type(path) == ZIX_FILE_TYPE_NONE) {
return false;
}
- char* real_path = lilv_path_canonical(path);
- bool matches = !strcmp(real_path, target);
- free(real_path);
+
+ char* const real_path = zix_canonical_path(NULL, path);
+ const bool matches = real_path && !strcmp(real_path, target);
+ zix_free(NULL, real_path);
return !matches;
}
-static int
-maybe_symlink(const char* oldpath, const char* newpath)
+static ZixStatus
+create_link(const char* oldpath, const char* newpath)
{
- if (link_exists(newpath, oldpath)) {
- return 0;
- }
+ const ZixStringView parent_path = zix_path_parent_path(newpath);
+ char* const parent = zix_string_view_copy(NULL, parent_path);
- const int st = lilv_symlink(oldpath, newpath);
- if (st) {
- LILV_ERRORF(
- "Failed to link %s => %s (%s)\n", newpath, oldpath, strerror(errno));
+ char* const relpath = zix_path_lexically_relative(NULL, oldpath, parent);
+
+ ZixStatus st = ZIX_STATUS_SUCCESS;
+ if ((st = zix_create_symlink(relpath, newpath))) {
+ if ((st = zix_create_hard_link(oldpath, newpath))) {
+ LILV_ERRORF(
+ "Failed to link %s => %s (%s)\n", newpath, oldpath, zix_strerror(st));
+ }
}
+ zix_free(NULL, relpath);
+ zix_free(NULL, parent);
return st;
}
+static ZixStatus
+maybe_symlink(const char* oldpath, const char* newpath)
+{
+ return link_exists(newpath, oldpath) ? ZIX_STATUS_SUCCESS
+ : create_link(oldpath, newpath);
+}
+
static void
write_property_array(const LilvState* state,
const PropertyArray* array,
@@ -1178,16 +1221,17 @@ lilv_state_make_links(const LilvState* state, const char* dir)
for (ZixTreeIter* i = zix_tree_begin(state->abs2rel);
i != zix_tree_end(state->abs2rel);
i = zix_tree_iter_next(i)) {
- const PathMap* pm = (const PathMap*)zix_tree_get(i);
+ const PathMap* const pm = (const PathMap*)zix_tree_get(i);
+ char* const path = zix_path_join(NULL, dir, pm->rel);
- char* path = lilv_path_absolute_child(pm->rel, dir);
- if (lilv_path_is_child(pm->abs, state->copy_dir) &&
- strcmp(state->copy_dir, dir)) {
+ if (state->copy_dir && path_is_child(pm->abs, state->copy_dir) &&
+ !!strcmp(state->copy_dir, dir)) {
// Link directly to snapshot in the copy directory
maybe_symlink(pm->abs, path);
- } else if (!lilv_path_is_child(pm->abs, dir)) {
+ } else if (!path_is_child(pm->abs, dir)) {
const char* link_dir = state->link_dir ? state->link_dir : dir;
- char* pat = lilv_path_absolute_child(pm->rel, link_dir);
+ char* pat = zix_path_join(NULL, link_dir, pm->rel);
+
if (!strcmp(dir, link_dir)) {
// Link directory is save directory, make link at exact path
remove(pat);
@@ -1195,17 +1239,18 @@ lilv_state_make_links(const LilvState* state, const char* dir)
} else {
// Make a link in the link directory to external file
char* lpath = lilv_find_free_path(pat, link_exists, pm->abs);
- if (!lilv_path_exists(lpath)) {
- if (lilv_symlink(pm->abs, lpath)) {
+ if (zix_file_type(lpath) == ZIX_FILE_TYPE_NONE) {
+ const ZixStatus st = create_link(pm->abs, lpath);
+ if (st) {
LILV_ERRORF("Failed to link %s => %s (%s)\n",
pm->abs,
lpath,
- strerror(errno));
+ zix_strerror(st));
}
}
// Make a link in the save directory to the external link
- char* target = lilv_path_relative_to(lpath, dir);
+ char* target = zix_path_lexically_relative(NULL, lpath, dir);
maybe_symlink(lpath, path);
free(target);
free(lpath);
@@ -1225,17 +1270,21 @@ lilv_state_save(LilvWorld* world,
const char* dir,
const char* filename)
{
- if (!filename || !dir || lilv_create_directories(dir)) {
+ if (!filename || !dir || zix_create_directories(NULL, dir)) {
return 1;
}
- char* abs_dir = real_dir(dir);
- char* const path = lilv_path_join(abs_dir, filename);
- FILE* fd = fopen(path, "w");
+ char* const abs_dir = zix_canonical_path(NULL, dir);
+ if (!abs_dir) {
+ return 2;
+ }
+
+ char* const path = zix_path_join(NULL, abs_dir, filename);
+ FILE* fd = path ? fopen(path, "w") : NULL;
if (!fd) {
LILV_ERRORF("Failed to open %s (%s)\n", path, strerror(errno));
- free(abs_dir);
- free(path);
+ zix_free(NULL, abs_dir);
+ zix_free(NULL, path);
return 4;
}
@@ -1251,9 +1300,9 @@ lilv_state_save(LilvWorld* world,
lilv_state_write(world, map, unmap, state, ttl, (const char*)node.buf, dir);
// Set saved dir and uri (FIXME: const violation)
- free(state->dir);
+ zix_free(NULL, state->dir);
lilv_node_free(state->uri);
- ((LilvState*)state)->dir = lilv_strdup(abs_dir);
+ ((LilvState*)state)->dir = zix_path_join(NULL, abs_dir, "");
((LilvState*)state)->uri = lilv_new_uri(world, (const char*)node.buf);
serd_node_free(&file);
@@ -1263,15 +1312,15 @@ lilv_state_save(LilvWorld* world,
// Add entry to manifest
if (!ret) {
- char* const manifest = lilv_path_join(abs_dir, "manifest.ttl");
+ char* const manifest = zix_path_join(NULL, abs_dir, "manifest.ttl");
ret = add_state_to_manifest(world, state->plugin_uri, manifest, uri, path);
- free(manifest);
+ zix_free(NULL, manifest);
}
- free(abs_dir);
- free(path);
+ zix_free(NULL, abs_dir);
+ zix_free(NULL, path);
return ret;
}
@@ -1307,7 +1356,7 @@ static void
try_unlink(const char* state_dir, const char* path)
{
if (!strncmp(state_dir, path, strlen(state_dir))) {
- if (lilv_path_exists(path) && lilv_remove(path)) {
+ if (zix_file_type(path) != ZIX_FILE_TYPE_NONE && zix_remove(path)) {
LILV_ERRORF("Failed to remove %s (%s)\n", path, strerror(errno));
}
}
@@ -1317,7 +1366,7 @@ static char*
get_canonical_path(const LilvNode* const node)
{
char* const path = lilv_node_get_path(node, NULL);
- char* const real_path = lilv_path_canonical(path);
+ char* const real_path = zix_canonical_path(NULL, path);
free(path);
return real_path;
@@ -1334,8 +1383,10 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
LilvNode* bundle = lilv_new_file_uri(world, NULL, state->dir);
LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle);
char* manifest_path = get_canonical_path(manifest);
- const bool has_manifest = lilv_path_exists(manifest_path);
- SordModel* model = sord_new(world->world, SORD_SPO, false);
+ const bool has_manifest =
+ manifest_path && zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR;
+
+ SordModel* model = sord_new(world->world, SORD_SPO, false);
if (has_manifest) {
// Read manifest into temporary local model
@@ -1353,11 +1404,11 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
// Remove state file
const uint8_t* uri = sord_node_get_string(file);
char* path = (char*)serd_file_uri_parse(uri, NULL);
- char* real_path = lilv_path_canonical(path);
- if (path) {
+ char* real_path = zix_canonical_path(NULL, path);
+ if (real_path) {
try_unlink(state->dir, real_path);
}
- serd_free(real_path);
+ zix_free(NULL, real_path);
serd_free(path);
}
@@ -1383,9 +1434,9 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
i != zix_tree_end(state->abs2rel);
i = zix_tree_iter_next(i)) {
const PathMap* pm = (const PathMap*)zix_tree_get(i);
- char* path = lilv_path_join(state->dir, pm->rel);
+ char* path = zix_path_join(NULL, state->dir, pm->rel);
try_unlink(state->dir, path);
- free(path);
+ zix_free(NULL, path);
}
} else {
// State loaded from model, get paths from loaded properties
@@ -1397,7 +1448,7 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
}
}
- if (lilv_remove(state->dir)) {
+ if (zix_remove(state->dir)) {
LILV_ERRORF(
"Failed to remove directory %s (%s)\n", state->dir, strerror(errno));
}
@@ -1412,7 +1463,7 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
}
sord_free(model);
- lilv_free(manifest_path);
+ zix_free(NULL, manifest_path);
lilv_node_free(manifest);
lilv_node_free(bundle);
@@ -1460,7 +1511,7 @@ lilv_state_equals(const LilvState* a, const LilvState* b)
{
if (!lilv_node_equals(a->plugin_uri, b->plugin_uri) ||
(a->label && !b->label) || (b->label && !a->label) ||
- (a->label && b->label && strcmp(a->label, b->label)) ||
+ (a->label && b->label && !!strcmp(a->label, b->label)) ||
a->props.n != b->props.n || a->n_values != b->n_values) {
return false;
}
@@ -1469,8 +1520,8 @@ lilv_state_equals(const LilvState* a, const LilvState* b)
PortValue* const av = &a->values[i];
PortValue* const bv = &b->values[i];
if (av->atom->size != bv->atom->size || av->atom->type != bv->atom->type ||
- strcmp(av->symbol, bv->symbol) ||
- memcmp(av->atom + 1, bv->atom + 1, av->atom->size)) {
+ !!strcmp(av->symbol, bv->symbol) ||
+ !!memcmp(av->atom + 1, bv->atom + 1, av->atom->size)) {
return false;
}
}
@@ -1483,11 +1534,13 @@ lilv_state_equals(const LilvState* a, const LilvState* b)
}
if (ap->type == a->atom_Path) {
- if (!lilv_file_equals(lilv_state_rel2abs(a, (char*)ap->value),
- lilv_state_rel2abs(b, (char*)bp->value))) {
+ if (!zix_file_equals(NULL,
+ lilv_state_rel2abs(a, (char*)ap->value),
+ lilv_state_rel2abs(b, (char*)bp->value))) {
return false;
}
- } else if (ap->size != bp->size || memcmp(ap->value, bp->value, ap->size)) {
+ } else if (ap->size != bp->size ||
+ !!memcmp(ap->value, bp->value, ap->size)) {
return false;
}
}
diff --git a/src/ui.c b/src/ui.c
index 84f8cef..2be49ec 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
diff --git a/src/util.c b/src/util.c
index 92f72b9..c0047d9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,37 +1,26 @@
-/*
- Copyright 2007-2019 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 "filesystem.h"
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
#include "lilv_internal.h"
#include "lilv/lilv.h"
#include "serd/serd.h"
+#include "zix/allocator.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
+#include "zix/string_view.h"
#include <sys/stat.h>
-#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
-#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h> // IWYU pragma: keep
void
lilv_free(void* ptr)
@@ -47,7 +36,7 @@ lilv_strjoin(const char* first, ...)
memcpy(result, first, len);
- va_list args;
+ va_list args; // NOLINT(cppcoreguidelines-init-variables)
va_start(args, first);
while (1) {
const char* const s = va_arg(args, const char*);
@@ -127,10 +116,9 @@ lilv_get_lang(void)
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] >= 'a' && env_lang[i] <= 'z') ||
+ (env_lang[i] >= '0' && env_lang[i] <= '9')) {
+ lang[i] = env_lang[i]; // Lowercase letter or 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';
@@ -231,7 +219,7 @@ lilv_find_free_path(const char* in_path,
char* path = (char*)malloc(in_path_len + 7);
memcpy(path, in_path, in_path_len + 1);
- for (unsigned i = 2; i < 1000000u; ++i) {
+ for (unsigned i = 2U; i < 1000000U; ++i) {
if (!exists(path, user_data)) {
return path;
}
@@ -251,13 +239,13 @@ static void
update_latest(const char* path, const char* name, void* data)
{
Latest* latest = (Latest*)data;
- char* entry_path = lilv_path_join(path, name);
+ char* entry_path = zix_path_join(NULL, path, name);
unsigned num = 0;
if (sscanf(entry_path, latest->pattern, &num) == 1) {
struct stat st;
if (!stat(entry_path, &st)) {
if (st.st_mtime >= latest->time) {
- free(latest->latest);
+ zix_free(NULL, latest->latest);
latest->latest = entry_path;
}
} else {
@@ -265,7 +253,7 @@ update_latest(const char* path, const char* name, void* data)
}
}
if (entry_path != latest->latest) {
- free(entry_path);
+ zix_free(NULL, entry_path);
}
}
@@ -273,8 +261,9 @@ update_latest(const char* path, const char* name, void* data)
char*
lilv_get_latest_copy(const char* path, const char* copy_path)
{
- char* copy_dir = lilv_path_parent(copy_path);
- Latest latest = {lilv_strjoin(copy_path, ".%u", NULL), 0, NULL};
+ char* copy_dir = zix_string_view_copy(NULL, zix_path_parent_path(copy_path));
+
+ Latest latest = {lilv_strjoin(copy_path, ".%u", NULL), 0, NULL};
struct stat st;
if (!stat(path, &st)) {
@@ -283,9 +272,9 @@ lilv_get_latest_copy(const char* path, const char* copy_path)
LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno));
}
- lilv_dir_for_each(copy_dir, &latest, update_latest);
+ zix_dir_for_each(copy_dir, &latest, update_latest);
free(latest.pattern);
- free(copy_dir);
+ zix_free(NULL, copy_dir);
return latest.latest;
}
diff --git a/src/world.c b/src/world.c
index 47dc147..b0ef24d 100644
--- a/src/world.c
+++ b/src/world.c
@@ -1,27 +1,13 @@
-/*
- Copyright 2007-2019 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 "filesystem.h"
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
#include "lilv_config.h" // IWYU pragma: keep
#include "lilv_internal.h"
#include "lilv/lilv.h"
#include "serd/serd.h"
#include "sord/sord.h"
-#include "zix/common.h"
+#include "zix/filesystem.h"
#include "zix/tree.h"
#include "lv2/core/lv2.h"
@@ -29,7 +15,6 @@
#ifdef LILV_DYN_MANIFEST
# include "lv2/dynmanifest/dynmanifest.h"
-# include <dlfcn.h>
#endif
#include <assert.h>
@@ -42,6 +27,16 @@
static int
lilv_world_drop_graph(LilvWorld* world, const SordNode* graph);
+static int
+lilv_lib_compare(const void* a, const void* b, const void* user_data);
+
+static void
+destroy_node(void* const ptr, const void* const user_data)
+{
+ (void)user_data;
+ lilv_node_free((LilvNode*)ptr);
+}
+
LilvWorld*
lilv_world_new(void)
{
@@ -61,10 +56,11 @@ lilv_world_new(void)
world->plugin_classes = lilv_plugin_classes_new();
world->plugins = lilv_plugins_new();
world->zombies = lilv_plugins_new();
- world->loaded_files = zix_tree_new(
- false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free);
- world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL);
+ world->loaded_files =
+ zix_tree_new(NULL, false, lilv_resource_node_cmp, NULL, destroy_node, NULL);
+
+ world->libs = zix_tree_new(NULL, false, lilv_lib_compare, NULL, NULL, NULL);
#define NS_DCTERMS "http://purl.org/dc/terms/"
#define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#"
@@ -337,15 +333,6 @@ lilv_world_find_nodes_internal(LilvWorld* world,
(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;
- serd_uri_parse(base_uri_str, &base_uri);
- return serd_node_new_uri_from_string(uri_str, &base_uri, NULL);
-}
-
const uint8_t*
lilv_world_blank_node_prefix(LilvWorld* world)
{
@@ -374,7 +361,7 @@ lilv_header_compare_by_uri(const void* a, const void* b, const void* user_data)
handle the case where the same library is loaded with different bundles, and
consequently different contents (mainly plugins).
*/
-int
+static int
lilv_lib_compare(const void* a, const void* b, const void* user_data)
{
(void)user_data;
@@ -506,7 +493,7 @@ lilv_world_add_plugin(LilvWorld* world,
sord_iter_free(files);
}
-SerdStatus
+static SerdStatus
lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri)
{
const SerdNode* base = sord_node_to_serd_node(uri->node);
@@ -674,10 +661,24 @@ lilv_dynmanifest_free(LilvDynManifest* dynmanifest)
LilvNode*
lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri)
{
- SerdNode manifest_uri = lilv_new_uri_relative_to_base(
- (const uint8_t*)"manifest.ttl", sord_node_get_string(bundle_uri->node));
- LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf);
- serd_node_free(&manifest_uri);
+ // Get the string and length of the given bundle URI
+ size_t bundle_uri_length = 0U;
+ const char* const bundle_uri_string =
+ (const char*)sord_node_get_string_counted(bundle_uri->node,
+ &bundle_uri_length);
+ if (!bundle_uri_length) {
+ return NULL;
+ }
+
+ // Build the manifest URI by inserting a separating "/" if necessary
+ const char last = bundle_uri_string[bundle_uri_length - 1U];
+ char* const manifest_uri_string =
+ (last == '/') ? lilv_strjoin(bundle_uri_string, "manifest.ttl", NULL)
+ : lilv_strjoin(bundle_uri_string, "/", "manifest.ttl", NULL);
+
+ // Make a node from the manifeset URI to return
+ LilvNode* const manifest = lilv_new_uri(world, manifest_uri_string);
+ free(manifest_uri_string);
return manifest;
}
@@ -749,6 +750,9 @@ lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri)
SordNode* bundle_node = bundle_uri->node;
LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri);
+ if (!manifest) {
+ return;
+ }
// Read manifest into model with graph = bundle_node
SerdStatus st = lilv_world_load_graph(world, bundle_node, manifest);
@@ -928,7 +932,7 @@ lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri)
still be used.
*/
ZixTreeIter* i = zix_tree_begin((ZixTree*)world->plugins);
- while (i != zix_tree_end((ZixTree*)world->plugins)) {
+ while (i && i != zix_tree_end((ZixTree*)world->plugins)) {
LilvPlugin* p = (LilvPlugin*)zix_tree_get(i);
ZixTreeIter* next = zix_tree_iter_next(i);
@@ -964,7 +968,7 @@ lilv_world_load_directory(LilvWorld* world, const char* dir_path)
{
char* path = lilv_expand(dir_path);
if (path) {
- lilv_dir_for_each(path, world, load_dir_entry);
+ zix_dir_for_each(path, world, load_dir_entry);
free(path);
}
}
@@ -1100,11 +1104,11 @@ lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri)
size_t uri_len = 0;
const uint8_t* const uri_str =
sord_node_get_string_counted(uri->node, &uri_len);
- if (strncmp((const char*)uri_str, "file:", 5)) {
+ if (!!strncmp((const char*)uri_str, "file:", 5)) {
return SERD_FAILURE; // Not a local file
}
- if (strcmp((const char*)uri_str + uri_len - 4, ".ttl")) {
+ if (!!strcmp((const char*)uri_str + uri_len - 4, ".ttl")) {
return SERD_FAILURE; // Not a Turtle file
}
diff --git a/src/zix/common.h b/src/zix/common.h
deleted file mode 100644
index d47586c..0000000
--- a/src/zix/common.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- Copyright 2016-2020 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.
-*/
-
-#ifndef ZIX_COMMON_H
-#define ZIX_COMMON_H
-
-#include <stdbool.h>
-
-/**
- @addtogroup zix
- @{
-*/
-
-/** @cond */
-#if defined(_WIN32) && !defined(ZIX_STATIC) && defined(ZIX_INTERNAL)
-# define ZIX_API __declspec(dllexport)
-#elif defined(_WIN32) && !defined(ZIX_STATIC)
-# define ZIX_API __declspec(dllimport)
-#elif defined(__GNUC__)
-# define ZIX_API __attribute__((visibility("default")))
-#else
-# define ZIX_API
-#endif
-
-#ifdef __GNUC__
-# define ZIX_PURE_FUNC __attribute__((pure))
-# define ZIX_CONST_FUNC __attribute__((const))
-# define ZIX_MALLOC_FUNC __attribute__((malloc))
-#else
-# define ZIX_PURE_FUNC
-# define ZIX_CONST_FUNC
-# define ZIX_MALLOC_FUNC
-#endif
-
-#define ZIX_PURE_API \
- ZIX_API \
- ZIX_PURE_FUNC
-
-#define ZIX_CONST_API \
- ZIX_API \
- ZIX_CONST_FUNC
-
-#define ZIX_MALLOC_API \
- ZIX_API \
- ZIX_MALLOC_FUNC
-
-/** @endcond */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __GNUC__
-# define ZIX_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1)))
-#else
-# define ZIX_LOG_FUNC(fmt, arg1)
-#endif
-
-// Unused parameter macro to suppresses warnings and make it impossible to use
-#if defined(__cplusplus)
-# define ZIX_UNUSED(name)
-#elif defined(__GNUC__)
-# define ZIX_UNUSED(name) name##_unused __attribute__((__unused__))
-#else
-# define ZIX_UNUSED(name) name
-#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;
-
-static inline const char*
-zix_strerror(const ZixStatus status)
-{
- switch (status) {
- case ZIX_STATUS_SUCCESS:
- return "Success";
- case ZIX_STATUS_ERROR:
- return "Unknown error";
- case ZIX_STATUS_NO_MEM:
- return "Out of memory";
- case ZIX_STATUS_NOT_FOUND:
- return "Not found";
- case ZIX_STATUS_EXISTS:
- return "Exists";
- case ZIX_STATUS_BAD_ARG:
- return "Bad argument";
- case ZIX_STATUS_BAD_PERMS:
- return "Bad permissions";
- }
- return "Unknown error";
-}
-
-/**
- Function for comparing two elements.
-*/
-typedef int (*ZixComparator)(const void* a,
- const void* b,
- const 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 */
diff --git a/src/zix/tree.c b/src/zix/tree.c
deleted file mode 100644
index 9faf13c..0000000
--- a/src/zix/tree.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- Copyright 2011-2020 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 "zix/tree.h"
-
-#include "zix/common.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.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 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
-
-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;
-}
-
-static 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);
- }
-}
-
-void
-zix_tree_free(ZixTree* t)
-{
- if (t) {
- zix_tree_free_rec(t, t->root);
- free(t);
- }
-}
-
-size_t
-zix_tree_size(const ZixTree* t)
-{
- return t->size;
-}
-
-static 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 `p`.
- *
- * p q
- * / \ / \
- * A q => p C
- * / \ / \
- * B C A B
- */
-static 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 `p`.
- *
- * p q
- * / \ / \
- * q C => A p
- * / \ / \
- * A B B C
- *
- */
-static 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 `p->left` then right about `p`.
- *
- * p r
- * / \ / \
- * q D => q p
- * / \ / \ / \
- * A r A B C D
- * / \
- * B C
- *
- */
-static 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 `p->right` then right about `p`.
- *
- * p r
- * / \ / \
- * A q => p q
- * / \ / \ / \
- * r D A B C D
- * / \
- * B C
- *
- */
-static 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;
-}
-
-static 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;
-}
-
-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 || 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;
-}
-
-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
- int 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;
-}
-
-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;
- }
-
- if (cmp < 0) {
- n = n->left;
- } else {
- n = n->right;
- }
- }
-
- *ti = n;
- return (n) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_NOT_FOUND;
-}
-
-void*
-zix_tree_get(const ZixTreeIter* ti)
-{
- return ti ? ti->data : NULL;
-}
-
-ZixTreeIter*
-zix_tree_begin(ZixTree* t)
-{
- if (!t->root) {
- return NULL;
- }
-
- ZixTreeNode* n = t->root;
- while (n->left) {
- n = n->left;
- }
-
- return n;
-}
-
-ZixTreeIter*
-zix_tree_end(ZixTree* ZIX_UNUSED(t))
-{
- return NULL;
-}
-
-ZixTreeIter*
-zix_tree_rbegin(ZixTree* t)
-{
- if (!t->root) {
- return NULL;
- }
-
- ZixTreeNode* n = t->root;
- while (n->right) {
- n = n->right;
- }
-
- return n;
-}
-
-ZixTreeIter*
-zix_tree_rend(ZixTree* ZIX_UNUSED(t))
-{
- return NULL;
-}
-
-bool
-zix_tree_iter_is_end(const ZixTreeIter* i)
-{
- return !i;
-}
-
-bool
-zix_tree_iter_is_rend(const ZixTreeIter* i)
-{
- return !i;
-}
-
-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;
-}
-
-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;
-}
diff --git a/src/zix/tree.h b/src/zix/tree.h
deleted file mode 100644
index a2d5fe7..0000000
--- a/src/zix/tree.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- Copyright 2011-2020 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.
-*/
-
-#ifndef ZIX_TREE_H
-#define ZIX_TREE_H
-
-#include "zix/common.h"
-
-#include <stdbool.h>
-#include <stddef.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 `t`.
-*/
-ZIX_API
-void
-zix_tree_free(ZixTree* t);
-
-/**
- Return the number of elements in `t`.
-*/
-ZIX_PURE_API
-size_t
-zix_tree_size(const ZixTree* t);
-
-/**
- Insert the element `e` into `t` and point `ti` at the new element.
-*/
-ZIX_API
-ZixStatus
-zix_tree_insert(ZixTree* t, void* e, ZixTreeIter** ti);
-
-/**
- Remove the item pointed at by `ti` from `t`.
-*/
-ZIX_API
-ZixStatus
-zix_tree_remove(ZixTree* t, ZixTreeIter* ti);
-
-/**
- Set `ti` to an element equal to `e` in `t`.
- If no such item exists, `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_PURE_API
-void*
-zix_tree_get(const ZixTreeIter* ti);
-
-/**
- Return an iterator to the first (smallest) element in `t`.
-*/
-ZIX_PURE_API
-ZixTreeIter*
-zix_tree_begin(ZixTree* t);
-
-/**
- Return an iterator the the element one past the last element in `t`.
-*/
-ZIX_CONST_API
-ZixTreeIter*
-zix_tree_end(ZixTree* t);
-
-/**
- Return true iff `i` is an iterator to the end of its tree.
-*/
-ZIX_CONST_API
-bool
-zix_tree_iter_is_end(const ZixTreeIter* i);
-
-/**
- Return an iterator to the last (largest) element in `t`.
-*/
-ZIX_PURE_API
-ZixTreeIter*
-zix_tree_rbegin(ZixTree* t);
-
-/**
- Return an iterator the the element one before the first element in `t`.
-*/
-ZIX_CONST_API
-ZixTreeIter*
-zix_tree_rend(ZixTree* t);
-
-/**
- Return true iff `i` is an iterator to the reverse end of its tree.
-*/
-ZIX_CONST_API
-bool
-zix_tree_iter_is_rend(const ZixTreeIter* i);
-
-/**
- Return an iterator that points to the element one past `i`.
-*/
-ZIX_PURE_API
-ZixTreeIter*
-zix_tree_iter_next(ZixTreeIter* i);
-
-/**
- Return an iterator that points to the element one before `i`.
-*/
-ZIX_PURE_API
-ZixTreeIter*
-zix_tree_iter_prev(ZixTreeIter* i);
-
-/**
- @}
- @}
-*/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ZIX_TREE_H */
diff --git a/subprojects/sphinxygen.wrap b/subprojects/sphinxygen.wrap
new file mode 100644
index 0000000..9707d1a
--- /dev/null
+++ b/subprojects/sphinxygen.wrap
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+[wrap-file]
+directory = sphinxygen-1.0.4
+source_url = https://download.drobilla.net/sphinxygen-1.0.4.tar.gz
+source_filename = sphinxygen-1.0.4.tar.gz
+source_hash = 12fa9f18ed9fca608f272520072257ba61fd9eff25613f86d83d4fce14fc01f5
+
+# [wrap-git]
+# url = https://gitlab.com/drobilla/sphinxygen.git
+# push-url = ssh://git@gitlab.com:drobilla/sphinxygen.git
+# revision = v1.0.4
+# depth = 1
diff --git a/test/.clang-tidy b/test/.clang-tidy
index a6f6844..f6f74ab 100644
--- a/test/.clang-tidy
+++ b/test/.clang-tidy
@@ -1,42 +1,19 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
Checks: >
- *,
- -*-else-after-return,
-*-magic-numbers,
- -*-uppercase-literal-suffix,
- -*-vararg,
-android-cloexec-fopen,
- -bugprone-assert-side-effect,
-bugprone-branch-clone,
- -bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
- -bugprone-not-null-terminated-result,
- -bugprone-reserved-identifier,
- -bugprone-suspicious-string-compare,
- -cert-dcl37-c,
- -cert-dcl50-cpp,
- -cert-dcl51-cpp,
- -cert-err34-c,
- -clang-analyzer-alpha.*,
+ -cert-err33-c,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
+ -concurrency-mt-unsafe,
-cppcoreguidelines-avoid-non-const-global-variables,
- -cppcoreguidelines-macro-usage,
-cppcoreguidelines-narrowing-conversions,
- -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
- -fuchsia-overloaded-operator,
- -google-explicit-constructor,
- -google-readability-todo,
- -hicpp-explicit-conversions,
-hicpp-multiway-paths-covered,
- -hicpp-no-array-decay,
-hicpp-signed-bitwise,
-llvm-header-guard,
- -llvmlibc-*,
- -misc-no-recursion,
- -misc-non-private-member-variables-in-classes,
- -misc-unused-parameters,
- -modernize-return-braced-init-list,
- -modernize-use-trailing-return-type,
- -readability-implicit-bool-conversion,
-WarningsAsErrors: '*'
-HeaderFilterRegex: '.*'
-FormatStyle: file
+ -readability-function-cognitive-complexity,
+ -readability-suspicious-call-argument,
+InheritParentConfig: true
diff --git a/test/bad_syntax.lv2/bad_syntax.c b/test/bad_syntax.lv2/bad_syntax.c
index da9c041..b1b52e7 100644
--- a/test/bad_syntax.lv2/bad_syntax.c
+++ b/test/bad_syntax.lv2/bad_syntax.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Bad syntax in plugin data file
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/bad_syntax.lv2/meson.build b/test/bad_syntax.lv2/meson.build
new file mode 100644
index 0000000..dbda502
--- /dev/null
+++ b/test/bad_syntax.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'bad_syntax',
+ files('bad_syntax.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'bad_syntax.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ configuration: config,
+ input: files(f + '.in'),
+ output: f,
+ )
+endforeach
+
+test(
+ 'bad_syntax',
+ executable(
+ 'test_bad_syntax',
+ files('test_bad_syntax.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/bad_syntax.lv2/test_bad_syntax.c b/test/bad_syntax.lv2/test_bad_syntax.c
index 5f10828..39729d4 100644
--- a/test/bad_syntax.lv2/test_bad_syntax.c
+++ b/test/bad_syntax.lv2/test_bad_syntax.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/bad-syntax"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/cpp/.clang-tidy b/test/cpp/.clang-tidy
new file mode 100644
index 0000000..5d20fa0
--- /dev/null
+++ b/test/cpp/.clang-tidy
@@ -0,0 +1,19 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+Checks: >
+ -cert-dcl50-cpp,
+ -cppcoreguidelines-macro-usage,
+ -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
+ -fuchsia-overloaded-operator,
+ -google-explicit-constructor,
+ -google-readability-todo,
+ -hicpp-explicit-conversions,
+ -hicpp-no-array-decay,
+ -misc-non-private-member-variables-in-classes,
+ -modernize-return-braced-init-list,
+ -modernize-use-nodiscard,
+ -modernize-use-trailing-return-type,
+ -readability-implicit-bool-conversion,
+HeaderFilterRegex: '.*/lilvmm\.hpp'
+InheritParentConfig: true
diff --git a/test/cpp/meson.build b/test/cpp/meson.build
new file mode 100644
index 0000000..5b8169c
--- /dev/null
+++ b/test/cpp/meson.build
@@ -0,0 +1,37 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+cpp_suppressions = []
+if cpp.get_id() == 'gcc'
+ cpp_suppressions += [
+ '-Wno-cast-align',
+ '-Wno-padded',
+ ]
+elif cpp.get_id() == 'clang'
+ cpp_suppressions += [
+ '-Wno-c++98-compat',
+ '-Wno-cast-align',
+ '-Wno-cast-qual',
+ '-Wno-documentation-unknown-command',
+ '-Wno-padded',
+ '-Wno-poison-system-directories',
+ '-Wno-reserved-id-macro',
+ ]
+elif cpp.get_id() == 'msvc'
+ cpp_suppressions += [
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4820', # padding added after construct
+ ]
+endif
+
+test(
+ 'lilv_hpp',
+ executable(
+ 'test_lilv_hpp',
+ files('test_lilv_hpp.cpp'),
+ cpp_args: test_args + cpp_suppressions,
+ dependencies: [lv2_dep, lilv_static_dep],
+ include_directories: include_directories('../../src'),
+ ),
+ suite: 'unit',
+)
diff --git a/test/cpp/test_lilv_hpp.cpp b/test/cpp/test_lilv_hpp.cpp
new file mode 100644
index 0000000..7e6de72
--- /dev/null
+++ b/test/cpp/test_lilv_hpp.cpp
@@ -0,0 +1,12 @@
+// Copyright 2017-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#include "lilv/lilvmm.hpp"
+
+int
+main()
+{
+ const Lilv::World world{};
+
+ return 0;
+}
diff --git a/test/failed_instantiation.lv2/failed_instantiation.c b/test/failed_instantiation.lv2/failed_instantiation.c
index ecab647..2d75c1a 100644
--- a/test/failed_instantiation.lv2/failed_instantiation.c
+++ b/test/failed_instantiation.lv2/failed_instantiation.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Failed instantiation
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/failed_instantiation.lv2/meson.build b/test/failed_instantiation.lv2/meson.build
new file mode 100644
index 0000000..966eed0
--- /dev/null
+++ b/test/failed_instantiation.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'failed_instantiation',
+ files('failed_instantiation.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'failed_instantiation.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ configuration: config,
+ input: files(f + '.in'),
+ output: f,
+ )
+endforeach
+
+test(
+ 'failed_instantiation',
+ executable(
+ 'test_failed_instantiation',
+ files('test_failed_instantiation.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/failed_instantiation.lv2/test_failed_instantiation.c b/test/failed_instantiation.lv2/test_failed_instantiation.c
index 8dbefc3..ed46d5a 100644
--- a/test/failed_instantiation.lv2/test_failed_instantiation.c
+++ b/test/failed_instantiation.lv2/test_failed_instantiation.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/failed-instantiation"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c b/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c
index c7c08cf..2d0baee 100644
--- a/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c
+++ b/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Failed lib descriptor
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/failed_lib_descriptor.lv2/meson.build b/test/failed_lib_descriptor.lv2/meson.build
new file mode 100644
index 0000000..61de196
--- /dev/null
+++ b/test/failed_lib_descriptor.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'failed_lib_descriptor',
+ files('failed_lib_descriptor.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'failed_lib_descriptor.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'failed_lib_descriptor',
+ executable(
+ 'test_failed_lib_descriptor',
+ files('test_failed_lib_descriptor.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c b/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c
index 71a3b96..9a9641b 100644
--- a/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c
+++ b/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/failed-lib-descriptor"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/lib_descriptor.lv2/lib_descriptor.c b/test/lib_descriptor.lv2/lib_descriptor.c
index ab27c2b..bae1659 100644
--- a/test/lib_descriptor.lv2/lib_descriptor.c
+++ b/test/lib_descriptor.lv2/lib_descriptor.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Missing descriptor
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
@@ -96,12 +82,7 @@ get_plugin(LV2_Lib_Handle handle, uint32_t index)
{
(void)handle;
- switch (index) {
- case 0:
- return &descriptor;
- default:
- return NULL;
- }
+ return index ? NULL : &descriptor;
}
static const LV2_Lib_Descriptor lib = {NULL,
diff --git a/test/lib_descriptor.lv2/meson.build b/test/lib_descriptor.lv2/meson.build
new file mode 100644
index 0000000..ea29b6a
--- /dev/null
+++ b/test/lib_descriptor.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'lib_descriptor',
+ files('lib_descriptor.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'lib_descriptor.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'lib_descriptor',
+ executable(
+ 'test_lib_descriptor',
+ files('test_lib_descriptor.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/lib_descriptor.lv2/test_lib_descriptor.c b/test/lib_descriptor.lv2/test_lib_descriptor.c
index bf79be8..e971662 100644
--- a/test/lib_descriptor.lv2/test_lib_descriptor.c
+++ b/test/lib_descriptor.lv2/test_lib_descriptor.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/lib-descriptor"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/lilv_cxx_test.cpp b/test/lilv_cxx_test.cpp
deleted file mode 100644
index 31d5e4e..0000000
--- a/test/lilv_cxx_test.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- Copyright 2017-2019 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 "lilv/lilvmm.hpp"
-
-int
-main()
-{
- Lilv::World world;
-
- return 0;
-}
diff --git a/test/lilv_test_uri_map.h b/test/lilv_test_uri_map.h
index 5f85c86..b4fba0f 100644
--- a/test/lilv_test_uri_map.h
+++ b/test/lilv_test_uri_map.h
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#ifndef LILV_TEST_URI_MAP_H
#define LILV_TEST_URI_MAP_H
@@ -23,14 +10,13 @@
#include "serd/serd.h"
#include <assert.h>
-#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
- char** uris;
- size_t n_uris;
+ char** uris;
+ uint32_t n_uris;
} LilvTestUriMap;
static inline void
@@ -43,7 +29,7 @@ lilv_test_uri_map_init(LilvTestUriMap* const map)
static inline void
lilv_test_uri_map_clear(LilvTestUriMap* const map)
{
- for (size_t i = 0; i < map->n_uris; ++i) {
+ for (uint32_t i = 0; i < map->n_uris; ++i) {
free(map->uris[i]);
}
@@ -57,7 +43,7 @@ map_uri(LV2_URID_Map_Handle handle, const char* uri)
{
LilvTestUriMap* map = (LilvTestUriMap*)handle;
- for (size_t i = 0; i < map->n_uris; ++i) {
+ for (uint32_t i = 0; i < map->n_uris; ++i) {
if (!strcmp(map->uris[i], uri)) {
return i + 1;
}
diff --git a/test/lilv_test_utils.c b/test/lilv_test_utils.c
index f658f1b..c3c47f0 100644
--- a/test/lilv_test_utils.c
+++ b/test/lilv_test_utils.c
@@ -1,28 +1,13 @@
-/*
- Copyright 2020 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.
-*/
-
-#define _POSIX_C_SOURCE 200809L /* for setenv */
+// Copyright 2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_test_utils.h"
-#include "../src/filesystem.h"
-#include "../src/lilv_internal.h"
-
#include "lilv/lilv.h"
#include "serd/serd.h"
+#include "zix/allocator.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
#include <errno.h>
#include <stdbool.h>
@@ -46,13 +31,13 @@ lilv_test_env_new(void)
env->plugin2_uri = lilv_new_uri(world, "http://example.org/foobar");
// Set custom LV2_PATH in build directory to only use test data
- char* test_path = lilv_path_canonical(LILV_TEST_DIR);
- char* lv2_path = lilv_strjoin(test_path, "/test_lv2_path", NULL);
+ char* test_path = zix_canonical_path(NULL, LILV_TEST_DIR);
+ char* lv2_path = zix_path_join(NULL, test_path, "lv2");
LilvNode* path = lilv_new_string(world, lv2_path);
lilv_world_set_option(world, LILV_OPTION_LV2_PATH, path);
- free(lv2_path);
- free(test_path);
lilv_node_free(path);
+ zix_free(NULL, lv2_path);
+ zix_free(NULL, test_path);
return env;
}
@@ -60,10 +45,10 @@ lilv_test_env_new(void)
void
lilv_test_env_free(LilvTestEnv* env)
{
- free(env->test_content_path);
- free(env->test_manifest_path);
- free(env->test_bundle_uri);
- free(env->test_bundle_path);
+ zix_free(NULL, env->test_content_path);
+ zix_free(NULL, env->test_manifest_path);
+ lilv_node_free(env->test_bundle_uri);
+ zix_free(NULL, env->test_bundle_path);
lilv_node_free(env->plugin2_uri);
lilv_node_free(env->plugin1_uri);
lilv_world_free(env->world);
@@ -77,16 +62,16 @@ create_bundle(LilvTestEnv* env,
const char* plugin)
{
{
- char* const test_dir = lilv_path_canonical(LILV_TEST_DIR);
- char* const bundle_dir = lilv_path_join(test_dir, name);
+ char* const test_dir = zix_canonical_path(NULL, LILV_TEST_DIR);
+ char* const bundle_dir = zix_path_join(NULL, test_dir, name);
- env->test_bundle_path = lilv_path_join(bundle_dir, "");
+ env->test_bundle_path = zix_path_join(NULL, bundle_dir, "");
- lilv_free(bundle_dir);
- lilv_free(test_dir);
+ zix_free(NULL, bundle_dir);
+ zix_free(NULL, test_dir);
}
- if (lilv_create_directories(env->test_bundle_path)) {
+ if (zix_create_directories(NULL, env->test_bundle_path)) {
fprintf(stderr,
"Failed to create directory '%s' (%s)\n",
env->test_bundle_path,
@@ -98,9 +83,12 @@ create_bundle(LilvTestEnv* env,
(const uint8_t*)env->test_bundle_path, NULL, NULL, true);
env->test_bundle_uri = lilv_new_uri(env->world, (const char*)s.buf);
+
env->test_manifest_path =
- lilv_path_join(env->test_bundle_path, "manifest.ttl");
- env->test_content_path = lilv_path_join(env->test_bundle_path, "plugin.ttl");
+ zix_path_join(NULL, env->test_bundle_path, "manifest.ttl");
+
+ env->test_content_path =
+ zix_path_join(NULL, env->test_bundle_path, "plugin.ttl");
serd_node_free(&s);
@@ -152,21 +140,21 @@ void
delete_bundle(LilvTestEnv* env)
{
if (env->test_content_path) {
- lilv_remove(env->test_content_path);
+ zix_remove(env->test_content_path);
}
if (env->test_manifest_path) {
- lilv_remove(env->test_manifest_path);
+ zix_remove(env->test_manifest_path);
}
if (env->test_bundle_path) {
remove(env->test_bundle_path);
}
- free(env->test_content_path);
- free(env->test_manifest_path);
- free(env->test_bundle_uri);
- free(env->test_bundle_path);
+ zix_free(NULL, env->test_content_path);
+ zix_free(NULL, env->test_manifest_path);
+ lilv_node_free(env->test_bundle_uri);
+ zix_free(NULL, env->test_bundle_path);
env->test_content_path = NULL;
env->test_manifest_path = NULL;
@@ -188,3 +176,16 @@ set_env(const char* name, const char* value)
setenv(name, value, 1);
#endif
}
+
+char*
+lilv_create_temporary_directory(const char* pattern)
+{
+ char* const tmpdir = zix_temp_directory_path(NULL);
+ char* const path_pattern = zix_path_join(NULL, tmpdir, pattern);
+ char* const result = zix_create_temporary_directory(NULL, path_pattern);
+
+ zix_free(NULL, path_pattern);
+ zix_free(NULL, tmpdir);
+
+ return result;
+}
diff --git a/test/lilv_test_utils.h b/test/lilv_test_utils.h
index 76d9bc1..f01b5b4 100644
--- a/test/lilv_test_utils.h
+++ b/test/lilv_test_utils.h
@@ -1,18 +1,5 @@
-/*
- Copyright 2020 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.
-*/
+// Copyright 2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#ifndef LILV_TEST_UTILS_H
#define LILV_TEST_UTILS_H
@@ -92,4 +79,8 @@ delete_bundle(LilvTestEnv* env);
void
set_env(const char* name, const char* value);
+// Create a unique temporary directory
+char*
+lilv_create_temporary_directory(const char* pattern);
+
#endif // LILV_TEST_UTILS_H
diff --git a/test/core.lv2/lv2core.ttl b/test/lv2/core.lv2/lv2core.ttl
index 5659487..5659487 100644
--- a/test/core.lv2/lv2core.ttl
+++ b/test/lv2/core.lv2/lv2core.ttl
diff --git a/test/core.lv2/manifest.ttl b/test/lv2/core.lv2/manifest.ttl
index a77ad71..a77ad71 100644
--- a/test/core.lv2/manifest.ttl
+++ b/test/lv2/core.lv2/manifest.ttl
diff --git a/test/lv2/core.lv2/meson.build b/test/lv2/core.lv2/meson.build
new file mode 100644
index 0000000..0d02ae1
--- /dev/null
+++ b/test/lv2/core.lv2/meson.build
@@ -0,0 +1,11 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+ttl_files = files(
+ 'lv2core.ttl',
+ 'manifest.ttl',
+)
+
+foreach file : ttl_files
+ configure_file(copy: true, input: file, output: '@PLAINNAME@')
+endforeach
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..d305dad
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,115 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+####################
+# Project Metadata #
+####################
+
+if get_option('warning_level') == 'everything'
+ # Check release metadata
+ if not meson.is_subproject()
+ autoship = find_program('autoship', required: false)
+ if autoship.found()
+ test('autoship', autoship, args: ['test', lilv_src_root], suite: 'data')
+ endif
+ endif
+
+ # Check licensing metadata
+ reuse = find_program('reuse', required: false)
+ if reuse.found()
+ test(
+ 'REUSE',
+ reuse,
+ args: ['--root', lilv_src_root, 'lint'],
+ suite: 'data',
+ )
+ endif
+endif
+
+##############
+# Test Setup #
+##############
+
+test_args = ['-DLILV_STATIC']
+if cc.get_id() == 'msvc'
+ test_args += [
+ '/wd4464', # relative include path contains '..'
+ ]
+endif
+
+subdir('lv2/core.lv2')
+
+################
+# Bundle Tests #
+################
+
+subdir('bad_syntax.lv2')
+subdir('failed_instantiation.lv2')
+subdir('failed_lib_descriptor.lv2')
+subdir('lib_descriptor.lv2')
+subdir('missing_descriptor.lv2')
+subdir('missing_name.lv2')
+subdir('missing_plugin.lv2')
+subdir('missing_port.lv2')
+subdir('missing_port_name.lv2')
+subdir('new_version.lv2')
+subdir('old_version.lv2')
+subdir('test_plugin.lv2')
+
+################
+# C++ Bindings #
+################
+
+if not get_option('bindings_cpp').disabled()
+ subdir('cpp')
+endif
+
+##############
+# Unit Tests #
+##############
+
+unit_tests = [
+ 'bad_port_index',
+ 'bad_port_symbol',
+ 'classes',
+ 'discovery',
+ 'get_symbol',
+ 'no_author',
+ 'no_verify',
+ 'plugin',
+ 'port',
+ 'preset',
+ 'project',
+ 'project_no_author',
+ 'prototype',
+ 'reload_bundle',
+ 'replace_version',
+ 'state',
+ 'string',
+ 'ui',
+ 'util',
+ 'value',
+ 'verify',
+ 'world',
+]
+
+define_args = [
+ '-DLILV_TEST_BUNDLE="@0@/"'.format(
+ meson.current_build_dir() / 'test_plugin.lv2',
+ ),
+ '-DLILV_TEST_DIR="@0@/"'.format(meson.current_build_dir()),
+]
+
+foreach unit : unit_tests
+ test(
+ unit,
+ executable(
+ 'test_@0@'.format(unit),
+ files('lilv_test_utils.c', 'test_@0@.c'.format(unit)),
+ c_args: define_args + test_args + c_suppressions,
+ include_directories: include_directories('../src'),
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ suite: 'unit',
+ )
+endforeach
diff --git a/test/missing_descriptor.lv2/meson.build b/test/missing_descriptor.lv2/meson.build
new file mode 100644
index 0000000..b4ad32f
--- /dev/null
+++ b/test/missing_descriptor.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'missing_descriptor',
+ files('missing_descriptor.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'missing_descriptor.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'missing_descriptor',
+ executable(
+ 'test_missing_descriptor',
+ files('test_missing_descriptor.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/missing_descriptor.lv2/missing_descriptor.c b/test/missing_descriptor.lv2/missing_descriptor.c
index ec1b473..ffcf7d6 100644
--- a/test/missing_descriptor.lv2/missing_descriptor.c
+++ b/test/missing_descriptor.lv2/missing_descriptor.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Missing descriptor
- Copyright 2011-2018 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.
-*/
+// Copyright 2011-2018 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/missing_descriptor.lv2/test_missing_descriptor.c b/test/missing_descriptor.lv2/test_missing_descriptor.c
index 330e534..b737048 100644
--- a/test/missing_descriptor.lv2/test_missing_descriptor.c
+++ b/test/missing_descriptor.lv2/test_missing_descriptor.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/missing-descriptor"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/missing_name.lv2/meson.build b/test/missing_name.lv2/meson.build
new file mode 100644
index 0000000..c32cbb5
--- /dev/null
+++ b/test/missing_name.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'missing_name',
+ files('missing_name.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'missing_name.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'missing_name',
+ executable(
+ 'test_missing_name',
+ files('test_missing_name.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/missing_name.lv2/missing_name.c b/test/missing_name.lv2/missing_name.c
index 8c6e6fe..8538e73 100644
--- a/test/missing_name.lv2/missing_name.c
+++ b/test/missing_name.lv2/missing_name.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Missing name
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/missing_name.lv2/test_missing_name.c b/test/missing_name.lv2/test_missing_name.c
index 5cb069a..a8df1ab 100644
--- a/test/missing_name.lv2/test_missing_name.c
+++ b/test/missing_name.lv2/test_missing_name.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/missing-name"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/missing_plugin.lv2/meson.build b/test/missing_plugin.lv2/meson.build
new file mode 100644
index 0000000..b5819ff
--- /dev/null
+++ b/test/missing_plugin.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'missing_plugin',
+ files('missing_plugin.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'missing_plugin.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'missing_plugin',
+ executable(
+ 'test_missing_plugin',
+ files('test_missing_plugin.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/missing_plugin.lv2/missing_plugin.c b/test/missing_plugin.lv2/missing_plugin.c
index 8ca146c..f496c6d 100644
--- a/test/missing_plugin.lv2/missing_plugin.c
+++ b/test/missing_plugin.lv2/missing_plugin.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Missing plugin
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/missing_plugin.lv2/test_missing_plugin.c b/test/missing_plugin.lv2/test_missing_plugin.c
index 861fcba..6eb1705 100644
--- a/test/missing_plugin.lv2/test_missing_plugin.c
+++ b/test/missing_plugin.lv2/test_missing_plugin.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/missing-plugin"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/missing_port.lv2/meson.build b/test/missing_port.lv2/meson.build
new file mode 100644
index 0000000..f6138d8
--- /dev/null
+++ b/test/missing_port.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'missing_port',
+ files('missing_port.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'missing_port.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'missing_port',
+ executable(
+ 'test_missing_port',
+ files('test_missing_port.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/missing_port.lv2/missing_port.c b/test/missing_port.lv2/missing_port.c
index c567d55..ce98c30 100644
--- a/test/missing_port.lv2/missing_port.c
+++ b/test/missing_port.lv2/missing_port.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Missing port
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/missing_port.lv2/test_missing_port.c b/test/missing_port.lv2/test_missing_port.c
index ec6713c..463fd63 100644
--- a/test/missing_port.lv2/test_missing_port.c
+++ b/test/missing_port.lv2/test_missing_port.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/missing-port"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/missing_port_name.lv2/meson.build b/test/missing_port_name.lv2/meson.build
new file mode 100644
index 0000000..3bddcee
--- /dev/null
+++ b/test/missing_port_name.lv2/meson.build
@@ -0,0 +1,36 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'missing_port_name',
+ files('missing_port_name.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'missing_port_name.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
+test(
+ 'missing_port_name',
+ executable(
+ 'test_missing_port_name',
+ files('test_missing_port_name.c'),
+ c_args: c_suppressions + test_args,
+ dependencies: [lv2_dep, lilv_static_dep],
+ ),
+ args: [meson.current_build_dir() / ''],
+ suite: 'plugin',
+)
+
diff --git a/test/missing_port_name.lv2/missing_port_name.c b/test/missing_port_name.lv2/missing_port_name.c
index 7a00945..d10498f 100644
--- a/test/missing_port_name.lv2/missing_port_name.c
+++ b/test/missing_port_name.lv2/missing_port_name.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Missing port name
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/missing_port_name.lv2/test_missing_port_name.c b/test/missing_port_name.lv2/test_missing_port_name.c
index 4d017d9..58e8120 100644
--- a/test/missing_port_name.lv2/test_missing_port_name.c
+++ b/test/missing_port_name.lv2/test_missing_port_name.c
@@ -1,15 +1,12 @@
-#undef NDEBUG
+// Copyright 2015-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
-#include "../src/filesystem.h"
+#undef NDEBUG
#include "lilv/lilv.h"
-#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#define PLUGIN_URI "http://example.org/missing-port-name"
@@ -25,12 +22,8 @@ main(int argc, char** argv)
LilvWorld* world = lilv_world_new();
// Load test plugin bundle
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, bundle_path);
lilv_world_load_bundle(world, bundle_uri);
- free(abs_bundle);
- serd_node_free(&bundle);
lilv_node_free(bundle_uri);
LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
diff --git a/test/new_version.lv2/meson.build b/test/new_version.lv2/meson.build
new file mode 100644
index 0000000..bd90443
--- /dev/null
+++ b/test/new_version.lv2/meson.build
@@ -0,0 +1,24 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'new_version',
+ files('new_version.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'new_version.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
diff --git a/test/new_version.lv2/new_version.c b/test/new_version.lv2/new_version.c
index 4de48e7..64be4f5 100644
--- a/test/new_version.lv2/new_version.c
+++ b/test/new_version.lv2/new_version.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - New version
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/old_version.lv2/meson.build b/test/old_version.lv2/meson.build
new file mode 100644
index 0000000..09434b1
--- /dev/null
+++ b/test/old_version.lv2/meson.build
@@ -0,0 +1,24 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'old_version',
+ files('old_version.c'),
+ c_args: c_suppressions,
+ dependencies: lv2_dep,
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'old_version.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
diff --git a/test/old_version.lv2/old_version.c b/test/old_version.lv2/old_version.c
index 7f97dad..64be4f5 100644
--- a/test/old_version.lv2/old_version.c
+++ b/test/old_version.lv2/old_version.c
@@ -1,19 +1,5 @@
-/*
- Lilv Test Plugin - Old version
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/core/lv2.h"
diff --git a/test/test_bad_port_index.c b/test/test_bad_port_index.c
index 985d74e..99bdfc6 100644
--- a/test/test_bad_port_index.c
+++ b/test/test_bad_port_index.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_bad_port_symbol.c b/test/test_bad_port_symbol.c
index ae34ad0..2422e15 100644
--- a/test/test_bad_port_symbol.c
+++ b/test/test_bad_port_symbol.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_classes.c b/test/test_classes.c
index 332d847..2d33a57 100644
--- a/test/test_classes.c
+++ b/test/test_classes.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_discovery.c b/test/test_discovery.c
index f7f30ea..7d38207 100644
--- a/test/test_discovery.c
+++ b/test/test_discovery.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_filesystem.c b/test/test_filesystem.c
deleted file mode 100644
index 0a4aa4d..0000000
--- a/test/test_filesystem.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- Copyright 2020 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.
-*/
-
-#undef NDEBUG
-
-#include "lilv_internal.h"
-
-#include "../src/filesystem.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static bool
-equals(char* string, const char* expected)
-{
- const bool result = !strcmp(string, expected);
- free(string);
- return result;
-}
-
-static void
-test_temp_directory_path(void)
-{
- char* tmpdir = lilv_temp_directory_path();
-
- assert(lilv_is_directory(tmpdir));
-
- free(tmpdir);
-}
-
-static void
-test_path_is_absolute(void)
-{
- assert(lilv_path_is_absolute("/a/b"));
- assert(lilv_path_is_absolute("/a"));
- assert(lilv_path_is_absolute("/"));
-
- assert(!lilv_path_is_absolute("a/b"));
- assert(!lilv_path_is_absolute("a"));
- assert(!lilv_path_is_absolute("."));
-
-#ifdef _WIN32
- assert(lilv_path_is_absolute("C:/a/b"));
- assert(lilv_path_is_absolute("C:\\a\\b"));
- assert(lilv_path_is_absolute("D:/a/b"));
- assert(lilv_path_is_absolute("D:\\a\\b"));
-#endif
-}
-
-static void
-test_path_is_child(void)
-{
- assert(lilv_path_is_child("/a/b", "/a"));
- assert(lilv_path_is_child("/a/b", "/a/"));
- assert(lilv_path_is_child("/a/b/", "/a"));
- assert(lilv_path_is_child("/a/b/", "/a/"));
-
- assert(!lilv_path_is_child("/a/b", "/a/c"));
- assert(!lilv_path_is_child("/a/b", "/a/c/"));
- assert(!lilv_path_is_child("/a/b/", "/a/c"));
- assert(!lilv_path_is_child("/a/b/", "/a/c/"));
-
- assert(!lilv_path_is_child("/a/b", "/c"));
- assert(!lilv_path_is_child("/a/b", "/c/"));
- assert(!lilv_path_is_child("/a/b/", "/c"));
- assert(!lilv_path_is_child("/a/b/", "/c/"));
-}
-
-static void
-test_path_current(void)
-{
- char* cwd = lilv_path_current();
-
- assert(lilv_is_directory(cwd));
-
- free(cwd);
-}
-
-static void
-test_path_absolute(void)
-{
- const char* const short_path = "a";
- const char* const long_path = "a/b/c";
-
- char* const cwd = lilv_path_current();
- char* const expected_short = lilv_path_join(cwd, short_path);
- char* const expected_long = lilv_path_join(cwd, long_path);
-
- assert(equals(lilv_path_absolute(short_path), expected_short));
- assert(equals(lilv_path_absolute(long_path), expected_long));
-
- free(expected_long);
- free(expected_short);
- free(cwd);
-}
-
-static void
-test_path_absolute_child(void)
-{
- const char* const parent = "/parent";
- const char* const short_path = "a";
- const char* const long_path = "a/b/c";
-
- char* const expected_short = lilv_path_join(parent, short_path);
- char* const expected_long = lilv_path_join(parent, long_path);
-
- assert(equals(lilv_path_absolute_child(short_path, parent), expected_short));
-
- assert(equals(lilv_path_absolute_child(long_path, parent), expected_long));
-
- free(expected_long);
- free(expected_short);
-}
-
-static void
-test_path_relative_to(void)
-{
- assert(equals(lilv_path_relative_to("/a/b", "/a/"), "b"));
- assert(equals(lilv_path_relative_to("/a", "/b/c/"), "/a"));
- assert(equals(lilv_path_relative_to("/a/b/c", "/a/b/d/"), "../c"));
- assert(equals(lilv_path_relative_to("/a/b/c", "/a/b/d/e/"), "../../c"));
-
-#ifdef _WIN32
- assert(equals(lilv_path_relative_to("C:/a/b", "C:/a/"), "b"));
- assert(equals(lilv_path_relative_to("C:/a", "C:/b/c/"), "../../a"));
- assert(equals(lilv_path_relative_to("C:/a/b/c", "C:/a/b/d/"), "../c"));
- assert(equals(lilv_path_relative_to("C:/a/b/c", "C:/a/b/d/e/"), "../../c"));
-
- assert(equals(lilv_path_relative_to("C:\\a\\b", "C:\\a\\"), "b"));
- assert(equals(lilv_path_relative_to("C:\\a", "C:\\b\\c\\"), "..\\..\\a"));
- assert(
- equals(lilv_path_relative_to("C:\\a\\b\\c", "C:\\a\\b\\d\\"), "..\\c"));
- assert(equals(lilv_path_relative_to("C:\\a\\b\\c", "C:\\a\\b\\d\\e\\"),
- "..\\..\\c"));
-#endif
-}
-
-static void
-test_path_parent(void)
-{
- assert(equals(lilv_path_parent("/"), "/"));
- assert(equals(lilv_path_parent("//"), "/"));
- assert(equals(lilv_path_parent("/a"), "/"));
- assert(equals(lilv_path_parent("/a/"), "/"));
- assert(equals(lilv_path_parent("/a///b/"), "/a"));
- assert(equals(lilv_path_parent("/a///b//"), "/a"));
- assert(equals(lilv_path_parent("/a/b"), "/a"));
- assert(equals(lilv_path_parent("/a/b/"), "/a"));
- assert(equals(lilv_path_parent("/a/b/c"), "/a/b"));
- assert(equals(lilv_path_parent("/a/b/c/"), "/a/b"));
- assert(equals(lilv_path_parent("a"), "."));
-}
-
-static void
-test_path_filename(void)
-{
- // Cases from cppreference.com for std::filesystem::path::filename
- assert(equals(lilv_path_filename("/foo/bar.txt"), "bar.txt"));
- assert(equals(lilv_path_filename("/foo/.bar"), ".bar"));
- assert(equals(lilv_path_filename("/foo/bar/"), ""));
- assert(equals(lilv_path_filename("/foo/."), "."));
- assert(equals(lilv_path_filename("/foo/.."), ".."));
- assert(equals(lilv_path_filename("."), "."));
- assert(equals(lilv_path_filename(".."), ".."));
- assert(equals(lilv_path_filename("/"), ""));
- assert(equals(lilv_path_filename("//host"), "host"));
-
-#ifdef _WIN32
- assert(equals(lilv_path_filename("C:/foo/bar.txt"), "bar.txt"));
- assert(equals(lilv_path_filename("C:\\foo\\bar.txt"), "bar.txt"));
- assert(equals(lilv_path_filename("foo/bar.txt"), "bar.txt"));
- assert(equals(lilv_path_filename("foo\\bar.txt"), "bar.txt"));
-#endif
-}
-
-static void
-test_path_join(void)
-{
- assert(lilv_path_join(NULL, NULL) == NULL);
- assert(lilv_path_join(NULL, "") == NULL);
-
-#ifdef _WIN32
- assert(equals(lilv_path_join("", NULL), "\\"));
- assert(equals(lilv_path_join("", ""), "\\"));
- assert(equals(lilv_path_join("a", ""), "a\\"));
- assert(equals(lilv_path_join("a", NULL), "a\\"));
- assert(equals(lilv_path_join("a", "b"), "a\\b"));
-#else
- assert(equals(lilv_path_join("", NULL), "/"));
- assert(equals(lilv_path_join("", ""), "/"));
- assert(equals(lilv_path_join("a", ""), "a/"));
- assert(equals(lilv_path_join("a", NULL), "a/"));
- assert(equals(lilv_path_join("a", "b"), "a/b"));
-#endif
-
- assert(equals(lilv_path_join("/a", ""), "/a/"));
- assert(equals(lilv_path_join("/a/b", ""), "/a/b/"));
- assert(equals(lilv_path_join("/a/", ""), "/a/"));
- assert(equals(lilv_path_join("/a/b/", ""), "/a/b/"));
- assert(equals(lilv_path_join("a/b", ""), "a/b/"));
- assert(equals(lilv_path_join("a/", ""), "a/"));
- assert(equals(lilv_path_join("a/b/", ""), "a/b/"));
-
- assert(equals(lilv_path_join("/a", NULL), "/a/"));
- assert(equals(lilv_path_join("/a/b", NULL), "/a/b/"));
- assert(equals(lilv_path_join("/a/", NULL), "/a/"));
- assert(equals(lilv_path_join("/a/b/", NULL), "/a/b/"));
- assert(equals(lilv_path_join("a/b", NULL), "a/b/"));
- assert(equals(lilv_path_join("a/", NULL), "a/"));
- assert(equals(lilv_path_join("a/b/", NULL), "a/b/"));
-
- assert(equals(lilv_path_join("/a", "b"), "/a/b"));
- assert(equals(lilv_path_join("/a/", "b"), "/a/b"));
- assert(equals(lilv_path_join("a/", "b"), "a/b"));
-
- assert(equals(lilv_path_join("/a", "b/"), "/a/b/"));
- assert(equals(lilv_path_join("/a/", "b/"), "/a/b/"));
- assert(equals(lilv_path_join("a", "b/"), "a/b/"));
- assert(equals(lilv_path_join("a/", "b/"), "a/b/"));
-
-#ifdef _WIN32
- assert(equals(lilv_path_join("C:/a", "b"), "C:/a/b"));
- assert(equals(lilv_path_join("C:\\a", "b"), "C:\\a\\b"));
- assert(equals(lilv_path_join("C:/a", "b/"), "C:/a/b/"));
- assert(equals(lilv_path_join("C:\\a", "b\\"), "C:\\a\\b\\"));
-#endif
-}
-
-static void
-test_path_canonical(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const file_path = lilv_path_join(temp_dir, "lilv_test_file");
-
- FILE* f = fopen(file_path, "w");
- fprintf(f, "test\n");
- fclose(f);
-
-#ifndef _WIN32
- // Test symlink resolution
-
- char* const link_path = lilv_path_join(temp_dir, "lilv_test_link");
-
- assert(!lilv_symlink(file_path, link_path));
-
- char* const real_file_path = lilv_path_canonical(file_path);
- char* const real_link_path = lilv_path_canonical(link_path);
-
- assert(!strcmp(real_file_path, real_link_path));
-
- assert(!lilv_remove(link_path));
- free(real_link_path);
- free(real_file_path);
- free(link_path);
-#endif
-
- // Test dot segment resolution
-
- char* const parent_dir_1 = lilv_path_join(temp_dir, "..");
- char* const parent_dir_2 = lilv_path_parent(temp_dir);
- char* const real_parent_dir_1 = lilv_path_canonical(parent_dir_1);
- char* const real_parent_dir_2 = lilv_path_canonical(parent_dir_2);
-
- assert(!strcmp(real_parent_dir_1, real_parent_dir_2));
-
- // Clean everything up
-
- assert(!lilv_remove(file_path));
- assert(!lilv_remove(temp_dir));
-
- free(real_parent_dir_2);
- free(real_parent_dir_1);
- free(parent_dir_2);
- free(parent_dir_1);
- free(file_path);
- free(temp_dir);
-}
-
-static void
-test_path_exists(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const file_path = lilv_path_join(temp_dir, "lilv_test_file");
-
- assert(!lilv_path_exists(file_path));
-
- FILE* f = fopen(file_path, "w");
- fprintf(f, "test\n");
- fclose(f);
-
- assert(lilv_path_exists(file_path));
-
- assert(!lilv_remove(file_path));
- assert(!lilv_remove(temp_dir));
-
- free(file_path);
- free(temp_dir);
-}
-
-static void
-test_is_directory(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const file_path = lilv_path_join(temp_dir, "lilv_test_file");
-
- assert(lilv_is_directory(temp_dir));
- assert(!lilv_is_directory(file_path)); // Nonexistent
-
- FILE* f = fopen(file_path, "w");
- fprintf(f, "test\n");
- fclose(f);
-
- assert(!lilv_is_directory(file_path)); // File
-
- assert(!lilv_remove(file_path));
- assert(!lilv_remove(temp_dir));
-
- free(file_path);
- free(temp_dir);
-}
-
-static void
-test_copy_file(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const file_path = lilv_path_join(temp_dir, "lilv_test_file");
- char* const copy_path = lilv_path_join(temp_dir, "lilv_test_copy");
-
- FILE* f = fopen(file_path, "w");
- fprintf(f, "test\n");
- fclose(f);
-
- assert(!lilv_copy_file(file_path, copy_path));
- assert(lilv_file_equals(file_path, copy_path));
-
- if (lilv_path_exists("/dev/full")) {
- // Copy short file (error after flushing)
- assert(lilv_copy_file(file_path, "/dev/full") == ENOSPC);
-
- // Copy long file (error during writing)
- f = fopen(file_path, "w");
- for (size_t i = 0; i < 4096; ++i) {
- fprintf(f, "test\n");
- }
- fclose(f);
- assert(lilv_copy_file(file_path, "/dev/full") == ENOSPC);
- }
-
- assert(!lilv_remove(copy_path));
- assert(!lilv_remove(file_path));
- assert(!lilv_remove(temp_dir));
-
- free(copy_path);
- free(file_path);
- free(temp_dir);
-}
-
-static void
-test_flock(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const file_path = lilv_path_join(temp_dir, "lilv_test_file");
-
- FILE* const f1 = fopen(file_path, "w");
- FILE* const f2 = fopen(file_path, "w");
-
- assert(!lilv_flock(f1, true, false));
- assert(lilv_flock(f2, true, false));
- assert(!lilv_flock(f1, false, false));
-
- fclose(f2);
- fclose(f1);
- assert(!lilv_remove(file_path));
- assert(!lilv_remove(temp_dir));
- free(file_path);
- free(temp_dir);
-}
-
-typedef struct {
- size_t n_names;
- char** names;
-} FileList;
-
-static void
-visit(const char* const path, const char* const name, void* const data)
-{
- (void)path;
-
- FileList* file_list = (FileList*)data;
-
- file_list->names =
- (char**)realloc(file_list->names, sizeof(char*) * ++file_list->n_names);
-
- file_list->names[file_list->n_names - 1] = lilv_strdup(name);
-}
-
-static void
-test_dir_for_each(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const path1 = lilv_path_join(temp_dir, "lilv_test_1");
- char* const path2 = lilv_path_join(temp_dir, "lilv_test_2");
-
- FILE* const f1 = fopen(path1, "w");
- FILE* const f2 = fopen(path2, "w");
- fprintf(f1, "test\n");
- fprintf(f2, "test\n");
- fclose(f2);
- fclose(f1);
-
- FileList file_list = {0, NULL};
- lilv_dir_for_each(temp_dir, &file_list, visit);
-
- assert((!strcmp(file_list.names[0], "lilv_test_1") &&
- !strcmp(file_list.names[1], "lilv_test_2")) ||
- (!strcmp(file_list.names[0], "lilv_test_2") &&
- !strcmp(file_list.names[1], "lilv_test_1")));
-
- assert(!lilv_remove(path2));
- assert(!lilv_remove(path1));
- assert(!lilv_remove(temp_dir));
-
- free(file_list.names[0]);
- free(file_list.names[1]);
- free(file_list.names);
- free(path2);
- free(path1);
- free(temp_dir);
-}
-
-static void
-test_create_temporary_directory(void)
-{
- char* const path1 = lilv_create_temporary_directory("lilvXXXXXX");
-
- assert(lilv_is_directory(path1));
-
- char* const path2 = lilv_create_temporary_directory("lilvXXXXXX");
-
- assert(strcmp(path1, path2));
- assert(lilv_is_directory(path2));
-
- assert(!lilv_remove(path2));
- assert(!lilv_remove(path1));
- free(path2);
- free(path1);
-}
-
-static void
-test_create_directories(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
-
- assert(lilv_is_directory(temp_dir));
-
- char* const child_dir = lilv_path_join(temp_dir, "child");
- char* const grandchild_dir = lilv_path_join(child_dir, "grandchild");
-
- assert(!lilv_create_directories(grandchild_dir));
- assert(lilv_is_directory(grandchild_dir));
- assert(lilv_is_directory(child_dir));
-
- char* const file_path = lilv_path_join(temp_dir, "lilv_test_file");
- FILE* const f = fopen(file_path, "w");
-
- fprintf(f, "test\n");
- fclose(f);
-
- assert(lilv_create_directories(file_path));
-
- assert(!lilv_remove(file_path));
- assert(!lilv_remove(grandchild_dir));
- assert(!lilv_remove(child_dir));
- assert(!lilv_remove(temp_dir));
- free(file_path);
- free(child_dir);
- free(grandchild_dir);
- free(temp_dir);
-}
-
-static void
-test_file_equals(void)
-{
- char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX");
- char* const path1 = lilv_path_join(temp_dir, "lilv_test_1");
- char* const path2 = lilv_path_join(temp_dir, "lilv_test_2");
-
- FILE* const f1 = fopen(path1, "w");
- FILE* const f2 = fopen(path2, "w");
- fprintf(f1, "test\n");
- fprintf(f2, "test\n");
-
- assert(lilv_file_equals(path1, path2));
-
- fprintf(f2, "diff\n");
- fflush(f2);
-
- assert(!lilv_file_equals(path1, path2));
-
- fclose(f2);
- fclose(f1);
-
- assert(!lilv_remove(path2));
- assert(!lilv_remove(path1));
- assert(!lilv_remove(temp_dir));
-
- free(path2);
- free(path1);
- free(temp_dir);
-}
-
-int
-main(void)
-{
- test_temp_directory_path();
- test_path_is_absolute();
- test_path_is_child();
- test_path_current();
- test_path_absolute();
- test_path_absolute_child();
- test_path_relative_to();
- test_path_parent();
- test_path_filename();
- test_path_join();
- test_path_canonical();
- test_path_exists();
- test_is_directory();
- test_copy_file();
- test_flock();
- test_dir_for_each();
- test_create_temporary_directory();
- test_create_directories();
- test_file_equals();
-
- return 0;
-}
diff --git a/test/test_get_symbol.c b/test/test_get_symbol.c
index 5337c63..5dc5898 100644
--- a/test/test_get_symbol.c
+++ b/test/test_get_symbol.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_no_author.c b/test/test_no_author.c
index aa91198..396ae9e 100644
--- a/test/test_no_author.c
+++ b/test/test_no_author.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_no_verify.c b/test/test_no_verify.c
index e71c483..66f81e9 100644
--- a/test/test_no_verify.c
+++ b/test/test_no_verify.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_plugin.c b/test/test_plugin.c
index 2a427dc..e2b9b53 100644
--- a/test/test_plugin.c
+++ b/test/test_plugin.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test.lv2/manifest.ttl.in b/test/test_plugin.lv2/manifest.ttl.in
index bc3952c..48b009b 100644
--- a/test/test.lv2/manifest.ttl.in
+++ b/test/test_plugin.lv2/manifest.ttl.in
@@ -3,5 +3,5 @@
<http://example.org/lilv-test-plugin>
a lv2:Plugin ;
- lv2:binary <test@SHLIB_EXT@> ;
- rdfs:seeAlso <test.ttl> .
+ lv2:binary <test_plugin@SHLIB_EXT@> ;
+ rdfs:seeAlso <test_plugin.ttl> .
diff --git a/test/test_plugin.lv2/meson.build b/test/test_plugin.lv2/meson.build
new file mode 100644
index 0000000..e6c54cf
--- /dev/null
+++ b/test/test_plugin.lv2/meson.build
@@ -0,0 +1,24 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+module = shared_module(
+ 'test_plugin',
+ files('test_plugin.c'),
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, zix_dep],
+ gnu_symbol_visibility: 'hidden',
+ name_prefix: '',
+)
+
+extension = '.' + module.full_path().split('.')[-1]
+config = configuration_data({'SHLIB_EXT': extension})
+ttl_files = ['manifest.ttl', 'test_plugin.ttl']
+
+foreach f : ttl_files
+ configure_file(
+ input: files(f + '.in'),
+ output: f,
+ configuration: config,
+ )
+endforeach
+
diff --git a/test/test.lv2/test.c b/test/test_plugin.lv2/test_plugin.c
index 2be34b4..124f64c 100644
--- a/test/test.lv2/test.c
+++ b/test/test_plugin.lv2/test_plugin.c
@@ -1,31 +1,12 @@
-/*
- Lilv Test Plugin
- Copyright 2011-2019 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.
-*/
-
-#define _POSIX_C_SOURCE 200809L
+// Copyright 2011-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lv2/atom/atom.h"
#include "lv2/core/lv2.h"
#include "lv2/state/state.h"
#include "lv2/urid/urid.h"
-
-#ifdef _MSC_VER
-# include <io.h>
-# define mkstemp(pat) _mktemp(pat)
-#endif
+#include "zix/filesystem.h"
+#include "zix/path.h"
#include <stdint.h>
#include <stdio.h>
@@ -34,8 +15,6 @@
#define TEST_URI "http://example.org/lilv-test-plugin"
-#define TMP_TEMPLATE "lilv_testXXXXXX"
-
enum { TEST_INPUT = 0, TEST_OUTPUT = 1, TEST_CONTROL = 2 };
typedef struct {
@@ -46,7 +25,7 @@ typedef struct {
LV2_URID atom_Float;
} uris;
- char tmp_file_path[sizeof(TMP_TEMPLATE)];
+ char* tmp_dir_path;
char* rec_file_path;
FILE* rec_file;
@@ -67,6 +46,7 @@ cleanup(LV2_Handle instance)
test->free_path->free_path(test->free_path->handle, test->rec_file_path);
}
+ free(test->tmp_dir_path);
free(instance);
}
@@ -104,8 +84,7 @@ instantiate(const LV2_Descriptor* descriptor,
return NULL;
}
- strncpy(test->tmp_file_path, TMP_TEMPLATE, strlen(TMP_TEMPLATE) + 1);
- mkstemp(test->tmp_file_path);
+ test->tmp_dir_path = zix_temp_directory_path(NULL);
LV2_State_Make_Path* make_path = NULL;
@@ -137,8 +116,9 @@ instantiate(const LV2_Descriptor* descriptor,
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");
+ } else {
+ fprintf(test->rec_file, "instantiate\n");
}
- fprintf(test->rec_file, "instantiate\n");
}
return (LV2_Handle)test;
@@ -272,15 +252,26 @@ save(LV2_Handle instance,
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
if (map_path) {
- FILE* file = fopen(plugin->tmp_file_path, "w");
+ const char* const file_name = "temp_file.txt";
+
+ char* const tmp_file_path =
+ zix_path_join(NULL, plugin->tmp_dir_path, file_name);
+
+ FILE* file = fopen(tmp_file_path, "w");
+ if (!file) {
+ fprintf(stderr, "error: Failed to open file %s\n", tmp_file_path);
+ free(tmp_file_path);
+ return LV2_STATE_ERR_UNKNOWN;
+ }
+
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);
+
+ char* apath = map_path->abstract_path(map_path->handle, tmp_file_path);
+ char* apath2 = map_path->abstract_path(map_path->handle, tmp_file_path);
+ free(tmp_file_path);
+ if (!!strcmp(apath, apath2)) {
+ fprintf(stderr, "error: Path %s != %s\n", apath, apath2);
}
store(callback_data,
@@ -381,7 +372,7 @@ restore(LV2_Handle instance,
char str[8];
size_t n_read = fread(str, 1, sizeof(str), f);
fclose(f);
- if (strncmp(str, "Hello\n", n_read)) {
+ if (!!strncmp(str, "Hello\n", n_read)) {
fprintf(
stderr, "error: Restored bad file contents `%s' != `Hello'\n", str);
}
@@ -432,10 +423,5 @@ LV2_SYMBOL_EXPORT
const LV2_Descriptor*
lv2_descriptor(uint32_t index)
{
- switch (index) {
- case 0:
- return &descriptor;
- default:
- return NULL;
- }
+ return index ? NULL : &descriptor;
}
diff --git a/test/test.lv2/test.ttl.in b/test/test_plugin.lv2/test_plugin.ttl.in
index 1c16b4c..1c16b4c 100644
--- a/test/test.lv2/test.ttl.in
+++ b/test/test_plugin.lv2/test_plugin.ttl.in
diff --git a/test/test_port.c b/test/test_port.c
index 3ea0abc..e05dcde 100644
--- a/test/test_port.c
+++ b/test/test_port.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_preset.c b/test/test_preset.c
index 151b0e6..d091318 100644
--- a/test/test_preset.c
+++ b/test/test_preset.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_project.c b/test/test_project.c
index 7da42bd..cfce35a 100644
--- a/test/test_project.c
+++ b/test/test_project.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_project_no_author.c b/test/test_project_no_author.c
index 3ee9c85..5b0e57d 100644
--- a/test/test_project_no_author.c
+++ b/test/test_project_no_author.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_prototype.c b/test/test_prototype.c
index 10a3657..4e17a63 100644
--- a/test/test_prototype.c
+++ b/test/test_prototype.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_reload_bundle.c b/test/test_reload_bundle.c
index a8f9044..a2630fc 100644
--- a/test/test_reload_bundle.c
+++ b/test/test_reload_bundle.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_replace_version.c b/test/test_replace_version.c
index 7ec5519..c6fb3e6 100644
--- a/test/test_replace_version.c
+++ b/test/test_replace_version.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_state.c b/test/test_state.c
index 533c3a9..67325d2 100644
--- a/test/test_state.c
+++ b/test/test_state.c
@@ -1,31 +1,19 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
#include "lilv_test_uri_map.h"
#include "lilv_test_utils.h"
-#include "../src/filesystem.h"
-
#include "lilv/lilv.h"
#include "lv2/core/lv2.h"
#include "lv2/state/state.h"
#include "lv2/urid/urid.h"
#include "serd/serd.h"
+#include "zix/allocator.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
#ifdef _WIN32
# include <direct.h>
@@ -128,11 +116,17 @@ create_test_directories(void)
/* On MacOS, temporary directories from mkdtemp involve symlinks, so
resolve it here so that path comparisons in tests work. */
- dirs.top = lilv_path_canonical(top);
- dirs.shared = lilv_path_join(dirs.top, "shared");
- dirs.scratch = lilv_path_join(dirs.shared, "scratch");
- dirs.copy = lilv_path_join(dirs.shared, "copy");
- dirs.link = lilv_path_join(dirs.shared, "link");
+ dirs.top = zix_canonical_path(NULL, top);
+ dirs.shared = zix_path_join(NULL, dirs.top, "shared");
+ dirs.scratch = zix_path_join(NULL, dirs.shared, "scratch");
+ dirs.copy = zix_path_join(NULL, dirs.shared, "copy");
+ dirs.link = zix_path_join(NULL, dirs.shared, "link");
+
+ assert(dirs.top);
+ assert(dirs.shared);
+ assert(dirs.scratch);
+ assert(dirs.copy);
+ assert(dirs.link);
assert(!mkdir(dirs.shared, 0700));
assert(!mkdir(dirs.scratch, 0700));
@@ -157,28 +151,28 @@ remove_file(const char* path, const char* name, void* data)
{
(void)data;
- char* const full_path = lilv_path_join(path, name);
- assert(!lilv_remove(full_path));
+ char* const full_path = zix_path_join(NULL, path, name);
+ assert(!zix_remove(full_path));
free(full_path);
}
static void
cleanup_test_directories(const TestDirectories dirs)
{
- lilv_dir_for_each(dirs.scratch, NULL, remove_file);
- lilv_dir_for_each(dirs.copy, NULL, remove_file);
- lilv_dir_for_each(dirs.link, NULL, remove_file);
-
- assert(!lilv_remove(dirs.link));
- assert(!lilv_remove(dirs.copy));
- assert(!lilv_remove(dirs.scratch));
- assert(!lilv_remove(dirs.shared));
- assert(!lilv_remove(dirs.top));
-
- free(dirs.link);
- free(dirs.copy);
- free(dirs.scratch);
- free(dirs.shared);
+ zix_dir_for_each(dirs.scratch, NULL, remove_file);
+ zix_dir_for_each(dirs.copy, NULL, remove_file);
+ zix_dir_for_each(dirs.link, NULL, remove_file);
+
+ assert(!zix_remove(dirs.link));
+ assert(!zix_remove(dirs.copy));
+ assert(!zix_remove(dirs.scratch));
+ assert(!zix_remove(dirs.shared));
+ assert(!zix_remove(dirs.top));
+
+ zix_free(NULL, dirs.link);
+ zix_free(NULL, dirs.copy);
+ zix_free(NULL, dirs.scratch);
+ zix_free(NULL, dirs.shared);
free(dirs.top);
}
@@ -194,20 +188,24 @@ get_port_value(const char* port_symbol,
*size = sizeof(float);
*type = ctx->atom_Float;
return &ctx->in;
- } else if (!strcmp(port_symbol, "output")) {
+ }
+
+ if (!strcmp(port_symbol, "output")) {
*size = sizeof(float);
*type = ctx->atom_Float;
return &ctx->out;
- } else if (!strcmp(port_symbol, "control")) {
+ }
+
+ if (!strcmp(port_symbol, "control")) {
*size = sizeof(float);
*type = ctx->atom_Float;
return &ctx->control;
- } else {
- fprintf(
- stderr, "error: get_port_value for nonexistent port `%s'\n", port_symbol);
- *size = *type = 0;
- return NULL;
}
+
+ fprintf(
+ stderr, "error: get_port_value for nonexistent port `%s'\n", port_symbol);
+ *size = *type = 0;
+ return NULL;
}
static void
@@ -239,16 +237,14 @@ make_scratch_path(LV2_State_Make_Path_Handle handle, const char* path)
{
TestDirectories* dirs = (TestDirectories*)handle;
- return lilv_path_join(dirs->scratch, path);
+ return zix_path_join(NULL, dirs->scratch, path);
}
static const LilvPlugin*
load_test_plugin(const TestContext* const ctx)
{
LilvWorld* world = ctx->env->world;
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(LILV_TEST_BUNDLE);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, LILV_TEST_BUNDLE);
LilvNode* plugin_uri = lilv_new_uri(world, TEST_PLUGIN_URI);
lilv_world_load_bundle(world, bundle_uri);
@@ -258,8 +254,6 @@ load_test_plugin(const TestContext* const ctx)
lilv_node_free(plugin_uri);
lilv_node_free(bundle_uri);
- serd_node_free(&bundle);
- free(abs_bundle);
assert(plugin);
return plugin;
@@ -565,7 +559,8 @@ count_statements(const char* path)
SerdNode uri = serd_node_new_file_uri((const uint8_t*)path, NULL, NULL, true);
- assert(!serd_reader_read_file(reader, uri.buf));
+ assert(uri.buf);
+ assert(!serd_reader_read_file(reader, (const uint8_t*)uri.buf));
serd_node_free(&uri);
serd_reader_free(reader);
@@ -601,11 +596,11 @@ test_to_files(void)
assert(ctx->out == 1.0);
// Check that the test plugin has made its recording scratch file
- char* const recfile_path = lilv_path_join(dirs.scratch, "recfile");
- assert(lilv_path_exists(recfile_path));
+ char* const recfile_path = zix_path_join(NULL, dirs.scratch, "recfile");
+ assert(zix_file_type(recfile_path) == ZIX_FILE_TYPE_REGULAR);
// Get state
- char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2");
+ char* const bundle_1_path = zix_path_join(NULL, dirs.top, "state1.lv2");
LilvState* const state_1 =
state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path);
@@ -613,8 +608,8 @@ test_to_files(void)
assert(lilv_state_get_num_properties(state_1) == 10);
// Check that a snapshop of the recfile was created
- char* const recfile_copy_1 = lilv_path_join(dirs.copy, "recfile");
- assert(lilv_path_exists(recfile_copy_1));
+ char* const recfile_copy_1 = zix_path_join(NULL, dirs.copy, "recfile");
+ assert(zix_file_type(recfile_copy_1) == ZIX_FILE_TYPE_REGULAR);
// Save state to a bundle
assert(!lilv_state_save(ctx->env->world,
@@ -626,24 +621,28 @@ test_to_files(void)
"state.ttl"));
// Check that a manifest exists
- char* const manifest_path = lilv_path_join(bundle_1_path, "manifest.ttl");
- assert(lilv_path_exists(manifest_path));
+ char* const manifest_path =
+ zix_path_join(NULL, bundle_1_path, "manifest.ttl");
+ assert(zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR);
// Check that the expected statements are in the manifest file
assert(count_statements(manifest_path) == 3);
// Check that a link to the recfile exists in the saved bundle
- char* const recfile_link_1 = lilv_path_join(bundle_1_path, "recfile");
- assert(lilv_path_exists(recfile_link_1));
+ char* const recfile_link_1 = zix_path_join(NULL, bundle_1_path, "recfile");
+ assert(zix_file_type(recfile_link_1) == ZIX_FILE_TYPE_REGULAR);
+#ifndef _WIN32
+ assert(zix_symlink_type(recfile_link_1) == ZIX_FILE_TYPE_SYMLINK);
+#endif
// Check that link points to the corresponding copy
- assert(lilv_file_equals(recfile_link_1, recfile_copy_1));
+ assert(zix_file_equals(NULL, recfile_link_1, recfile_copy_1));
// Run plugin again to modify recording file data
lilv_instance_run(instance, 2);
// Get updated state
- char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2");
+ char* const bundle_2_path = zix_path_join(NULL, dirs.top, "state2.lv2");
LilvState* const state_2 =
state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path);
@@ -657,33 +656,36 @@ test_to_files(void)
"state.ttl"));
// Check that a new snapshop of the recfile was created
- char* const recfile_copy_2 = lilv_path_join(dirs.copy, "recfile.2");
- assert(lilv_path_exists(recfile_copy_2));
+ char* const recfile_copy_2 = zix_path_join(NULL, dirs.copy, "recfile.2");
+ assert(zix_file_type(recfile_copy_2) == ZIX_FILE_TYPE_REGULAR);
// Check that a link to the recfile exists in the updated bundle
- char* const recfile_link_2 = lilv_path_join(bundle_2_path, "recfile");
- assert(lilv_path_exists(recfile_link_2));
+ char* const recfile_link_2 = zix_path_join(NULL, bundle_2_path, "recfile");
+ assert(zix_file_type(recfile_link_2) == ZIX_FILE_TYPE_REGULAR);
+#ifndef _WIN32
+ assert(zix_symlink_type(recfile_link_2) == ZIX_FILE_TYPE_SYMLINK);
+#endif
// Check that link points to the corresponding copy
- assert(lilv_file_equals(recfile_link_2, recfile_copy_2));
+ assert(zix_file_equals(NULL, recfile_link_2, recfile_copy_2));
lilv_instance_free(instance);
- lilv_dir_for_each(bundle_2_path, NULL, remove_file);
- lilv_dir_for_each(bundle_1_path, NULL, remove_file);
- assert(!lilv_remove(bundle_2_path));
- assert(!lilv_remove(bundle_1_path));
+ zix_dir_for_each(bundle_2_path, NULL, remove_file);
+ zix_dir_for_each(bundle_1_path, NULL, remove_file);
+ assert(!zix_remove(bundle_2_path));
+ assert(!zix_remove(bundle_1_path));
cleanup_test_directories(dirs);
- free(recfile_link_2);
- free(recfile_copy_2);
+ zix_free(NULL, recfile_link_2);
+ zix_free(NULL, recfile_copy_2);
lilv_state_free(state_2);
- free(bundle_2_path);
- free(recfile_link_1);
- free(manifest_path);
- free(recfile_copy_1);
+ zix_free(NULL, bundle_2_path);
+ zix_free(NULL, recfile_link_1);
+ zix_free(NULL, manifest_path);
+ zix_free(NULL, recfile_copy_1);
lilv_state_free(state_1);
- free(bundle_1_path);
- free(recfile_path);
+ zix_free(NULL, bundle_1_path);
+ zix_free(NULL, recfile_path);
test_context_free(ctx);
}
@@ -706,7 +708,7 @@ test_multi_save(void)
assert(instance);
// Get state
- char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2");
+ char* const bundle_1_path = zix_path_join(NULL, dirs.top, "state1.lv2");
LilvState* const state_1 =
state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path);
@@ -720,12 +722,13 @@ test_multi_save(void)
"state.ttl"));
// Check that a manifest exists
- char* const manifest_path = lilv_path_join(bundle_1_path, "manifest.ttl");
- assert(lilv_path_exists(manifest_path));
+ char* const manifest_path =
+ zix_path_join(NULL, bundle_1_path, "manifest.ttl");
+ assert(zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR);
// Check that the state file exists
- char* const state_path = lilv_path_join(bundle_1_path, "state.ttl");
- assert(lilv_path_exists(state_path));
+ char* const state_path = zix_path_join(NULL, bundle_1_path, "state.ttl");
+ assert(zix_file_type(state_path) == ZIX_FILE_TYPE_REGULAR);
// Check that the expected statements are in the files
assert(count_statements(manifest_path) == 3);
@@ -741,14 +744,14 @@ test_multi_save(void)
"state.ttl"));
// Check that everything is the same
- assert(lilv_path_exists(manifest_path));
- assert(lilv_path_exists(state_path));
+ assert(zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR);
+ assert(zix_file_type(state_path) == ZIX_FILE_TYPE_REGULAR);
assert(count_statements(manifest_path) == 3);
assert(count_statements(state_path) == 21);
lilv_instance_free(instance);
- lilv_dir_for_each(bundle_1_path, NULL, remove_file);
- lilv_remove(bundle_1_path);
+ zix_dir_for_each(bundle_1_path, NULL, remove_file);
+ zix_remove(bundle_1_path);
cleanup_test_directories(dirs);
free(state_path);
@@ -786,7 +789,7 @@ test_files_round_trip(void)
assert(ctx->out == 1.0);
// Save first state to a bundle
- char* const bundle_1_1_path = lilv_path_join(dirs.top, "state1_1.lv2");
+ char* const bundle_1_1_path = zix_path_join(NULL, dirs.top, "state1_1.lv2");
LilvState* const state_1_1 =
state_from_instance(plugin, instance, ctx, &dirs, bundle_1_1_path);
@@ -799,7 +802,7 @@ test_files_round_trip(void)
"state.ttl"));
// Save first state to another bundle
- char* const bundle_1_2_path = lilv_path_join(dirs.top, "state1_2.lv2");
+ char* const bundle_1_2_path = zix_path_join(NULL, dirs.top, "state1_2.lv2");
LilvState* const state_1_2 =
state_from_instance(plugin, instance, ctx, &dirs, bundle_1_2_path);
@@ -812,8 +815,10 @@ test_files_round_trip(void)
"state.ttl"));
// Load both first state bundles and check that the results are equal
- char* const state_1_1_path = lilv_path_join(bundle_1_1_path, "state.ttl");
- char* const state_1_2_path = lilv_path_join(bundle_1_2_path, "state.ttl");
+ char* const state_1_1_path =
+ zix_path_join(NULL, bundle_1_1_path, "state.ttl");
+ char* const state_1_2_path =
+ zix_path_join(NULL, bundle_1_2_path, "state.ttl");
LilvState* state_1_1_loaded =
lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_1_1_path);
@@ -829,7 +834,7 @@ test_files_round_trip(void)
lilv_instance_run(instance, 2);
// Save updated state to a bundle
- char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2");
+ char* const bundle_2_path = zix_path_join(NULL, dirs.top, "state2.lv2");
LilvState* const state_2 =
state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path);
@@ -842,7 +847,7 @@ test_files_round_trip(void)
"state.ttl"));
// Load updated state bundle and check that it differs from the others
- char* const state_2_path = lilv_path_join(bundle_2_path, "state.ttl");
+ char* const state_2_path = zix_path_join(NULL, bundle_2_path, "state.ttl");
LilvState* state_2_loaded =
lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_2_path);
@@ -851,12 +856,12 @@ test_files_round_trip(void)
assert(!lilv_state_equals(state_1_1_loaded, state_2_loaded));
lilv_instance_free(instance);
- lilv_dir_for_each(bundle_1_1_path, NULL, remove_file);
- lilv_dir_for_each(bundle_1_2_path, NULL, remove_file);
- lilv_dir_for_each(bundle_2_path, NULL, remove_file);
- lilv_remove(bundle_1_1_path);
- lilv_remove(bundle_1_2_path);
- lilv_remove(bundle_2_path);
+ zix_dir_for_each(bundle_1_1_path, NULL, remove_file);
+ zix_dir_for_each(bundle_1_2_path, NULL, remove_file);
+ zix_dir_for_each(bundle_2_path, NULL, remove_file);
+ zix_remove(bundle_1_1_path);
+ zix_remove(bundle_1_2_path);
+ zix_remove(bundle_2_path);
cleanup_test_directories(dirs);
lilv_state_free(state_2_loaded);
@@ -904,7 +909,7 @@ test_world_round_trip(void)
assert(ctx->out == 1.0);
// Save state to a bundle
- char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/");
+ char* const bundle_path = zix_path_join(NULL, dirs.top, "state.lv2/");
LilvState* const start_state =
state_from_instance(plugin, instance, ctx, &dirs, bundle_path);
@@ -969,7 +974,7 @@ test_label_round_trip(void)
lilv_state_set_label(state, "Monopoly on violence");
// Save to a bundle
- char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/");
+ char* const bundle_path = zix_path_join(NULL, dirs.top, "state.lv2/");
assert(!lilv_state_save(ctx->env->world,
&ctx->map,
&ctx->unmap,
@@ -979,7 +984,7 @@ test_label_round_trip(void)
"state.ttl"));
// Load bundle and check the label and that the states are equal
- char* const state_path = lilv_path_join(bundle_path, "state.ttl");
+ char* const state_path = zix_path_join(NULL, bundle_path, "state.ttl");
LilvState* const loaded =
lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_path);
@@ -1020,6 +1025,18 @@ test_bad_subject(void)
}
static void
+test_missing_path(void)
+{
+ TestContext* const ctx = test_context_new();
+ LilvState* const state = lilv_state_new_from_file(
+ ctx->env->world, &ctx->map, NULL, "/does/not/exist");
+
+ assert(!state);
+
+ test_context_free(ctx);
+}
+
+static void
count_file(const char* path, const char* name, void* data)
{
(void)path;
@@ -1056,7 +1073,7 @@ test_delete(void)
assert(ctx->out == 1.0);
// Save state to a bundle
- char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/");
+ char* const bundle_path = zix_path_join(NULL, dirs.top, "state.lv2/");
LilvState* const state =
state_from_instance(plugin, instance, ctx, &dirs, bundle_path);
@@ -1070,7 +1087,7 @@ test_delete(void)
// Count the number of shared files before doing anything
unsigned n_shared_files_before = 0;
- lilv_dir_for_each(dirs.shared, &n_shared_files_before, count_file);
+ zix_dir_for_each(dirs.shared, &n_shared_files_before, count_file);
lilv_instance_free(instance);
@@ -1079,11 +1096,11 @@ test_delete(void)
// Ensure the number of shared files is the same after deletion
unsigned n_shared_files_after = 0;
- lilv_dir_for_each(dirs.shared, &n_shared_files_after, count_file);
+ zix_dir_for_each(dirs.shared, &n_shared_files_after, count_file);
assert(n_shared_files_before == n_shared_files_after);
// Ensure the state directory has been deleted
- assert(!lilv_path_exists(bundle_path));
+ assert(zix_file_type(bundle_path) == ZIX_FILE_TYPE_NONE);
cleanup_test_directories(dirs);
@@ -1107,6 +1124,7 @@ main(void)
test_world_round_trip();
test_label_round_trip();
test_bad_subject();
+ test_missing_path();
test_delete();
return 0;
diff --git a/test/test_string.c b/test/test_string.c
index 2d610bb..48021ed 100644
--- a/test/test_string.c
+++ b/test/test_string.c
@@ -1,20 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
-
-#define _POSIX_C_SOURCE 200809L /* for setenv */
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
@@ -36,19 +21,27 @@ main(void)
#ifndef _WIN32
char* s = NULL;
+ const char* const home = getenv("HOME");
+
setenv("LILV_TEST_1", "test", 1);
- char* home_foo = lilv_strjoin(getenv("HOME"), "/foo", NULL);
+
assert(!strcmp((s = lilv_expand("$LILV_TEST_1")), "test"));
free(s);
- assert(!strcmp((s = lilv_expand("~")), getenv("HOME")));
- free(s);
- assert(!strcmp((s = lilv_expand("~foo")), "~foo"));
- free(s);
- assert(!strcmp((s = lilv_expand("~/foo")), home_foo));
- free(s);
+ if (home) {
+ assert(!strcmp((s = lilv_expand("~")), home));
+ free(s);
+ assert(!strcmp((s = lilv_expand("~foo")), "~foo"));
+ free(s);
+
+ char* const home_foo = lilv_strjoin(home, "/foo", NULL);
+ assert(!strcmp((s = lilv_expand("~/foo")), home_foo));
+ free(s);
+ free(home_foo);
+ }
+
assert(!strcmp((s = lilv_expand("$NOT_A_VAR")), "$NOT_A_VAR"));
free(s);
- free(home_foo);
+
unsetenv("LILV_TEST_1");
#endif
diff --git a/test/test_ui.c b/test/test_ui.c
index d14f54f..78ea871 100644
--- a/test/test_ui.c
+++ b/test/test_ui.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_util.c b/test/test_util.c
index 8c8f36a..2e609da 100644
--- a/test/test_util.c
+++ b/test/test_util.c
@@ -1,67 +1,38 @@
-/*
- Copyright 2007-2020 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.
-*/
-
-#define _XOPEN_SOURCE 600 /* for mkstemp */
+// Copyright 2007-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
-#ifdef _WIN32
-# include "lilv_internal.h"
-#endif
+#include "lilv_test_utils.h"
-#include "../src/filesystem.h"
-
-#ifdef _WIN32
-# include <io.h>
-# define mkstemp(pat) _mktemp(pat)
-#endif
+#include "lilv/lilv.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
#include <assert.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
int
main(void)
{
- assert(!lilv_path_canonical(NULL));
+ char* const dir = lilv_create_temporary_directory("lilv_test_util_XXXXXX");
- char a_path[16];
- char b_path[16];
- strncpy(a_path, "copy_a_XXXXXX", sizeof(a_path));
- strncpy(b_path, "copy_b_XXXXXX", sizeof(b_path));
- mkstemp(a_path);
- mkstemp(b_path);
+ char* const a_path = zix_path_join(NULL, dir, "copy_a_XXXXXX");
+ char* const b_path = zix_path_join(NULL, dir, "copy_b_XXXXXX");
- FILE* fa = fopen(a_path, "w");
- FILE* fb = fopen(b_path, "w");
+ FILE* const fa = fopen(a_path, "w");
+ FILE* const fb = fopen(b_path, "w");
fprintf(fa, "AA\n");
fprintf(fb, "AB\n");
- fclose(fa);
fclose(fb);
+ fclose(fa);
- assert(lilv_copy_file("does/not/exist", "copy"));
- assert(lilv_copy_file(a_path, "not/a/dir/copy"));
- assert(!lilv_copy_file(a_path, "copy_c"));
- assert(!lilv_file_equals(a_path, b_path));
- assert(lilv_file_equals(a_path, a_path));
- assert(lilv_file_equals(a_path, "copy_c"));
- assert(!lilv_file_equals("does/not/exist", b_path));
- assert(!lilv_file_equals(a_path, "does/not/exist"));
- assert(!lilv_file_equals("does/not/exist", "/does/not/either"));
+ assert(!zix_remove(a_path));
+ assert(!zix_remove(b_path));
+ assert(!zix_remove(dir));
+ lilv_free(b_path);
+ lilv_free(a_path);
+ lilv_free(dir);
return 0;
}
diff --git a/test/test_value.c b/test/test_value.c
index 8061029..a37c886 100644
--- a/test/test_value.c
+++ b/test/test_value.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_verify.c b/test/test_verify.c
index d20712e..e066751 100644
--- a/test/test_verify.c
+++ b/test/test_verify.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/test/test_world.c b/test/test_world.c
index 762907f..fda8595 100644
--- a/test/test_world.c
+++ b/test/test_world.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2020 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.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
diff --git a/tools/.clang-tidy b/tools/.clang-tidy
new file mode 100644
index 0000000..d8434e2
--- /dev/null
+++ b/tools/.clang-tidy
@@ -0,0 +1,16 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+Checks: >
+ -*-magic-numbers,
+ -android-cloexec-fopen,
+ -bugprone-narrowing-conversions,
+ -cert-err33-c,
+ -cert-err34-c,
+ -cppcoreguidelines-avoid-non-const-global-variables,
+ -cppcoreguidelines-narrowing-conversions,
+ -hicpp-signed-bitwise,
+ -llvm-header-guard,
+ -misc-no-recursion,
+ -readability-function-cognitive-complexity,
+InheritParentConfig: true
diff --git a/tools/bench.h b/tools/bench.h
new file mode 100644
index 0000000..d87102e
--- /dev/null
+++ b/tools/bench.h
@@ -0,0 +1,38 @@
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+/**
+ @file bench.h A simple real-time benchmarking API.
+*/
+
+#ifndef BENCH_H
+#define BENCH_H
+
+#include <time.h>
+
+typedef struct timespec BenchmarkTime;
+
+static inline double
+bench_elapsed_s(const BenchmarkTime* start, const BenchmarkTime* end)
+{
+ return ((end->tv_sec - start->tv_sec) +
+ ((end->tv_nsec - start->tv_nsec) * 0.000000001));
+}
+
+static inline BenchmarkTime
+bench_start(void)
+{
+ BenchmarkTime start_t;
+ clock_gettime(CLOCK_REALTIME, &start_t);
+ return start_t;
+}
+
+static inline double
+bench_end(const BenchmarkTime* start_t)
+{
+ BenchmarkTime end_t;
+ clock_gettime(CLOCK_REALTIME, &end_t);
+ return bench_elapsed_s(start_t, &end_t);
+}
+
+#endif /* BENCH_H */
diff --git a/utils/lilv.bash_completion b/tools/lilv.bash_completion
index 4a553a7..d5de5e2 100644
--- a/utils/lilv.bash_completion
+++ b/tools/lilv.bash_completion
@@ -1,10 +1,9 @@
-# Bash auto-completion script written for lv2info and lv2jack.
-# Could be adapted to any other program that takes an
-# LV2 plugin URI as parameter.
+# Copyright 2012-2022 David Robillard <d@drobilla.net>
+# Copyright 2009 Lars Luthman <lars.luthman@gmail.com>
+# SPDX-License-Identifier: 0BSD OR ISC
-# 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.
+# Bash auto-completion script written for lv2info. Could be adapted to any
+# other program that takes an LV2 plugin URI as parameter.
# For some reason Bash splits the command line not only at whitespace
# but also at ':' signs before putting the parts into COMP_WORDS.
@@ -54,6 +53,3 @@ function _lv2info() {
}
complete -F _lv2info lv2info
-
-# And the same for lv2jack.
-complete -F _lv2info lv2jack
diff --git a/utils/lv2apply.c b/tools/lv2apply.c
index e042999..9c74bf3 100644
--- a/utils/lv2apply.c
+++ b/tools/lv2apply.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv/lilv.h"
@@ -219,11 +206,11 @@ print_usage(int status)
fprintf(status ? stderr : stdout,
"Usage: lv2apply [OPTION]... PLUGIN_URI\n"
"Apply an LV2 plugin to an audio file.\n\n"
- " -i IN_FILE Input file\n"
- " -o OUT_FILE Output file\n"
- " -c SYM VAL Control value\n"
- " --help Display this help and exit\n"
- " --version Display version information and exit\n");
+ " -V, --version Display version information and exit\n"
+ " -c SYM VAL Control value\n"
+ " -h, --help Display this help and exit\n"
+ " -i IN_FILE Input file\n"
+ " -o OUT_FILE Output file\n");
return status;
}
@@ -236,13 +223,13 @@ main(int argc, char** argv)
/* Parse command line arguments */
const char* plugin_uri = NULL;
for (int i = 1; i < argc; ++i) {
- if (!strcmp(argv[i], "--version")) {
+ if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
free(self.params);
print_version();
return 0;
}
- if (!strcmp(argv[i], "--help")) {
+ if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
free(self.params);
return print_usage(0);
}
diff --git a/utils/lv2bench.c b/tools/lv2bench.c
index c355727..4b7eef7 100644
--- a/utils/lv2bench.c
+++ b/tools/lv2bench.c
@@ -1,20 +1,5 @@
-/*
- Copyright 2012-2019 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.
-*/
-
-#define _POSIX_C_SOURCE 200809L
+// Copyright 2012-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv/lilv.h"
#include "lv2/atom/atom.h"
@@ -60,11 +45,11 @@ print_usage(void)
printf("lv2bench - Benchmark all installed and supported LV2 plugins.\n");
printf("Usage: lv2bench [OPTIONS] [PLUGIN_URI]\n");
printf("\n");
+ printf(" -V, --version Display version information and exit\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
@@ -79,7 +64,7 @@ bench(const LilvPlugin* p, uint32_t sample_count, uint32_t block_size)
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 buf = (float*)calloc(block_size * 2UL, sizeof(float));
float* const in = buf;
float* const out = buf + block_size;
if (!buf) {
@@ -216,12 +201,12 @@ main(int argc, char** argv)
int a = 1;
for (; a < argc; ++a) {
- if (!strcmp(argv[a], "--version")) {
+ if (!strcmp(argv[a], "-V") || !strcmp(argv[a], "--version")) {
print_version();
return 0;
}
- if (!strcmp(argv[a], "--help")) {
+ if (!strcmp(argv[a], "-h") || !strcmp(argv[a], "--help")) {
print_usage();
return 0;
}
diff --git a/utils/lv2info.c b/tools/lv2info.c
index 81a3ed4..55acd09 100644
--- a/utils/lv2info.c
+++ b/tools/lv2info.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_config.h"
@@ -343,10 +330,10 @@ 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"
+ " -V, --version Display version information and exit\n"
+ " -h, --help Display this help and exit\n"
+ " -m FILE Add record of plugin to manifest FILE\n"
+ " -p FILE Write Turtle description of plugin to FILE\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");
@@ -364,12 +351,12 @@ main(int argc, char** argv)
const char* manifest_file = NULL;
const char* plugin_uri = NULL;
for (int i = 1; i < argc; ++i) {
- if (!strcmp(argv[i], "--version")) {
+ if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
print_version();
return 0;
}
- if (!strcmp(argv[i], "--help")) {
+ if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
print_usage();
return 0;
}
diff --git a/utils/lv2ls.c b/tools/lv2ls.c
index 9226b89..8203262 100644
--- a/utils/lv2ls.c
+++ b/tools/lv2ls.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 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.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_config.h"
@@ -53,9 +40,9 @@ print_usage(void)
printf("Usage: lv2ls [OPTION]...\n");
printf("List all installed LV2 plugins.\n");
printf("\n");
+ printf(" -V, --version Display version information and exit\n");
+ printf(" -h, --help Display this help and exit\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(
@@ -69,10 +56,10 @@ main(int argc, char** argv)
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")) {
+ } else if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
print_version();
return 0;
- } else if (!strcmp(argv[i], "--help")) {
+ } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
print_usage();
return 0;
} else {
diff --git a/tools/meson.build b/tools/meson.build
new file mode 100644
index 0000000..6fa08e3
--- /dev/null
+++ b/tools/meson.build
@@ -0,0 +1,91 @@
+# Copyright 2021-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR ISC
+
+include_dirs = include_directories('../src')
+
+#############################
+# "Basic" (Lilv-Only) Tools #
+#############################
+
+basic_tools = [
+ 'lv2info',
+ 'lv2ls',
+]
+
+foreach tool : basic_tools
+ exe = executable(
+ tool,
+ files(tool + '.c'),
+ c_args: c_suppressions,
+ dependencies: lilv_dep,
+ include_directories: include_dirs,
+ install: true,
+ )
+
+ meson.override_find_program(tool, exe)
+
+ install_man(files('..' / 'doc' / tool + '.1'))
+endforeach
+
+install_data(
+ files('lilv.bash_completion'),
+ install_dir: get_option('sysconfdir') / 'bash_completion.d',
+ rename: 'lilv',
+)
+
+###########################
+# lv2apply (uses sndfile) #
+###########################
+
+sndfile_dep = dependency(
+ 'sndfile',
+ version: '>= 1.0.0',
+ required: get_option('tools'),
+)
+
+if sndfile_dep.found()
+ lv2apply = executable(
+ 'lv2apply',
+ files('lv2apply.c'),
+ c_args: c_suppressions,
+ dependencies: [lilv_dep, sndfile_dep],
+ include_directories: include_dirs,
+ install: true,
+ )
+
+ meson.override_find_program('lv2apply', lv2apply)
+
+ install_man(files('..' / 'doc' / 'lv2apply.1'))
+endif
+
+#################################
+# lv2bench (uses clock_gettime) #
+#################################
+
+if host_machine.system() != 'windows'
+ rt_dep = cc.find_library('rt', required: false)
+
+ clock_gettime_code = '''#include <time.h>
+int main(void) { struct timespec t; return clock_gettime(CLOCK_MONOTONIC, &t); }
+'''
+
+ if cc.compiles(
+ clock_gettime_code,
+ args: platform_defines,
+ dependencies: [rt_dep],
+ name: 'clock_gettime',
+ )
+ lv2bench = executable(
+ 'lv2bench',
+ files('lv2bench.c'),
+ c_args: c_suppressions,
+ dependencies: [lilv_dep, rt_dep, sndfile_dep],
+ include_directories: include_dirs,
+ install: true,
+ )
+
+ meson.override_find_program('lv2bench', lv2bench)
+
+ install_man(files('..' / 'doc' / 'lv2bench.1'))
+ endif
+endif
diff --git a/utils/uri_table.h b/tools/uri_table.h
index 5a337a3..e17b02a 100644
--- a/utils/uri_table.h
+++ b/tools/uri_table.h
@@ -1,18 +1,5 @@
-/*
- Copyright 2011-2019 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.
-*/
+// Copyright 2011-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
/**
@file uri_table.h A toy URI map/unmap implementation.
diff --git a/utils/bench.h b/utils/bench.h
deleted file mode 100644
index 505631f..0000000
--- a/utils/bench.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Copyright 2011-2019 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.
-*/
-
-/**
- @file bench.h A simple real-time benchmarking API.
-*/
-
-#ifndef BENCH_H
-#define BENCH_H
-
-#define _POSIX_C_SOURCE 200809L
-
-#include <time.h>
-
-typedef struct timespec BenchmarkTime;
-
-static inline double
-bench_elapsed_s(const BenchmarkTime* start, const BenchmarkTime* end)
-{
- return ((end->tv_sec - start->tv_sec) +
- ((end->tv_nsec - start->tv_nsec) * 0.000000001));
-}
-
-static inline BenchmarkTime
-bench_start(void)
-{
- BenchmarkTime start_t;
- clock_gettime(CLOCK_REALTIME, &start_t);
- return start_t;
-}
-
-static inline double
-bench_end(const BenchmarkTime* start_t)
-{
- BenchmarkTime end_t;
- clock_gettime(CLOCK_REALTIME, &end_t);
- return bench_elapsed_s(start_t, &end_t);
-}
-
-#endif /* BENCH_H */
diff --git a/utils/lilv-bench.c b/utils/lilv-bench.c
deleted file mode 100644
index 56b7fee..0000000
--- a/utils/lilv-bench.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Copyright 2007-2012 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 "lilv/lilv.h"
-
-int
-main(void)
-{
- 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;
-}
diff --git a/waf b/waf
deleted file mode 100755
index 887215c..0000000
--- a/waf
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-# Minimal waf script for projects that include waflib directly
-
-import sys
-import inspect
-import os
-
-try:
- from waflib import Context, Scripting
-except Exception as e:
- sys.stderr.write('error: Failed to import waf (%s)\n' % e)
- if os.path.exists('.git'):
- sys.stderr.write("Are submodules up to date? "
- "Try 'git submodule update --init --recursive'\n")
-
- sys.exit(1)
-
-
-def main():
- script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main)))
- project_path = os.path.dirname(script_path)
- Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path)
-
-
-if __name__ == '__main__':
- main()
diff --git a/waflib b/waflib
deleted file mode 160000
-Subproject b600c928b221a001faeab7bd92786d0b25714bc
diff --git a/wscript b/wscript
deleted file mode 100644
index 7005967..0000000
--- a/wscript
+++ /dev/null
@@ -1,633 +0,0 @@
-#!/usr/bin/env python
-
-import glob
-import os
-import shutil
-import sys
-
-from waflib import Build, Options, Logs
-from waflib.extras import autowaf
-
-# Library and package version (UNIX style major, minor, micro)
-# major increment <=> incompatible changes
-# minor increment <=> compatible changes (additions)
-# micro increment <=> no interface changes
-LILV_VERSION = '0.24.13'
-LILV_MAJOR_VERSION = '0'
-
-# Mandatory waf variables
-APPNAME = 'lilv' # Package name for waf dist
-VERSION = LILV_VERSION # Package version for waf dist
-top = '.' # Source directory
-out = 'build' # Build directory
-
-# Release variables
-uri = 'http://drobilla.net/sw/lilv'
-dist_pattern = 'http://download.drobilla.net/lilv-%d.%d.%d.tar.bz2'
-post_tags = ['Hacking', 'LAD', 'LV2', 'Lilv']
-
-tests = [
- 'test_bad_port_index',
- 'test_bad_port_symbol',
- 'test_classes',
- 'test_discovery',
- 'test_filesystem',
- 'test_get_symbol',
- 'test_no_author',
- 'test_no_verify',
- 'test_plugin',
- 'test_port',
- 'test_preset',
- 'test_project',
- 'test_project_no_author',
- 'test_prototype',
- 'test_reload_bundle',
- 'test_replace_version',
- 'test_state',
- 'test_string',
- 'test_ui',
- 'test_util',
- 'test_value',
- 'test_verify',
- 'test_world',
-]
-
-test_plugins = [
- 'bad_syntax',
- 'failed_instantiation',
- 'failed_lib_descriptor',
- 'lib_descriptor',
- 'missing_descriptor',
- 'missing_name',
- 'missing_plugin',
- 'missing_port',
- 'missing_port_name',
- 'new_version',
- 'old_version'
-]
-
-
-def options(ctx):
- ctx.load('compiler_c')
- ctx.load('compiler_cxx')
- ctx.load('python')
- opt = ctx.configuration_options()
- ctx.add_flags(
- opt,
- {'no-utils': 'do not build command line utilities',
- 'no-bindings': 'do not build python bindings',
- 'dyn-manifest': 'build support for dynamic manifests',
- 'no-bash-completion': 'do not install bash completion script',
- 'static': 'build static library',
- 'no-shared': 'do not build shared library',
- 'static-progs': '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', cache=True)
- try:
- conf.load('compiler_cxx', cache=True)
- conf.define('LILV_CXX', True)
- except Exception:
- pass
-
- if not Options.options.no_bindings:
- try:
- conf.load('python', cache=True)
- conf.check_python_version((2, 6, 0))
- conf.env.LILV_PYTHON = 1
- except Exception as e:
- Logs.warn('Failed to configure Python (%s)\n' % e)
-
- conf.load('autowaf', cache=True)
- autowaf.set_c_lang(conf, 'c99')
-
- if conf.env.DOCS:
- conf.load('sphinx')
-
- conf.env.BASH_COMPLETION = not Options.options.no_bash_completion
- 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')
-
- if Options.options.strict:
- # Check for programs used by lint target
- conf.find_program("flake8", var="FLAKE8", mandatory=False)
- conf.find_program("clang-tidy", var="CLANG_TIDY", mandatory=False)
- conf.find_program("iwyu_tool", var="IWYU_TOOL", mandatory=False)
-
- if Options.options.ultra_strict:
- autowaf.add_compiler_flags(conf.env, '*', {
- 'clang': [
- '-Wno-documentation-unknown-command',
- '-Wno-nullability-extension',
- ]
- })
-
- autowaf.add_compiler_flags(conf.env, 'c', {
- 'clang': [
- '-Wno-cast-align',
- '-Wno-cast-qual',
- '-Wno-double-promotion',
- '-Wno-float-equal',
- '-Wno-format-nonliteral',
- '-Wno-implicit-float-conversion',
- '-Wno-implicit-int-conversion',
- '-Wno-padded',
- '-Wno-reserved-id-macro',
- '-Wno-shorten-64-to-32',
- '-Wno-sign-conversion',
- '-Wno-switch-enum',
- '-Wno-vla',
- ],
- 'gcc': [
- '-Wno-cast-align',
- '-Wno-cast-qual',
- '-Wno-conversion',
- '-Wno-double-promotion',
- '-Wno-float-equal',
- '-Wno-padded',
- '-Wno-stack-protector',
- '-Wno-suggest-attribute=const',
- '-Wno-suggest-attribute=pure',
- '-Wno-switch-enum',
- '-Wno-vla',
- ],
- 'msvc': [
- '/wd4061', # enumerator in switch is not explicitly handled
- '/wd4365', # signed/unsigned mismatch
- '/wd4514', # unreferenced inline function has been removed
- '/wd4774', # format string is not a string literal
- '/wd4820', # padding added after construct
- '/wd4996', # POSIX name for this item is deprecated
- ],
- })
-
- autowaf.add_compiler_flags(conf.env, 'cxx', {
- 'clang': [
- '-Wno-extra-semi',
- ],
- 'gcc': [
- '-Wno-effc++',
- '-Wno-extra-semi',
- '-Wno-pedantic',
- ],
- })
-
- conf.check_pkg('lv2 >= 1.18.0', uselib_store='LV2')
- conf.check_pkg('serd-0 >= 0.30.0', uselib_store='SERD')
- conf.check_pkg('sord-0 >= 0.14.0', uselib_store='SORD')
- conf.check_pkg('sratom-0 >= 0.4.0', uselib_store='SRATOM')
- conf.check_pkg('sndfile >= 1.0.0', uselib_store='SNDFILE', mandatory=False)
-
- defines = ['_POSIX_C_SOURCE=200809L', '_BSD_SOURCE', '_DEFAULT_SOURCE']
- if conf.env.DEST_OS == 'darwin':
- defines += ['_DARWIN_C_SOURCE']
-
- rt_lib = ['rt']
- if conf.env.DEST_OS == 'darwin' or conf.env.DEST_OS == 'win32':
- rt_lib = []
-
- conf.check_function('c', 'lstat',
- header_name = ['sys/stat.h'],
- defines = defines,
- define_name = 'HAVE_LSTAT',
- return_type = 'int',
- arg_types = 'const char*, struct stat*',
- mandatory = False)
-
- conf.check_function('c', 'flock',
- header_name = 'sys/file.h',
- defines = defines,
- define_name = 'HAVE_FLOCK',
- return_type = 'int',
- arg_types = 'int, int',
- mandatory = False)
-
- conf.check_function('c', 'fileno',
- header_name = 'stdio.h',
- defines = defines,
- define_name = 'HAVE_FILENO',
- return_type = 'int',
- arg_types = 'FILE*',
- mandatory = False)
-
- conf.check_function('c', 'clock_gettime',
- header_name = ['sys/time.h', 'time.h'],
- defines = ['_POSIX_C_SOURCE=200809L'],
- define_name = 'HAVE_CLOCK_GETTIME',
- uselib_store = 'CLOCK_GETTIME',
- lib = rt_lib,
- return_type = 'int',
- arg_types = 'clockid_t, struct timespec*',
- mandatory = False)
-
- conf.check_cc(define_name = 'HAVE_LIBDL',
- lib = 'dl',
- mandatory = False)
-
- if Options.options.dyn_manifest:
- conf.define('LILV_DYN_MANIFEST', 1)
-
- lilv_path_sep = ':'
- lilv_dir_sep = '/'
- if conf.env.DEST_OS == 'win32':
- lilv_path_sep = ';'
- lilv_dir_sep = '\\\\'
-
- conf.define('LILV_PATH_SEP', lilv_path_sep)
- conf.define('LILV_DIR_SEP', lilv_dir_sep)
-
- # Set default LV2 path
- lv2_path = Options.options.default_lv2_path
- if lv2_path == '':
- if conf.env.DEST_OS == '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 conf.env.DEST_OS == 'haiku':
- lv2_path = lilv_path_sep.join(['~/.lv2',
- '/boot/common/add-ons/lv2'])
- elif conf.env.DEST_OS == '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])
-
- if sys.platform == 'win32':
- lv2_path = lv2_path.replace('%', '%%')
-
- conf.define('LILV_DEFAULT_LV2_PATH', lv2_path)
-
- # Set up environment for building/using as a subproject
- autowaf.set_lib_env(conf, 'lilv', LILV_VERSION,
- include_path=str(conf.path.find_node('include')))
-
- conf.define('LILV_NO_DEFAULT_CONFIG', 1)
-
- autowaf.display_summary(
- conf,
- {'Default LV2_PATH': lv2_path,
- 'Utilities': bool(conf.env.BUILD_UTILS),
- 'Unit tests': bool(conf.env.BUILD_TESTS),
- 'Dynamic manifest support': conf.is_defined('LILV_DYN_MANIFEST'),
- 'Python bindings': bool(conf.env.LILV_PYTHON)})
-
-
-def build_util(bld, name, defines, libs=''):
- obj = bld(features = 'c cprogram',
- source = name + '.c',
- includes = ['.', 'include', './src', './utils'],
- use = 'liblilv',
- uselib = 'SERD SORD SRATOM LV2 ' + libs,
- 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('include/lilv/*.h'))
- bld.install_files(includedir, bld.path.ant_glob('include/lilv/*.hpp'))
-
- lib_source = '''
- src/collections.c
- src/filesystem.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 = []
- libflags = ['-fvisibility=hidden']
- defines = []
- if bld.is_defined('HAVE_LIBDL'):
- lib += ['dl']
- if bld.env.DEST_OS == 'win32':
- lib = []
- if bld.env.MSVC_COMPILER:
- libflags = []
-
- # 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',
- 'LILV_PKG_LIBS': ' -l'.join([''] + lib)})
-
- # Shared Library
- if bld.env.BUILD_SHARED:
- obj = bld(features = 'c cshlib',
- export_includes = ['.', 'include'],
- source = lib_source,
- includes = ['.', 'include', './src'],
- name = 'liblilv',
- target = 'lilv-%s' % LILV_MAJOR_VERSION,
- vnum = LILV_VERSION,
- install_path = '${LIBDIR}',
- defines = ['LILV_INTERNAL'],
- cflags = libflags,
- lib = lib,
- uselib = 'SERD SORD SRATOM LV2')
-
- # Static library
- if bld.env.BUILD_STATIC:
- obj = bld(features = 'c cstlib',
- export_includes = ['.', 'include'],
- source = lib_source,
- includes = ['.', 'include', './src'],
- name = 'liblilv_static',
- target = 'lilv-%s' % LILV_MAJOR_VERSION,
- vnum = LILV_VERSION,
- install_path = '${LIBDIR}',
- defines = defines + ['LILV_STATIC', 'LILV_INTERNAL'],
- uselib = 'SERD SORD SRATOM LV2')
-
- # Python bindings
- if bld.env.LILV_PYTHON:
- bld(features = 'subst',
- is_copy = True,
- source = 'bindings/python/lilv.py',
- target = 'lilv.py',
- install_path = '${PYTHONDIR}')
-
- if bld.env.BUILD_TESTS:
- import re
-
- test_libs = lib
- test_cflags = ['']
- test_linkflags = ['']
- if not bld.env.NO_COVERAGE:
- test_cflags += ['--coverage']
- test_linkflags += ['--coverage']
-
- # Copy skeleton LV2 bundle for tests
- for name in ('manifest.ttl', 'lv2core.ttl'):
- bld(features = 'subst',
- is_copy = True,
- source = 'test/core.lv2/' + name,
- target = 'test/test_lv2_path/core.lv2/' + name,
- install_path = None)
-
- # Make a pattern for shared objects without the 'lib' prefix
- module_pattern = re.sub('^lib', '', bld.env.cshlib_PATTERN)
- shlib_ext = module_pattern[module_pattern.rfind('.'):]
-
- for p in ['test'] + test_plugins:
- obj = bld(features = 'c cshlib',
- source = 'test/%s.lv2/%s.c' % (p, p),
- name = p,
- target = 'test/%s.lv2/%s' % (p, p),
- install_path = None,
- defines = defines + ['LILV_STATIC'],
- cflags = test_cflags,
- linkflags = test_linkflags,
- lib = test_libs,
- uselib = 'LV2')
- obj.env.cshlib_PATTERN = module_pattern
-
- for p in test_plugins:
- if not bld.path.find_node('test/%s.lv2/test_%s.c' % (p, p)):
- continue
-
- obj = bld(features = 'c cprogram',
- source = 'test/%s.lv2/test_%s.c' % (p, p),
- target = 'test/test_%s' % p,
- includes = ['.', 'include', './src'],
- use = 'liblilv_profiled',
- install_path = None,
- defines = defines + ['LILV_STATIC'],
- cflags = test_cflags,
- linkflags = test_linkflags,
- lib = test_libs,
- uselib = 'SERD SORD SRATOM LV2')
-
- # Test plugin data files
- for p in ['test'] + test_plugins:
- for i in ['manifest.ttl.in', p + '.ttl.in']:
- bundle = 'test/%s.lv2/' % p
- bld(features = 'subst',
- source = bundle + i,
- target = bundle + 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 = ['.', 'include', './src'],
- name = 'liblilv_profiled',
- target = 'lilv_profiled',
- install_path = None,
- defines = defines + ['LILV_STATIC', 'LILV_INTERNAL'],
- cflags = test_cflags,
- linkflags = test_linkflags,
- lib = test_libs,
- uselib = 'SERD SORD SRATOM LV2')
-
- # Unit test program
- testdir = bld.path.get_bld().make_node('test').abspath()
- bpath = os.path.join(testdir, 'test.lv2')
- bpath = bpath.replace('\\', '/')
- testdir = testdir.replace('\\', '/')
- for test in tests:
- obj = bld(features = 'c cprogram',
- source = ['test/%s.c' % test,
- 'test/lilv_test_utils.c'],
- includes = ['.', 'include', './src'],
- use = 'liblilv_profiled',
- lib = test_libs,
- uselib = 'SERD SORD SRATOM LV2',
- target = 'test/' + test,
- install_path = None,
- defines = (defines +
- ['LILV_STATIC'] +
- ['LILV_TEST_BUNDLE=\"%s/\"' % bpath] +
- ['LILV_TEST_DIR=\"%s/\"' % testdir]),
- cflags = test_cflags,
- linkflags = test_linkflags)
-
- # C++ API test
- if 'COMPILER_CXX' in bld.env:
- obj = bld(features = 'cxx cxxprogram',
- source = 'test/lilv_cxx_test.cpp',
- includes = ['.', 'include', './src'],
- use = 'liblilv_profiled',
- lib = test_libs,
- uselib = 'SERD SORD SRATOM LV2',
- target = 'test/lilv_cxx_test',
- install_path = None,
- defines = ['LILV_STATIC'],
- cxxflags = test_cflags,
- linkflags = test_linkflags)
-
- if bld.env.LILV_PYTHON:
- test_bundle = 'bindings/bindings_test_plugin.lv2/'
-
- # Copy Python unittest files
- for i in ['test_api.py']:
- bld(features = 'subst',
- is_copy = True,
- source = 'bindings/test/python/' + i,
- target = 'bindings/' + i,
- install_path = None)
-
- # Build bindings test plugin
- obj = bld(features = 'c cshlib',
- source = 'bindings/test/bindings_test_plugin.c',
- name = 'bindings_test_plugin',
- target = test_bundle + '/bindings_test_plugin',
- install_path = None,
- defines = defines,
- cflags = test_cflags,
- linkflags = test_linkflags,
- lib = test_libs,
- uselib = 'LV2')
- obj.env.cshlib_PATTERN = module_pattern
-
- # Bindings test plugin data files
- for i in ['manifest.ttl.in', 'bindings_test_plugin.ttl.in']:
- bld(features = 'subst',
- source = 'bindings/test/' + i,
- target = test_bundle + i.replace('.in', ''),
- install_path = None,
- SHLIB_EXT = shlib_ext)
-
- # Utilities
- if bld.env.BUILD_UTILS:
- utils = '''
- utils/lilv-bench
- utils/lv2info
- utils/lv2ls
- '''
- for i in utils.split():
- build_util(bld, i, defines)
-
- if bld.env.HAVE_SNDFILE:
- obj = build_util(bld, 'utils/lv2apply', defines, 'SNDFILE')
-
- # lv2bench (less portable than other utilities)
- if (bld.env.DEST_OS != 'win32' and
- bld.is_defined('HAVE_CLOCK_GETTIME') and
- not bld.env.STATIC_PROGS):
- obj = build_util(bld, 'utils/lv2bench', defines)
- if bld.env.DEST_OS != 'darwin':
- obj.lib = ['rt']
-
- # Documentation
- if bld.env.DOCS:
- bld.recurse('doc/c')
-
- # 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')
-
- bld.add_post_fun(autowaf.run_ldconfig)
-
-
-def test(tst):
- with tst.group('unit') as check:
- for test in tests:
- check(['./test/' + test])
-
- if tst.is_defined('LILV_CXX'):
- check(['./test/lilv_cxx_test'])
-
- if tst.env.LILV_PYTHON:
- with tst.group('python') as check:
- check(['python', '-m', 'unittest', 'discover', 'bindings/'])
-
- with tst.group('plugin') as check:
- for p in test_plugins:
- prog_name = tst.env.cprogram_PATTERN % ('test_' + p)
- if os.path.exists(os.path.join('test', prog_name)):
- check(['./test/test_' + p, 'test/%s.lv2/' % p])
-
- try:
- shutil.rmtree('state')
- except Exception:
- pass
-
-
-class LintContext(Build.BuildContext):
- fun = cmd = 'lint'
-
-
-def lint(ctx):
- "checks code for style issues"
- import subprocess
-
- st = 0
-
- if "FLAKE8" in ctx.env:
- Logs.info("Running flake8")
- st = subprocess.call([ctx.env.FLAKE8[0],
- "wscript",
- "--ignore",
- "E101,E129,W191,E221,W504,E251,E241,E741"])
- else:
- Logs.warn("Not running flake8")
-
- if "IWYU_TOOL" in ctx.env:
- Logs.info("Running include-what-you-use")
- cmd = [ctx.env.IWYU_TOOL[0], "-o", "clang", "-p", "build"]
- output = subprocess.check_output(cmd).decode('utf-8')
- if 'error: ' in output:
- sys.stdout.write(output)
- st += 1
- else:
- Logs.warn("Not running include-what-you-use")
-
- if "CLANG_TIDY" in ctx.env and "clang" in ctx.env.CC[0]:
- Logs.info("Running clang-tidy")
- sources = glob.glob('src/*.c') + glob.glob('tests/*.c')
- sources = list(map(os.path.abspath, sources))
- procs = []
- for source in sources:
- cmd = [ctx.env.CLANG_TIDY[0], "--quiet", "-p=.", source]
- procs += [subprocess.Popen(cmd, cwd="build")]
-
- for proc in procs:
- stdout, stderr = proc.communicate()
- st += proc.returncode
- else:
- Logs.warn("Not running clang-tidy")
-
- if st != 0:
- sys.exit(st)