OSSP CVS Repository

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

Check-in Number: 1143
Date: 2001-Oct-10 17:01:56 (local)
2001-Oct-10 15:01:56 (UTC)
User:rse
Branch:
Comment: Implemented a new sub-library OSSP TS (Test Suite) and use this new beast for the first cut of an OSSP SA test suite. The TS library produces nice test suite reports like this one (for a failed test suite):

| Test Suite: OSSP SA (Socket Abstraction Library) | __________________________________________________________________ | Test: socket address abstraction .............................. OK | Test: socket abstraction .................................. FAILED | Ops, 1/1 checks failed! Detailed report follows: | Check: testerliX [sa_test.c:43] | Log: sorry [sa_test.c:44] | __________________________________________________________________ | Test Summary: 2 tests (1 ok, 1 failed), 5 checks (4 ok, 1 failed) | Test Suite: FAILED (Test Suite Failed)

Or this one (for a successfull test suite):

| Test Suite: OSSP SA (Socket Abstraction Library) | __________________________________________________________________ | Test: socket address abstraction .............................. OK | Test: socket abstraction ...................................... OK | __________________________________________________________________ | Test Summary: 2 tests (2 ok, 0 failed), 5 checks (5 ok, 0 failed) | Test Suite: OK (Test Suite Successfully)

Tickets:
Inspections:
Files:
ossp-pkg/sa/Makefile.in      1.7 -> 1.8     2 inserted, 2 deleted
ossp-pkg/sa/sa_test.c      1.7 -> 1.8     36 inserted, 76 deleted
ossp-pkg/sa/ts.c      added-> 1.1
ossp-pkg/sa/ts.h      added-> 1.1

ossp-pkg/sa/Makefile.in 1.7 -> 1.8

--- Makefile.in  2001/10/08 15:01:26     1.7
+++ Makefile.in  2001/10/10 15:01:56     1.8
@@ -51,7 +51,7 @@
 LIB_OBJS    = sa.lo
 
 TST_NAME    = sa_test
-TST_OBJS    = sa_test.o
+TST_OBJS    = sa_test.o ts.o
 
 .SUFFIXES:
 .SUFFIXES: .c .o .lo
@@ -59,7 +59,7 @@
 all: $(LIB_NAME) $(TST_NAME)
 
 .c.o:
