aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format30
-rw-r--r--.gitlab-ci.yml4
-rw-r--r--.reuse/dep55
-rw-r--r--.suppress.cppcheck4
-rw-r--r--include/serd/serd.h15
-rw-r--r--meson.build1
-rw-r--r--meson_options.txt12
-rw-r--r--src/byte_sink.h8
-rw-r--r--src/byte_source.h4
-rw-r--r--src/n3.c28
-rw-r--r--src/node.h4
-rw-r--r--src/reader.c4
-rw-r--r--src/reader.h23
-rw-r--r--src/serd_internal.h4
-rw-r--r--src/stack.h16
-rw-r--r--src/string_utils.h8
-rw-r--r--src/system.c1
-rw-r--r--src/uri.c16
-rw-r--r--src/uri_utils.h12
-rw-r--r--src/writer.c185
-rw-r--r--test/headers/test_headers.c3
-rw-r--r--test/meson.build252
-rw-r--r--test/serd_test_util/__init__.py29
-rw-r--r--test/test_env.c4
-rw-r--r--test/test_node.c6
-rwxr-xr-xtest/test_quiet.py12
-rw-r--r--test/test_reader.c78
-rw-r--r--test/test_reader_writer.c24
-rwxr-xr-xtest/test_stdin.py37
-rw-r--r--test/test_string.c3
-rw-r--r--test/test_uri.c107
-rwxr-xr-xtest/test_write_error.py9
-rw-r--r--test/test_writer.c1
33 files changed, 486 insertions, 463 deletions
diff --git a/.clang-format b/.clang-format
index 26b10123..1ec52448 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,17 +1,29 @@
-# Copyright 2020-2023 David Robillard <d@drobilla.net>
+# Copyright 2020-2024 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
---
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
-AlignEscapedNewlinesLeft: true
+AlignEscapedNewlines: Left
+AttributeMacros:
+ - SERD_ALLOCATED
+ - SERD_API
+ - SERD_CONST_API
+ - SERD_CONST_FUNC
+ - SERD_FALLTHROUGH
+ - SERD_MALLOC_FUNC
+ - SERD_NODISCARD
+ - SERD_NONNULL
+ - SERD_NULLABLE
+ - SERD_PURE_API
+ - SERD_PURE_FUNC
BasedOnStyle: Mozilla
BraceWrapping:
- AfterNamespace: false
AfterClass: true
AfterEnum: false
AfterExternBlock: false
AfterFunction: true
+ AfterNamespace: false
AfterStruct: false
SplitEmptyFunction: false
SplitEmptyRecord: false
@@ -21,20 +33,10 @@ IndentCaseLabels: false
IndentPPDirectives: AfterHash
KeepEmptyLinesAtTheStartOfBlocks: false
SpacesInContainerLiterals: false
-AttributeMacros:
- - SERD_ALLOCATED
- - SERD_API
- - SERD_CONST_FINC
- - SERD_FALLTHROUGH
- - SERD_MALLOC_FUNC
- - SERD_NODISCARD
- - SERD_NONNULL
- - SERD_NULLABLE
- - SERD_PURE_FUNC
StatementMacros:
- SERD_DEPRECATED_BY
- - SERD_LOG_FUNC
- SERD_DISABLE_NULL_WARNINGS
+ - SERD_LOG_FUNC
- SERD_RESTORE_WARNINGS
- _Pragma
...
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ec20e2f7..41904c85 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -41,7 +41,7 @@ sanitize:
stage: build
image: lv2plugin/debian-x64-clang
script:
- - meson setup build -Db_lundef=false -Dbuildtype=plain -Dc_std=c11 -Ddocs=disabled -Dwarning_level=3 -Dwerror=true
+ - meson setup build -Db_lundef=false -Dbuildtype=plain -Dc_std=c11 -Ddocs=disabled -Dlint=true -Dwarning_level=3 -Dwerror=true
- ninja -C build test
variables:
CC: "clang"
@@ -158,4 +158,4 @@ pages:
paths:
- public
only:
- - master
+ - main
diff --git a/.reuse/dep5 b/.reuse/dep5
index 3173226a..78dc2af5 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -3,6 +3,11 @@ Upstream-Name: serd
Upstream-Contact: David Robillard <d@drobilla.net>
Source: https://gitlab.com/drobilla/serd
+Files: .suppress.cppcheck
+Copyright: 2024 David Robillard <d@drobilla.net>
+Comment: Contributed to the Commons as a tool configuration
+License: 0BSD OR ISC
+
Files: test/w3c/*
Copyright: 2010 World Wide Web Consortium, (MIT, ERCIM, Keio, Beihang) and others.
Comment: Standard test suites from the W3C
diff --git a/.suppress.cppcheck b/.suppress.cppcheck
new file mode 100644
index 00000000..292f6884
--- /dev/null
+++ b/.suppress.cppcheck
@@ -0,0 +1,4 @@
+assignmentInAssert
+normalCheckLevelMaxBranches
+redundantInitialization
+unreadVariable
diff --git a/include/serd/serd.h b/include/serd/serd.h
index 1f84950b..19b4a49c 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -127,8 +127,7 @@ typedef enum {
} SerdStatus;
/// Return a string describing a status code
-SERD_CONST_API
-const uint8_t* SERD_NONNULL
+SERD_CONST_API const uint8_t* SERD_NONNULL
serd_strerror(SerdStatus status);
/**
@@ -268,8 +267,7 @@ serd_file_uri_parse(const uint8_t* SERD_NONNULL uri,
uint8_t* SERD_UNSPECIFIED* SERD_NULLABLE hostname);
/// Return true iff `utf8` starts with a valid URI scheme
-SERD_PURE_API
-bool
+SERD_PURE_API bool
serd_uri_string_has_scheme(const uint8_t* SERD_NULLABLE utf8);
/// Parse `utf8`, writing result to `out`
@@ -501,8 +499,7 @@ SERD_API SerdNode
serd_node_copy(const SerdNode* SERD_NULLABLE node);
/// Return true iff `a` is equal to `b`
-SERD_PURE_API
-bool
+SERD_PURE_API bool
serd_node_equals(const SerdNode* SERD_NONNULL a,
const SerdNode* SERD_NONNULL b);
@@ -717,8 +714,7 @@ serd_reader_set_error_sink(SerdReader* SERD_NONNULL reader,
void* SERD_UNSPECIFIED error_handle);
/// Return the `handle` passed to serd_reader_new()
-SERD_PURE_API
-void* SERD_UNSPECIFIED
+SERD_PURE_API void* SERD_UNSPECIFIED
serd_reader_get_handle(const SerdReader* SERD_NONNULL reader);
/**
@@ -868,8 +864,7 @@ SERD_API void
serd_writer_free(SerdWriter* SERD_NULLABLE writer);
/// Return the env used by `writer`
-SERD_PURE_API
-SerdEnv* SERD_NONNULL
+SERD_PURE_API SerdEnv* SERD_NONNULL
serd_writer_get_env(SerdWriter* SERD_NONNULL writer);
/**
diff --git a/meson.build b/meson.build
index 4b01ff9c..2a05f8a6 100644
--- a/meson.build
+++ b/meson.build
@@ -16,6 +16,7 @@ project(
)
serd_src_root = meson.current_source_dir()
+serd_build_root = meson.current_build_dir()
major_version = meson.project_version().split('.')[0]
version_suffix = '-@0@'.format(major_version)
versioned_name = 'serd' + version_suffix
diff --git a/meson_options.txt b/meson_options.txt
index 09fc2334..30473e89 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,10 +4,10 @@
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,
@@ -16,20 +16,20 @@ option('lint', type: 'boolean', value: false, yield: true,
option('man', type: 'feature', value: 'enabled', yield: true,
description: 'Install man pages')
-option('man_html', type: 'feature', value: 'auto', yield: true,
+option('man_html', type: 'feature', yield: true,
description: 'Build HTML man pages')
-option('singlehtml', type: 'feature', value: 'auto', yield: true,
+option('singlehtml', type: 'feature', yield: true,
description: 'Build single-page HTML documentation')
option('static', type: 'boolean', value: false, yield: true,
description: 'Statically link executables')
-option('tests', type: 'feature', value: 'auto', yield: true,
+option('tests', type: 'feature', yield: true,
description: 'Build tests')
option('title', type: 'string', value: 'Serd',
description: 'Project title')
-option('tools', type: 'feature', value: 'auto', yield: true,
+option('tools', type: 'feature', yield: true,
description: 'Build command line utilities')
diff --git a/src/byte_sink.h b/src/byte_sink.h
index 65b5eb12..b99b5551 100644
--- a/src/byte_sink.h
+++ b/src/byte_sink.h
@@ -22,7 +22,7 @@ typedef struct SerdByteSinkImpl {
} SerdByteSink;
static inline SerdByteSink
-serd_byte_sink_new(SerdSink sink, void* stream, size_t block_size)
+serd_byte_sink_new(SerdSink sink, void* const stream, const size_t block_size)
{
SerdByteSink bsink = {sink, stream, NULL, 0, block_size};
@@ -34,7 +34,7 @@ serd_byte_sink_new(SerdSink sink, void* stream, size_t block_size)
}
static inline SerdStatus
-serd_byte_sink_flush(SerdByteSink* bsink)
+serd_byte_sink_flush(SerdByteSink* const bsink)
{
if (bsink->block_size > 1 && bsink->size > 0) {
const size_t size = bsink->size;
@@ -48,7 +48,7 @@ serd_byte_sink_flush(SerdByteSink* bsink)
}
static inline void
-serd_byte_sink_free(SerdByteSink* bsink)
+serd_byte_sink_free(SerdByteSink* const bsink)
{
serd_byte_sink_flush(bsink);
serd_free_aligned(bsink->buf);
@@ -56,7 +56,7 @@ serd_byte_sink_free(SerdByteSink* bsink)
}
static inline size_t
-serd_byte_sink_write(const void* buf, size_t len, SerdByteSink* bsink)
+serd_byte_sink_write(const void* buf, size_t len, SerdByteSink* const bsink)
{
if (len == 0) {
return 0;
diff --git a/src/byte_source.h b/src/byte_source.h
index afd9ccb9..961fae72 100644
--- a/src/byte_source.h
+++ b/src/byte_source.h
@@ -58,14 +58,14 @@ SerdStatus
serd_byte_source_page(SerdByteSource* source);
static inline SERD_PURE_FUNC uint8_t
-serd_byte_source_peek(SerdByteSource* source)
+serd_byte_source_peek(SerdByteSource* const source)
{
assert(source->prepared);
return source->read_buf[source->read_head];
}
static inline SerdStatus
-serd_byte_source_advance(SerdByteSource* source)
+serd_byte_source_advance(SerdByteSource* const source)
{
SerdStatus st = SERD_SUCCESS;
diff --git a/src/n3.c b/src/n3.c
index e5a06c77..b0c958e2 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -172,7 +172,7 @@ bad_char(SerdReader* const reader, const char* const fmt, const uint8_t c)
static SerdStatus
read_utf8_bytes(SerdReader* const reader,
uint8_t bytes[4],
- uint32_t* const size,
+ uint8_t* const size,
const uint8_t c)
{
*size = utf8_num_bytes(c);
@@ -181,9 +181,9 @@ read_utf8_bytes(SerdReader* const reader,
}
bytes[0] = c;
- for (unsigned i = 1; i < *size; ++i) {
+ for (uint8_t i = 1U; i < *size; ++i) {
const int b = peek_byte(reader);
- if (b == EOF || ((uint8_t)b & 0x80) == 0) {
+ if (b == EOF || ((uint8_t)b & 0x80U) == 0U) {
return bad_char(reader, "invalid UTF-8 continuation 0x%X\n", (uint8_t)b);
}
@@ -196,7 +196,7 @@ read_utf8_bytes(SerdReader* const reader,
static SerdStatus
read_utf8_character(SerdReader* const reader, const Ref dest, const uint8_t c)
{
- uint32_t size = 0;
+ uint8_t size = 0U;
uint8_t bytes[4] = {0, 0, 0, 0};
SerdStatus st = read_utf8_bytes(reader, bytes, &size, c);
if (st) {
@@ -214,7 +214,7 @@ read_utf8_code(SerdReader* const reader,
uint32_t* const code,
const uint8_t c)
{
- uint32_t size = 0;
+ uint8_t size = 0U;
uint8_t bytes[4] = {0, 0, 0, 0};
SerdStatus st = read_utf8_bytes(reader, bytes, &size, c);
if (st) {
@@ -740,12 +740,12 @@ read_IRIREF(SerdReader* const reader, Ref* const dest)
SERD_ERR_BAD_SYNTAX,
"invalid IRI character (escape %%%02X)\n",
(unsigned)c);
- if (reader->strict) {
+ if (!reader->strict) {
+ st = SERD_FAILURE;
+ push_byte(reader, *dest, c);
+ } else {
break;
}
-
- st = SERD_FAILURE;
- push_byte(reader, *dest, c);
} else if (!(c & 0x80)) {
push_byte(reader, *dest, c);
} else if (read_utf8_character(reader, *dest, (uint8_t)c)) {
@@ -925,10 +925,10 @@ read_verb(SerdReader* const reader, Ref* const dest)
*/
*dest = push_node(reader, SERD_CURIE, "", 0);
- SerdStatus st = read_PN_PREFIX(reader, *dest);
- bool ate_dot = false;
- SerdNode* node = deref(reader, *dest);
- const int next = peek_byte(reader);
+ SerdStatus st = read_PN_PREFIX(reader, *dest);
+ bool ate_dot = false;
+ const SerdNode* const node = deref(reader, *dest);
+ const int next = peek_byte(reader);
if (!st && node->n_bytes == 1 && node->buf[0] == 'a' && next != ':' &&
!is_PN_CHARS_BASE((uint32_t)next)) {
pop_node(reader, *dest);
@@ -1540,7 +1540,7 @@ token_equals(SerdReader* const reader,
const char* const tok,
const size_t n)
{
- SerdNode* const node = deref(reader, ref);
+ const SerdNode* const node = deref(reader, ref);
if (!node || node->n_bytes != n) {
return false;
}
diff --git a/src/node.h b/src/node.h
index a4d5dcd5..c0886391 100644
--- a/src/node.h
+++ b/src/node.h
@@ -15,13 +15,13 @@ struct SerdNodeImpl {
};
static inline char* SERD_NONNULL
-serd_node_buffer(SerdNode* SERD_NONNULL node)
+serd_node_buffer(SerdNode* const SERD_NONNULL node)
{
return (char*)(node + 1);
}
static inline const char* SERD_NONNULL
-serd_node_buffer_c(const SerdNode* SERD_NONNULL node)
+serd_node_buffer_c(const SerdNode* const SERD_NONNULL node)
{
return (const char*)(node + 1);
}
diff --git a/src/reader.c b/src/reader.c
index aa24a9ca..5cd978bf 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -127,8 +127,8 @@ pop_node(SerdReader* const reader, const Ref ref)
SERD_STACK_ASSERT_TOP(reader, ref);
--reader->n_allocs;
#endif
- SerdNode* const node = deref(reader, ref);
- uint8_t* const top = reader->stack.buf + reader->stack.size;
+ SerdNode* const node = deref(reader, ref);
+ const uint8_t* const top = reader->stack.buf + reader->stack.size;
serd_stack_pop_aligned(&reader->stack, (size_t)(top - (uint8_t*)node));
}
return 0;
diff --git a/src/reader.h b/src/reader.h
index 9b558d1f..a867ffc0 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -12,8 +12,8 @@
#include <assert.h>
#include <stdbool.h>
+#include <stddef.h>
#include <stdint.h>
-#include <stdio.h>
#ifdef SERD_STACK_CHECK
# define SERD_STACK_ASSERT_TOP(reader, ref) \
@@ -110,15 +110,15 @@ SerdStatus
read_turtleTrigDoc(SerdReader* reader);
static inline int
-peek_byte(SerdReader* reader)
+peek_byte(SerdReader* const reader)
{
SerdByteSource* source = &reader->source;
- return source->eof ? EOF : (int)source->read_buf[source->read_head];
+ return source->eof ? -1 : (int)source->read_buf[source->read_head];
}
static inline SerdStatus
-skip_byte(SerdReader* reader, const int byte)
+skip_byte(SerdReader* const reader, const int byte)
{
(void)byte;
@@ -128,7 +128,7 @@ skip_byte(SerdReader* reader, const int byte)
}
static inline int SERD_NODISCARD
-eat_byte_safe(SerdReader* reader, const int byte)
+eat_byte_safe(SerdReader* const reader, const int byte)
{
(void)byte;
@@ -139,7 +139,7 @@ eat_byte_safe(SerdReader* reader, const int byte)
}
static inline int SERD_NODISCARD
-eat_byte_check(SerdReader* reader, const int byte)
+eat_byte_check(SerdReader* const reader, const int byte)
{
const int c = peek_byte(reader);
if (c != byte) {
@@ -150,7 +150,7 @@ eat_byte_check(SerdReader* reader, const int byte)
}
static inline SerdStatus
-eat_string(SerdReader* reader, const char* str, unsigned n)
+eat_string(SerdReader* const reader, const char* const str, const unsigned n)
{
for (unsigned i = 0; i < n; ++i) {
if (!eat_byte_check(reader, ((const uint8_t*)str)[i])) {
@@ -161,9 +161,9 @@ eat_string(SerdReader* reader, const char* str, unsigned n)
}
static inline SerdStatus
-push_byte(SerdReader* reader, Ref ref, const int c)
+push_byte(SerdReader* const reader, const Ref ref, const int c)
{
- assert(c != EOF);
+ assert(c >= 0);
SERD_STACK_ASSERT_TOP(reader, ref);
uint8_t* const s = (uint8_t*)serd_stack_push(&reader->stack, 1);
@@ -180,7 +180,10 @@ push_byte(SerdReader* reader, Ref ref, const int c)
}
static inline void
-push_bytes(SerdReader* reader, Ref ref, const uint8_t* bytes, unsigned len)
+push_bytes(SerdReader* const reader,
+ const Ref ref,
+ const uint8_t* const bytes,
+ const unsigned len)
{
for (unsigned i = 0; i < len; ++i) {
push_byte(reader, ref, bytes[i]);
diff --git a/src/serd_internal.h b/src/serd_internal.h
index 388c12ec..5508c111 100644
--- a/src/serd_internal.h
+++ b/src/serd_internal.h
@@ -20,7 +20,9 @@
/* Error reporting */
static inline void
-serd_error(SerdErrorSink error_sink, void* handle, const SerdError* e)
+serd_error(const SerdErrorSink error_sink,
+ void* const handle,
+ const SerdError* const e)
{
if (error_sink) {
error_sink(handle, e);
diff --git a/src/stack.h b/src/stack.h
index 388dd054..f82de9d2 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -24,7 +24,7 @@ typedef struct {
#define SERD_STACK_BOTTOM sizeof(void*)
static inline SerdStack
-serd_stack_new(size_t size)
+serd_stack_new(const size_t size)
{
SerdStack stack;
stack.buf = (uint8_t*)calloc(size, 1);
@@ -34,13 +34,13 @@ serd_stack_new(size_t size)
}
static inline bool
-serd_stack_is_empty(const SerdStack* stack)
+serd_stack_is_empty(const SerdStack* const stack)
{
return stack->size <= SERD_STACK_BOTTOM;
}
static inline void
-serd_stack_free(SerdStack* stack)
+serd_stack_free(SerdStack* const stack)
{
free(stack->buf);
stack->buf = NULL;
@@ -49,7 +49,7 @@ serd_stack_free(SerdStack* stack)
}
static inline void*
-serd_stack_push(SerdStack* stack, size_t n_bytes)
+serd_stack_push(SerdStack* const stack, const size_t n_bytes)
{
const size_t new_size = stack->size + n_bytes;
if (stack->buf_size < new_size) {
@@ -64,14 +64,16 @@ serd_stack_push(SerdStack* stack, size_t n_bytes)
}
static inline void
-serd_stack_pop(SerdStack* stack, size_t n_bytes)
+serd_stack_pop(SerdStack* const stack, const size_t n_bytes)
{
assert(stack->size >= n_bytes);
stack->size -= n_bytes;
}
static inline void*
-serd_stack_push_aligned(SerdStack* stack, size_t n_bytes, size_t align)
+serd_stack_push_aligned(SerdStack* const stack,
+ const size_t n_bytes,
+ const size_t align)
{
// Push one byte to ensure space for a pad count
serd_stack_push(stack, 1);
@@ -89,7 +91,7 @@ serd_stack_push_aligned(SerdStack* stack, size_t n_bytes, size_t align)
}
static inline void
-serd_stack_pop_aligned(SerdStack* stack, size_t n_bytes)
+serd_stack_pop_aligned(SerdStack* const stack, const size_t n_bytes)
{
// Pop requested space down to aligned location
serd_stack_pop(stack, n_bytes);
diff --git a/src/string_utils.h b/src/string_utils.h
index 2ce90ac9..7c8348ca 100644
--- a/src/string_utils.h
+++ b/src/string_utils.h
@@ -107,7 +107,7 @@ serd_strcasecmp(const char* s1, const char* s2)
return (c1 == c2) ? 0 : (c1 < c2) ? -1 : +1;
}
-static inline uint32_t
+static inline uint8_t
utf8_num_bytes(const uint8_t leading)
{
return ((leading & 0x80U) == 0x00U) ? 1U // Starts with `0'
@@ -119,18 +119,18 @@ utf8_num_bytes(const uint8_t leading)
/// Return the code point of a UTF-8 character with known length
static inline uint32_t
-parse_counted_utf8_char(const uint8_t* utf8, size_t size)
+parse_counted_utf8_char(const uint8_t* const utf8, const uint8_t size)
{
uint32_t c = utf8[0] & ((1U << (8U - size)) - 1U);
for (size_t i = 1; i < size; ++i) {
- c = (c << 6) | (utf8[i] & 0x3FU);
+ c = (c << 6U) | (utf8[i] & 0x3FU);
}
return c;
}
/// Parse a UTF-8 character, set *size to the length, and return the code point
static inline uint32_t
-parse_utf8_char(const uint8_t* utf8, size_t* size)
+parse_utf8_char(const uint8_t* const utf8, uint8_t* const size)
{
switch (*size = utf8_num_bytes(utf8[0])) {
case 1:
diff --git a/src/system.c b/src/system.c
index 072d2ed5..84916060 100644
--- a/src/system.c
+++ b/src/system.c
@@ -15,7 +15,6 @@
#endif
#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/uri.c b/src/uri.c
index 9856ce45..b18cd3aa 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -15,7 +15,7 @@
#include <string.h>
const uint8_t*
-serd_uri_to_path(const uint8_t* uri)
+serd_uri_to_path(const uint8_t* const uri)
{
assert(uri);
@@ -344,7 +344,7 @@ serd_uri_resolve(const SerdURI* const r,
/** Write the path of `uri` starting at index `i` */
static size_t
-write_path_tail(SerdSink sink,
+write_path_tail(const SerdSink sink,
void* const stream,
const SerdURI* const uri,
const size_t i)
@@ -372,7 +372,7 @@ write_path_tail(SerdSink sink,
/** Write the path of `uri` relative to the path of `base`. */
static size_t
-write_rel_path(SerdSink sink,
+write_rel_path(const SerdSink sink,
void* const stream,
const SerdURI* const uri,
const SerdURI* const base)
@@ -413,7 +413,7 @@ write_rel_path(SerdSink sink,
}
static uint8_t
-serd_uri_path_starts_without_slash(const SerdURI* uri)
+serd_uri_path_starts_without_slash(const SerdURI* const uri)
{
return ((uri->path_base.len || uri->path.len) &&
((!uri->path_base.len || uri->path_base.buf[0] != '/') &&
@@ -425,7 +425,7 @@ size_t
serd_uri_serialise_relative(const SerdURI* const uri,
const SerdURI* const base,
const SerdURI* const root,
- SerdSink sink,
+ const SerdSink sink,
void* const stream)
{
assert(uri);
@@ -441,7 +441,7 @@ serd_uri_serialise_relative(const SerdURI* const uri,
SERD_DISABLE_NULL_WARNINGS
- if (!relative || (!len && base->query.buf)) {
+ if (!relative || (!len && base && base->query.buf)) {
if (uri->scheme.buf) {
len += sink(uri->scheme.buf, uri->scheme.len, stream);
len += sink(":", 1, stream);
@@ -481,7 +481,9 @@ serd_uri_serialise_relative(const SerdURI* const uri,
/// See http://tools.ietf.org/html/rfc3986#section-5.3
size_t
-serd_uri_serialise(const SerdURI* const uri, SerdSink sink, void* const stream)
+serd_uri_serialise(const SerdURI* const uri,
+ const SerdSink sink,
+ void* const stream)
{
assert(uri);
assert(sink);
diff --git a/src/uri_utils.h b/src/uri_utils.h
index 0d3bd74e..4005b47d 100644
--- a/src/uri_utils.h
+++ b/src/uri_utils.h
@@ -18,20 +18,20 @@ typedef struct {
} SlashIndexes;
static inline bool
-chunk_equals(const SerdChunk* a, const SerdChunk* b)
+chunk_equals(const SerdChunk* const a, const SerdChunk* const b)
{
return a->len == b->len &&
!strncmp((const char*)a->buf, (const char*)b->buf, a->len);
}
static inline size_t
-uri_path_len(const SerdURI* uri)
+uri_path_len(const SerdURI* const uri)
{
return uri->path_base.len + uri->path.len;
}
static inline uint8_t
-uri_path_at(const SerdURI* uri, size_t i)
+uri_path_at(const SerdURI* const uri, const size_t i)
{
return (i < uri->path_base.len) ? uri->path_base.buf[i]
: uri->path.buf[i - uri->path_base.len];
@@ -46,7 +46,7 @@ uri_path_at(const SerdURI* uri, size_t i)
otherwise it may merely share some leading path components).
*/
static inline SERD_PURE_FUNC SlashIndexes
-uri_rooted_index(const SerdURI* uri, const SerdURI* root)
+uri_rooted_index(const SerdURI* const uri, const SerdURI* const root)
{
SlashIndexes indexes = {SIZE_MAX, SIZE_MAX};
@@ -84,14 +84,14 @@ uri_rooted_index(const SerdURI* uri, const SerdURI* root)
/** Return true iff `uri` shares path components with `root` */
static inline SERD_PURE_FUNC bool
-uri_is_related(const SerdURI* uri, const SerdURI* root)
+uri_is_related(const SerdURI* const uri, const SerdURI* const root)
{
return uri_rooted_index(uri, root).shared != SIZE_MAX;
}
/** Return true iff `uri` is within the base of `root` */
static inline SERD_PURE_FUNC bool
-uri_is_under(const SerdURI* uri, const SerdURI* root)
+uri_is_under(const SerdURI* const uri, const SerdURI* const root)
{
const SlashIndexes indexes = uri_rooted_index(uri, root);
return indexes.shared && indexes.shared != SIZE_MAX &&
diff --git a/src/writer.c b/src/writer.c
index e4ef5651..3905cb9c 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -143,7 +143,7 @@ write_node(SerdWriter* writer,
SerdStatementFlags flags);
SERD_NODISCARD static bool
-supports_abbrev(const SerdWriter* writer)
+supports_abbrev(const SerdWriter* const writer)
{
return writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG;
}
@@ -162,7 +162,7 @@ free_context(WriteContext* const ctx)
SERD_LOG_FUNC(3, 4)
static SerdStatus
-w_err(SerdWriter* writer, SerdStatus st, const char* fmt, ...)
+w_err(SerdWriter* const writer, const SerdStatus st, const char* const fmt, ...)
{
/* TODO: This results in errors with no file information, which is not
helpful when re-serializing a file (particularly for "undefined
@@ -179,7 +179,7 @@ w_err(SerdWriter* writer, SerdStatus st, const char* fmt, ...)
}
static void
-copy_node(SerdNode* dst, const SerdNode* src)
+copy_node(SerdNode* const dst, const SerdNode* const src)
{
const size_t new_size = src->n_bytes + 1U;
uint8_t* const new_buf = (uint8_t*)realloc((char*)dst->buf, new_size);
@@ -210,7 +210,7 @@ push_context(SerdWriter* const writer,
}
static void
-pop_context(SerdWriter* writer)
+pop_context(SerdWriter* const writer)
{
// Replace the current context with the top of the stack
free_context(&writer->context);
@@ -223,7 +223,7 @@ pop_context(SerdWriter* writer)
}
SERD_NODISCARD static size_t
-sink(const void* buf, size_t len, SerdWriter* writer)
+sink(const void* const buf, const size_t len, SerdWriter* const writer)
{
const size_t written = serd_byte_sink_write(buf, len, &writer->byte_sink);
if (written != len) {
@@ -239,7 +239,7 @@ sink(const void* buf, size_t len, SerdWriter* writer)
}
SERD_NODISCARD static inline SerdStatus
-esink(const void* buf, size_t len, SerdWriter* writer)
+esink(const void* const buf, const size_t len, SerdWriter* const writer)
{
return sink(buf, len, writer) == len ? SERD_SUCCESS : SERD_ERR_BAD_WRITE;
}
@@ -247,10 +247,10 @@ esink(const void* buf, size_t len, SerdWriter* writer)
// Write a single character, as an escape for single byte characters
// (Caller prints any single byte characters that don't need escaping)
static size_t
-write_character(SerdWriter* writer,
- const uint8_t* utf8,
- size_t* size,
- SerdStatus* st)
+write_character(SerdWriter* const writer,
+ const uint8_t* const utf8,
+ uint8_t* const size,
+ SerdStatus* const st)
{
char escape[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const uint32_t c = parse_utf8_char(utf8, size);
@@ -288,10 +288,10 @@ uri_must_escape(const uint8_t c)
}
static size_t
-write_uri(SerdWriter* writer,
- const uint8_t* utf8,
- size_t n_bytes,
- SerdStatus* st)
+write_uri(SerdWriter* const writer,
+ const uint8_t* const utf8,
+ const size_t n_bytes,
+ SerdStatus* const st)
{
size_t len = 0;
for (size_t i = 0; i < n_bytes;) {
@@ -315,14 +315,14 @@ write_uri(SerdWriter* writer,
}
// Write UTF-8 character
- size_t size = 0;
+ uint8_t size = 0U;
len += write_character(writer, utf8 + i, &size, st);
i += size;
if (*st && (writer->style & SERD_STYLE_STRICT)) {
break;
}
- if (size == 0) {
+ if (!size) {
// Corrupt input, write percent-encoded bytes and scan to next start
char escape[4] = {0, 0, 0, 0};
for (; i < n_bytes && (utf8[i] & 0x80); ++i) {
@@ -336,7 +336,9 @@ write_uri(SerdWriter* writer,
}
SERD_NODISCARD static SerdStatus
-ewrite_uri(SerdWriter* writer, const uint8_t* utf8, size_t n_bytes)
+ewrite_uri(SerdWriter* const writer,
+ const uint8_t* const utf8,
+ const size_t n_bytes)
{
SerdStatus st = SERD_SUCCESS;
write_uri(writer, utf8, n_bytes, &st);
@@ -347,7 +349,7 @@ ewrite_uri(SerdWriter* writer, const uint8_t* utf8, size_t n_bytes)
}
SERD_NODISCARD static SerdStatus
-write_uri_from_node(SerdWriter* writer, const SerdNode* node)
+write_uri_from_node(SerdWriter* const writer, const SerdNode* const node)
{
return ewrite_uri(writer, node->buf, node->n_bytes);
}
@@ -369,7 +371,9 @@ lname_must_escape(const uint8_t c)
}
SERD_NODISCARD static SerdStatus
-write_lname(SerdWriter* writer, const uint8_t* utf8, size_t n_bytes)
+write_lname(SerdWriter* const writer,
+ const uint8_t* const utf8,
+ const size_t n_bytes)
{
SerdStatus st = SERD_SUCCESS;
for (size_t i = 0; i < n_bytes; ++i) {
@@ -395,10 +399,10 @@ write_lname(SerdWriter* writer, const uint8_t* utf8, size_t n_bytes)
}
SERD_NODISCARD static SerdStatus
-write_text(SerdWriter* writer,
- TextContext ctx,
- const uint8_t* utf8,
- size_t n_bytes)
+write_text(SerdWriter* const writer,
+ const TextContext ctx,
+ const uint8_t* const utf8,
+ const size_t n_bytes)
{
size_t n_consecutive_quotes = 0;
SerdStatus st = SERD_SUCCESS;
@@ -484,19 +488,19 @@ write_text(SerdWriter* writer,
}
// Write UTF-8 character
- size_t size = 0;
+ uint8_t size = 0U;
write_character(writer, utf8 + i - 1, &size, &st);
if (st && (writer->style & SERD_STYLE_STRICT)) {
return st;
}
- if (size == 0) {
+ if (!size) {
// Corrupt input, write replacement character and scan to the next start
st = esink(replacement_char, sizeof(replacement_char), writer);
- for (; i < n_bytes && (utf8[i] & 0x80); ++i) {
+ for (; i < n_bytes && (utf8[i] & 0x80U); ++i) {
}
} else {
- i += size - 1;
+ i += size - 1U;
}
}
@@ -509,7 +513,7 @@ typedef struct {
} UriSinkContext;
SERD_NODISCARD static size_t
-uri_sink(const void* buf, size_t len, void* stream)
+uri_sink(const void* const buf, const size_t len, void* const stream)
{
UriSinkContext* const context = (UriSinkContext*)stream;
SerdWriter* const writer = context->writer;
@@ -518,7 +522,7 @@ uri_sink(const void* buf, size_t len, void* stream)
}
SERD_NODISCARD static SerdStatus
-write_newline(SerdWriter* writer)
+write_newline(SerdWriter* const writer)
{
SerdStatus st = SERD_SUCCESS;
@@ -531,7 +535,7 @@ write_newline(SerdWriter* writer)
}
SERD_NODISCARD static SerdStatus
-write_sep(SerdWriter* writer, const Sep sep)
+write_sep(SerdWriter* const writer, const Sep sep)
{
SerdStatus st = SERD_SUCCESS;
const SepRule* const rule = &rules[sep];
@@ -585,7 +589,7 @@ write_sep(SerdWriter* writer, const Sep sep)
}
static void
-free_anon_stack(SerdWriter* writer)
+free_anon_stack(SerdWriter* const writer)
{
while (!serd_stack_is_empty(&writer->anon_stack)) {
pop_context(writer);
@@ -593,7 +597,7 @@ free_anon_stack(SerdWriter* writer)
}
static SerdStatus
-reset_context(SerdWriter* writer, const unsigned flags)
+reset_context(SerdWriter* const writer, const unsigned flags)
{
free_anon_stack(writer);
@@ -639,11 +643,11 @@ get_xsd_name(const SerdEnv* const env, const SerdNode* const datatype)
}
SERD_NODISCARD static SerdStatus
-write_literal(SerdWriter* writer,
- const SerdNode* node,
- const SerdNode* datatype,
- const SerdNode* lang,
- SerdStatementFlags flags)
+write_literal(SerdWriter* const writer,
+ const SerdNode* const node,
+ const SerdNode* const datatype,
+ const SerdNode* const lang,
+ const SerdStatementFlags flags)
{
SerdStatus st = SERD_SUCCESS;
@@ -679,7 +683,7 @@ write_literal(SerdWriter* writer,
// Return true iff `buf` is a valid prefixed name prefix or suffix
static bool
-is_name(const uint8_t* buf, const size_t len)
+is_name(const uint8_t* const buf, const size_t len)
{
// TODO: This is more strict than it should be
for (size_t i = 0; i < len; ++i) {
@@ -692,9 +696,9 @@ is_name(const uint8_t* buf, const size_t len)
}
SERD_NODISCARD static SerdStatus
-write_uri_node(SerdWriter* const writer,
- const SerdNode* node,
- const Field field)
+write_uri_node(SerdWriter* const writer,
+ const SerdNode* const node,
+ const Field field)
{
SerdStatus st = SERD_SUCCESS;
SerdNode prefix = SERD_NODE_NULL;
@@ -741,8 +745,8 @@ write_uri_node(SerdWriter* const writer,
serd_uri_parse(node->buf, &uri);
SERD_RESTORE_WARNINGS
serd_uri_resolve(&uri, &in_base_uri, &abs_uri);
- bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri);
- SerdURI* root = rooted ? &writer->root_uri : &writer->base_uri;
+ const bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri);
+ const SerdURI* root = rooted ? &writer->root_uri : &writer->base_uri;
UriSinkContext ctx = {writer, SERD_SUCCESS};
if (!uri_is_under(&abs_uri, root) || writer->syntax == SERD_NTRIPLES ||
writer->syntax == SERD_NQUADS) {
@@ -789,7 +793,7 @@ write_curie(SerdWriter* const writer, const SerdNode* const node)
SERD_NODISCARD static SerdStatus
write_blank(SerdWriter* const writer,
- const SerdNode* node,
+ const SerdNode* const node,
const Field field,
const SerdStatementFlags flags)
{
@@ -828,12 +832,12 @@ write_blank(SerdWriter* const writer,
}
SERD_NODISCARD static SerdStatus
-write_node(SerdWriter* writer,
- const SerdNode* node,
- const SerdNode* datatype,
- const SerdNode* lang,
- Field field,
- SerdStatementFlags flags)
+write_node(SerdWriter* const writer,
+ const SerdNode* const node,
+ const SerdNode* const datatype,
+ const SerdNode* const lang,
+ const Field field,
+ const SerdStatementFlags flags)
{
return (node->type == SERD_LITERAL)
? write_literal(writer, node, datatype, lang, flags)
@@ -844,13 +848,15 @@ write_node(SerdWriter* writer,
}
static bool
-is_resource(const SerdNode* node)
+is_resource(const SerdNode* const node)
{
return node->buf && node->type > SERD_LITERAL;
}
SERD_NODISCARD static SerdStatus
-write_pred(SerdWriter* writer, SerdStatementFlags flags, const SerdNode* pred)
+write_pred(SerdWriter* const writer,
+ const SerdStatementFlags flags,
+ const SerdNode* const pred)
{
SerdStatus st = SERD_SUCCESS;
@@ -864,12 +870,12 @@ write_pred(SerdWriter* writer, SerdStatementFlags flags, const SerdNode* pred)
}
SERD_NODISCARD static SerdStatus
-write_list_next(SerdWriter* writer,
- SerdStatementFlags flags,
- const SerdNode* predicate,
- const SerdNode* object,
- const SerdNode* datatype,
- const SerdNode* lang)
+write_list_next(SerdWriter* const writer,
+ const SerdStatementFlags flags,
+ const SerdNode* const predicate,
+ const SerdNode* const object,
+ const SerdNode* const datatype,
+ const SerdNode* const lang)
{
SerdStatus st = SERD_SUCCESS;
@@ -888,7 +894,7 @@ write_list_next(SerdWriter* writer,
}
SERD_NODISCARD static SerdStatus
-terminate_context(SerdWriter* writer)
+terminate_context(SerdWriter* const writer)
{
SerdStatus st = SERD_SUCCESS;
@@ -904,14 +910,14 @@ terminate_context(SerdWriter* writer)
}
SerdStatus
-serd_writer_write_statement(SerdWriter* writer,
- SerdStatementFlags flags,
- const SerdNode* graph,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* object,
- const SerdNode* datatype,
- const SerdNode* lang)
+serd_writer_write_statement(SerdWriter* const writer,
+ SerdStatementFlags flags,
+ const SerdNode* const graph,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const object,
+ const SerdNode* const datatype,
+ const SerdNode* const lang)
{
assert(writer);
assert(subject);
@@ -1064,7 +1070,7 @@ serd_writer_write_statement(SerdWriter* writer,
}
SerdStatus
-serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
+serd_writer_end_anon(SerdWriter* const writer, const SerdNode* const node)
{
assert(writer);
@@ -1095,7 +1101,7 @@ serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
}
SerdStatus
-serd_writer_finish(SerdWriter* writer)
+serd_writer_finish(SerdWriter* const writer)
{
assert(writer);
@@ -1107,12 +1113,12 @@ serd_writer_finish(SerdWriter* writer)
}
SerdWriter*
-serd_writer_new(SerdSyntax syntax,
- SerdStyle style,
- SerdEnv* env,
- const SerdURI* base_uri,
- SerdSink ssink,
- void* stream)
+serd_writer_new(const SerdSyntax syntax,
+ const SerdStyle style,
+ SerdEnv* const env,
+ const SerdURI* const base_uri,
+ SerdSink ssink,
+ void* const stream)
{
assert(env);
assert(ssink);
@@ -1135,9 +1141,9 @@ serd_writer_new(SerdSyntax syntax,
}
void
-serd_writer_set_error_sink(SerdWriter* writer,
- SerdErrorSink error_sink,
- void* error_handle)
+serd_writer_set_error_sink(SerdWriter* const writer,
+ const SerdErrorSink error_sink,
+ void* const error_handle)
{
assert(writer);
assert(error_sink);
@@ -1146,7 +1152,8 @@ serd_writer_set_error_sink(SerdWriter* writer,
}
void
-serd_writer_chop_blank_prefix(SerdWriter* writer, const uint8_t* prefix)
+serd_writer_chop_blank_prefix(SerdWriter* const writer,
+ const uint8_t* const prefix)
{
assert(writer);
@@ -1163,7 +1170,7 @@ serd_writer_chop_blank_prefix(SerdWriter* writer, const uint8_t* prefix)
}
SerdStatus
-serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri)
+serd_writer_set_base_uri(SerdWriter* const writer, const SerdNode* const uri)
{
assert(writer);
@@ -1185,7 +1192,7 @@ serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri)
}
SerdStatus
-serd_writer_set_root_uri(SerdWriter* writer, const SerdNode* uri)
+serd_writer_set_root_uri(SerdWriter* const writer, const SerdNode* const uri)
{
assert(writer);
@@ -1205,9 +1212,9 @@ serd_writer_set_root_uri(SerdWriter* writer, const SerdNode* uri)
}
SerdStatus
-serd_writer_set_prefix(SerdWriter* writer,
- const SerdNode* name,
- const SerdNode* uri)
+serd_writer_set_prefix(SerdWriter* const writer,
+ const SerdNode* const name,
+ const SerdNode* const uri)
{
assert(writer);
assert(name);
@@ -1231,7 +1238,7 @@ serd_writer_set_prefix(SerdWriter* writer,
}
void
-serd_writer_free(SerdWriter* writer)
+serd_writer_free(SerdWriter* const writer)
{
if (!writer) {
return;
@@ -1250,14 +1257,14 @@ serd_writer_free(SerdWriter* writer)
}
SerdEnv*
-serd_writer_get_env(SerdWriter* writer)
+serd_writer_get_env(SerdWriter* const writer)
{
assert(writer);
return writer->env;
}
size_t
-serd_file_sink(const void* buf, size_t len, void* stream)
+serd_file_sink(const void* const buf, const size_t len, void* const stream)
{
assert(buf);
assert(stream);
@@ -1265,7 +1272,7 @@ serd_file_sink(const void* buf, size_t len, void* stream)
}
size_t
-serd_chunk_sink(const void* buf, size_t len, void* stream)
+serd_chunk_sink(const void* const buf, const size_t len, void* const stream)
{
assert(buf);
assert(stream);
@@ -1281,7 +1288,7 @@ serd_chunk_sink(const void* buf, size_t len, void* stream)
}
uint8_t*
-serd_chunk_sink_finish(SerdChunk* stream)
+serd_chunk_sink_finish(SerdChunk* const stream)
{
assert(stream);
serd_chunk_sink("", 1, stream);
diff --git a/test/headers/test_headers.c b/test/headers/test_headers.c
index c855c103..62be0976 100644
--- a/test/headers/test_headers.c
+++ b/test/headers/test_headers.c
@@ -3,8 +3,7 @@
#include "serd/serd.h" // IWYU pragma: keep
-SERD_CONST_FUNC
-int
+SERD_CONST_FUNC int
main(void)
{
return 0;
diff --git a/test/meson.build b/test/meson.build
index 33f86dfb..4d770304 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -4,109 +4,6 @@
run_suite = find_program('run_suite.py')
wrapper = meson.get_external_property('exe_wrapper', '')
-########################
-# Scripts and Metadata #
-########################
-
-plot_script_paths = [
- '../scripts/serd_bench.py',
-]
-
-simple_script_paths = [
- '../scripts/check_formatting.py',
- 'serd_test_util/__init__.py',
- 'run_suite.py',
- 'test_quiet.py',
- 'test_stdin.py',
- 'test_write_error.py',
-]
-
-ttl_metadata_file_paths = [
- '../serd.ttl',
- 'extra/abbreviate/manifest.ttl',
- 'extra/bad/manifest.ttl',
- 'extra/big/manifest.ttl',
- 'extra/full/manifest.ttl',
- 'extra/good/manifest.ttl',
- 'extra/lax/manifest.ttl',
- 'extra/perfect/manifest.ttl',
- 'extra/prefix/manifest.ttl',
- 'extra/pretty/manifest.ttl',
- 'extra/qualify/manifest.ttl',
- 'extra/root/manifest.ttl',
-]
-
-plot_scripts = files(plot_script_paths)
-simple_scripts = files(simple_script_paths)
-python_script_paths = simple_script_paths + plot_script_paths
-python_scripts = plot_scripts + simple_scripts
-
-if get_option('lint')
- # Check release metadata
- if not meson.is_subproject()
- autoship = find_program('autoship', required: false)
- if autoship.found()
- test('autoship', autoship, args: ['test', serd_src_root], suite: 'data')
- endif
- endif
-
- # Check licensing metadata
- reuse = find_program('reuse', required: false)
- if reuse.found()
- test(
- 'REUSE',
- reuse,
- args: ['--root', serd_src_root, 'lint'],
- suite: 'data',
- )
- endif
-
- # Check script formatting
- black = find_program('black', required: false)
- if black.found()
- black_opts = ['--check', '-q', '-l', '79']
- foreach script_path : python_script_paths
- script = files(script_path)
- name = script_path.underscorify()
- test(name, black, args: black_opts + [script], suite: 'scripts')
- endforeach
- endif
-
- # Check scripts for errors with flake8
- flake8 = find_program('flake8', required: false)
- if flake8.found()
- test('flake8', flake8, args: python_scripts, suite: 'scripts')
- endif
-
- # Check scripts for errors with pylint
- pylint = find_program('pylint', required: false)
- if pylint.found()
- pymod = import('python')
- plot_py = pymod.find_installation(
- 'python3',
- modules: ['matplotlib'],
- required: false,
- )
-
- pylint_args = ['--disable', 'bad-option-value'] + simple_scripts
- if plot_py.found()
- pylint_args += plot_scripts
- endif
-
- test('pylint', pylint, args: pylint_args, suite: 'scripts')
- endif
-
- # Check Turtle formatting with serdi
- foreach ttl_file_path : ttl_metadata_file_paths
- test(
- ttl_file_path.underscorify(),
- check_formatting_py,
- args: [files(ttl_file_path), serdi, '-o', 'turtle'],
- suite: 'data',
- )
- endforeach
-endif
-
###################
# Header Warnings #
###################
@@ -117,7 +14,7 @@ subdir('headers')
# Unit Tests #
##############
-unit_tests = [
+unit_test_names = [
'env',
'free_null',
'node',
@@ -128,12 +25,16 @@ unit_tests = [
'writer',
]
-foreach unit : unit_tests
+unit_test_sources = files('headers/test_headers.c')
+
+foreach name : unit_test_names
+ source = files('test_@0@.c'.format(name))
+ unit_test_sources += source
test(
- unit,
+ name,
executable(
- 'test_@0@'.format(unit),
- files('test_@0@.c'.format(unit)),
+ 'test_@0@'.format(name),
+ source,
c_args: c_suppressions,
dependencies: serd_dep,
),
@@ -392,3 +293,138 @@ if is_variable('serdi')
)
endforeach
endif
+
+########
+# Lint #
+########
+
+plot_script_paths = [
+ '../scripts/serd_bench.py',
+]
+
+simple_script_paths = [
+ '../scripts/check_formatting.py',
+ 'serd_test_util/__init__.py',
+ 'run_suite.py',
+ 'test_quiet.py',
+ 'test_stdin.py',
+ 'test_write_error.py',
+]
+
+ttl_metadata_file_paths = [
+ '../serd.ttl',
+ 'extra/abbreviate/manifest.ttl',
+ 'extra/bad/manifest.ttl',
+ 'extra/big/manifest.ttl',
+ 'extra/full/manifest.ttl',
+ 'extra/good/manifest.ttl',
+ 'extra/lax/manifest.ttl',
+ 'extra/perfect/manifest.ttl',
+ 'extra/prefix/manifest.ttl',
+ 'extra/pretty/manifest.ttl',
+ 'extra/qualify/manifest.ttl',
+ 'extra/root/manifest.ttl',
+]
+
+plot_scripts = files(plot_script_paths)
+simple_scripts = files(simple_script_paths)
+python_script_paths = simple_script_paths + plot_script_paths
+python_scripts = plot_scripts + simple_scripts
+
+if get_option('lint')
+ all_sources = sources + unit_test_sources + files('../src/serdi.c')
+
+ if not meson.is_subproject()
+ # Check release metadata
+ autoship = find_program('autoship', required: false)
+ if autoship.found()
+ test('autoship', autoship, args: ['test', serd_src_root], suite: 'data')
+ endif
+
+ # Check code with cppcheck
+ cppcheck = find_program('cppcheck', required: false)
+ if cppcheck.found()
+ compdb_path = join_paths(serd_build_root, 'compile_commands.json')
+ suppress_path = join_paths(serd_src_root, '.suppress.cppcheck')
+ test(
+ 'cppcheck',
+ cppcheck,
+ args: [
+ '--enable=warning,style,performance,portability',
+ '--error-exitcode=1',
+ '--project=' + compdb_path,
+ '--suppressions-list=' + suppress_path,
+ '-q',
+ ],
+ suite: 'code',
+ )
+ endif
+ endif
+
+ # Check licensing metadata
+ reuse = find_program('reuse', required: false)
+ if reuse.found()
+ test(
+ 'REUSE',
+ reuse,
+ args: ['--root', serd_src_root, 'lint'],
+ 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 + all_sources,
+ suite: 'code',
+ )
+ endif
+
+ # Check script formatting
+ black = find_program('black', required: false)
+ if black.found()
+ black_opts = ['--check', '-q', '-l', '79']
+ foreach script_path : python_script_paths
+ script = files(script_path)
+ name = script_path.underscorify()
+ test(name, black, args: black_opts + [script], suite: 'scripts')
+ endforeach
+ endif
+
+ # Check scripts for errors with flake8
+ flake8 = find_program('flake8', required: false)
+ if flake8.found()
+ test('flake8', flake8, args: python_scripts, suite: 'scripts')
+ endif
+
+ # Check scripts for errors with pylint
+ pylint = find_program('pylint', required: false)
+ if pylint.found()
+ pymod = import('python')
+ plot_py = pymod.find_installation(
+ 'python3',
+ modules: ['matplotlib'],
+ required: false,
+ )
+
+ pylint_args = ['--disable', 'bad-option-value'] + simple_scripts
+ if plot_py.found()
+ pylint_args += plot_scripts
+ endif
+
+ test('pylint', pylint, args: pylint_args, suite: 'scripts')
+ endif
+
+ # Check Turtle formatting with serdi
+ foreach ttl_file_path : ttl_metadata_file_paths
+ test(
+ ttl_file_path.underscorify(),
+ check_formatting_py,
+ args: [files(ttl_file_path), serdi, '-o', 'turtle'],
+ suite: 'data',
+ )
+ endforeach
+endif
diff --git a/test/serd_test_util/__init__.py b/test/serd_test_util/__init__.py
index 8027462b..ad417762 100644
--- a/test/serd_test_util/__init__.py
+++ b/test/serd_test_util/__init__.py
@@ -8,10 +8,12 @@
# pylint: disable=consider-using-f-string
# pylint: disable=invalid-name
+import argparse
import datetime
import difflib
import os
import re
+import shlex
import subprocess
import sys
import urllib.parse
@@ -51,6 +53,33 @@ def error(message):
sys.stderr.write("\n")
+def wrapper_args(description, with_input=False):
+ """Return the command line arguments for a wrapped test."""
+
+ parser = argparse.ArgumentParser(description)
+ parser.add_argument("--serdi", default="./serdi", help="serdi executable")
+ parser.add_argument("--wrapper", default="", help="executable wrapper")
+ if with_input:
+ parser.add_argument("input", help="input file")
+
+ return parser.parse_args(sys.argv[1:])
+
+
+def command_output(wrapper, command, stdin=None):
+ """Run a command and check that stdout matches the expected output."""
+
+ proc = subprocess.run(
+ shlex.split(wrapper) + command,
+ capture_output=True,
+ check=True,
+ encoding="utf-8",
+ input=stdin,
+ )
+
+ assert wrapper or not proc.stderr
+ return proc.stdout
+
+
def print_result_summary(results):
"""Print test result summary to stdout or stderr as appropriate."""
diff --git a/test/test_env.c b/test/test_env.c
index d51e0595..903ae3f2 100644
--- a/test/test_env.c
+++ b/test/test_env.c
@@ -13,7 +13,9 @@
#define USTR(s) ((const uint8_t*)(s))
static SerdStatus
-count_prefixes(void* handle, const SerdNode* name, const SerdNode* uri)
+count_prefixes(void* const handle,
+ const SerdNode* const name,
+ const SerdNode* const uri)
{
(void)name;
(void)uri;
diff --git a/test/test_node.c b/test/test_node.c
index af14171b..28db00ea 100644
--- a/test/test_node.c
+++ b/test/test_node.c
@@ -24,7 +24,7 @@
#endif
static void
-test_strtod(double dbl, double max_delta)
+check_strtod(const double dbl, const double max_delta)
{
char buf[1024];
snprintf(buf, sizeof(buf), "%f", dbl);
@@ -56,7 +56,7 @@ test_string_to_double(void)
const double delta = fabs(num - expt_test_nums[i]);
assert(delta <= DBL_EPSILON);
- test_strtod(expt_test_nums[i], DBL_EPSILON);
+ check_strtod(expt_test_nums[i], DBL_EPSILON);
}
}
@@ -285,7 +285,5 @@ main(void)
test_node_from_string();
test_node_from_substring();
test_uri_node_from_node();
-
- printf("Success\n");
return 0;
}
diff --git a/test/test_quiet.py b/test/test_quiet.py
index 42d05785..676284bb 100755
--- a/test/test_quiet.py
+++ b/test/test_quiet.py
@@ -3,20 +3,14 @@
# Copyright 2022 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: ISC
-"""Test serdi quiet option."""
+"""Test quiet command-line option."""
-import argparse
-import sys
import shlex
import subprocess
-parser = argparse.ArgumentParser(description=__doc__)
+import serd_test_util as util
-parser.add_argument("--serdi", default="./serdi", help="path to serdi")
-parser.add_argument("--wrapper", default="", help="executable wrapper")
-parser.add_argument("input", help="invalid input file")
-
-args = parser.parse_args(sys.argv[1:])
+args = util.wrapper_args(__doc__, True)
command = shlex.split(args.wrapper) + [args.serdi, "-q", args.input]
proc = subprocess.run(
command, check=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE
diff --git a/test/test_reader.c b/test/test_reader.c
index 18794f9e..e185b915 100644
--- a/test/test_reader.c
+++ b/test/test_reader.c
@@ -26,7 +26,7 @@ typedef struct {
} ReaderTest;
static SerdStatus
-test_base_sink(void* const handle, const SerdNode* const uri)
+base_sink(void* const handle, const SerdNode* const uri)
{
(void)uri;
@@ -36,9 +36,9 @@ test_base_sink(void* const handle, const SerdNode* const uri)
}
static SerdStatus
-test_prefix_sink(void* const handle,
- const SerdNode* const name,
- const SerdNode* const uri)
+prefix_sink(void* const handle,
+ const SerdNode* const name,
+ const SerdNode* const uri)
{
(void)name;
(void)uri;
@@ -49,14 +49,14 @@ test_prefix_sink(void* const handle,
}
static SerdStatus
-test_statement_sink(void* const handle,
- SerdStatementFlags flags,
- const SerdNode* const graph,
- const SerdNode* const subject,
- const SerdNode* const predicate,
- const SerdNode* const object,
- const SerdNode* const object_datatype,
- const SerdNode* const object_lang)
+statement_sink(void* const handle,
+ SerdStatementFlags flags,
+ const SerdNode* const graph,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const object,
+ const SerdNode* const object_datatype,
+ const SerdNode* const object_lang)
{
(void)flags;
(void)graph;
@@ -72,7 +72,7 @@ test_statement_sink(void* const handle,
}
static SerdStatus
-test_end_sink(void* const handle, const SerdNode* const node)
+end_sink(void* const handle, const SerdNode* const node)
{
(void)node;
@@ -85,13 +85,8 @@ static void
test_read_string(void)
{
ReaderTest rt = {0, 0, 0, 0};
- SerdReader* const reader = serd_reader_new(SERD_TURTLE,
- &rt,
- NULL,
- test_base_sink,
- test_prefix_sink,
- test_statement_sink,
- test_end_sink);
+ SerdReader* const reader = serd_reader_new(
+ SERD_TURTLE, &rt, NULL, base_sink, prefix_sink, statement_sink, end_sink);
assert(reader);
assert(serd_reader_get_handle(reader) == &rt);
@@ -113,7 +108,10 @@ test_read_string(void)
/// Reads a null byte after a statement, then succeeds again (like a socket)
static size_t
-eof_test_read(void* buf, size_t size, size_t nmemb, void* stream)
+eof_test_read(void* const buf,
+ const size_t size,
+ const size_t nmemb,
+ void* const stream)
{
assert(size == 1);
assert(nmemb == 1);
@@ -149,7 +147,7 @@ eof_test_read(void* buf, size_t size, size_t nmemb, void* stream)
}
static int
-eof_test_error(void* stream)
+eof_test_error(void* const stream)
{
(void)stream;
return 0;
@@ -167,13 +165,8 @@ test_read_eof_file(const char* const path)
fseek(f, 0L, SEEK_SET);
ReaderTest rt = {0, 0, 0, 0};
- SerdReader* const reader = serd_reader_new(SERD_TURTLE,
- &rt,
- NULL,
- test_base_sink,
- test_prefix_sink,
- test_statement_sink,
- test_end_sink);
+ SerdReader* const reader = serd_reader_new(
+ SERD_TURTLE, &rt, NULL, base_sink, prefix_sink, statement_sink, end_sink);
fseek(f, 0L, SEEK_SET);
serd_reader_start_stream(reader, f, (const uint8_t*)"test", true);
@@ -198,13 +191,8 @@ static void
test_read_eof_by_byte(void)
{
ReaderTest rt = {0, 0, 0, 0};
- SerdReader* const reader = serd_reader_new(SERD_TURTLE,
- &rt,
- NULL,
- test_base_sink,
- test_prefix_sink,
- test_statement_sink,
- test_end_sink);
+ SerdReader* const reader = serd_reader_new(
+ SERD_TURTLE, &rt, NULL, base_sink, prefix_sink, statement_sink, end_sink);
size_t n_reads = 0U;
serd_reader_start_source_stream(reader,
@@ -249,13 +237,8 @@ test_read_nquads_chunks(const char* const path)
fseek(f, 0, SEEK_SET);
ReaderTest rt = {0, 0, 0, 0};
- SerdReader* const reader = serd_reader_new(SERD_NQUADS,
- &rt,
- NULL,
- test_base_sink,
- test_prefix_sink,
- test_statement_sink,
- test_end_sink);
+ SerdReader* const reader = serd_reader_new(
+ SERD_NQUADS, &rt, NULL, base_sink, prefix_sink, statement_sink, end_sink);
assert(reader);
assert(serd_reader_get_handle(reader) == &rt);
@@ -330,13 +313,8 @@ test_read_turtle_chunks(const char* const path)
fseek(f, 0, SEEK_SET);
ReaderTest rt = {0, 0, 0, 0};
- SerdReader* const reader = serd_reader_new(SERD_TURTLE,
- &rt,
- NULL,
- test_base_sink,
- test_prefix_sink,
- test_statement_sink,
- test_end_sink);
+ SerdReader* const reader = serd_reader_new(
+ SERD_TURTLE, &rt, NULL, base_sink, prefix_sink, statement_sink, end_sink);
assert(reader);
assert(serd_reader_get_handle(reader) == &rt);
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index c229d1c5..515d5e5b 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -54,14 +54,14 @@ static const char* const doc_string =
"( eg:o ) eg:t eg:u .\n";
static SerdStatus
-test_statement_sink(void* handle,
- SerdStatementFlags flags,
- const SerdNode* graph,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* object,
- const SerdNode* object_datatype,
- const SerdNode* object_lang)
+test_statement_sink(void* const handle,
+ const SerdStatementFlags flags,
+ const SerdNode* const graph,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const object,
+ const SerdNode* const object_datatype,
+ const SerdNode* const object_lang)
{
(void)flags;
(void)subject;
@@ -164,8 +164,9 @@ test_writer(const char* const path)
assert(serd_writer_end_anon(writer, NULL));
assert(serd_writer_get_env(writer) == env);
- uint8_t buf[] = {0x80, 0, 0, 0, 0};
- SerdNode s = serd_node_from_string(SERD_URI, USTR(""));
+ const uint8_t buf[] = {0x80, 0, 0, 0, 0};
+
+ SerdNode s = serd_node_from_string(SERD_URI, USTR(""));
SerdNode p = serd_node_from_string(SERD_URI, USTR("http://example.org/pred"));
SerdNode o = serd_node_from_string(SERD_LITERAL, buf);
@@ -264,7 +265,7 @@ test_writer(const char* const path)
}
static void
-test_reader(const char* path)
+test_reader(const char* const path)
{
ReaderTest* rt = (ReaderTest*)calloc(1, sizeof(ReaderTest));
SerdReader* reader = serd_reader_new(
@@ -332,6 +333,5 @@ main(void)
assert(!remove(path));
free(path);
- printf("Success\n");
return 0;
}
diff --git a/test/test_stdin.py b/test/test_stdin.py
index f976ca52..fb01f4ee 100755
--- a/test/test_stdin.py
+++ b/test/test_stdin.py
@@ -7,37 +7,14 @@
# pylint: disable=consider-using-f-string
-import argparse
-import sys
-import shlex
-import subprocess
-import tempfile
+import serd_test_util as util
-parser = argparse.ArgumentParser(description=__doc__)
+args = util.wrapper_args(__doc__)
+command = [args.serdi, "-i", "ntriples", "-", "http://example.org"]
-parser.add_argument("--serdi", default="./serdi", help="path to serdi")
-parser.add_argument("--wrapper", default="", help="executable wrapper")
+DOC = "<{0}s> <{0}p> <{0}o> .".format("http://example.org/")
-args = parser.parse_args(sys.argv[1:])
-command = shlex.split(args.wrapper) + [args.serdi, "-"]
+lines = util.command_output(args.wrapper, command, DOC).splitlines(True)
-DOCUMENT = "<{0}s> <{0}p> <{0}o> .".format("http://example.org/")
-
-with tempfile.TemporaryFile() as out:
- proc = subprocess.run(
- command,
- check=False,
- encoding="utf-8",
- input=DOCUMENT,
- stdout=out,
- stderr=subprocess.PIPE,
- )
-
- assert proc.returncode == 0
- assert args.wrapper or len(proc.stderr) == 0
-
- out.seek(0)
- lines = out.readlines()
-
- assert len(lines) == 1
- assert lines[0].decode("utf-8").strip() == DOCUMENT
+assert len(lines) == 1
+assert lines[0].strip() == DOC
diff --git a/test/test_string.c b/test/test_string.c
index 23835ca9..1af3f45a 100644
--- a/test/test_string.c
+++ b/test/test_string.c
@@ -7,7 +7,6 @@
#include <assert.h>
#include <stdint.h>
-#include <stdio.h>
#include <string.h>
static void
@@ -57,7 +56,5 @@ main(void)
{
test_strlen();
test_strerror();
-
- printf("Success\n");
return 0;
}
diff --git a/test/test_uri.c b/test/test_uri.c
index fc5eab71..7315a0fc 100644
--- a/test/test_uri.c
+++ b/test/test_uri.c
@@ -8,7 +8,6 @@
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
-#include <stdio.h>
#include <string.h>
#define USTR(s) ((const uint8_t*)(s))
@@ -37,11 +36,11 @@ test_uri_string_has_scheme(void)
}
static void
-test_file_uri(const char* const hostname,
- const char* const path,
- const bool escape,
- const char* const expected_uri,
- const char* expected_path)
+check_file_uri(const char* const hostname,
+ const char* const path,
+ const bool escape,
+ const char* const expected_uri,
+ const char* expected_path)
{
if (!expected_path) {
expected_path = path;
@@ -112,62 +111,62 @@ test_uri_to_path(void)
static void
test_uri_parsing(void)
{
- test_file_uri(NULL, "C:/My 100%", true, "file:///C:/My%20100%%", NULL);
- test_file_uri(NULL, "/foo/bar", true, "file:///foo/bar", NULL);
- test_file_uri("bhost", "/foo/bar", true, "file://bhost/foo/bar", NULL);
- test_file_uri(NULL, "a/relative path", false, "a/relative path", NULL);
- test_file_uri(
+ check_file_uri(NULL, "C:/My 100%", true, "file:///C:/My%20100%%", NULL);
+ check_file_uri(NULL, "/foo/bar", true, "file:///foo/bar", NULL);
+ check_file_uri("bhost", "/foo/bar", true, "file://bhost/foo/bar", NULL);
+ check_file_uri(NULL, "a/relative path", false, "a/relative path", NULL);
+ check_file_uri(
NULL, "a/relative <path>", true, "a/relative%20%3Cpath%3E", NULL);
#ifdef _WIN32
- test_file_uri(
+ check_file_uri(
NULL, "C:\\My 100%", true, "file:///C:/My%20100%%", "C:/My 100%");
- test_file_uri(NULL,
- "\\drive\\relative",
- true,
- "file:///drive/relative",
- "/drive/relative");
-
- test_file_uri(NULL,
- "C:\\Program Files\\Serd",
- true,
- "file:///C:/Program%20Files/Serd",
- "C:/Program Files/Serd");
-
- test_file_uri("ahost",
- "C:\\Pointless Space",
- true,
- "file://ahost/C:/Pointless%20Space",
- "C:/Pointless Space");
+ check_file_uri(NULL,
+ "\\drive\\relative",
+ true,
+ "file:///drive/relative",
+ "/drive/relative");
+
+ check_file_uri(NULL,
+ "C:\\Program Files\\Serd",
+ true,
+ "file:///C:/Program%20Files/Serd",
+ "C:/Program Files/Serd");
+
+ check_file_uri("ahost",
+ "C:\\Pointless Space",
+ true,
+ "file://ahost/C:/Pointless%20Space",
+ "C:/Pointless Space");
#else
/* What happens with Windows paths on other platforms is a bit weird, but
more or less unavoidable. It doesn't work to interpret backslashes as
path separators on any other platform. */
- test_file_uri("ahost",
- "C:\\Pointless Space",
- true,
- "file://ahost/C:%5CPointless%20Space",
- "/C:\\Pointless Space");
-
- test_file_uri(NULL,
- "\\drive\\relative",
- true,
- "%5Cdrive%5Crelative",
- "\\drive\\relative");
-
- test_file_uri(NULL,
- "C:\\Program Files\\Serd",
- true,
- "file:///C:%5CProgram%20Files%5CSerd",
- "/C:\\Program Files\\Serd");
-
- test_file_uri("ahost",
- "C:\\Pointless Space",
- true,
- "file://ahost/C:%5CPointless%20Space",
- "/C:\\Pointless Space");
+ check_file_uri("ahost",
+ "C:\\Pointless Space",
+ true,
+ "file://ahost/C:%5CPointless%20Space",
+ "/C:\\Pointless Space");
+
+ check_file_uri(NULL,
+ "\\drive\\relative",
+ true,
+ "%5Cdrive%5Crelative",
+ "\\drive\\relative");
+
+ check_file_uri(NULL,
+ "C:\\Program Files\\Serd",
+ true,
+ "file:///C:%5CProgram%20Files%5CSerd",
+ "/C:\\Program Files\\Serd");
+
+ check_file_uri("ahost",
+ "C:\\Pointless Space",
+ true,
+ "file://ahost/C:%5CPointless%20Space",
+ "/C:\\Pointless Space");
#endif
// Test tolerance of NULL hostname parameter
@@ -208,7 +207,7 @@ test_uri_from_string(void)
}
static inline bool
-chunk_equals(const SerdChunk* a, const SerdChunk* b)
+chunk_equals(const SerdChunk* const a, const SerdChunk* const b)
{
return (!a->len && !b->len && !a->buf && !b->buf) ||
(a->len && b->len && a->buf && b->buf &&
@@ -382,7 +381,5 @@ main(void)
test_uri_parsing();
test_uri_from_string();
test_relative_uri();
-
- printf("Success\n");
return 0;
}
diff --git a/test/test_write_error.py b/test/test_write_error.py
index 35fde232..b62f981a 100755
--- a/test/test_write_error.py
+++ b/test/test_write_error.py
@@ -5,19 +5,14 @@
"""Test errors writing to a file."""
-import argparse
import sys
import shlex
import subprocess
import os
-parser = argparse.ArgumentParser(description=__doc__)
+import serd_test_util as util
-parser.add_argument("--serdi", default="./serdi", help="path to serdi")
-parser.add_argument("--wrapper", default="", help="executable wrapper")
-parser.add_argument("input", help="valid input file")
-
-args = parser.parse_args(sys.argv[1:])
+args = util.wrapper_args(__doc__, True)
command = shlex.split(args.wrapper) + [args.serdi, args.input]
if os.path.exists("/dev/full"):
diff --git a/test/test_writer.c b/test/test_writer.c
index 6c765148..9e94e139 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -112,7 +112,6 @@ test_write_nested_anon(void)
"\t\t<http://example.org/p4> <http://example.org/o4>\n"
"\t] .\n";
- fprintf(stderr, "%s\n", out);
assert(!strcmp((char*)out, expected));
serd_free(out);
}