OSSP CVS Repository

ossp - Check-in [2045]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2045
Date: 2002-Apr-01 11:03:49 (local)
2002-Apr-01 09:03:49 (UTC)
User:rse
Branch:
Comment: - switch to our OSSP ts sub-library - switch from str_config.h to just config.h
Tickets:
Inspections:
Files:
ossp-pkg/str/.cvsignore      1.12 -> 1.13     13 inserted, 14 deleted
ossp-pkg/str/Makefile.in      1.44 -> 1.45     4 inserted, 5 deleted
ossp-pkg/str/configure.ac      1.10 -> 1.11     1 inserted, 1 deleted
ossp-pkg/str/str_p.h      1.19 -> 1.20     4 inserted, 2 deleted
ossp-pkg/str/str_test.c      1.24 -> 1.25     92 inserted, 164 deleted
ossp-pkg/str/ts.c      added-> 1.1
ossp-pkg/str/ts.h      added-> 1.1

ossp-pkg/str/.cvsignore 1.12 -> 1.13

--- .cvsignore   2002/01/24 16:30:04     1.12
+++ .cvsignore   2002/04/01 09:03:49     1.13
@@ -1,26 +1,25 @@
-Makefile
-config.log
-config.cache
-config.status
-str-config
-str_config.h
-str_config.h.in
-str_test
 *.core
-*.lo
 *.la
+*.lo
 .libs
-libtool
-str_pcre_gen
-str_pcre_tab.c
+Makefile
+config.cache
 config.guess
+config.h
+config.h.in
+config.log
+config.status
 config.sub
 configure
+libtool
 libtool.m4
 ltmain.sh
 shtool
-str.3
+str-config
 str-config.1
+str.3
 str.h
 str_pcre.tab
-config.h.in
+str_pcre_gen
+str_pcre_tab.c
+str_test


ossp-pkg/str/Makefile.in 1.44 -> 1.45

--- Makefile.in  2002/04/01 08:32:54     1.44
+++ Makefile.in  2002/04/01 09:03:49     1.45
@@ -104,8 +104,8 @@
         $(LIBTOOL) --mode=link --quiet $(CC) -o libstr.la $(OBJS) -rpath $(libdir) \
         -version-info `$(SHTOOL) version -l c -d libtool str_version.c`
 
-str_test: str_test.o libstr.la
-        $(LIBTOOL) --mode=link --quiet $(CC) $(LDFLAGS) -o str_test str_test.o libstr.la $(LIBS)
+str_test: str_test.o ts.o libstr.la
+        $(LIBTOOL) --mode=link --quiet $(CC) $(LDFLAGS) -o str_test str_test.o ts.o libstr.la $(LIBS)
 
 str-config.1: str-config.pod $(_VERSION_FILE)
         BASENAME="str-config"; SEC=1; \
@@ -116,7 +116,6 @@
         NAME="Str"; ONELINE="String Library"; \
         $(_MANPAGE)
 
-
 str_pcre.lo: str_pcre.tab str_pcre.c
 str_pcre.tab: str_pcre.c
         $(CC) $(CFLAGS) -DSTR_PCRE_TAB $(LDFLAGS) -o str_pcre.gen str_pcre.c $(LIBS)
@@ -147,7 +146,7 @@
         
 distclean: clean
         $(RM) str-config
-        $(RM) str_config.h
+        $(RM) config.h
         $(RM) str_pcre.tab
         $(RM) config.log config.cache config.status
         $(RM) libtool
@@ -156,7 +155,7 @@
 
 realclean: distclean
         $(RM) config.guess config.sub ltmain.sh libtool.m4
-        $(RM) configure str_config.h.in
+        $(RM) configure config.h.in
         $(RM) str-config.1 str.3
         $(RM) shtool
 


ossp-pkg/str/configure.ac 1.10 -> 1.11

--- configure.ac 2002/04/01 08:32:54     1.10
+++ configure.ac 2002/04/01 09:03:49     1.11
@@ -34,7 +34,7 @@
 AC_CHECK_EXTLIB([Dmalloc], dmalloc, dmalloc_debug, dmalloc.h, 
                 [AC_DEFINE(WITH_DMALLOC, 1, [Define to 1 if building with Dmalloc])])
 
-AC_CONFIG_HEADERS(str_config.h)
+AC_CONFIG_HEADERS(config.h)
 AC_CONFIG_FILES([Makefile str.h str-config])
 AC_CONFIG_COMMANDS([adjustment], [chmod a+x str-config])
 AC_OUTPUT


ossp-pkg/str/str_p.h 1.19 -> 1.20

--- str_p.h      2002/04/01 08:32:54     1.19
+++ str_p.h      2002/04/01 09:03:49     1.20
@@ -30,13 +30,15 @@
 #ifndef _STR_P_H_
 #define _STR_P_H_
 
-#include "str.h"
-#include "str_config.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <stdlib.h>     /* for malloc, etc. */
 #include <math.h>       /* for modf(3) */
 #include <string.h>     /* ... */
 
+#include "str.h"
 #include "str_pcre.h"
 
 #if defined(HAVE_DMALLOC_H) && defined(WITH_DMALLOC)


ossp-pkg/str/str_test.c 1.24 -> 1.25

