fix that test.h is not standalone - fixes #927 default tip

Wed, 26 Aug 2026 16:03:54 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 26 Aug 2026 16:03:54 +0200
changeset 1710
d53be93acc10
parent 1709
560a60fcf6ee

fix that test.h is not standalone - fixes #927

make/update-rules.sh file | annotate | diff | comparison | revisions
src/cx/test.h file | annotate | diff | comparison | revisions
tests/Makefile file | annotate | diff | comparison | revisions
tests/test_header_only.c file | annotate | diff | comparison | revisions
tests/test_szmul.c file | annotate | diff | comparison | revisions
--- a/make/update-rules.sh	Sun May 24 12:18:44 2026 +0200
+++ b/make/update-rules.sh	Wed Aug 26 16:03:54 2026 +0200
@@ -47,6 +47,7 @@
 sed '/FORCE:/q' Makefile.old > Makefile
 echo >> Makefile
 for file in `ls *.c` ; do
+  if [ "$file" = "test_header_only.c" ]; then continue; fi
   "$CC" -MT "$target/${file%.c}\$(OBJ_EXT)" -MM $CFLAGS $extra_flags "$file"
   printf '\t@echo "Compiling $<"\n'
   printf '\t$(CC) -o $@ $(CFLAGS) %s -c $<\n\n' "$extra_flags"
