chiark / gitweb /
65a3ab02c0ee4f20cd62e8c11f068f02c52c575d
[disorder] / libtests / test.c
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2005, 2007, 2008 Richard Kettlewell
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 /** @file lib/test.c @brief Library tests */
19
20 #include "test.h"
21 #include "version.h"
22 #include <getopt.h>
23
24 long long tests, errors;
25 int fail_first;
26 int verbose;
27 int skipped;
28
29 void count_error(void) {
30   ++errors;
31   if(fail_first)
32     abort();
33 }
34
35 const char *format(const char *s) {
36   struct dynstr d;
37   int c;
38   char buf[10];
39
40   dynstr_init(&d);
41   while((c = (unsigned char)*s++)) {
42     if(c >= ' ' && c <= '~')
43       dynstr_append(&d, c);
44     else {
45       sprintf(buf, "\\x%02X", (unsigned)c);
46       dynstr_append_string(&d, buf);
47     }
48   }
49   dynstr_terminate(&d);
50   return d.vec;
51 }
52
53 const char *format_utf32(const uint32_t *s) {
54   struct dynstr d;
55   uint32_t c;
56   char buf[64];
57
58   dynstr_init(&d);
59   while((c = *s++)) {
60     sprintf(buf, " %04lX", (long)c);
61     dynstr_append_string(&d, buf);
62   }
63   dynstr_terminate(&d);
64   return d.vec;
65 }
66
67 uint32_t *ucs4parse(const char *s) {
68   struct dynstr_ucs4 d;
69   char *e;
70
71   dynstr_ucs4_init(&d);
72   while(*s) {
73     errno = 0;
74     dynstr_ucs4_append(&d, strtoul(s, &e, 0));
75     if(errno) fatal(errno, "strtoul (%s)", s);
76     s = e;
77   }
78   dynstr_ucs4_terminate(&d);
79   return d.vec;
80 }
81
82 const char *do_printf(const char *fmt, ...) {
83   va_list ap;
84   char *s;
85   int rc;
86
87   va_start(ap, fmt);
88   rc = byte_vasprintf(&s, fmt, ap);
89   va_end(ap);
90   if(rc < 0)
91     return 0;
92   return s;
93 }
94
95 jmp_buf fatal_env;
96
97 void test_exitfn(int rc) {
98   assert(rc != 0);
99   longjmp(fatal_env, rc);
100 }
101
102 static const struct option options[] = {
103   { "verbose", no_argument, 0, 'v' },
104   { "fail-first", no_argument, 0, 'F' },
105   { "help", no_argument, 0, 'h' },
106   { "version", no_argument, 0, 'V' },
107 };
108
109 /* display usage message and terminate */
110 static void help(void) {
111   xprintf("Usage:\n"
112           "  %s [OPTIONS]\n"
113           "Options:\n"
114           "  --help, -h               Display usage message\n"
115           "  --version, -V            Display version number\n"
116           "  --verbose, -v            Verbose output\n"
117           "  --fail-first, -F         Stop on first failure\n",
118           progname);
119   xfclose(stdout);
120   exit(0);
121 }
122
123 void test_init(int argc, char **argv) {
124   int n;
125
126   set_progname(argv);
127   mem_init();
128   while((n = getopt_long(argc, argv, "vFhV", options, 0)) >= 0) {
129     switch(n) {
130     case 'v': verbose = 1; break;
131     case 'F': fail_first = 1; break;
132     case 'h': help();
133     case 'V': version(progname);
134     default: exit(1);
135     }
136   }
137   if(getenv("FAIL_FIRST"))
138     fail_first = 1;
139 }
140
141
142 /*
143 Local Variables:
144 c-basic-offset:2
145 comment-column:40
146 fill-column:79
147 indent-tabs-mode:nil
148 End:
149 */