8c162c8877ea971f08e2a787b5bb08b3ded72cb7
[fw/sdcc] / support / regression / fwk / lib / testfwk.c
1 /** Test framework support functions.
2  */
3 #include <testfwk.h>
4 #ifndef NO_VARARGS
5 #include <stdarg.h>
6 #endif
7
8 #ifdef SDCC_ds390
9 #include <tinibios.h> /* main() must see the ISR declarations */
10 #endif
11
12 #ifdef SDCC_mcs51
13 /* until changed, isr's must have a prototype in the module containing main */
14 void T2_isr (void) interrupt 5;
15 #endif
16
17 /** Define this if the port's div or mod functions are broken.
18     A slow loop based method will be substituded.
19 */
20 //#define BROKEN_DIV_MOD                1
21
22 extern void _putchar(char c);
23 extern void _initEmu(void);
24 extern void _exitEmu(void);
25
26 int __numTests = 0;
27 static int __numFailures = 0;
28
29 #if BROKEN_DIV_MOD
30 static int
31 __div(int num, int denom)
32 {
33     int q = 0;
34     while (num >= denom) {
35         q++;
36         num -= denom;
37     }
38     return q;
39 }
40
41 static int
42 __mod(int num, int denom)
43 {
44     while (num >= denom) {
45         num -= denom;
46     }
47     return num;
48 }
49 #else
50 #define __div(num, denom) ((num) / (denom))
51 #define __mod(num, denom) ((num) % (denom))
52 #endif
53
54 void
55 __prints(const char *s)
56 {
57   char c;
58
59   while ('\0' != (c = *s)) {
60     _putchar(c);
61     ++s;
62   }
63 }
64
65 void
66 __printn(int n)
67 {
68   if (0 == n) {
69     _putchar('0');
70   }
71   else {
72     static char buf[6];
73     char *p = &buf[sizeof(buf) - 1];
74     char neg = 0;
75
76     buf[sizeof(buf) - 1] = '\0';
77
78     if (0 > n) {
79       n = -n;
80       neg = 1;
81     }
82   
83     while (0 != n) {
84       *--p = '0' + __mod(n, 10);
85       n = __div(n, 10);
86     }
87
88     if (neg)
89       _putchar('-');
90
91     __prints(p);
92   }
93 }
94
95 #ifndef NO_VARARGS
96 void
97 __printf(const char *szFormat, ...)
98 {
99   va_list ap;
100   va_start(ap, szFormat);
101
102   while (*szFormat) {
103     if (*szFormat == '%') {
104       switch (*++szFormat) {
105       case 's': {
106         char *sz = va_arg(ap, char *);
107         __prints(sz);
108         break;
109       }
110       case 'u': {
111         int i = va_arg(ap, int);
112         __printn(i);
113         break;
114       }
115       case '%':
116         _putchar('%');
117         break;
118       default:
119         break;
120       }
121     }
122     else {
123       _putchar(*szFormat);
124     }
125     szFormat++;
126   }
127   va_end(ap);
128 }
129
130 void
131 __fail(const char *szMsg, const char *szCond, const char *szFile, int line)
132 {
133   __printf("--- FAIL: \"%s\" on %s at %s:%u\n", szMsg, szCond, szFile, line);
134   __numFailures++;
135 }
136
137 int
138 main(void)
139 {
140   _initEmu();
141
142   __printf("--- Running: %s\n", __getSuiteName());
143
144   __runSuite();
145
146   __printf("--- Summary: %u/%u/%u: %u failed of %u tests in %u cases.\n",
147      __numFailures, __numTests, __numCases,
148      __numFailures, __numTests, __numCases
149      );
150
151   _exitEmu();
152
153   return 0;
154 }
155 #else
156 void
157 __fail(const char *szMsg, const char *szCond, const char *szFile, int line)
158 {
159   __prints("--- FAIL: \"");
160   __prints(szMsg);
161   __prints("\" on ");
162   __prints(szCond);
163   __prints(" at ");
164   __prints(szFile);
165   _putchar(':');
166   __printn(line);
167   _putchar('\n');
168
169   __numFailures++;
170 }
171
172 int
173 main(void)
174 {
175   _initEmu();
176
177   __prints("--- Running: ");
178   __prints(__getSuiteName());
179   _putchar('\n');
180
181   __runSuite();
182
183   __prints("--- Summary: ");
184   __printn(__numFailures);
185   _putchar('/');
186   __printn(__numTests);
187   _putchar('/');
188   __printn(__numCases);
189   __prints(": ");
190   __printn(__numFailures);
191   __prints(" failed of ");
192   __printn(__numTests);
193   __prints(" tests in ");
194   __printn(__numCases);
195   __prints(" cases.\n");
196
197   _exitEmu();
198
199   return 0;
200 }
201 #endif