--- a/src/cx/test.h	Sun May 24 12:18:44 2026 +0200
+++ b/src/cx/test.h	Wed Aug 26 16:03:54 2026 +0200
@@ -48,7 +48,7 @@
  * 
  * CX_TEST(function_name) {
  *   // memory allocation and other stuff here
- *   #CX_TEST_DO {
+ *   CX_TEST_DO {
  *     // tests with CX_TEST_ASSERT() and/or
  *     // calls with CX_TEST_CALL_SUBROUTINE() here
  *   }
@@ -67,8 +67,7 @@
 #ifndef UCX_TEST_H
 #define	UCX_TEST_H
 
-#include "common.h"
-
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <setjmp.h>
@@ -90,8 +89,11 @@
 /** Type for the CxTestSuite. */
 typedef struct CxTestSuite CxTestSuite;
 
+/** Output function compatible to cx_write_func */
+typedef size_t (*cx_test_output_func)(const void*, size_t, size_t, void*);
+
 /** Pointer to a test function. */
-typedef void(*CxTest)(CxTestSuite *, void *, cx_write_func);
+typedef void(*CxTest)(CxTestSuite *, void *, cx_test_output_func);
 
 /** Type for the internal list of test cases. */
 typedef struct CxTestSet CxTestSet;
@@ -132,7 +134,6 @@
  * @param name optional name of the suite
  * @return a new test suite
  */
-CX_NONNULL CX_NODISCARD  CX_CSTR_ARG(1) CX_MALLOC
 static inline CxTestSuite* cx_test_suite_new(const char *name) {
     CxTestSuite* suite = (CxTestSuite*) malloc(sizeof(CxTestSuite));
     if (suite != NULL) {
@@ -150,7 +151,7 @@
  *
  * @param suite the test suite to free
  */
-CX_INLINE void cx_test_suite_free(CxTestSuite* suite) {
+static inline void cx_test_suite_free(CxTestSuite* suite) {
     if (suite == NULL) return;
     CxTestSet *l = suite->tests;
     while (l != NULL) {
@@ -169,8 +170,7 @@
  * @retval zero success
  * @retval non-zero failure
  */
-CX_NONNULL
-CX_INLINE int cx_test_register(CxTestSuite* suite, CxTest test) {
+static inline int cx_test_register(CxTestSuite* suite, CxTest test) {
     CxTestSet *t = (CxTestSet*) malloc(sizeof(CxTestSet));
     if (t) {
         t->test = test;
@@ -196,8 +196,8 @@
  * @param out_target the target buffer or file to write the output to
  * @param out_writer the write function writing to @p out_target
  */
-CX_NONNULL
-CX_INLINE void cx_test_run(CxTestSuite *suite, void *out_target, cx_write_func out_writer) {
+static inline void cx_test_run(CxTestSuite *suite, void *out_target,
+        cx_test_output_func out_writer) {
     if (suite->name == NULL) {
         out_writer("*** Test Suite ***\n", 1, 19, out_target);
     } else {
@@ -225,7 +225,8 @@
  * @param suite (@c CxTestSuite*) the test suite to run
  * @param file (@c FILE*) the target file to write the output to
  */
-#define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, (cx_write_func)fwrite)
+#define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, \
+        (cx_test_output_func) fwrite)
 
 /**
  * Runs a test suite and writes the test log to stdout.
@@ -240,7 +241,8 @@
  * 
  * @param name the name of the test function
  */
-#define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_)
+#define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, \
+        cx_test_output_func _writefnc_)
 
 /**
  * Defines the scope of a test.
@@ -290,7 +292,8 @@
  * written to the test suites output stream.
  * @param condition (@c bool) the condition to check
  */
-#define CX_TEST_ASSERT(condition) CX_TEST_ASSERTM(condition, #condition " failed")
+#define CX_TEST_ASSERT(condition) \
+        CX_TEST_ASSERTM(condition, #condition " failed")
 
 /**
  * Macro for a test subroutine function header.
@@ -304,7 +307,8 @@
  * @see CX_TEST_CALL_SUBROUTINE()
  */
 #define CX_TEST_SUBROUTINE(name,...) void name(CxTestSuite* _suite_,\
-        void *_output_, cx_write_func _writefnc_, jmp_buf _env_, __VA_ARGS__)
+        void *_output_, cx_test_output_func _writefnc_, \
+        jmp_buf _env_, __VA_ARGS__)
 
 /**
  * Macro for calling a test subroutine.
--- a/tests/Makefile	Sun May 24 12:18:44 2026 +0200
+++ b/tests/Makefile	Wed Aug 26 16:03:54 2026 +0200
@@ -40,11 +40,16 @@
 OBJ_EXT=.o
 OBJ=$(SRC:%.c=$(TEST_DIR)/%$(OBJ_EXT))
 
-all: $(TEST_DIR) $(TEST_DIR)/ucxtest
+all: $(TEST_DIR) $(TEST_DIR)/ucxtest $(TEST_DIR)/test_header_only$(OBJ_EXT)
 
 $(TEST_DIR)/ucxtest: $(OBJ) $(build_dir)/libucx_static.a
 	$(CC) -o $@ $(LDFLAGS) $+
 
+# tests that the test.h can be used header-only
+$(TEST_DIR)/test_header_only$(OBJ_EXT): ../src/cx/test.h
+	@echo "Checking if test.h is standalone"
+	$(CC) -o "$@" -c test_header_only.c
+
 $(build_dir)/libucx_static.a:
 	test -f "$@"
 
@@ -54,29 +59,29 @@
 FORCE:
 
 $(TEST_DIR)/test_allocator$(OBJ_EXT): test_allocator.c ../src/cx/test.h \
- ../src/cx/common.h ../src/cx/allocator.h
+ ../src/cx/allocator.h ../src/cx/common.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_buffer$(OBJ_EXT): test_buffer.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/buffer.h ../src/cx/allocator.h ../src/cx/string.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_compare$(OBJ_EXT): test_compare.c ../src/cx/test.h \
- ../src/cx/common.h ../src/cx/compare.h
+ ../src/cx/compare.h ../src/cx/common.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_hash_key$(OBJ_EXT): test_hash_key.c ../src/cx/test.h \
- ../src/cx/common.h ../src/cx/hash_key.h ../src/cx/string.h \
+ ../src/cx/hash_key.h ../src/cx/common.h ../src/cx/string.h \
  ../src/cx/allocator.h ../src/cx/string.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_hash_map$(OBJ_EXT): test_hash_map.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/array_list.h ../src/cx/list.h ../src/cx/collection.h \
  ../src/cx/allocator.h ../src/cx/iterator.h ../src/cx/compare.h \
  ../src/cx/list.h ../src/cx/hash_map.h ../src/cx/map.h ../src/cx/string.h \
@@ -85,7 +90,7 @@
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_iterator$(OBJ_EXT): test_iterator.c ../src/cx/test.h \
- ../src/cx/common.h ../src/cx/iterator.h
+ ../src/cx/iterator.h ../src/cx/common.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
@@ -99,7 +104,7 @@
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_kv_list$(OBJ_EXT): test_kv_list.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/kv_list.h ../src/cx/list.h ../src/cx/collection.h \
  ../src/cx/allocator.h ../src/cx/iterator.h ../src/cx/compare.h \
  ../src/cx/map.h ../src/cx/string.h ../src/cx/hash_key.h
@@ -107,7 +112,7 @@
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_list$(OBJ_EXT): test_list.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/compare.h ../src/cx/array_list.h ../src/cx/list.h \
  ../src/cx/collection.h ../src/cx/allocator.h ../src/cx/iterator.h \
  ../src/cx/compare.h ../src/cx/linked_list.h ../src/cx/kv_list.h \
@@ -116,19 +121,19 @@
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_mempool$(OBJ_EXT): test_mempool.c ../src/cx/test.h \
- ../src/cx/common.h ../src/cx/mempool.h ../src/cx/allocator.h
+ ../src/cx/mempool.h ../src/cx/common.h ../src/cx/allocator.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_printf$(OBJ_EXT): test_printf.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/printf.h ../src/cx/string.h ../src/cx/allocator.h \
  ../src/cx/buffer.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_properties$(OBJ_EXT): test_properties.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/properties.h ../src/cx/string.h ../src/cx/allocator.h \
  ../src/cx/map.h ../src/cx/collection.h ../src/cx/iterator.h \
  ../src/cx/compare.h ../src/cx/hash_key.h ../src/cx/buffer.h \
@@ -137,13 +142,13 @@
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_streams$(OBJ_EXT): test_streams.c ../src/cx/test.h \
- ../src/cx/common.h ../src/cx/streams.h ../src/cx/buffer.h \
+ ../src/cx/streams.h ../src/cx/common.h ../src/cx/buffer.h \
  ../src/cx/allocator.h ../src/cx/string.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
 
 $(TEST_DIR)/test_string$(OBJ_EXT): test_string.c ../src/cx/test.h \
- ../src/cx/common.h util_allocator.h ../src/cx/allocator.h \
+ util_allocator.h ../src/cx/allocator.h ../src/cx/common.h \
  ../src/cx/string.h ../src/cx/allocator.h ../src/cx/compare.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -I../src -c $<
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_header_only.c	Wed Aug 26 16:03:54 2026 +0200
@@ -0,0 +1,45 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Mike Becker, Olaf Wintermann All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../src/cx/test.h"
+
+/* this file does not add meaningful executable tests
+ * it's purpose is to show that compilation is possible as standalone file
+ */
+
+CX_TEST_SUBROUTINE(foo, int x) {
+    CX_TEST_ASSERT(x == 42);
+    CX_TEST_ASSERTM(x == 42, "value invalid");
+}
+
+CX_TEST(dummy) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(foo, 42);
+    }
+}
+
--- a/tests/test_szmul.c	Sun May 24 12:18:44 2026 +0200
+++ b/tests/test_szmul.c	Wed Aug 26 16:03:54 2026 +0200
@@ -27,6 +27,9 @@
  */
 
 #include "cx/test.h"
+#include "cx/common.h"
+
+#include <stdint.h>
 
 CX_TEST(test_szmul) {
     size_t r;

mercurial