diff options
-rw-r--r-- | .clang-tidy | 3 | ||||
-rw-r--r-- | benchmark/tree_bench.c | 33 | ||||
-rw-r--r-- | meson.build | 3 | ||||
-rw-r--r-- | meson_options.txt | 16 | ||||
-rw-r--r-- | src/.clang-tidy | 1 | ||||
-rw-r--r-- | src/btree.c | 2 | ||||
-rw-r--r-- | src/filesystem.c | 1 | ||||
-rw-r--r-- | test/.clang-tidy | 5 | ||||
-rw-r--r-- | test/failing_allocator.c | 18 | ||||
-rw-r--r-- | test/failing_allocator.h | 13 | ||||
-rw-r--r-- | test/meson.build | 81 | ||||
-rw-r--r-- | test/test_allocator.c | 2 | ||||
-rw-r--r-- | test/test_btree.c | 4 | ||||
-rw-r--r-- | test/test_filesystem.c | 4 | ||||
-rw-r--r-- | test/test_hash.c | 4 | ||||
-rw-r--r-- | test/test_ring.c | 4 | ||||
-rw-r--r-- | test/test_string_view.c | 5 | ||||
-rw-r--r-- | test/test_tree.c | 4 |
18 files changed, 106 insertions, 97 deletions
diff --git a/.clang-tidy b/.clang-tidy index 1c5a762..aefcd13 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,4 +1,4 @@ -# Copyright 2020-2022 David Robillard <d@drobilla.net> +# Copyright 2020-2024 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC Checks: > @@ -9,6 +9,7 @@ Checks: > -hicpp-multiway-paths-covered, -llvmlibc-*, -misc-include-cleaner, + -readability-avoid-nested-conditional-operator, -readability-identifier-length, WarningsAsErrors: '*' HeaderFilterRegex: '.*' diff --git a/benchmark/tree_bench.c b/benchmark/tree_bench.c index b9e230e..8cc2711 100644 --- a/benchmark/tree_bench.c +++ b/benchmark/tree_bench.c @@ -16,7 +16,6 @@ ZIX_DISABLE_GLIB_WARNINGS ZIX_RESTORE_WARNINGS #include <inttypes.h> -#include <stdarg.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -55,15 +54,11 @@ g_int_cmp(const void* a, const void* b, void* user_data) return int_cmp(a, b, user_data); } -ZIX_LOG_FUNC(1, 2) static int -test_fail(const char* fmt, ...) +test_fail(const char* const prefix, const uintptr_t value) { - va_list args; - va_start(args, fmt); fprintf(stderr, "error: "); - vfprintf(stderr, fmt, args); - va_end(args); + fprintf(stderr, "%s %" PRIuPTR "\n", prefix, value); return EXIT_FAILURE; } @@ -93,7 +88,7 @@ bench_zix_tree(size_t n_elems, ZixStatus status = zix_tree_insert(t, (void*)r, &ti); if (status) { - return test_fail("Failed to insert %" PRIuPTR "\n", r); + return test_fail("Failed to insert", r); } } fprintf(insert_dat, "\t%lf", bench_end(&insert_start)); @@ -103,10 +98,10 @@ bench_zix_tree(size_t n_elems, for (size_t i = 0; i < n_elems; i++) { r = unique_rand(i); if (zix_tree_find(t, (void*)r, &ti)) { - return test_fail("Failed to find %" PRIuPTR "\n", r); + return test_fail("Failed to find", r); } if ((uintptr_t)zix_tree_get(ti) != r) { - return test_fail("Failed to get %" PRIuPTR "\n", r); + return test_fail("Failed to get", r); } } fprintf(search_dat, "\t%lf", bench_end(&search_start)); @@ -127,10 +122,10 @@ bench_zix_tree(size_t n_elems, ZixTreeIter* item = NULL; if (zix_tree_find(t, (void*)r, &item)) { - return test_fail("Failed to find %" PRIuPTR " to delete\n", r); + return test_fail("Failed on delete to find", r); } if (zix_tree_remove(t, item)) { - return test_fail("Failed to remove %" PRIuPTR "\n", r); + return test_fail("Failed to remove", r); } } fprintf(del_dat, "\t%lf", bench_end(&del_start)); @@ -160,7 +155,7 @@ bench_zix_btree(size_t n_elems, ZixStatus status = zix_btree_insert(t, (void*)r); if (status) { - return test_fail("Failed to insert %" PRIuPTR "\n", r); + return test_fail("Failed to insert", r); } } fprintf(insert_dat, "\t%lf", bench_end(&insert_start)); @@ -170,10 +165,10 @@ bench_zix_btree(size_t n_elems, for (size_t i = 0; i < n_elems; i++) { r = unique_rand(i); if (zix_btree_find(t, (void*)r, &ti)) { - return test_fail("Failed to find %" PRIuPTR "\n", r); + return test_fail("Failed to find", r); } if ((uintptr_t)zix_btree_get(ti) != r) { - return test_fail("Failed to get %" PRIuPTR "\n", r); + return test_fail("Failed to get", r); } } fprintf(search_dat, "\t%lf", bench_end(&search_start)); @@ -195,7 +190,7 @@ bench_zix_btree(size_t n_elems, void* removed = NULL; ZixBTreeIter next = zix_btree_end(t); if (zix_btree_remove(t, (void*)r, &removed, &next)) { - return test_fail("Failed to remove %" PRIuPTR "\n", r); + return test_fail("Failed to remove", r); } } fprintf(del_dat, "\t%lf", bench_end(&del_start)); @@ -225,7 +220,7 @@ bench_glib(size_t n_elems, GSequenceIter* iter = g_sequence_insert_sorted(t, (void*)r, g_int_cmp, NULL); if (!iter || g_sequence_iter_is_end(iter)) { - return test_fail("Failed to insert %" PRIuPTR "\n", r); + return test_fail("Failed to insert", r); } } fprintf(insert_dat, "\t%lf", bench_end(&insert_start)); @@ -236,7 +231,7 @@ bench_glib(size_t n_elems, r = unique_rand(i); GSequenceIter* iter = g_sequence_lookup(t, (void*)r, g_int_cmp, NULL); if (!iter || g_sequence_iter_is_end(iter)) { - return test_fail("Failed to find %" PRIuPTR "\n", r); + return test_fail("Failed to find", r); } } fprintf(search_dat, "\t%lf", bench_end(&search_start)); @@ -256,7 +251,7 @@ bench_glib(size_t n_elems, r = unique_rand(i); GSequenceIter* iter = g_sequence_lookup(t, (void*)r, g_int_cmp, NULL); if (!iter || g_sequence_iter_is_end(iter)) { - return test_fail("Failed to remove %" PRIuPTR "\n", r); + return test_fail("Failed to remove", r); } g_sequence_remove(iter); } diff --git a/meson.build b/meson.build index f84642b..3ec4c41 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -# Copyright 2020-2023 David Robillard <d@drobilla.net> +# Copyright 2020-2024 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC project( @@ -49,6 +49,7 @@ if cc.get_id() in ['clang', 'emscripten'] '-Wno-declaration-after-statement', '-Wno-implicit-fallthrough', # Really for clang < 12 '-Wno-padded', + '-Wno-switch-default', '-Wno-unsafe-buffer-usage', ] diff --git a/meson_options.txt b/meson_options.txt index 3eac738..0ae44d1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,34 +1,34 @@ # Copyright 2020-2023 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -option('benchmarks', type: 'feature', value: 'auto', yield: true, +option('benchmarks', type: 'feature', yield: true, description: 'Build benchmarks') option('checks', type: 'feature', value: 'enabled', yield: true, description: 'Check for platform-specific features') -option('docs', type: 'feature', value: 'auto', yield: true, +option('docs', type: 'feature', yield: true, description: 'Build documentation') -option('html', type: 'feature', value: 'auto', yield: true, +option('html', type: 'feature', yield: true, description: 'Build paginated HTML documentation') option('lint', type: 'boolean', value: false, yield: true, description: 'Run code quality checks') -option('posix', type: 'feature', value: 'auto', yield: true, +option('posix', type: 'feature', yield: true, description: 'Use POSIX system facilities') -option('singlehtml', type: 'feature', value: 'auto', yield: true, +option('singlehtml', type: 'feature', yield: true, description: 'Build single-page HTML documentation') -option('threads', type: 'feature', value: 'auto', yield: true, +option('threads', type: 'feature', yield: true, description: 'Enable thread support') -option('tests', type: 'feature', value: 'auto', yield: true, +option('tests', type: 'feature', yield: true, description: 'Build tests') -option('tests_cpp', type: 'feature', value: 'auto', yield: true, +option('tests_cpp', type: 'feature', yield: true, description: 'Build C++ standard library comparison tests') option('title', type: 'string', value: 'Zix', diff --git a/src/.clang-tidy b/src/.clang-tidy index 5647a8f..b3b1960 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -4,6 +4,7 @@ Checks: > -*-magic-numbers, -bugprone-easily-swappable-parameters, + -bugprone-multi-level-implicit-pointer-conversion, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -llvm-header-guard, -misc-no-recursion, diff --git a/src/btree.c b/src/btree.c index 7970796..db7f922 100644 --- a/src/btree.c +++ b/src/btree.c @@ -394,6 +394,7 @@ zix_btree_leaf_find(const ZixBTree* const t, t->cmp, t->cmp_data, n->data.leaf.vals, n->n_vals, e, equal); } +ZIX_PURE_FUNC static inline bool zix_btree_can_remove_from(const ZixBTreeNode* const n) { @@ -401,6 +402,7 @@ zix_btree_can_remove_from(const ZixBTreeNode* const n) return n->n_vals > zix_btree_min_vals(n); } +ZIX_PURE_FUNC static inline bool zix_btree_is_full(const ZixBTreeNode* const n) { diff --git a/src/filesystem.c b/src/filesystem.c index 61487e9..c6a1fa4 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -18,6 +18,7 @@ #include <fcntl.h> #include <sys/stat.h> +#include <sys/types.h> #include <errno.h> #include <stdbool.h> diff --git a/test/.clang-tidy b/test/.clang-tidy index 2d684a6..f869db0 100644 --- a/test/.clang-tidy +++ b/test/.clang-tidy @@ -1,16 +1,17 @@ -# Copyright 2020-2022 David Robillard <d@drobilla.net> +# Copyright 2020-2024 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC Checks: > + -*-macro-to-enum, -*-magic-numbers, -android-cloexec-fopen, -bugprone-easily-swappable-parameters, + -bugprone-multi-level-implicit-pointer-conversion, -cert-err33-c, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -cppcoreguidelines-avoid-non-const-global-variables, -google-readability-casting, -llvm-header-guard, - -modernize-macro-to-enum, -performance-no-int-to-ptr, -readability-function-cognitive-complexity, InheritParentConfig: true diff --git a/test/failing_allocator.c b/test/failing_allocator.c index 684a8ec..53a5216 100644 --- a/test/failing_allocator.c +++ b/test/failing_allocator.c @@ -1,10 +1,10 @@ -// Copyright 2021 David Robillard <d@drobilla.net> +// Copyright 2021-2024 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #include "failing_allocator.h" -#include "zix/allocator.h" -#include "zix/attributes.h" +#include <zix/allocator.h> +#include <zix/attributes.h> #include <stdbool.h> #include <stddef.h> @@ -107,3 +107,15 @@ zix_failing_allocator(void) return failing_allocator; } + +size_t +zix_failing_allocator_reset(ZixFailingAllocator* const allocator, + const size_t n_allowed) +{ + const size_t n_allocations = allocator->n_allocations; + + allocator->n_allocations = 0U; + allocator->n_remaining = n_allowed; + + return n_allocations; +} diff --git a/test/failing_allocator.h b/test/failing_allocator.h index 982874d..5f6d220 100644 --- a/test/failing_allocator.h +++ b/test/failing_allocator.h @@ -1,8 +1,8 @@ -// Copyright 2021 David Robillard <d@drobilla.net> +// Copyright 2021-2024 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC -#ifndef ZIX_FAILING_ALLOCATOR_H -#define ZIX_FAILING_ALLOCATOR_H +#ifndef ZIX_TEST_FAILING_ALLOCATOR_H +#define ZIX_TEST_FAILING_ALLOCATOR_H #include "zix/allocator.h" @@ -15,7 +15,12 @@ typedef struct { size_t n_remaining; ///< Number of remaining successful allocations } ZixFailingAllocator; +/// Return an allocator configured by default to succeed ZixFailingAllocator zix_failing_allocator(void); -#endif // ZIX_FAILING_ALLOCATOR_H +/// Reset an allocator to fail after some number of "allowed" allocations +size_t +zix_failing_allocator_reset(ZixFailingAllocator* allocator, size_t n_allowed); + +#endif // ZIX_TEST_FAILING_ALLOCATOR_H diff --git a/test/meson.build b/test/meson.build index 96fe455..6aa4e95 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,64 +1,55 @@ # Copyright 2020-2024 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC -if not meson.is_subproject() and get_option('lint') - # Check release metadata - autoship = find_program('autoship', required: get_option('tests')) - if autoship.found() - test( - 'autoship', - autoship, - args: ['test', zix_src_root], - suite: 'data', - ) +######## +# Lint # +######## + +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, args: ['test', zix_src_root], suite: 'data') + endif + + # Check code with cppcheck + cppcheck = find_program('cppcheck', required: false) + if cppcheck.found() + compdb_path = join_paths(zix_build_root, 'compile_commands.json') + cppcheck_args = [ + '--enable=warning,style,performance,portability', + '--error-exitcode=1', + '--project=' + compdb_path, + '--suppress=constParameterCallback', + '--suppress=constParameterPointer', + '--suppress=normalCheckLevelMaxBranches', + '--suppress=unreadVariable', + '-q', + ] + test('cppcheck', cppcheck, args: cppcheck_args, suite: 'code') + endif endif # Check licensing metadata reuse = find_program('reuse', required: get_option('tests')) if reuse.found() - test( - 'REUSE', - reuse, - args: ['--root', zix_src_root, 'lint'], - suite: 'data', - ) + reuse_args = ['--root', zix_src_root, 'lint'] + test('REUSE', reuse, args: reuse_args, suite: 'data') endif # Check code formatting clang_format = find_program('clang-format', required: false) if clang_format.found() - test( - 'format', - clang_format, - args: ['--Werror', '--dry-run'] + c_headers + sources, - suite: 'code', - ) - endif - - # Check code with cppcheck - if not meson.is_subproject() - cppcheck = find_program('cppcheck', required: false) - if cppcheck.found() - compdb_path = join_paths(zix_build_root, 'compile_commands.json') - test( - 'cppcheck', - cppcheck, - args: [ - '--check-level=exhaustive', - '--enable=warning,style,performance,portability', - '--error-exitcode=1', - '--project=' + compdb_path, - '--suppress=constParameterCallback', - '--suppress=constParameterPointer', - '--suppress=unreadVariable', - '-q', - ], - suite: 'code', - ) - endif + clang_format_args = ['--Werror', '--dry-run'] + c_headers + sources + test('format', clang_format, args: clang_format_args, suite: 'code') endif endif +############## +# Unit Tests # +############## + # Set warning suppression flags specific to tests test_suppressions = [] if host_machine.system() == 'windows' diff --git a/test/test_allocator.c b/test/test_allocator.c index 9ecbfa0..2677624 100644 --- a/test/test_allocator.c +++ b/test/test_allocator.c @@ -122,7 +122,7 @@ static void test_failing_allocator(void) { ZixFailingAllocator allocator = zix_failing_allocator(); - allocator.n_remaining = 0; + zix_failing_allocator_reset(&allocator, 0); assert(!zix_malloc(&allocator.base, 16U)); assert(!zix_calloc(&allocator.base, 16U, 1U)); diff --git a/test/test_btree.c b/test/test_btree.c index e918799..a3183c6 100644 --- a/test/test_btree.c +++ b/test/test_btree.c @@ -563,9 +563,9 @@ test_failed_alloc(void) assert(!stress(&allocator.base, 0, 4096)); // Test that each allocation failing is handled gracefully - const size_t n_new_allocs = allocator.n_allocations; + const size_t n_new_allocs = zix_failing_allocator_reset(&allocator, 0); for (size_t i = 0U; i < n_new_allocs; ++i) { - allocator.n_remaining = i; + zix_failing_allocator_reset(&allocator, i); assert(stress(&allocator.base, 0, 4096)); } } diff --git a/test/test_filesystem.c b/test/test_filesystem.c index 87a3d15..e6180fb 100644 --- a/test/test_filesystem.c +++ b/test/test_filesystem.c @@ -172,9 +172,7 @@ test_file_type(void) assert(!zix_remove(file_path)); close(fd); } - } else { - fprintf(stderr, "warning: Skipped socket test with oddly long TMPDIR\n"); - } + } // otherwise, TMPDIR is oddly long, skip test close(sock); free(addr); diff --git a/test/test_hash.c b/test/test_hash.c index 3d3ca95..8ee6b82 100644 --- a/test/test_hash.c +++ b/test/test_hash.c @@ -366,9 +366,9 @@ test_failed_alloc(void) assert(!stress(&allocator.base, 16)); // Test that each allocation failing is handled gracefully - const size_t n_new_allocs = allocator.n_allocations; + const size_t n_new_allocs = zix_failing_allocator_reset(&allocator, 0); for (size_t i = 0U; i < n_new_allocs; ++i) { - allocator.n_remaining = i; + zix_failing_allocator_reset(&allocator, i); assert(stress(&allocator.base, 16)); } } diff --git a/test/test_ring.c b/test/test_ring.c index b1845ce..06d50ee 100644 --- a/test/test_ring.c +++ b/test/test_ring.c @@ -170,9 +170,9 @@ test_failed_alloc(void) assert(ring); // Test that each allocation failing is handled gracefully - const size_t n_new_allocs = allocator.n_allocations; + const size_t n_new_allocs = zix_failing_allocator_reset(&allocator, 0); for (size_t i = 0U; i < n_new_allocs; ++i) { - allocator.n_remaining = i; + zix_failing_allocator_reset(&allocator, i); assert(!zix_ring_new(&allocator.base, 512)); } diff --git a/test/test_string_view.c b/test/test_string_view.c index 52b824d..764edcb 100644 --- a/test/test_string_view.c +++ b/test/test_string_view.c @@ -5,6 +5,7 @@ #include "failing_allocator.h" +#include "zix/allocator.h" #include "zix/string_view.h" #include <assert.h> @@ -94,7 +95,7 @@ test_copy(void) ZixFailingAllocator allocator = zix_failing_allocator(); // Copying a string takes exactly one allocation - allocator.n_remaining = 1U; + zix_failing_allocator_reset(&allocator, 1U); char* const copy = zix_string_view_copy(&allocator.base, orig); assert(copy); @@ -102,7 +103,7 @@ test_copy(void) zix_free(&allocator.base, copy); // Check that allocation failure is handled gracefully - allocator.n_remaining = 0U; + zix_failing_allocator_reset(&allocator, 0U); assert(!zix_string_view_copy(&allocator.base, orig)); } diff --git a/test/test_tree.c b/test/test_tree.c index fae6d85..ff63999 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -211,9 +211,9 @@ test_failed_alloc(void) assert(!stress(&allocator.base, 0, 16)); // Test that each allocation failing is handled gracefully - const size_t n_new_allocs = allocator.n_allocations; + const size_t n_new_allocs = zix_failing_allocator_reset(&allocator, 0); for (size_t i = 0U; i < n_new_allocs; ++i) { - allocator.n_remaining = i; + zix_failing_allocator_reset(&allocator, i); assert(stress(&allocator.base, 0, 16)); } } |