--- str_test.c   2002/04/01 08:32:54     1.24
+++ str_test.c   2002/04/01 09:03:49     1.25
@@ -30,40 +30,40 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "str.h"
-#include "str_config.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #if defined(HAVE_DMALLOC_H) && defined(WITH_DMALLOC)
 #include "dmalloc.h"
 #endif
 
+#include "str.h"
+#include "ts.h"
+
 #define LONG_STRING 1024
 
 /*
  * Test String Length
  */
 
-static void test_length(int *ok, int *fail)
+TS_TEST(test_length)
 {
-    if (str_len(NULL) == 0)
-        (*ok)++;
-    else 
-        (*fail)++;
-
-    if (str_len("") == 0)
-        (*ok)++;
-    else 
-        (*fail)++;
-
-    if (str_len("a") == 1)
-        (*ok)++;
-    else 
-        (*fail)++;
-
-    if (str_len("foo bar quux") == 12)
-        (*ok)++;
-    else 
-        (*fail)++;
+    ts_test_check(TS_CTX, "NULL handling");
+    if (str_len(NULL) != 0)
+        ts_test_fail(TS_CTX, "unexpected non-zero return");
+
+    ts_test_check(TS_CTX, "empty string handling");
+    if (str_len("") != 0)
+        ts_test_fail(TS_CTX, "unexpected non-zero return");
+
+    ts_test_check(TS_CTX, "short string handling");
+    if (str_len("a") != 1)
+        ts_test_fail(TS_CTX, "unexpected return != 1");
+
+    ts_test_check(TS_CTX, "longer string handling");
+    if (str_len("foo bar quux") != 12)
+        ts_test_fail(TS_CTX, "unexpected return != 12");
     return;
 }
 
@@ -87,22 +87,18 @@
     { NULL, 0, NULL, 0 }
 };
 
-static void test_locate(int *ok, int *fail)
+TS_TEST(test_locate)
 {
     int i;
     char *rv;
 
     for (i = 0; loctab[i].s != NULL; i++) {
         rv = str_locate(loctab[i].s, loctab[i].n, loctab[i].p);
-        printf("str_locate(\"%s\", %d, \"%s\") = \"%s\"\n",
-                loctab[i].s, loctab[i].n, loctab[i].p, rv == NULL ? "[NULL]" : rv);
-        if ((rv-loctab[i].s == loctab[i].o) || (rv == NULL && loctab[i].o == -1))
-            (*ok)++;
-        else {
-            fprintf(stderr, "ERROR: result was \"%s\", expected \"%s\"\n",
-                    rv, loctab[i].s+loctab[i].o);
-            (*fail)++;
-        }
+        ts_test_check(TS_CTX, "str_locate(\"%s\", %d, \"%s\") = \"%s\"",
+                      loctab[i].s, loctab[i].n, loctab[i].p, rv == NULL ? "[NULL]" : rv);
+        if (!((rv-loctab[i].s == loctab[i].o) || (rv == NULL && loctab[i].o == -1)))
+            ts_test_fail(TS_CTX, "result was \"%s\", expected \"%s\"",
+                         rv, loctab[i].s+loctab[i].o);
     }
     return;
 }
@@ -129,22 +125,18 @@
     { NULL, 0, NULL, 0, 0 }
 };
 
-static void test_span(int *ok, int *fail)
+TS_TEST(test_span)
 {
     int i;
     char *rv;
 
     for (i = 0; spantab[i].s != NULL; i++) {
         rv = str_span(spantab[i].s, spantab[i].n, spantab[i].cs, spantab[i].m);
-        printf("str_span(\"%s\", %d, \"%s\", %d) = \"%s\"\n",
-                spantab[i].s, spantab[i].n, spantab[i].cs, spantab[i].m, rv);
-        if (rv-spantab[i].s == spantab[i].o)
-            (*ok)++;
-        else {
-            fprintf(stderr, "ERROR: result was \"%s\", expected \"%s\"\n",
-                    rv, spantab[i].s+spantab[i].o);
-            (*fail)++;
-        }
+        ts_test_check(TS_CTX, "str_span(\"%s\", %d, \"%s\", %d) = \"%s\"",
+                      spantab[i].s, spantab[i].n, spantab[i].cs, spantab[i].m, rv);
+        if (rv-spantab[i].s != spantab[i].o)
+            ts_test_fail(TS_CTX, "result was \"%s\", expected \"%s\"",
+                         rv, spantab[i].s+spantab[i].o);
     }
     return;
 }
@@ -198,7 +190,7 @@
     return;
 }
 
