diff options
-rw-r--r-- | .clang-tidy | 13 | ||||
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | .reuse/dep5 | 2 | ||||
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | doc/meson.build | 8 | ||||
-rw-r--r-- | meson.build | 153 | ||||
-rw-r--r-- | meson/suppressions/meson.build | 189 | ||||
-rw-r--r-- | meson/warnings/meson.build | 238 | ||||
-rw-r--r-- | meson_options.txt | 16 | ||||
-rw-r--r-- | src/jack.c | 3 | ||||
-rw-r--r-- | src/jalv.c | 1 | ||||
-rw-r--r-- | src/jalv_console.c | 2 | ||||
-rw-r--r-- | src/jalv_gtk.c | 245 | ||||
-rw-r--r-- | src/jalv_qt.cpp | 34 | ||||
-rw-r--r-- | src/log.c | 1 | ||||
-rw-r--r-- | src/state.c | 3 | ||||
-rw-r--r-- | subprojects/zix.wrap | 18 | ||||
-rw-r--r-- | test/meson.build | 8 |
18 files changed, 388 insertions, 558 deletions
diff --git a/.clang-tidy b/.clang-tidy index 0b547da..6262c89 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,12 +4,11 @@ Checks: > -*-magic-numbers, -*-named-parameter, -*-narrowing-conversions, - -*-reserved-identifier, - -*-uppercase-literal-suffix, -altera-*, + -bugprone-assignment-in-if-condition, -bugprone-branch-clone, -bugprone-easily-swappable-parameters, - -bugprone-macro-parentheses, + -bugprone-suspicious-realloc-usage, -cert-err33-c, -cert-err34-c, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, @@ -27,12 +26,20 @@ Checks: > -llvm-header-guard, -llvmlibc-*, -misc-no-recursion, + -misc-use-anonymous-namespace, + -modernize-macro-to-enum, + -modernize-use-nodiscard, -modernize-use-trailing-return-type, -readability-function-cognitive-complexity, -readability-identifier-length, -readability-implicit-bool-conversion, -readability-non-const-parameter, -readability-static-accessed-through-instance, +CheckOptions: + - key: hicpp-uppercase-literal-suffix.NewSuffixes + value: 'L;U;UL;ULL' + - key: readability-uppercase-literal-suffix.NewSuffixes + value: 'L;U;UL;ULL' WarningsAsErrors: '*' HeaderFilterRegex: '.*' FormatStyle: file @@ -4,8 +4,11 @@ build/ subprojects/lilv/ subprojects/lv2/ +subprojects/packagecache/ subprojects/serd/ subprojects/sord/ +subprojects/sphinxygen-1.0.4/ subprojects/sratom/ subprojects/suil/ +subprojects/zix-0.4.0/ subprojects/zix/ diff --git a/.reuse/dep5 b/.reuse/dep5 index 771c0b4..110b66c 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -3,7 +3,7 @@ Upstream-Name: jalv Upstream-Contact: David Robillard <d@drobilla.net> Source: https://gitlab.com/drobilla/jalv -Files: .clang* .clant.json .gitignore AUTHORS NEWS jalv.desktop.in jalv.ttl meson_options.txt +Files: .clang* .clant.json .gitignore AUTHORS NEWS jalv.desktop.in jalv.ttl Copyright: 2010-2022 David Robillard <d@drobilla.net> License: 0BSD OR ISC @@ -1,11 +1,16 @@ -jalv (1.6.9) stable; urgency=medium +jalv (1.6.9) unstable; urgency=medium + * Add missing short versions of command line options + * Add option to install tool man pages * Build Qt UI with -fPIC + * Clean up command line help output + * Fix clashing command line options * Remove Gtk2 interface * Replace use of deprecated Gtk interfaces * Switch to external zix dependency + * Use Gtk switches instead of checkboxes for toggle controls - -- David Robillard <d@drobilla.net> Sun, 11 Dec 2022 20:10:11 +0000 + -- David Robillard <d@drobilla.net> Thu, 14 Mar 2024 18:26:10 +0000 jalv (1.6.8) stable; urgency=medium diff --git a/doc/meson.build b/doc/meson.build index 64299d1..be25581 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -1,12 +1,12 @@ -# Copyright 2022 David Robillard <d@drobilla.net> +# Copyright 2022-2023 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -install_man('jalv.1') +install_man(files('jalv.1')) if not get_option('gtk3').disabled() - install_man('jalv.gtk3.1') + install_man(files('jalv.gtk3.1')) endif if not get_option('qt5').disabled() - install_man('jalv.qt5.1') + install_man(files('jalv.qt5.1')) endif diff --git a/meson.build b/meson.build index 29a4194..c73c612 100644 --- a/meson.build +++ b/meson.build @@ -1,16 +1,19 @@ # Copyright 2020-2022 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -project('jalv', ['c', 'cpp'], - version: '1.6.9', - license: 'ISC', - meson_version: '>= 0.56.0', - default_options: [ - 'b_ndebug=if-release', - 'buildtype=release', - 'c_std=c99', - 'cpp_std=c++14', - ]) +project( + 'jalv', + ['c', 'cpp'], + default_options: [ + 'b_ndebug=if-release', + 'buildtype=release', + 'c_std=c99', + 'cpp_std=c++14', + ], + license: 'ISC', + meson_version: '>= 0.56.0', + version: '1.6.9', +) jalv_src_root = meson.current_source_dir() major_version = meson.project_version().split('.')[0] @@ -28,11 +31,6 @@ if add_languages(['cpp'], native: false, required: get_option('cxx')) cpp = meson.get_compiler('cpp') endif -# Set global warning flags -if get_option('strict') and not meson.is_subproject() - subdir('meson/warnings') -endif - # Set global warning suppressions subdir('meson/suppressions') add_project_arguments(c_suppressions, language: ['c']) @@ -57,7 +55,7 @@ zix_dep = dependency( 'tests_cpp=disabled', ], fallback: ['zix', 'zix_dep'], - version: '>= 0.3.0', + version: '>= 0.4.0', ) serd_dep = dependency( @@ -68,7 +66,7 @@ serd_dep = dependency( 'tools=disabled', ], fallback: ['serd', 'serd_dep'], - version: '>= 0.30.0', + version: '>= 0.32.2', ) sord_dep = dependency( @@ -79,7 +77,7 @@ sord_dep = dependency( 'tools=disabled', ], fallback: ['sord', 'sord_dep'], - version: '>= 0.14.0', + version: '>= 0.16.16', ) lv2_dep = dependency( @@ -113,7 +111,7 @@ lilv_dep = dependency( 'tools=disabled', ], fallback: ['lilv', 'lilv_dep'], - version: '>= 0.24.0', + version: '>= 0.24.24', ) suil_dep = dependency( @@ -131,15 +129,19 @@ suil_dep = dependency( # Drivers # ########### -portaudio_dep = dependency('portaudio-2.0', - version: '>= 2.0.0', - include_type: 'system', - required: get_option('portaudio')) +portaudio_dep = dependency( + 'portaudio-2.0', + include_type: 'system', + required: get_option('portaudio'), + version: '>= 2.0.0', +) -jack_dep = dependency('jack', - version: '>= 0.120.0', - include_type: 'system', - required: get_option('jack')) +jack_dep = dependency( + 'jack', + include_type: 'system', + required: get_option('jack'), + version: '>= 0.120.0', +) backend_sources = files() if get_option('jack').enabled() and get_option('portaudio').enabled() @@ -191,11 +193,13 @@ else ] endif -# Check for platform features with the build system -if get_option('checks') - platform_defines += [ - '-DJALV_NO_DEFAULT_CONFIG', - ] +# Build platform-specific configuration arguments +if get_option('checks').disabled() + # Generic build without platform-specific features + platform_defines += ['-DJALV_NO_DEFAULT_CONFIG'] +elif get_option('checks').enabled() + # Only use the features detected by the build system + platform_defines += ['-DJALV_NO_DEFAULT_CONFIG'] if no_posix platform_defines += ['-DHAVE_FILENO=0'] @@ -220,29 +224,28 @@ int main(void) { void* mem; posix_memalign(&mem, 8, 8); }''' int main(void) { return sigaction(SIGINT, 0, 0); }''' platform_defines += '-DHAVE_FILENO=@0@'.format( - cc.compiles(fileno_code, - args: platform_defines, - name: 'fileno').to_int()) + cc.compiles(fileno_code, args: platform_defines, name: 'fileno').to_int(), + ) platform_defines += '-DHAVE_ISATTY=@0@'.format( - cc.compiles(isatty_code, - args: platform_defines, - name: 'isatty').to_int()) + cc.compiles(isatty_code, args: platform_defines, name: 'isatty').to_int(), + ) platform_defines += '-DHAVE_MLOCK=@0@'.format( - cc.compiles(mlock_code, - args: platform_defines, - name: 'mlock').to_int()) + cc.compiles(mlock_code, args: platform_defines, name: 'mlock').to_int(), + ) platform_defines += '-DHAVE_POSIX_MEMALIGN=@0@'.format( - cc.compiles(posix_memalign_code, - args: platform_defines, - name: 'posix_memalign').to_int()) + cc.compiles( + posix_memalign_code, + args: platform_defines, + name: 'posix_memalign', + ).to_int(), + ) platform_defines += '-DHAVE_SIGACTION=@0@'.format( - cc.compiles(sigaction_code, - args: platform_defines, - name: 'sigaction').to_int()) + cc.compiles(sigaction_code, args: platform_defines, name: 'sigaction').to_int(), + ) endif jack_metadata_code = '''#include <jack/metadata.h> @@ -252,28 +255,36 @@ int main(void) { return !!&jack_set_property; }''' int main(void) { return !!&jack_port_type_get_buffer_size; }''' platform_defines += '-DHAVE_JACK_METADATA=@0@'.format( - cc.compiles(jack_metadata_code, - args: platform_defines, - name: 'jack_metadata').to_int()) + cc.compiles( + jack_metadata_code, + args: platform_defines, + name: 'jack_metadata', + ).to_int(), + ) platform_defines += '-DHAVE_JACK_PORT_TYPE_GET_BUFFER_SIZE=@0@'.format( - cc.compiles(jack_port_type_get_buffer_size_code, - args: platform_defines, - name: 'jack_port_type_get_buffer_size').to_int()) + cc.compiles( + jack_port_type_get_buffer_size_code, + args: platform_defines, + name: 'jack_port_type_get_buffer_size', + ).to_int(), + ) endif ############ # Programs # ############ -sources = backend_sources + files( - 'src/control.c', - 'src/jalv.c', - 'src/log.c', - 'src/lv2_evbuf.c', - 'src/state.c', - 'src/symap.c', - 'src/worker.c', +sources = ( + backend_sources + files( + 'src/control.c', + 'src/jalv.c', + 'src/log.c', + 'src/lv2_evbuf.c', + 'src/state.c', + 'src/symap.c', + 'src/worker.c', + ) ) common_dependencies = [ @@ -317,14 +328,14 @@ if not get_option('gtk3').disabled() 'gdk-3.0', include_type: 'system', required: get_option('gtk3'), - version: '>= 3.0.0', + version: '>= 3.12.0', ) gtk3_dep = dependency( 'gtk+-3.0', include_type: 'system', required: get_option('gtk3'), - version: '>= 3.0.0', + version: '>= 3.12.0', ) if gdk3_dep.found() and gtk3_dep.found() @@ -333,11 +344,13 @@ if not get_option('gtk3').disabled() config.set('APP_HUMAN_NAME', 'Jalv') config.set('BINDIR', get_option('prefix') / get_option('bindir')) - configure_file(configuration: config, - input: files('jalv.desktop.in'), - output: 'jalv.desktop', - install: true, - install_dir: get_option('datadir') / 'applications') + configure_file( + configuration: config, + input: files('jalv.desktop.in'), + install: true, + install_dir: get_option('datadir') / 'applications', + output: 'jalv.desktop', + ) executable( 'jalv.gtk3', @@ -396,7 +409,9 @@ endif # Documentation # ################# -subdir('doc') +if not get_option('man').disabled() + subdir('doc') +endif ######### # Tests # diff --git a/meson/suppressions/meson.build b/meson/suppressions/meson.build index 51383dc..b338d31 100644 --- a/meson/suppressions/meson.build +++ b/meson/suppressions/meson.build @@ -1,65 +1,9 @@ -# Copyright 2020-2022 David Robillard <d@drobilla.net> +# Copyright 2020-2023 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -# Project-specific warning suppressions. -# -# This should be used in conjunction with the generic "warnings" sibling that -# enables all reasonable warnings for the compiler. It lives here just to keep -# the top-level meson.build more readable. - -clang_common_suppressions = [ - '-Wno-atomic-implicit-seq-cst', - '-Wno-c99-extensions', - '-Wno-cast-align', - '-Wno-cast-qual', - '-Wno-disabled-macro-expansion', - '-Wno-documentation-unknown-command', - '-Wno-double-promotion', - '-Wno-float-conversion', - '-Wno-float-equal', - '-Wno-format-nonliteral', - '-Wno-implicit-fallthrough', - '-Wno-implicit-float-conversion', - '-Wno-nullability-extension', - '-Wno-padded', - '-Wno-redundant-parens', - '-Wno-reserved-id-macro', - '-Wno-reserved-identifier', - '-Wno-shorten-64-to-32', - '-Wno-sign-conversion', - '-Wno-switch-enum', - '-Wno-unknown-warning-option', - '-Wno-unused-macros', - '-Wno-unused-parameter', -] - -gcc_common_suppressions = [ - '-Wno-cast-align', - '-Wno-cast-qual', - '-Wno-conversion', - '-Wno-double-promotion', - '-Wno-float-conversion', - '-Wno-float-equal', - '-Wno-inline', - '-Wno-padded', - '-Wno-pedantic', - '-Wno-stack-protector', - '-Wno-switch-default', - '-Wno-switch-enum', - '-Wno-unused-macros', - '-Wno-unused-parameter', -] - -if host_machine.system() == 'darwin' - clang_common_suppressions += [ - '-Wno-documentation', # JACK - '-Wno-documentation-deprecated-sync', # JACK - ] -elif host_machine.system() == 'freebsd' - clang_common_suppressions += [ - '-Wno-c11-extensions', # isnan and friends - ] -endif +# Project-specific warning suppressions + +warning_level = get_option('warning_level') ##### # C # @@ -68,28 +12,93 @@ endif if is_variable('cc') c_suppressions = [] - if get_option('strict') - if cc.get_id() == 'clang' - c_suppressions += clang_common_suppressions + [ + if cc.get_id() == 'clang' + if warning_level == 'everything' + c_suppressions += [ '-Wno-bad-function-cast', + '-Wno-cast-align', + '-Wno-cast-function-type-strict', + '-Wno-cast-qual', '-Wno-declaration-after-statement', + '-Wno-disabled-macro-expansion', + '-Wno-documentation-unknown-command', # MacOS + '-Wno-double-promotion', + '-Wno-float-conversion', + '-Wno-float-equal', + '-Wno-format-nonliteral', + '-Wno-implicit-float-conversion', '-Wno-missing-noreturn', + '-Wno-padded', + '-Wno-reserved-id-macro', # MacOS + '-Wno-shorten-64-to-32', + '-Wno-sign-conversion', + '-Wno-switch-enum', + '-Wno-unsafe-buffer-usage', + '-Wno-unused-macros', + ] + + 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', + ] + endif + + if warning_level in ['everything', '3', '2'] + c_suppressions += [ + '-Wno-unused-parameter', ] + endif - elif cc.get_id() == 'gcc' - c_suppressions += gcc_common_suppressions + [ - '-Wno-array-bounds', + if host_machine.system() == 'darwin' + c_suppressions += [ + '-Wno-documentation', # JACK + '-Wno-documentation-deprecated-sync', # JACK + ] + elif host_machine.system() == 'freebsd' + c_suppressions += [ + '-Wno-c11-extensions', # isnan and friends + ] + endif + + elif cc.get_id() == 'gcc' + if warning_level == 'everything' + c_suppressions += [ '-Wno-bad-function-cast', '-Wno-c++-compat', + '-Wno-cast-align', + '-Wno-cast-qual', + '-Wno-conversion', + '-Wno-double-promotion', + '-Wno-float-equal', '-Wno-format-nonliteral', + '-Wno-inline', + '-Wno-padded', '-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-macros', ] + endif - elif cc.get_id() == 'msvc' + if warning_level in ['everything', '3', '2'] + c_suppressions += [ + '-Wno-unused-parameter', + ] + endif + + elif cc.get_id() == 'msvc' + if warning_level == 'everything' c_suppressions += [ '/wd4061', # enumerator in switch is not explicitly handled '/wd4090', # different const qualifiers @@ -122,18 +131,48 @@ endif if is_variable('cpp') cpp_suppressions = [] - if get_option('strict') - if cpp.get_id() == 'clang' - cpp_suppressions = clang_common_suppressions + [ - '-Wno-extra-semi-stmt', - '-Wno-old-style-cast', + if cpp.get_id() == 'clang' + if warning_level == 'everything' + cpp_suppressions += [ + '-Wno-c++98-compat-pedantic', + '-Wno-cast-align', # MacOS + '-Wno-cast-qual', # MacOS + '-Wno-documentation-unknown-command', # MacOS + '-Wno-double-promotion', + '-Wno-float-conversion', + '-Wno-implicit-float-conversion', + '-Wno-old-style-cast', # MacOS + '-Wno-padded', + '-Wno-redundant-parens', + '-Wno-reserved-id-macro', # MacOS + '-Wno-shorten-64-to-32', + '-Wno-sign-conversion', + '-Wno-unsafe-buffer-usage', '-Wno-weak-vtables', - '-Wno-zero-as-null-pointer-constant', + '-Wno-zero-as-null-pointer-constant', # MacOS ] - elif cpp.get_id() == 'gcc' - cpp_suppressions = gcc_common_suppressions + [ + if not meson.is_cross_build() + cpp_suppressions += [ + '-Wno-poison-system-directories', + ] + endif + endif + + if warning_level in ['everything', '3'] + cpp_suppressions += [ + '-Wno-nullability-extension', + ] + endif + + elif cpp.get_id() == 'gcc' + if warning_level == 'everything' + cpp_suppressions += [ + '-Wno-cast-align', # LV2 + '-Wno-cast-qual', # LV2 + '-Wno-conversion', '-Wno-effc++', + '-Wno-padded', '-Wno-strict-overflow', '-Wno-suggest-attribute=const', '-Wno-suggest-attribute=pure', diff --git a/meson/warnings/meson.build b/meson/warnings/meson.build deleted file mode 100644 index cc13fc7..0000000 --- a/meson/warnings/meson.build +++ /dev/null @@ -1,238 +0,0 @@ -# Copyright 2020-2022 David Robillard <d@drobilla.net> -# SPDX-License-Identifier: 0BSD OR ISC - -# General code to enable approximately all warnings in GCC 12, clang, and MSVC. -# -# This is trivial for clang and MSVC, but GCC doesn't have an "everything" -# option, so we need to enable everything we want explicitly. Wall is assumed, -# but Wextra is not, for stability. -# -# These are collected from common.opt and c.opt in the GCC source, and manually -# curated with the help of the GCC documentation. Warnings that are -# application-specific, historical, or about compatibility between specific -# language revisions are omitted. The intent here is to have roughly the same -# meaning as clang's Weverything: extremely strict, but general. Specifically -# omitted are: -# -# General: -# -# Wabi= -# Waggregate-return -# Walloc-size-larger-than=BYTES -# Walloca-larger-than=BYTES -# Wframe-larger-than=BYTES -# Wlarger-than=BYTES -# Wstack-usage=BYTES -# Wsystem-headers -# Wtraditional -# Wtraditional-conversion -# Wtrampolines -# Wvla-larger-than=BYTES -# -# Build specific: -# -# Wpoison-system-directories -# -# C Specific: -# -# Wc11-c2x-compat -# Wc90-c99-compat -# Wc99-c11-compat -# Wdeclaration-after-statement -# Wtraditional -# Wtraditional-conversion -# -# C++ Specific: -# -# Wc++0x-compat -# Wc++1z-compat -# Wc++2a-compat -# Wctad-maybe-unsupported -# Wnamespaces -# Wtemplates - -gcc_common_warnings = [ - '-Walloc-zero', - '-Walloca', - '-Wanalyzer-too-complex', - '-Warith-conversion', - '-Warray-bounds=2', - '-Wattribute-alias=2', - '-Wbidi-chars=ucn', - '-Wcast-align=strict', - '-Wcast-function-type', - '-Wcast-qual', - '-Wclobbered', - '-Wconversion', - '-Wdate-time', - '-Wdisabled-optimization', - '-Wdouble-promotion', - '-Wduplicated-branches', - '-Wduplicated-cond', - '-Wempty-body', - '-Wendif-labels', - '-Wfloat-equal', - '-Wformat-overflow=2', - '-Wformat-signedness', - '-Wformat-truncation=2', - '-Wformat=2', - '-Wignored-qualifiers', - '-Wimplicit-fallthrough=3', - '-Winit-self', - '-Winline', - '-Winvalid-pch', - '-Wlogical-op', - '-Wmissing-declarations', - '-Wmissing-field-initializers', - '-Wmissing-include-dirs', - '-Wmultichar', - '-Wnormalized=nfc', - '-Wnull-dereference', - '-Wopenacc-parallelism', - '-Woverlength-strings', - '-Wpacked', - '-Wpacked-bitfield-compat', - '-Wpadded', - '-Wpointer-arith', - '-Wredundant-decls', - '-Wshadow', - '-Wshift-negative-value', - '-Wshift-overflow=2', - '-Wstack-protector', - '-Wstrict-aliasing=3', - '-Wstrict-overflow=5', - '-Wstring-compare', - '-Wstringop-overflow=3', - '-Wsuggest-attribute=cold', - '-Wsuggest-attribute=const', - '-Wsuggest-attribute=format', - '-Wsuggest-attribute=malloc', - '-Wsuggest-attribute=noreturn', - '-Wsuggest-attribute=pure', - '-Wswitch-default', - '-Wswitch-enum', - '-Wtrampolines', - '-Wtrivial-auto-var-init', - '-Wtype-limits', - '-Wundef', - '-Wuninitialized', - '-Wunsafe-loop-optimizations', - '-Wunused', - '-Wunused-const-variable=2', - '-Wunused-macros', - '-Wvector-operation-performance', - '-Wvla', - '-Wwrite-strings', -] - -##### -# C # -##### - -if is_variable('cc') and not is_variable('all_c_warnings') - all_c_warnings = [] - - if cc.get_id() == 'clang' - all_c_warnings += ['-Weverything'] - - if not meson.is_cross_build() - all_c_warnings += [ - '-Wno-poison-system-directories', - ] - endif - - elif cc.get_id() == 'gcc' - all_c_warnings += gcc_common_warnings + [ - '-Wabsolute-value', - '-Wbad-function-cast', - '-Wc++-compat', - '-Wenum-conversion', - '-Wjump-misses-init', - '-Wmissing-parameter-type', - '-Wmissing-prototypes', - '-Wnested-externs', - '-Wold-style-declaration', - '-Wold-style-definition', - '-Woverride-init', - '-Wsign-compare', - '-Wstrict-prototypes', - '-Wunsuffixed-float-constants', - ] - - elif cc.get_id() == 'msvc' - all_c_warnings += ['/Wall'] - endif - - all_c_warnings = cc.get_supported_arguments(all_c_warnings) - add_global_arguments(all_c_warnings, language: ['c']) -endif - -####### -# C++ # -####### - -if is_variable('cpp') - all_cpp_warnings = [] - - if cpp.get_id() == 'clang' - all_cpp_warnings += [ - '-Weverything', - '-Wno-c++98-compat', - '-Wno-c++98-compat-pedantic' - ] - - if not meson.is_cross_build() - all_cpp_warnings += [ - '-Wno-poison-system-directories', - ] - endif - - elif cpp.get_id() == 'gcc' - all_cpp_warnings += gcc_common_warnings + [ - '-Wabi-tag', - '-Waligned-new=all', - '-Wcatch-value=3', - '-Wcomma-subscript', - '-Wconditionally-supported', - '-Wctor-dtor-privacy', - '-Wdelete-non-virtual-dtor', - '-Wdeprecated', - '-Wdeprecated-copy', - '-Wdeprecated-copy-dtor', - '-Wdeprecated-enum-enum-conversion', - '-Wdeprecated-enum-float-conversion', - '-Weffc++', - '-Wexpansion-to-defined', - '-Wextra-semi', - '-Wimport', - '-Winvalid-imported-macros', - '-Wmismatched-tags', - '-Wmultiple-inheritance', - '-Wnoexcept', - '-Wnoexcept-type', - '-Wnon-virtual-dtor', - '-Wold-style-cast', - '-Woverloaded-virtual', - '-Wplacement-new=2', - '-Wredundant-move', - '-Wredundant-tags', - '-Wregister', - '-Wsign-compare', - '-Wsign-promo', - '-Wsized-deallocation', - '-Wstrict-null-sentinel', - '-Wsuggest-final-methods', - '-Wsuggest-final-types', - '-Wsuggest-override', - '-Wuseless-cast', - '-Wvirtual-inheritance', - '-Wvolatile', - '-Wzero-as-null-pointer-constant', - ] - - elif cpp.get_id() == 'msvc' - all_cpp_warnings += ['/Wall'] - endif - - all_cpp_warnings = cpp.get_supported_arguments(all_cpp_warnings) -endif diff --git a/meson_options.txt b/meson_options.txt index d420bf2..b5979d5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,5 +1,8 @@ -option('checks', type: 'boolean', value: true, yield: true, - description: 'Check for features with the build system') +# Copyright 2020-2023 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR ISC + +option('checks', type: 'feature', value: 'enabled', yield: true, + description: 'Check for platform-specific features') option('cxx', type: 'feature', value: 'auto', yield: true, description: 'Build C++ programs') @@ -13,15 +16,18 @@ option('portaudio', type: 'feature', value: 'auto', yield: true, option('jack', type: 'feature', value: 'auto', yield: true, description: 'Build JACK driver') +option('lint', type: 'boolean', value: false, yield: true, + description: 'Run code quality checks') + +option('man', type: 'feature', value: 'enabled', yield: true, + description: 'Install man pages') + option('posix', type: 'feature', value: 'auto', yield: true, description: 'Use POSIX system facilities') option('qt5', type: 'feature', value: 'auto', yield: true, description: 'Build Qt5 GUI') -option('strict', type: 'boolean', value: false, yield: true, - description: 'Enable ultra-strict warnings') - option('suil', type: 'feature', value: 'auto', yield: true, description: 'Use suil to load plugin UIs') @@ -8,11 +8,8 @@ #include "jalv_internal.h" #include "log.h" #include "lv2_evbuf.h" -#include "nodes.h" -#include "options.h" #include "port.h" #include "types.h" -#include "urids.h" #include "lilv/lilv.h" #include "lv2/atom/atom.h" @@ -9,7 +9,6 @@ #include "log.h" #include "lv2_evbuf.h" #include "nodes.h" -#include "options.h" #include "port.h" #include "state.h" #include "types.h" diff --git a/src/jalv_console.c b/src/jalv_console.c index 0c8dd06..635b668 100644 --- a/src/jalv_console.c +++ b/src/jalv_console.c @@ -51,7 +51,7 @@ print_usage(const char* name, bool error) " -t Print trace messages from plugin\n" " -U URI Load the UI with the given URI\n" " -V Display version information and exit\n" - " -x Exact JACK client name (exit if taken)\n"); + " -x Exit if the requested JACK client name is taken.\n"); return error ? 1 : 0; } diff --git a/src/jalv_gtk.c b/src/jalv_gtk.c index 013b136..5b7240b 100644 --- a/src/jalv_gtk.c +++ b/src/jalv_gtk.c @@ -5,18 +5,15 @@ #include "frontend.h" #include "jalv_internal.h" #include "log.h" -#include "nodes.h" #include "options.h" #include "port.h" #include "state.h" #include "types.h" -#include "urids.h" #include "lilv/lilv.h" #include "lv2/atom/atom.h" #include "lv2/atom/forge.h" #include "lv2/atom/util.h" -#include "lv2/core/attributes.h" #include "lv2/core/lv2.h" #include "lv2/ui/ui.h" #include "lv2/urid/urid.h" @@ -60,31 +57,9 @@ typedef struct { static float get_float(const LilvNode* node, float fallback) { - if (lilv_node_is_float(node) || lilv_node_is_int(node)) { - return lilv_node_as_float(node); - } - - return fallback; -} - -static GtkWidget* -new_box(gboolean horizontal, gint spacing) -{ - return gtk_box_new(horizontal ? GTK_ORIENTATION_HORIZONTAL - : GTK_ORIENTATION_VERTICAL, - spacing); -} - -static GtkWidget* -new_hscale(gdouble min, gdouble max, gdouble step) -{ - return gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step); -} - -static void -size_request(GtkWidget* widget, GtkRequisition* req) -{ - gtk_widget_get_preferred_size(widget, NULL, req); + return (lilv_node_is_float(node) || lilv_node_is_int(node)) + ? lilv_node_as_float(node) + : fallback; } static void @@ -96,28 +71,21 @@ on_window_destroy(GtkWidget* ZIX_UNUSED(widget), gpointer ZIX_UNUSED(data)) int jalv_frontend_init(int* argc, char*** argv, JalvOptions* opts) { - GOptionEntry entries[] = { - {"load", - 'l', - 0, - G_OPTION_ARG_STRING, - &opts->load, - "Load state from save directory", - "DIR"}, + const GOptionEntry entries[] = { {"preset", - 'p', + 'P', 0, G_OPTION_ARG_STRING, &opts->preset, "Load state from preset", "URI"}, - {"dump", - 'd', + {"scale-factor", + 'S', 0, - G_OPTION_ARG_NONE, - &opts->dump, - "Dump plugin <=> UI communication", - NULL}, + G_OPTION_ARG_DOUBLE, + &opts->scale_factor, + "UI scale factor", + "SCALE"}, {"ui-uri", 'U', 0, @@ -125,20 +93,41 @@ jalv_frontend_init(int* argc, char*** argv, JalvOptions* opts) &opts->ui_uri, "Load the UI with the given URI", "URI"}, - {"trace", - 't', + {"buffer-size", + 'b', + 0, + G_OPTION_ARG_INT, + &opts->buffer_size, + "Buffer size for plugin <=> UI communication", + "SIZE"}, + {"control", + 'c', + 0, + G_OPTION_ARG_STRING_ARRAY, + &opts->controls, + "Set control value (e.g. \"vol=1.4\")", + "SETTING"}, + {"dump", + 'd', 0, G_OPTION_ARG_NONE, - &opts->trace, - "Print trace messages from plugin", + &opts->dump, + "Dump plugin <=> UI communication", NULL}, - {"show-hidden", - 's', + {"generic-ui", + 'g', 0, G_OPTION_ARG_NONE, - &opts->show_hidden, - "Show controls for ports with notOnGUI property on generic UI", + &opts->generic_ui, + "Use Jalv generic UI and not the plugin UI", NULL}, + {"load", + 'l', + 0, + G_OPTION_ARG_STRING, + &opts->load, + "Load state from save directory", + "DIR"}, {"no-menu", 'm', 0, @@ -146,63 +135,50 @@ jalv_frontend_init(int* argc, char*** argv, JalvOptions* opts) &opts->no_menu, "Do not show Jalv menu on window", NULL}, - {"generic-ui", - 'g', + {"jack-name", + 'n', + 0, + G_OPTION_ARG_STRING, + &opts->name, + "JACK client name", + "NAME"}, + {"print-controls", + 'p', 0, G_OPTION_ARG_NONE, - &opts->generic_ui, - "Use Jalv generic UI and not the plugin UI", + &opts->print_controls, + "Print control output changes to stdout", NULL}, - {"buffer-size", - 'b', - 0, - G_OPTION_ARG_INT, - &opts->buffer_size, - "Buffer size for plugin <=> UI communication", - "SIZE"}, {"update-frequency", 'r', 0, G_OPTION_ARG_DOUBLE, &opts->update_rate, "UI update frequency", - NULL}, - {"scale-factor", - 0, - 0, - G_OPTION_ARG_DOUBLE, - &opts->scale_factor, - "UI scale factor", - NULL}, - {"control", - 'c', - 0, - G_OPTION_ARG_STRING_ARRAY, - &opts->controls, - "Set control value (e.g. \"vol=1.4\")", - NULL}, - {"print-controls", - 'p', + "HZ"}, + {"show-hidden", + 's', 0, G_OPTION_ARG_NONE, - &opts->print_controls, - "Print control output changes to stdout", + &opts->show_hidden, + "Show controls for ports with notOnGUI property on generic UI", NULL}, - {"jack-name", - 'n', + {"trace", + 't', 0, - G_OPTION_ARG_STRING, - &opts->name, - "JACK client name", + G_OPTION_ARG_NONE, + &opts->trace, + "Print trace messages from plugin", NULL}, {"exact-jack-name", 'x', 0, G_OPTION_ARG_NONE, &opts->name_exact, - "Exact JACK client name (exit if taken)", + "Exit if the requested JACK client name is taken", NULL}, {0, 0, 0, G_OPTION_ARG_NONE, 0, 0, 0}}; + GError* error = NULL; const int err = gtk_init_with_args(argc, @@ -474,7 +450,7 @@ on_save_preset_activate(GtkWidget* widget, void* ptr) free(dot_lv2); GtkWidget* content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - GtkBox* box = GTK_BOX(new_box(true, 8)); + GtkBox* box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8)); GtkWidget* uri_label = gtk_label_new("URI (Optional):"); GtkWidget* uri_entry = gtk_entry_new(); GtkWidget* add_prefix = @@ -546,7 +522,7 @@ on_delete_preset_activate(GtkWidget* widget, void* ptr) (GtkWindow*)jalv->window, (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), "_Cancel", - GTK_RESPONSE_REJECT, + GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_ACCEPT, NULL); @@ -669,6 +645,8 @@ control_changed(Jalv* jalv, } } else if (GTK_IS_TOGGLE_BUTTON(widget)) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), fvalue > 0.0f); + } else if (GTK_IS_SWITCH(widget)) { + gtk_switch_set_active(GTK_SWITCH(widget), fvalue > 0.f); } else if (GTK_IS_RANGE(widget)) { gtk_range_set_value(GTK_RANGE(widget), fvalue); } else { @@ -896,10 +874,12 @@ combo_changed(GtkComboBox* box, gpointer data) } static gboolean -toggle_changed(GtkToggleButton* button, gpointer data) +switch_changed(GtkSwitch* toggle_switch, gboolean state, gpointer data) { - set_float_control((const ControlID*)data, - gtk_toggle_button_get_active(button) ? 1.0f : 0.0f); + (void)toggle_switch; + (void)data; + + set_float_control((const ControlID*)data, state ? 1.0f : 0.0f); return FALSE; } @@ -951,6 +931,8 @@ make_combo(ControlID* record, float value) g_object_unref(list_store); gtk_widget_set_sensitive(combo, record->is_writable); + gtk_widget_set_halign(combo, GTK_ALIGN_START); + gtk_widget_set_hexpand(combo, FALSE); GtkCellRenderer* cell = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), cell, TRUE); @@ -967,13 +949,16 @@ make_combo(ControlID* record, float value) static Controller* make_log_slider(ControlID* record, float value) { - const float min = get_float(record->min, 0.0f); - const float max = get_float(record->max, 1.0f); - const float lmin = logf(min); - const float lmax = logf(max); - const float ldft = logf(value); - GtkWidget* scale = new_hscale(lmin, lmax, 0.001); - GtkWidget* spin = gtk_spin_button_new_with_range(min, max, 0.000001); + const float min = get_float(record->min, 0.0f); + const float max = get_float(record->max, 1.0f); + const float lmin = logf(min); + const float lmax = logf(max); + const float ldft = logf(value); + + GtkWidget* const scale = + gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, lmin, lmax, 0.001); + + GtkWidget* const spin = gtk_spin_button_new_with_range(min, max, 0.000001); gtk_widget_set_sensitive(scale, record->is_writable); gtk_widget_set_sensitive(spin, record->is_writable); @@ -995,11 +980,14 @@ make_log_slider(ControlID* record, float value) static Controller* make_slider(ControlID* record, float value) { - const float min = get_float(record->min, 0.0f); - const float max = get_float(record->max, 1.0f); - const double step = record->is_integer ? 1.0 : ((max - min) / 100.0); - GtkWidget* scale = new_hscale(min, max, step); - GtkWidget* spin = gtk_spin_button_new_with_range(min, max, step); + const float min = get_float(record->min, 0.0f); + const float max = get_float(record->max, 1.0f); + const double step = record->is_integer ? 1.0 : ((max - min) / 100.0); + + GtkWidget* const scale = + gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step); + + GtkWidget* const spin = gtk_spin_button_new_with_range(min, max, step); gtk_widget_set_sensitive(scale, record->is_writable); gtk_widget_set_sensitive(spin, record->is_writable); @@ -1036,22 +1024,24 @@ make_slider(ControlID* record, float value) } static Controller* -make_toggle(ControlID* record, float value) +make_toggle_switch(ControlID* record, float value) { - GtkWidget* check = gtk_check_button_new(); + GtkWidget* toggle_switch = gtk_switch_new(); + gtk_widget_set_halign(toggle_switch, GTK_ALIGN_START); + gtk_widget_set_hexpand(toggle_switch, FALSE); - gtk_widget_set_sensitive(check, record->is_writable); + gtk_widget_set_sensitive(toggle_switch, record->is_writable); if (value) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE); + gtk_switch_set_active(GTK_SWITCH(toggle_switch), TRUE); } if (record->is_writable) { g_signal_connect( - G_OBJECT(check), "toggled", G_CALLBACK(toggle_changed), record); + G_OBJECT(toggle_switch), "state-set", G_CALLBACK(switch_changed), record); } - return new_controller(NULL, check); + return new_controller(NULL, toggle_switch); } static Controller* @@ -1090,7 +1080,7 @@ make_controller(ControlID* control, float value) Controller* controller = NULL; if (control->is_toggle) { - controller = make_toggle(control, value); + controller = make_toggle_switch(control, value); } else if (control->is_enumeration) { controller = make_combo(control, value); } else if (control->is_logarithmic) { @@ -1133,9 +1123,6 @@ add_control_row(GtkWidget* grid, } else { gtk_grid_attach(GTK_GRID(grid), controller->control, 1, row, 2, 1); } - - gtk_widget_set_halign(controller->control, GTK_ALIGN_FILL); - gtk_widget_set_hexpand(controller->control, TRUE); } static int @@ -1156,6 +1143,7 @@ static GtkWidget* build_control_widget(Jalv* jalv, GtkWidget* window) { GtkWidget* port_grid = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(port_grid), 4); // Make an array of controls sorted by group GArray* controls = g_array_new(FALSE, TRUE, sizeof(ControlID*)); @@ -1343,14 +1331,16 @@ LilvNode* jalv_frontend_select_plugin(Jalv* jalv) { // Create the dialog - GtkWidget* const dialog = gtk_dialog_new_with_buttons("Plugin Selector", - NULL, - (GtkDialogFlags)0, - "_OK", - GTK_RESPONSE_ACCEPT, - "_Cancel", - GTK_RESPONSE_REJECT, - NULL); + GtkWidget* const dialog = gtk_dialog_new_with_buttons( + "Plugin Selector", + NULL, + (GtkDialogFlags)(GTK_DIALOG_USE_HEADER_BAR | GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT), + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Load", + GTK_RESPONSE_ACCEPT, + NULL); gtk_window_set_role(GTK_WINDOW(dialog), "plugin_selector"); gtk_window_set_default_size(GTK_WINDOW(dialog), 800, 600); @@ -1453,7 +1443,8 @@ jalv_frontend_open(Jalv* jalv) set_window_title(jalv); - GtkWidget* vbox = new_box(false, 0); + GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_window_set_role(GTK_WINDOW(window), "plugin_ui"); gtk_container_add(GTK_CONTAINER(window), vbox); @@ -1493,12 +1484,14 @@ jalv_frontend_open(Jalv* jalv) GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(ui_box), scroll_win); + gtk_widget_set_margin_top(controls, 8); + gtk_widget_set_margin_bottom(controls, 8); gtk_widget_show_all(vbox); GtkRequisition controls_size = {0, 0}; GtkRequisition box_size = {0, 0}; - size_request(GTK_WIDGET(controls), &controls_size); - size_request(GTK_WIDGET(vbox), &box_size); + gtk_widget_get_preferred_size(GTK_WIDGET(controls), NULL, &controls_size); + gtk_widget_get_preferred_size(GTK_WIDGET(vbox), NULL, &box_size); gtk_window_set_default_size( GTK_WINDOW(window), @@ -1526,5 +1519,3 @@ jalv_frontend_close(Jalv* ZIX_UNUSED(jalv)) s_jalv = NULL; return 0; } - -LV2_RESTORE_WARNINGS diff --git a/src/jalv_qt.cpp b/src/jalv_qt.cpp index 5c3cd59..a63a508 100644 --- a/src/jalv_qt.cpp +++ b/src/jalv_qt.cpp @@ -60,10 +60,10 @@ public: explicit FlowLayout(int margin, int hSpacing, int vSpacing); - FlowLayout(const FlowLayout&) = delete; + FlowLayout(const FlowLayout&) = delete; FlowLayout& operator=(const FlowLayout&) = delete; - FlowLayout(FlowLayout&&) = delete; + FlowLayout(FlowLayout&&) = delete; FlowLayout&& operator=(FlowLayout&&) = delete; ~FlowLayout() override; @@ -213,10 +213,10 @@ FlowLayout::doLayout(const QRect& rect, bool testOnly) const int bottom = 0; getContentsMargins(&left, &top, &right, &bottom); - QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); - int x = effectiveRect.x(); - int y = effectiveRect.y(); - int lineHeight = 0; + const QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); + int lineHeight = 0; QLayoutItem* item = nullptr; foreach (item, itemList) { @@ -396,7 +396,7 @@ Control::Control(PortContainer portContainer, QWidget* parent) } // Find and set min, max and default values for port - float defaultValue = ndef ? lilv_node_as_float(ndef) : port->control; + const float defaultValue = ndef ? lilv_node_as_float(ndef) : port->control; setRange(lilv_node_as_float(nmin), lilv_node_as_float(nmax)); setValue(defaultValue); @@ -505,10 +505,11 @@ Control::getValue() } if (isLogarithmic) { - return min * powf(max / min, (float)dial->value() / (steps - 1)); + return min * + powf(max / min, static_cast<float>(dial->value()) / (steps - 1)); } - return (float)dial->value() / steps; + return static_cast<float>(dial->value()) / steps; } int @@ -524,7 +525,7 @@ Control::stringWidth(const QString& str) void Control::dialChanged(int) { - float value = getValue(); + const float value = getValue(); label->setText(getValueLabel(value)); port->control = value; @@ -578,8 +579,8 @@ build_control_widget(Jalv* jalv) LilvNode* lastGroup = nullptr; QHBoxLayout* groupLayout = nullptr; for (int i = 0; i < portContainers.count(); ++i) { - PortContainer portContainer = portContainers[i]; - Port* port = portContainer.port; + const PortContainer portContainer = portContainers[i]; + Port* const port = portContainer.port; auto* const control = new Control(portContainer, nullptr); LilvNode* group = @@ -608,7 +609,7 @@ build_control_widget(Jalv* jalv) lilv_node_free(lastGroup); lastGroup = group; - uint32_t index = lilv_port_get_index(plugin, port->lilv_port); + const uint32_t index = lilv_port_get_index(plugin, port->lilv_port); jalv->ports[index].widget = control; } lilv_node_free(lastGroup); @@ -627,13 +628,14 @@ jalv_frontend_discover(Jalv*) float jalv_frontend_refresh_rate(Jalv*) { - return (float)QGuiApplication::primaryScreen()->refreshRate(); + return static_cast<float>(QGuiApplication::primaryScreen()->refreshRate()); } float jalv_frontend_scale_factor(Jalv*) { - return (float)QGuiApplication::primaryScreen()->devicePixelRatio(); + return static_cast<float>( + QGuiApplication::primaryScreen()->devicePixelRatio()); } LilvNode* @@ -696,7 +698,7 @@ jalv_frontend_open(Jalv* jalv) auto* const timer = new Timer(jalv); timer->start(1000 / jalv->ui_update_hz); - int ret = app->exec(); + const int ret = app->exec(); zix_sem_post(&jalv->done); return ret; } @@ -6,7 +6,6 @@ #include "jalv_config.h" #include "jalv_internal.h" #include "port.h" -#include "urids.h" #include "lilv/lilv.h" #include "lv2/log/log.h" diff --git a/src/state.c b/src/state.c index 3ae7954..282b907 100644 --- a/src/state.c +++ b/src/state.c @@ -5,14 +5,11 @@ #include "jalv_internal.h" #include "log.h" -#include "nodes.h" #include "port.h" #include "lilv/lilv.h" -#include "lv2/atom/forge.h" #include "lv2/core/lv2.h" #include "lv2/state/state.h" -#include "lv2/urid/urid.h" #include "zix/attributes.h" #include "zix/sem.h" diff --git a/subprojects/zix.wrap b/subprojects/zix.wrap index 31739c5..7a50ea2 100644 --- a/subprojects/zix.wrap +++ b/subprojects/zix.wrap @@ -1,8 +1,14 @@ -# Copyright 2022 David Robillard <d@drobilla.net> +# Copyright 2022-2023 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -[wrap-git] -url = https://gitlab.com/drobilla/zix.git -push-url = ssh://git@gitlab.com:drobilla/zix.git -revision = main -depth = 1 +[wrap-file] +directory = zix-0.4.0 +source_url = https://download.drobilla.net/zix-0.4.0.tar.xz +source_filename = zix-0.4.0.tar.xz +source_hash = ac88dbefd9d29bfdce1532165c957d19d474a8367b727edb7be7d524e6cf9a14 + +# [wrap-git] +# url = https://gitlab.com/drobilla/zix.git +# push-url = ssh://git@gitlab.com:drobilla/zix.git +# revision = v0.4.0 +# depth = 1 diff --git a/test/meson.build b/test/meson.build index a4c4571..d7d0e94 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,13 +1,14 @@ # Copyright 2019-2022 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -if get_option('strict') +if get_option('lint') if not meson.is_subproject() # Check release metadata autoship = find_program('autoship', required: get_option('tests')) if autoship.found() test( - 'autoship', autoship, + 'autoship', + autoship, args: ['test', jalv_src_root], suite: 'data', ) @@ -18,7 +19,8 @@ if get_option('strict') reuse = find_program('reuse', required: false) if reuse.found() test( - 'REUSE', reuse, + 'REUSE', + reuse, args: ['--root', jalv_src_root, 'lint'], suite: 'data', ) |