From cc3ede61012fc9f409b7c7e6197d5c563d11d7da Mon Sep 17 00:00:00 2001 From: Richard Kettlewell Date: Sun, 26 Oct 2008 10:38:48 +0000 Subject: [PATCH] Doxygen for C test infrastructure --- Doxyfile | 6 +++--- libtests/test.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- libtests/test.h | 45 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/Doxyfile b/Doxyfile index e2eca1d..c603807 100644 --- a/Doxyfile +++ b/Doxyfile @@ -295,7 +295,7 @@ INTERNAL_DOCS = YES # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. -CASE_SENSE_NAMES = YES +CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the @@ -307,7 +307,7 @@ HIDE_SCOPE_NAMES = YES # will put a list of the files that are included by a file in the documentation # of that file. -SHOW_INCLUDE_FILES = YES +SHOW_INCLUDE_FILES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. @@ -556,7 +556,7 @@ FILTER_SOURCE_FILES = NO # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. -SOURCE_BROWSER = YES +SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. diff --git a/libtests/test.c b/libtests/test.c index 6b2435e..73bfdd2 100644 --- a/libtests/test.c +++ b/libtests/test.c @@ -21,17 +21,37 @@ #include "version.h" #include -long long tests, errors; +/** @brief Count of tests */ +long long tests; + +/** @brief Count of errors */ +long long errors; + +/** @brief If set, first error will fail whole test */ int fail_first; + +/** @brief Verbose mode */ int verbose; + +/** @brief If set, test will return 'skipped' indicator */ int skipped; +/** @brief Count up an error + * + * If @ref fail_first is set then the test run is aborted. + */ void count_error(void) { ++errors; if(fail_first) abort(); } +/** @brief Render a string into printable ASCII + * @param s String to format + * @return Allocated copy of formatted string + * + * Replaces any non-ASCII characters with a hex escape. + */ const char *format(const char *s) { struct dynstr d; int c; @@ -50,6 +70,12 @@ const char *format(const char *s) { return d.vec; } +/** @brief Format a UTF-32 string into hex + * @param s String to format + * @return Allocated copy of formatted string + * + * Returns the hex codes of @p s separated by spaces. + */ const char *format_utf32(const uint32_t *s) { struct dynstr d; uint32_t c; @@ -64,6 +90,10 @@ const char *format_utf32(const uint32_t *s) { return d.vec; } +/** @brief Convert a string of hex codes to a UTF-32 string + * @param s String of hex codes, separated by spaces + * @return Allocated string, 0-terminated + */ uint32_t *ucs4parse(const char *s) { struct dynstr_ucs4 d; char *e; @@ -79,6 +109,11 @@ uint32_t *ucs4parse(const char *s) { return d.vec; } +/** @brief Format a string like asprintf() + * @param fmt Format string, per printf(3) + * @param ... Arguments + * @return Formatted string or null pointer on error + */ const char *do_printf(const char *fmt, ...) { va_list ap; char *s; @@ -92,8 +127,13 @@ const char *do_printf(const char *fmt, ...) { return s; } +/** @brief Jump buffer for exitfn() testing */ jmp_buf fatal_env; +/** @brief exitfn() callback for testing + * @param rc Value to return from setjmp() + * Jumps to @ref fatal_env + */ void test_exitfn(int rc) { assert(rc != 0); longjmp(fatal_env, rc); @@ -120,6 +160,10 @@ static void help(void) { exit(0); } +/** @brief Standard test program initialization + * @param argc Argument count + * @param argv Arguments + */ void test_init(int argc, char **argv) { int n; diff --git a/libtests/test.h b/libtests/test.h index b940413..cada395 100644 --- a/libtests/test.h +++ b/libtests/test.h @@ -68,7 +68,11 @@ extern int fail_first; extern int verbose; extern int skipped; -/** @brief Checks that @p expr is nonzero */ +/** @brief Checks that @p expr is nonzero + * @param expr Expression to check + * + * If @p expr is nonzero then logs an error (and continues). + */ #define insist(expr) do { \ if(!(expr)) { \ count_error(); \ @@ -78,6 +82,15 @@ extern int skipped; ++tests; \ } while(0) +/** @brief Check that a pair of strings match + * @param GOT What we actually got + * @param WANT What we wanted + * + * If @p GOT and @p WANT differ then logs an error (and continues). + * + * @p WANT is allowed to evaluate to a null pointer (but if it comes to + * anything else then must be safe to strcmp). + */ #define check_string(GOT, WANT) do { \ const char *got = GOT; \ const char *want = WANT; \ @@ -94,6 +107,15 @@ extern int skipped; ++tests; \ } while(0) +/** @brief Check that a string prefix matches + * @param GOT What we actually got + * @param WANT What we wanted + * + * If @p WANT is not a prefix of @p GOT then logs an error (and continues). + * + * @p WANT is allowed to evaluate to a null pointer (but if it comes to + * anything else then must be safe to strcmp). + */ #define check_string_prefix(GOT, WANT) do { \ const char *got = GOT; \ const char *want = WANT; \ @@ -110,6 +132,12 @@ extern int skipped; ++tests; \ } while(0) +/** @brief Check that a pair of integers match. + * @param GOT What we actually got + * @param WANT What we wanted + * + * If @p GOT and @p WANT differ then logs an error (and continues). + */ #define check_integer(GOT, WANT) do { \ const intmax_t got = GOT, want = WANT; \ if(got != want) { \ @@ -120,6 +148,12 @@ extern int skipped; ++tests; \ } while(0) +/** @brief Check that a function calls fatal() + * @param WHAT Expression to evaluate + * + * Evaluates WHAT and if it does not call fatal(), logs an error. In any case, + * continues. Modifies exitfn() so that fatal() isn't actually fatal. + */ #define check_fatal(WHAT) do { \ void (*const save_exitfn)(int) attribute((noreturn)) = exitfn; \ \ @@ -145,6 +179,15 @@ void test_init(int argc, char **argv); extern jmp_buf fatal_env; void test_exitfn(int) attribute((noreturn)); +/** @brief Common code for each test source file + * @param name Name of test + * + * Expands to a @c main function which: + * - calls test_init() + * - calls test_NAME() + * - reports a count of errors + * - returns the right exit status + */ #define TEST(name) \ int main(int argc, char **argv) { \ test_init(argc, argv); \ -- 2.11.0