-static void test_tokenize(int *ok, int *fail)
+TS_TEST(test_tokenize)
 {  
     char *cp;
     char *cp2;
@@ -207,23 +199,24 @@
     int i, j;
 
     for (i = 0; toktab[i].s != NULL; i++) {
-        fprintf(stderr, "Testing tokenization of %s\n", prstr(toktab[i].s)), prstr_free();
+        ts_test_check(TS_CTX, "tokenization of \"%s\"\n", prstr(toktab[i].s));
+        prstr_free();
         cp2 = cp = strdup(toktab[i].s);
         for (j = 0; j < 4; j++) {
             cp3 = strdup(cp);
             rc = str_token(&cp, toktab[i].d, toktab[i].q, toktab[i].c, toktab[i].f);
-            fprintf(stderr, "str_token(&%s, %s, %s, %s, %d) = %s\n",
-                    prstr(cp3), prstr(toktab[i].d),
-                    prstr(toktab[i].q), prstr(toktab[i].c),
-                    toktab[i].f, prstr(rc)), prstr_free();
+            ts_test_check(TS_CTX, "str_token(&%s, %s, %s, %s, %d) = %s",
+                          prstr(cp3), prstr(toktab[i].d),
+                          prstr(toktab[i].q), prstr(toktab[i].c),
+                          toktab[i].f, prstr(rc)), prstr_free();
             free(cp3);
             if (!(   (rc == NULL && toktab[i].r[j] == NULL)
                   || (rc != NULL && toktab[i].r[j] != NULL && strcmp(rc, toktab[i].r[j]) == 0))) {
-                fprintf(stderr, "ERROR: expected result is %s\n", prstr(toktab[i].r[j])), prstr_free();
+                ts_test_fail(TS_CTX, "expected result is \"%s\"", prstr(toktab[i].r[j]));
+                prstr_free();
             }
         }
         free(cp2);
-        fprintf(stderr, "\n");
     }
     return;
 }
@@ -253,14 +246,14 @@
     { NULL, NULL, NULL, NULL, NULL, NULL, 0 }
 };
 
