Added log methods, added mod test
[fw/sdcc] / support / regression / fwk / lib / testfwk.c
1 /** Test framework support functions.
2  */
3 #include <testfwk.h>
4 #include <stdarg.h>
5
6 /** Define this if the port's div or mod functions are broken.
7     A slow loop based method will be substituded.
8 */
9 #define BROKEN_DIV_MOD          1
10
11 void _putchar(char c);
12
13 #if BROKEN_DIV_MOD
14 int __div(int num, int denom)
15 {
16     int q = 0;
17     while (num >= denom) {
18         q++;
19         num -= denom;
20     }
21     return q;
22 }
23
24 int __mod(int num, int denom)
25 {
26     while (num >= denom) {
27         num -= denom;
28     }
29     return num;
30 }
31 #else
32 int __div(int num, int denom)
33 {
34     return num/denom;
35 }
36
37 int __mod(int num, int denom)
38 {
39     return num%denom;
40 }
41 #endif
42
43 static void _printn(int n) 
44 {
45     int rem;
46
47     if (n < 0) {
48         _putchar('-');
49         n = -n;
50     }
51
52     rem = __mod(n, 10);
53     if (rem != n) {
54         _printn(__div(n, 10));
55     }
56     _putchar('0' + rem);
57 }
58
59 void __printf(const char *szFormat, ...)
60 {
61     va_list ap;
62     va_start(ap, szFormat);
63
64     while (*szFormat) {
65         if (*szFormat == '%') {
66             switch (*++szFormat) {
67             case 's': {
68                 const char *sz = va_arg(ap, const char *);
69                 while (*sz) {
70                     _putchar(*sz++);
71                 }
72                 break;
73             }
74             case 'u': {
75                 int i = va_arg(ap, int);
76                 _printn(i);
77                 break;
78             }
79             case '%':
80                 _putchar('%');
81                 break;
82             default:
83                 break;
84             }
85         }
86         else {
87             _putchar(*szFormat);
88         }
89         szFormat++;
90     }
91     va_end(ap);
92 }
93
94 int __numTests;
95 int __numFailures;
96
97 void 
98 __fail(const char *szMsg, const char *szCond, const char *szFile, int line)
99 {
100     __printf("--- FAIL: \"%s\" on %s at %s:%u\n", szMsg, szCond, szFile, line);
101     __numFailures++;
102 }
103
104 int 
105 main(void)
106 {
107     TESTFUN **cases;
108     int numCases = 0;
109
110     __printf("--- Running: %s\n", getSuiteName());
111
112     cases = (TESTFUN **)suite();
113
114     while (*cases) {
115         __printf("Running %u\n", numCases);
116         (*cases)();
117         cases++;
118         numCases++;
119     }
120     
121     __printf("--- Summary: %u/%u/%u: %u failed of %u tests in %u cases.\n", 
122            __numFailures, __numTests, numCases,
123            __numFailures, __numTests, numCases
124            );
125
126     return __numFailures;
127 }