-        @$(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+        $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
 
 .c.lo:
         @$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $<


ossp-pkg/sa/sa_test.c 1.7 -> 1.8

--- sa_test.c    2001/10/08 15:08:46     1.7
+++ sa_test.c    2001/10/10 15:01:56     1.8
@@ -35,90 +35,50 @@
 #include <sys/utsname.h>
 #include <unistd.h>
 
+#include "ts.h"
 #include "sa.h"
 
-#define DIE_MARK \
-    __FILE__, __LINE__
-
-static void die(const char *file, int line, char *fmt, ...)
+TST_FUNC(test_sa)
 {
-    va_list ap;
+}
 
-    va_start(ap, fmt);
-    fprintf(stderr, "%s:%d:ERROR: ", file, line);
-    vfprintf(stderr, fmt, ap);
-    fprintf(stderr, "\n");
-    va_end(ap);
-    exit(1);
+TST_FUNC(test_saa)
+{
+    sa_addr_t *saa;
+    sa_rc_t rv;
+    char *cp1;
+    char *cp2;
+
+    tst_check(TST, "sa_addr_create");
+    if ((rv = sa_addr_create(&saa)) != SA_OK)
+        tst_fail(tst, "rv=%d (%s)", rv, sa_error(rv));
+    
+    tst_check(TST, "sa_addr_u2a");
+    cp1 = "inet://127.0.0.1:12345";
+    if ((rv = sa_addr_u2a(saa, cp1)) != SA_OK)
+        tst_fail(TST, "rv=%d (%s)", rv, sa_error(rv));
+
+    tst_check(TST, "sa_addr_a2u");
+    if ((rv = sa_addr_a2u(saa, &cp2)) != SA_OK)
+        tst_fail(TST, "rv=%d (%s)", rv, sa_error(rv));
+    if (strcmp(cp1, cp2) != 0)
+        tst_fail(TST, "import \"%s\" <-> export \"%s\"", cp1, cp2);
+
+    tst_check(tst, "sa_addr_destroy");
+    if ((rv = sa_addr_destroy(saa)) != SA_OK)
+        tst_fail(TST, "rv=%d (%s)", rv, sa_error(rv));
 }
 
-int main(int argc, char *argv[]) 
+int main(int argc, char *argv[])
 {
-    sa_addr_t *ra;
-    sa_addr_t *la;
-    sa_t *sa;
-    char caBuf[1024];
-    int nBuf;
-    char caTime[15+1];
-    time_t now;
-    struct tm *tm;
-    struct utsname uts;
-    char *cp;
-    char caTag[32+1];
-    char *cpHost;
+    ts_t *ts;
     int n;
 
-    /* create remote address */
-    if (sa_addr_create(&ra) != SA_OK)
-        die(DIE_MARK, "sa_addr_create (ra)");
-    if (sa_addr_u2a(ra, "inet://141.1.129.1:514") != SA_OK)
-        die(DIE_MARK, "sa_addr_u2a (ra)");
-
-    /* create local address */
-    if (sa_addr_create(&la) != SA_OK)
-        die(DIE_MARK, "sa_addr_create (la)");
-    if (sa_addr_u2a(la, "inet://0.0.0.0:0") != SA_OK)
-        die(DIE_MARK, "sa_addr_u2a (la)");
-
-    /* create datagram socket */
-    if (sa_create(&sa) != SA_OK)
-        die(DIE_MARK, "sa_create");
-    if (sa_type(sa, SA_TYPE_DATAGRAM) != SA_OK)
-        die(DIE_MARK, "sa_type");
-
-    /* bind socket to local address */
-    if (sa_bind(sa, la) != SA_OK)
-        die(DIE_MARK, "sa_bind");
-
-    /* RFC3164: The BSD syslog Protocol; C. Lonvick; August 2001. */
-    now = time(NULL);
-    tm = localtime(&now);
-    strftime(caTime, sizeof(caTime), "%b %e %H:%M:%S", tm);
-    if (uname(&uts) == -1)
-        die(DIE_MARK, "uname");
-    cpHost = strdup(uts.nodename);
-    if ((cp = strchr(cpHost, '.')) != NULL)
-        *cp = '\0';
-    strcpy(caTag, "progname[12]: ");
-    if (strlen(caTag) > 32)
-        caTag[32] = '\0';
-    sprintf(caBuf, "<16>%s %s %s[%ld]: %s", caTime, cpHost, 
-            argv[0], (long)getpid(), "test for Internet Datagram socket");
-    fprintf(stderr, "Send to syslog: \"%s\"\n", caBuf);
-
-    /* send message to syslogd(8) */
-    nBuf = strlen(caBuf);
-    if (sa_send(sa, caBuf, nBuf, (size_t *)&n, ra) != SA_OK)
-        die(DIE_MARK, "sa_writeto");
-
-    /* destroy socket and address objects */
-    if (sa_destroy(sa) != SA_OK)
-        die(DIE_MARK, "sa_destroy");
-    if (sa_addr_destroy(la) != SA_OK)
-        die(DIE_MARK, "sa_addr_destroy (la)");
-    if (sa_addr_destroy(ra) != SA_OK)
-        die(DIE_MARK, "sa_addr_destroy (ra)");
-
-    return 0;
+    ts = ts_new("OSSP SA (Socket Abstraction Library)");
+    ts_test(ts, test_saa, "socket address abstraction");
+    ts_test(ts, test_sa, "socket abstraction");
+    n = ts_run(ts);
+    ts_free(ts);
+    return n;
 }
 


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

*** /dev/null    Sat Nov 23 01:17:01 2024
--- -    Sat Nov 23 01:17:02 2024
***************
*** 0 ****
--- 1,463 ----
+ /*
+ **  TS - OSSP Test Suite Library
+ **  Copyright (c) 2001 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2001 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP TS, a 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 "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 tst_st {
+     RING_ENTRY(tst_t)  next;
+     char              *title;
+     tst_func_t         func;
+     const char        *file;
+     int                line;
+     RING_HEAD(tstc_t)  checks;
+ };
+ 
+ /* test suite */
+ struct ts_st {
+     char              *title;
+     RING_HEAD(tst_t)   tests;
+ };
+ 
+ /* minimal output-independent vprintf(3) variant which supports %{c,s,d,%} only */
+ static int ts_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_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_mvxprintf(NULL, 0, format, ap)) == -1)
+         return NULL;
+     if ((buffer = (char *)malloc(n+1)) == NULL)
+         return NULL;
+     ts_mvxprintf(buffer, n+1, format, ap2);
+     return buffer;
+ }
+ 
+ /* minimal asprintf(3) variant which supports %{c,s,d} only */
+ static char *ts_masprintf(const char *format, ...)
+ {
+     va_list ap;
+     char *cp;
+ 
+     va_start(ap, format);
+     cp = ts_mvasprintf(format, ap);
+     va_end(ap);
+     return cp;
+ }
+ 
+ /* create test suite */
+ ts_t *ts_new(const char *fmt, ...)
+ {
+     ts_t *ts;
+     va_list ap;
+ 
+     if ((ts = (ts_t *)malloc(sizeof(ts_t))) == NULL)
+         return NULL;
+     va_start(ap, fmt);
+     ts->title = ts_mvasprintf(fmt, ap);
+     RING_INIT(&ts->tests, tst_t, next);
+     va_end(ap);
+     return ts;
+ }
+ 
+ /* add test case to test suite */
+ void ts_test(ts_t *ts, tst_func_t func, const char *fmt, ...)
+ {
+     tst_t *tst;
+     va_list ap;
+ 
+     if (ts == NULL || func == NULL || fmt == NULL)
+         return;
+     if ((tst = (tst_t *)malloc(sizeof(tst_t))) == NULL)
+         return;
+     RING_ELEM_INIT(tst, next);
+     va_start(ap, fmt);
+     tst->title = ts_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, tst_t, next);
+     return;
+ }
+ 
+ /* run test suite */
+ int ts_run(ts_t *ts)
+ {
+     tst_t *tst;
+     tstc_t *tstc;
+     tstl_t *tstl;
+     int total_tests, total_tests_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_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, tst_t, next) {
+         cp = ts_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: %sX [%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_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_failed), total_tests_failed, 
+             total_checks, (total_checks - total_checks_failed), total_checks_failed); 
+     if (total_tests_failed > 0)
+         fprintf(stdout, " Test Suite: FAILED (Test Suite Failed)\n");
+     else
+         fprintf(stdout, " Test Suite: OK (Test Suite Passed Successfully)\n");
+     fprintf(stdout, "\n");
+     fflush(stdout);
+ 
+     return total_checks_failed;
+ }
+ 
+ /* destroy test suite */
+ void ts_free(ts_t *ts)
+ {
+     tst_t *tst;
+     tstc_t *tstc;
+     tstl_t *tstl;
+ 
+     if (ts == NULL)
+         return;
+     RING_FOREACH(tst, &ts->tests, tst_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(tst->title);
+     free(ts);
+     return;
+ }
+ 
+ /* annotate test case with file name and line number */
+ tst_t *tst_ctx(tst_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 tst_check(tst_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_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 tst_fail(tst_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_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 tst_log(tst_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_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/sa/ts.h -> 1.1

*** /dev/null    Sat Nov 23 01:17:01 2024
--- -    Sat Nov 23 01:17:02 2024
***************
*** 0 ****
--- 1,62 ----
+ /*
+ **  TS - OSSP Test Suite Library
+ **  Copyright (c) 2001 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2001 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2001 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP TS, a 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_
+ 
+ struct ts_st;
+ typedef struct ts_st ts_t;
+ 
+ struct tst_st;
+ typedef struct tst_st tst_t;
+ 
+ typedef void (*tst_func_t)(tst_t *);
+ 
+ #define TST_FUNC(name) \
+     static void name(tst_t *tst)
+ 
+ #define TST_CTX(tst) \
+     tst_ctx(tst, __FILE__, __LINE__)
+ 
+ #define TST \
+     TST_CTX(tst)
+ 
+ ts_t   *ts_new    (const char *fmt, ...);
+ void    ts_test   (ts_t *ts, tst_func_t func, const char *fmt, ...);
+ int     ts_run    (ts_t *ts);
+ void    ts_free   (ts_t *ts);
+ 
+ tst_t  *tst_ctx   (tst_t *tst, const char *file, int line);
+ void    tst_check (tst_t *tst, const char *fmt, ...);
+ void    tst_fail  (tst_t *tst, const char *fmt, ...);
+ void    tst_log   (tst_t *tst, const char *fmt, ...);
+ 
+ #endif /* _TS_H_ */
+ 

CVSTrac 2.0.1