-static void test_parsing(int *ok, int *fail)
+TS_TEST(test_parsing)
 {
     int i;
     int rv;
     char *r1, *r2, *r3, *r4;
 
     for (i = 0; test2_tab[i].s != NULL; i++) {
-        fprintf(stderr, "%d. str_parse(\"%s\", \"%s\", ...)\n", i, test2_tab[i].s, test2_tab[i].p);
+        ts_test_check(TS_CTX, "str_parse(\"%s\", \"%s\", ...)", test2_tab[i].s, test2_tab[i].p);
         if (*(test2_tab[i].p) == 's') {
             r1 = NULL;
             r2 = test2_tab[i].r2;
@@ -272,10 +265,6 @@
             r1 = r2 = r3 = r4 = NULL;
             rv = str_parse(test2_tab[i].s, test2_tab[i].p, &r1, &r2, &r3, &r4);
         }
-        fprintf(stderr, "%d. str_parse(\"%s\", \"%s\", ...) = %d + <%s><%s><%s><%s>\n",
-                i, test2_tab[i].s, test2_tab[i].p, rv,
-                r1 == NULL ? "NULL" : r1, r2 == NULL ? "NULL" : r2, 
-                r3 == NULL ? "NULL" : r3, r4 == NULL ? "NULL" : r4);
         if (rv != test2_tab[i].rv ||
             ((r1 == NULL && test2_tab[i].r1 != NULL) || 
              (r1 != NULL && test2_tab[i].r1 == NULL) || 
@@ -289,16 +278,13 @@
             ((r4 == NULL && test2_tab[i].r4 != NULL) || 
              (r4 != NULL && test2_tab[i].r4 == NULL) || 
              (r4 != NULL && test2_tab[i].r4 != NULL && strcmp(r4, test2_tab[i].r4) != 0))) {
-            fprintf(stderr, "    ERROR: expected result: %d + <%s><%s><%s><%s>\n",
-                    test2_tab[i].rv, 
-                    test2_tab[i].r1 == NULL ? "NULL" : test2_tab[i].r1,
-                    test2_tab[i].r2 == NULL ? "NULL" : test2_tab[i].r2,
-                    test2_tab[i].r3 == NULL ? "NULL" : test2_tab[i].r3,
-                    test2_tab[i].r4 == NULL ? "NULL" : test2_tab[i].r4);
-            (*fail)++;
+            ts_test_fail(TS_CTX, "expected result: %d + <%s><%s><%s><%s>",
+                         test2_tab[i].rv, 
+                         test2_tab[i].r1 == NULL ? "NULL" : test2_tab[i].r1,
+                         test2_tab[i].r2 == NULL ? "NULL" : test2_tab[i].r2,
+                         test2_tab[i].r3 == NULL ? "NULL" : test2_tab[i].r3,
+                         test2_tab[i].r4 == NULL ? "NULL" : test2_tab[i].r4);
         }
-        else
-            (*ok)++;
     }
     str_parse(NULL, NULL);
     return;
@@ -308,7 +294,7 @@
  * Test String Formatting
  */
 
-static void test_formatting(int *ok, int *fail)
+TS_TEST(test_formatting)
 {
     char buf1[LONG_STRING];
     char buf2[LONG_STRING];
@@ -347,160 +333,102 @@
     int x, y;
     int len;
 
-    fprintf(stderr, "\n** Testing str_format format codes against vendor sprintf **\n\n");
+    ts_test_check(TS_CTX, "str_format vs. vendor sprintf comparison");
 
     for (x = 0; fp_fmt[x] != NULL; x++) {
-        fprintf(stderr, "testing \"%s\"\n", fp_fmt[x]);
+        ts_test_check(TS_CTX, "str_format(..,..,\"%s\",..)", fp_fmt[x]);
         for (y = 0; fp_nums[y] != 0; y++) {
             len = str_format(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
             sprintf(buf2, fp_fmt[x], fp_nums[y]);
-            if (strcmp(buf1, buf2) != 0) {
-                fprintf(stderr, "  mismatch:\n");
-                fprintf(stderr, "    str_format: \"%s\"\n"
-                                "    sprintf:    \"%s\"\n", buf1, buf2);
-                (*fail)++;
-            }
-            else {
-                fprintf(stderr, "  ok: %d \"%s\" (%d)\n", len, buf1, (int)strlen(buf1));
-                (*ok)++;
-            }
+            if (strcmp(buf1, buf2) != 0)
+                ts_test_fail(TS_CTX, "mismatch: str_format: \"%s\", snprintf: \"%s\"", buf1, buf2);
         }
     }
 
     for (x = 0; int_fmt[x] != NULL; x++) {
-        fprintf(stderr, "testing \"%s\"\n", int_fmt[x]);
+        ts_test_check(TS_CTX, "str_format(..,..,\"%s\",..)", int_fmt[x]);
         for (y = 0; int_nums[y] != 0; y++) {
             len = str_format(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
             sprintf(buf2, int_fmt[x], int_nums[y]);
-            if (strcmp(buf1, buf2) != 0) {
-                fprintf(stderr, "  mismatch:\n");
-                fprintf(stderr, "    str_format: \"%s\"\n"
-                                "    sprintf:    \"%s\"\n", buf1, buf2);
-                (*fail)++;
-            }
-            else {
-                fprintf(stderr, "  ok: %d \"%s\" (%d)\n", len, buf1, (int)strlen(buf1));
-                (*ok)++;
-            }
+            if (strcmp(buf1, buf2) != 0)
+                ts_test_fail(TS_CTX, "mismatch: str_format: \"%s\", snprintf: \"%s\"", buf1, buf2);
         }
     }
     return;
 }
 
-static void test_base64_do(unsigned char *ucp, int ulen, int mode, int *ok, int *fail)
+/*
+ * Test Base64 Encoding/Decoding
+ */
+
+static void test_base64_do(ts_test_t *_t, unsigned char *ucp, int ulen, int mode)
 {
     unsigned char ucp2[1024];
     char cp[1024];
     int n1, n2, n3, n4;
     int i;
-    int fine;
 
     n1 = str_base64(NULL, 0, ucp, ulen, STR_BASE64_ENCODE|mode);
     n2 = str_base64(cp, sizeof(cp), ucp, ulen, STR_BASE64_ENCODE|mode);
-    if (n1 != n2) {
-        fprintf(stderr, "   ERROR: encoding length mismatch: %d vs. %d\n", n1, n2);
-        (*fail)++;
-    }
-    else
-        (*ok)++;
+    if (n1 != n2)
+        ts_test_fail(TS_CTX, "encoding length mismatch: %d vs. %d\n", n1, n2);
     n3 = str_base64(cp, n2, NULL, 0, STR_BASE64_DECODE|mode);
-    if (n3 != ulen) {
-        fprintf(stderr, "   ERROR: decoding check length mismatch: %d vs. %d\n", n3, ulen);
-        (*fail)++;
-    }
-    else
-        (*ok)++;
+    if (n3 != ulen)
+        ts_test_fail(TS_CTX, "decoding check length mismatch: %d vs. %d\n", n3, ulen);
     n4 = str_base64(cp, n2, ucp2, ulen, STR_BASE64_DECODE|mode);
-    if (n3 != n4) {
-        fprintf(stderr, "   ERROR: decoding length mismatch: %d vs. %d\n", n3, n4);
-        (*fail)++;
-    }
-    else
-        (*ok)++;
-    fine = TRUE;
+    if (n3 != n4)
+        ts_test_fail(TS_CTX, "decoding length mismatch: %d vs. %d\n", n3, n4);
     for (i = 0; i < 256; i++) {
         if (ucp[i] != ucp2[i]) {
-            fine = FALSE;
+            ts_test_fail(TS_CTX, "decoding contents mismatch\n");
             break;
         }
     }
-    if (!fine) {
-        fprintf(stderr, "   ERROR: decoding mismatch\n");
-        (*fail)++;
-    }
-    else
-        (*ok)++;
     return;
 }
 
-static void test_base64(int *ok, int *fail)
+TS_TEST(test_base64)
 {
     unsigned char ucp[256];
     int i;
     
-    fprintf(stderr, "\n** Testing str_base64 **\n\n");
-
-    fprintf(stderr, "1. Encode/Decode of 0 bytes\n");
+    ts_test_check(TS_CTX, "encode/decode of 0 bytes");
     for (i = 0; i < 256; i++)
         ucp[i] = 0x55;
-    test_base64_do(ucp, 256, STR_BASE64_STRICT, ok, fail);
+    test_base64_do(_t, ucp, 256, STR_BASE64_STRICT);
 
-    fprintf(stderr, "2. Encode/Decode of increasing bytes\n");
+    ts_test_check(TS_CTX, "encode/decode of increasing bytes\n");
     for (i = 0; i < 256; i++)
         ucp[i] = i;
-    test_base64_do(ucp, 256, STR_BASE64_STRICT, ok, fail);
+    test_base64_do(_t, ucp, 256, STR_BASE64_STRICT);
 
-    fprintf(stderr, "3. Encode/Decode of distributed bytes\n");
+    ts_test_check(TS_CTX, "encode/decode of distributed bytes\n");
     for (i = 0; i < 256; i++)
         ucp[i] = i*31;
-    test_base64_do(ucp, 256, STR_BASE64_STRICT, ok, fail);
+    test_base64_do(_t, ucp, 256, STR_BASE64_STRICT);
 
     return;
 }
 
 /*
- * Main Test Driver Program
+ * Main Test Suite Procedure
  */
 
-struct {
-    char *name;
-    void (*func)(int *, int *);
-    int ok;
-    int fail;
-} tests[] = {
-    { "Length",      test_length,      0, 0 },
-    { "Locating",    test_locate,      0, 0 },
-    { "Spanning",    test_span,        0, 0 },
-    { "Tokenizing",  test_tokenize,    0, 0 },
-    { "Parsing",     test_parsing,     0, 0 },
-    { "Formatting",  test_formatting,  0, 0 },
-    { "Base64",      test_base64,      0, 0 },
-    { NULL, NULL, 0,0 }
-};
-
 int main(int argc, char *argv[])
 {
-    int i;
-    int fail;
-    int ok;
+    ts_suite_t *ts;
+    int n;
 
-    ok = 0;
-    fail = 0;
-    fprintf(stderr, "\n");
-    fprintf(stderr, "String Library Test Suite\n");
-    fprintf(stderr, "________________________________________\n\n");
-    for (i = 0; tests[i].name != NULL; i++) {
-        fprintf(stderr, "==== Testing %s ====\n", tests[i].name);
-        tests[i].ok = tests[i].fail = 0;
-        tests[i].func(&tests[i].ok, &tests[i].fail);
-        fprintf(stderr, "==== Tests failed %d/%d ====\n", tests[i].fail, tests[i].ok+tests[i].fail);
-        fprintf(stderr, "\n");
-        ok += tests[i].ok;
-        fail += tests[i].fail;
-    }
-    fprintf(stderr, "________________________________________\n\n");
-    fprintf(stderr, "TOTAL: failed %d/%d\n", fail, fail+ok);
-    fprintf(stderr, "\n");
-    return fail;
+    ts = ts_suite_new("OSSP str (String Handling)");
+    ts_suite_test(ts, test_length,     "String Length Determination");
+    ts_suite_test(ts, test_locate,     "String Locating");
+    ts_suite_test(ts, test_span,       "String Spanning");
+    ts_suite_test(ts, test_tokenize,   "String Tokenizing");
+    ts_suite_test(ts, test_parsing,    "String Parsing");
+    ts_suite_test(ts, test_formatting, "String Formatting");
+    ts_suite_test(ts, test_base64,     "String Encoding/Decoding");
+    n = ts_suite_run(ts);
+    ts_suite_free(ts);
+    return n;
 }
 


ossp-pkg/str/ts.c -> 1.1

*** /dev/null    Tue Mar 11 06:05:13 2025
--- -    Tue Mar 11 06:05:32 2025
***************
*** 0 ****
--- 1,468 ----
+ /*
+ **  TS - OSSP Test Suite Library
+ **  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP TS, a small test suite library which
+ **  can be found at http://www.ossp.org/pkg/ts/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  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.
+ **
+ **  ts.c: test suite library
+ */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdarg.h>
+ 
+ #include "config.h"
+ #if defined(HAVE_DMALLOC_H) && defined(WITH_DMALLOC)
+ #include "dmalloc.h"
+ #endif
+ 
+ #include "ts.h"
+ 
+ /* embedded ring data structure library */
+ #define RING_ENTRY(elem) \
+     struct { elem *next; elem *prev; }
+ #define RING_HEAD(elem) \
+     struct { elem *next; elem *prev; }
+ #define RING_SENTINEL(hp, elem, link) \
+     (elem *)((char *)(hp) - ((size_t)(&((elem *)0)->link)))
+ #define RING_FIRST(hp) \
+     (hp)->next
+ #define RING_LAST(hp) \
+     (hp)->prev
+ #define RING_NEXT(ep, link) \
+     (ep)->link.next
+ #define RING_PREV(ep, link) \
+     (ep)->link.prev
+ #define RING_INIT(hp, elem, link) \
+     do { RING_FIRST((hp)) = RING_SENTINEL((hp), elem, link); \
+          RING_LAST((hp))  = RING_SENTINEL((hp), elem, link); } while (0)
+ #define RING_EMPTY(hp, elem, link) \
+     (RING_FIRST((hp)) == RING_SENTINEL((hp), elem, link))
+ #define RING_ELEM_INIT(ep, link) \
+     do { RING_NEXT((ep), link) = (ep); \
+          RING_PREV((ep), link) = (ep); } while (0)
+ #define RING_SPLICE_BEFORE(lep, ep1, epN, link) \
+     do { RING_NEXT((epN), link) = (lep); \
+          RING_PREV((ep1), link) = RING_PREV((lep), link); \
+          RING_NEXT(RING_PREV((lep), link), link) = (ep1); \
+          RING_PREV((lep), link) = (epN); } while (0)
+ #define RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
+     RING_SPLICE_BEFORE(RING_SENTINEL((hp), elem, link), (ep1), (epN), link)
+ #define RING_INSERT_TAIL(hp, nep, elem, link) \
+     RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
+ #define RING_FOREACH(ep, hp, elem, link) \
+     for ((ep)  = RING_FIRST((hp)); \
+          (ep) != RING_SENTINEL((hp), elem, link); \
+          (ep)  = RING_NEXT((ep), link))
+ 
+ /* test suite test log */
+ struct tstl_st;
+ typedef struct tstl_st tstl_t;
+ struct tstl_st {
+     RING_ENTRY(tstl_t) next;
+     char              *text;
+     const char        *file;
+     int                line;
+ };
+ 
+ /* test suite test check */
+ struct tstc_st;
+ typedef struct tstc_st tstc_t;
+ struct tstc_st {
+     RING_ENTRY(tstc_t) next;
+     char              *title;
+     int                failed;
+     const char        *file;
+     int                line;
+     RING_HEAD(tstl_t)  logs;
+ };
+ 
+ /* test suite test */
+ struct ts_test_st {
+     RING_ENTRY(ts_test_t)  next;
+     char              *title;
+     ts_test_cb_t         func;
+     const char        *file;
+     int                line;
+     RING_HEAD(tstc_t)  checks;
+ };
+ 
+ /* test suite */
+ struct ts_suite_st {
+     char              *title;
+     RING_HEAD(ts_test_t)   tests;
+ };
+ 
+ /* minimal output-independent vprintf(3) variant which supports %{c,s,d,%} only */
+ static int ts_suite_mvxprintf(char *buffer, size_t bufsize, const char *format, va_list ap)
+ {
+     /* sufficient integer buffer: <available-bits> x log_10(2) + safety */
+     char ibuf[((sizeof(int)*8)/3)+10]; 
+     char *cp;
+     char c;
+     int d;
+     int n;
+     int bytes;
+ 
+     if (format == NULL || ap == NULL)
+         return -1;
+     bytes = 0;
+     while (*format != '\0') {
+         if (*format == '%') {
+             c = *(format+1);
+             if (c == '%') {
+                 /* expand "%%" */
+                 cp = &c;
+                 n = sizeof(char);
+             }
+             else if (c == 'c') {
+                 /* expand "%c" */
+                 c = (char)va_arg(ap, int);
+                 cp = &c;
+                 n = sizeof(char);
+             }
+             else if (c == 's') {
+                 /* expand "%s" */
+                 if ((cp = (char *)va_arg(ap, char *)) == NULL)
+                     cp = "(null)";
+                 n = strlen(cp);
+             }
+             else if (c == 'd') {
+                 /* expand "%d" */
+                 d = (int)va_arg(ap, int);
+ #ifdef HAVE_SNPRINTF
+                 snprintf(ibuf, sizeof(ibuf), "%d", d); /* explicitly secure */
+ #else
+                 sprintf(ibuf, "%d", d);                /* implicitly secure */
+ #endif
+                 cp = ibuf;
+                 n = strlen(cp);
+             }
+             else {
+                 /* any other "%X" */
+                 cp = (char *)format;
+                 n  = 2;
+             }
+             format += 2;
+         }
+         else {
+             /* plain text */
+             cp = (char *)format;
+             if ((format = strchr(cp, '%')) == NULL)
+                 format = strchr(cp, '\0');
+             n = format - cp;
+         }
+         /* perform output operation */
+         if (buffer != NULL) {
+             if (n > bufsize)
+                 return -1;
+             memcpy(buffer, cp, n);
+             buffer  += n;
+             bufsize -= n;
+         }
+         bytes += n;
+     }
+     /* nul-terminate output */
+     if (buffer != NULL) {
+         if (bufsize == 0)
+             return -1;
+         *buffer = '\0';
+     }
+     return bytes;
+ }
+ 
+ /* minimal vasprintf(3) variant which supports %{c,s,d} only */
+ static char *ts_suite_mvasprintf(const char *format, va_list ap)
+ {
+     char *buffer;
+     int n;
+     va_list ap2;
+ 
+     if (format == NULL || ap == NULL)
+         return NULL;
+     ap2 = ap;
+     if ((n = ts_suite_mvxprintf(NULL, 0, format, ap)) == -1)
+         return NULL;
+     if ((buffer = (char *)malloc(n+1)) == NULL)
+         return NULL;
+     ts_suite_mvxprintf(buffer, n+1, format, ap2);
+     return buffer;
+ }
+ 
+ /* minimal asprintf(3) variant which supports %{c,s,d} only */
+ static char *ts_suite_masprintf(const char *format, ...)
+ {
+     va_list ap;
+     char *cp;
+ 
+     va_start(ap, format);
+     cp = ts_suite_mvasprintf(format, ap);
+     va_end(ap);
+     return cp;
+ }
+ 
+ /* create test suite */
+ ts_suite_t *ts_suite_new(const char *fmt, ...)
+ {
+     ts_suite_t *ts;
+     va_list ap;
+ 
+     if ((ts = (ts_suite_t *)malloc(sizeof(ts_suite_t))) == NULL)
+         return NULL;
+     va_start(ap, fmt);
+     ts->title = ts_suite_mvasprintf(fmt, ap);
+     RING_INIT(&ts->tests, ts_test_t, next);
+     va_end(ap);
+     return ts;
+ }
+ 
+ /* add test case to test suite */
+ void ts_suite_test(ts_suite_t *ts, ts_test_cb_t func, const char *fmt, ...)
+ {
+     ts_test_t *tst;
+     va_list ap;
+ 
+     if (ts == NULL || func == NULL || fmt == NULL)
+         return;
+     if ((tst = (ts_test_t *)malloc(sizeof(ts_test_t))) == NULL)
+         return;
+     RING_ELEM_INIT(tst, next);
+     va_start(ap, fmt);
+     tst->title = ts_suite_mvasprintf(fmt, ap);
+     va_end(ap);
+     tst->func = func;
+     tst->file = NULL;
+     tst->line = 0;
+     RING_INIT(&tst->checks, tstc_t, next);
+     RING_INSERT_TAIL(&ts->tests, tst, ts_test_t, next);
+     return;
+ }
+ 
+ /* run test suite */
+ int ts_suite_run(ts_suite_t *ts)
+ {
+     ts_test_t *tst;
+     tstc_t *tstc;
+     tstl_t *tstl;
+     int total_tests, total_tests_suite_failed;
+     int total_checks, total_checks_failed;
+     int test_checks, test_checks_failed;
+     const char *file;
+     int line;
+     char *cp;
+ 
+     if (ts == NULL)
+         return 0;
+ 
+     /* init total counters */
+     total_tests         = 0;
+     total_tests_suite_failed  = 0;
+     total_checks        = 0;
+     total_checks_failed = 0;
+ 
+     fprintf(stdout, "\n");
+     fprintf(stdout, " Test Suite: %s\n", ts->title);
+     fprintf(stdout, " __________________________________________________________________\n");
+     fprintf(stdout, "\n");
+     fflush(stdout);
+ 
+     /* iterate through all test cases */
+     RING_FOREACH(tst, &ts->tests, ts_test_t, next) {
+         cp = ts_suite_masprintf(" Test: %s ........................................"
+                                 "........................................", tst->title);
+         cp[60] = '\0';
+         fprintf(stdout, "%s", cp);
+         free(cp);
+         fflush(stdout);
+ 
+         /* init test case counters */
+         test_checks        = 0;
+         test_checks_failed = 0;
+ 
+         /* run the test case function */
+         tst->func(tst);
+ 
+         /* iterate through all performed checks to determine status */
+         RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
+             test_checks++;
+             if (tstc->failed)
+                 test_checks_failed++;
+         }
+ 
+         if (test_checks_failed > 0) {
+             /* some checks failed, so do detailed reporting of test case */
+             fprintf(stdout, " FAILED\n");
+             fprintf(stdout, "       Ops, %d/%d checks failed! Detailed report follows:\n",
+                     test_checks_failed, test_checks);
+             RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
+                 file = (tstc->file != NULL ? tstc->file : tst->file);
+                 line = (tstc->line != 0    ? tstc->line : tst->line);
+                 if (file != NULL)
+                     fprintf(stdout, "       Check: %s [%s:%d]\n", tstc->title, file, line);
+                 else
+                     fprintf(stdout, "       Check: %s\n", tstc->title);
+                 RING_FOREACH(tstl, &tstc->logs, tstl_t, next) {
+                     file = (tstl->file != NULL ? tstl->file : file);
+                     line = (tstl->line != 0    ? tstl->line : line);
+                     if (file != NULL)
+                         fprintf(stdout, "              Log: %s [%s:%d]\n", tstl->text, file, line);
+                     else
+                         fprintf(stdout, "              Log: %s\n", tstl->text);
+                 }
+             }
+         }
+         else {
+             /* test case ran successfully */
+             fprintf(stdout, ".... OK\n");
+         }
+         fflush(stdout);
+ 
+         /* accumulate counters */
+         total_checks += test_checks;
+         total_tests++;
+         if (test_checks_failed > 0) {
+             total_checks_failed += test_checks_failed;
+             total_tests_suite_failed++;
+         }
+     }
+ 
+     /* print test suite summary */
+     fprintf(stdout, " __________________________________________________________________\n");
+     fprintf(stdout, "\n");
+     fprintf(stdout, " Test Summary: %d tests (%d ok, %d failed), %d checks (%d ok, %d failed)\n", 
+             total_tests, (total_tests - total_tests_suite_failed), total_tests_suite_failed, 
+             total_checks, (total_checks - total_checks_failed), total_checks_failed); 
+     if (total_tests_suite_failed > 0)
+         fprintf(stdout, " Test Suite: FAILED\n");
+     else
+         fprintf(stdout, " Test Suite: OK\n");
+     fprintf(stdout, "\n");
+     fflush(stdout);
+ 
+     return total_checks_failed;
+ }
+ 
+ /* destroy test suite */
+ void ts_suite_free(ts_suite_t *ts)
+ {
+     ts_test_t *tst;
+     tstc_t *tstc;
+     tstl_t *tstl;
+ 
+     if (ts == NULL)
+         return;
+     RING_FOREACH(tst, &ts->tests, ts_test_t, next) {
+         RING_FOREACH(tstc, &tst->checks, tstc_t, next) {
+             RING_FOREACH(tstl, &tstc->logs, tstl_t, next) {
+                 free(tstl->text);
+             }
+             free(tstc->title);
+             free(tstc);
+         }
+         free(tst->title);
+         free(tst);
+     }
+     free(ts->title);
+     free(ts);
+     return;
+ }
+ 
+ /* annotate test case with file name and line number */
+ ts_test_t *ts_test_ctx(ts_test_t *tst, const char *file, int line)
+ {
+     if (tst != NULL && file != NULL) {
+         tst->file = file;
+         tst->line = line;
+     }
+     return tst;
+ }
+ 
+ /* annotate test case with check */
+ void ts_test_check(ts_test_t *tst, const char *fmt, ...)
+ {
+     tstc_t *tstc;
+     va_list ap;
+ 
+     if (tst == NULL || fmt == NULL)
+         return;
+     if ((tstc = (tstc_t *)malloc(sizeof(tstc_t))) == NULL)
+         return;
+     va_start(ap, fmt);
+     RING_ELEM_INIT(tstc, next);
+     tstc->title = ts_suite_mvasprintf(fmt, ap);
+     tstc->failed = 0;
+     tstc->file = tst->file;
+     tstc->line = tst->line;
+     RING_INIT(&tstc->logs, tstl_t, next);
+     RING_INSERT_TAIL(&tst->checks, tstc, tstc_t, next);
+     va_end(ap);
+     return;
+ }
+ 
+ /* annotate test case with log message and failure */
+ void ts_test_fail(ts_test_t *tst, const char *fmt, ...)
+ {
+     tstc_t *tstc;
+     tstl_t *tstl;
+     va_list ap;
+ 
+     if (tst == NULL || fmt == NULL)
+         return;
+     if ((tstl = (tstl_t *)malloc(sizeof(tstl_t))) == NULL)
+         return;
+     va_start(ap, fmt);
+     tstl->text = ts_suite_mvasprintf(fmt, ap);
+     tstl->file = tst->file;
+     tstl->line = tst->line;
+     RING_ELEM_INIT(tstl, next);
+     tstc = RING_LAST(&tst->checks);
+     RING_INSERT_TAIL(&tstc->logs, tstl, tstl_t, next);
+     tstc->failed = 1;
+     va_end(ap);
+     return;
+ }
+ 
+ /* annotate test case with log message only */
+ void ts_test_log(ts_test_t *tst, const char *fmt, ...)
+ {
+     tstc_t *tstc;
+     tstl_t *tstl;
+     va_list ap;
+ 
+     if (tst == NULL || fmt == NULL)
+         return;
+     if ((tstl = (tstl_t *)malloc(sizeof(tstl_t))) == NULL)
+         return;
+     va_start(ap, fmt);
+     tstl->text = ts_suite_mvasprintf(fmt, ap);
+     tstl->file = tst->file;
+     tstl->line = tst->line;
+     RING_ELEM_INIT(tstl, next);
+     tstc = RING_LAST(&tst->checks);
+     RING_INSERT_TAIL(&tstc->logs, tstl, tstl_t, next);
+     va_end(ap);
+     return;
+ }
+ 


ossp-pkg/str/ts.h -> 1.1

*** /dev/null    Tue Mar 11 06:05:13 2025
--- -    Tue Mar 11 06:05:32 2025
***************
*** 0 ****
--- 1,64 ----
+ /*
+ **  TS - OSSP Test Suite Library
+ **  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP TS, a small test suite library which
+ **  can be found at http://www.ossp.org/pkg/ts/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  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.
+ **
+ **  ts.h: test suite library API
+ */
+ 
+ #ifndef _TS_H_
+ #define _TS_H_
+ 
+ /* test suite object type */
+ struct ts_suite_st;
+ typedef struct ts_suite_st ts_suite_t;
+ 
+ /* test object type */
+ struct ts_test_st;
+ typedef struct ts_test_st ts_test_t;
+ 
+ /* test callback function type */
+ typedef void (*ts_test_cb_t)(ts_test_t *);
+ 
+ /* test suite operations */
+ ts_suite_t *ts_suite_new  (const char *fmt, ...);
+ void        ts_suite_test (ts_suite_t *s, ts_test_cb_t func, const char *fmt, ...);
+ int         ts_suite_run  (ts_suite_t *s);
+ void        ts_suite_free (ts_suite_t *s);
+ 
+ /* test operations */
+ ts_test_t  *ts_test_ctx   (ts_test_t *t, const char *file, int line);
+ void        ts_test_check (ts_test_t *t, const char *fmt, ...);
+ void        ts_test_fail  (ts_test_t *t, const char *fmt, ...);
+ void        ts_test_log   (ts_test_t *t, const char *fmt, ...);
+ 
+ /* test suite short-cut macros */
+ #define TS_TEST(name) \
+     static void name(ts_test_t *_t)
+ #define TS_CTX \
+     ts_test_ctx(_t, __FILE__, __LINE__)
+ 
+ #endif /* _TS_H_ */
+ 

CVSTrac 2.0.1