chiark / gitweb /
Doxygen for C test infrastructure
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 26 Oct 2008 10:38:48 +0000 (10:38 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 26 Oct 2008 10:38:48 +0000 (10:38 +0000)
Doxyfile
libtests/test.c
libtests/test.h

index e2eca1d244796495928983ad1ed82113d551f0ca..c6038072f5aefb987d805abd855ddaa2ad14b810 100644 (file)
--- 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.
index 6b2435e103afa7db74321fce8e6f263deeb7d3dd..73bfdd2a8421badb8ef5a7426bd58dd4a0d25646 100644 (file)
 #include "version.h"
 #include <getopt.h>
 
-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;
 
index b940413d0d4145e7c036a70bc310bf2acab0ad86..cada395ad03dcf55c8f0fcbc73d4775d928d7d7b 100644 (file)
@@ -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);                                              \