]>
Commit | Line | Data |
---|---|---|
a61fdf0a A |
1 | #include <string> |
2 | #include <sstream> | |
3 | #include <iostream> | |
4 | ||
5 | using namespace std; | |
6 | ||
7 | #define NELEMENTS(a) (sizeof (a)/sizeof *(a)) | |
8 | ||
9 | #define NO_RESULT (-1) | |
10 | #define PASS 1 | |
11 | #define FAIL 0 | |
12 | ||
13 | #define DBG bhole | |
14 | ||
15 | void | |
16 | bhole(...) | |
17 | { | |
18 | } | |
19 | ||
20 | class line_category | |
21 | { | |
22 | public: | |
23 | const char *key; | |
24 | char line[99999]; | |
25 | void (*test)(line_category &); | |
26 | int test_result; | |
27 | } lc; | |
28 | ||
29 | void | |
30 | deft(line_category &l) | |
31 | { | |
32 | l.test_result = PASS; | |
33 | } | |
34 | ||
35 | void | |
36 | pass_fail(line_category &l) | |
37 | { | |
38 | if(FAIL!=l.test_result) | |
39 | l.test_result = strnstr(l.line, "FAIL", 4)? FAIL: PASS; | |
40 | } | |
41 | ||
42 | void | |
43 | stderr_output(line_category &l) | |
44 | { | |
45 | if(FAIL==l.test_result) | |
46 | return; | |
47 | ||
48 | if(l.line[0]) | |
49 | l.test_result = FAIL; | |
50 | } | |
51 | ||
52 | void | |
53 | exit_test(line_category &l) | |
54 | { | |
55 | if(!atoi(l.line)) { | |
56 | DBG("exit_test(%s)==%d\n", l.line, atoi(l.line)); | |
57 | l.test_result = PASS; | |
58 | } | |
59 | } | |
60 | ||
61 | #define STDOUT "stdout: " | |
62 | #define STDERR "stderr: " | |
63 | #define CWD "cwd: " | |
64 | #define CMD "cmd: " | |
65 | #define SEXIT "exit: " | |
66 | line_category line_categories[] = { | |
67 | { CWD, "" , deft, NO_RESULT}, /* must be first */ | |
68 | { CMD, "", deft, NO_RESULT}, | |
69 | { STDOUT, "", pass_fail, NO_RESULT}, | |
70 | { STDERR, "", stderr_output, NO_RESULT }, | |
71 | { SEXIT, "", exit_test, NO_RESULT }, | |
72 | }; | |
73 | ||
74 | static line_category no_line_category = { "none", "no test", deft, NO_RESULT }; | |
75 | ||
76 | line_category & | |
77 | retrieve(line_category &l, const char *s) | |
78 | { | |
79 | unsigned j; | |
80 | line_category *lp = &l; | |
81 | //int final_result = PASS; | |
82 | ||
83 | for(j=0; j<NELEMENTS(line_categories); ++j,++lp) {//TODO: remove NELEMENTS | |
84 | if(!strcmp(lp->key, s)) { | |
85 | char *p; | |
86 | ||
87 | for(p=(char *)lp->line; *p; ++p) { | |
88 | switch(*p) { | |
89 | case '\0': | |
90 | break; | |
91 | case '"': | |
92 | case '<': | |
93 | *p = ' '; | |
94 | // fall thru | |
95 | default: | |
96 | continue; | |
97 | } | |
98 | } | |
99 | DBG("FOUND line_categories[j].line==%s\n", lp->line); | |
100 | return line_categories[j]; | |
101 | } | |
102 | } | |
103 | ||
104 | return no_line_category; | |
105 | } | |
106 | ||
107 | void | |
108 | xml_string_print(FILE *strm, const char *s) | |
109 | { | |
110 | fputc('"', strm); | |
111 | for( ; ; ++s) { | |
112 | switch(*s) { | |
113 | case '\0': | |
114 | break; | |
115 | case '&': | |
116 | fputs("&", strm); | |
117 | continue; | |
118 | default: | |
119 | fputc(*s, strm); | |
120 | continue; | |
121 | } | |
122 | break; | |
123 | } | |
124 | fputc('"', strm); | |
125 | } | |
126 | ||
127 | // | |
128 | // FAIL if stderr non-zero | |
129 | // FAIL if stdout=="FAIL" | |
130 | // UNRESOLVED if make exit non-zero | |
131 | // PASS otherwise | |
132 | // | |
133 | ||
134 | static int cnt; | |
135 | void | |
136 | dump_test(void) | |
137 | { | |
138 | unsigned j; | |
139 | int final_result = PASS; | |
140 | ||
141 | for(j=0; j<NELEMENTS(line_categories); ++j) { | |
142 | if(line_categories[j].line[0]) { | |
143 | line_categories[j].line[strlen(line_categories[j].line)-1] = '\0'; | |
144 | DBG("%s%s RESULT %d\n" | |
145 | , line_categories[j].key | |
146 | , line_categories[j].line | |
147 | , line_categories[j].test_result | |
148 | ); | |
149 | ||
150 | if(PASS==final_result) { | |
151 | final_result = line_categories[j].test_result; | |
152 | if(NO_RESULT==line_categories[j].test_result) { | |
153 | final_result = NO_RESULT; | |
154 | } else if(FAIL==line_categories[j].test_result) { | |
155 | final_result = FAIL; | |
156 | } | |
157 | } | |
158 | } | |
159 | } | |
160 | ||
161 | printf("<test name="); | |
162 | xml_string_print(stdout, retrieve(line_categories[0], CMD).line); | |
163 | printf(" result=\""); | |
164 | if(NO_RESULT==final_result) { | |
165 | printf("UNRESOLVED"); | |
166 | } else if(FAIL==final_result) { | |
167 | printf("FAIL"); | |
168 | } else { | |
169 | printf("PASS"); | |
170 | } | |
171 | printf("\" "); | |
172 | ||
173 | char *s = retrieve(line_categories[0], CWD).line; | |
174 | if(*s) { | |
175 | char detail[9999]; | |
176 | char fn[9999]; | |
177 | FILE *strm; | |
178 | ||
179 | strncpy(fn, s, sizeof fn); | |
180 | strncat(fn, "/comment.txt", sizeof fn); | |
181 | strm = fopen(fn, "r"); | |
182 | if(strm) { | |
183 | if(fgets(detail, -1+sizeof detail, strm)) { | |
184 | detail[strlen(detail)-1] = '\0'; | |
185 | printf("detail="); | |
186 | xml_string_print(stdout, detail); | |
187 | } | |
188 | } | |
189 | } | |
190 | printf(">\n"); | |
191 | ||
192 | printf(" <diagnostics>\n"); | |
193 | s = retrieve(line_categories[0], STDERR).line; | |
194 | if(*s) { | |
195 | printf(" <diagnostic line=\"%d\" message=", ++cnt); | |
196 | xml_string_print(stdout, s); | |
197 | printf(" severity=\"ERROR\"/>\n"); | |
198 | } | |
199 | #if 1 | |
200 | s = retrieve(line_categories[0], STDOUT).line; | |
201 | if(*s) { | |
202 | printf(" <diagnostic line=\"%d\" message=", ++cnt); | |
203 | xml_string_print(stdout, s); | |
204 | printf(" severity=\"note\"/>\n"); | |
205 | } | |
206 | #endif | |
207 | printf(" </diagnostics>\n"); | |
208 | printf("</test>\n\n"); | |
209 | ||
210 | for(j=0; j<NELEMENTS(line_categories); ++j) { | |
211 | line_categories[j].line[0] = '\0'; | |
212 | line_categories[j].test_result = NO_RESULT; | |
213 | } | |
214 | } | |
215 | ||
216 | int | |
217 | main(int argc, char **argv) | |
218 | { | |
219 | int firsttime = 1; | |
220 | ||
221 | ||
222 | if(argc>1) | |
223 | cnt = atoi(argv[1]); | |
224 | ||
225 | for(;;) { | |
226 | char line[99999]; | |
227 | int i; | |
228 | ||
229 | line[0] = '\0'; | |
230 | fgets(line, sizeof line, stdin); | |
231 | if(feof(stdin)) { | |
232 | dump_test(); | |
233 | break; | |
234 | } | |
235 | ||
236 | for(i=0; ; ++i) { | |
237 | size_t len = strlen(line_categories[i].key); | |
238 | ||
239 | //DBG("strnstr(%s, %s, %u)\n", line, line_categories[i].key, len); | |
240 | if(strnstr(line, line_categories[i].key, len)) { | |
241 | if(firsttime) | |
242 | firsttime = 0; | |
243 | else if(0==i) | |
244 | dump_test(); | |
245 | ||
246 | char *lp = &line[len]; | |
247 | //DBG("%s%s", line_categories[i].key, lp); | |
248 | strncpy(line_categories[i].line, lp, sizeof line_categories[i].line); | |
249 | line_categories[i].test(line_categories[i]); | |
250 | break; | |
251 | } | |
252 | ||
253 | if(i==NELEMENTS(line_categories)-1) { | |
254 | DBG("BADLINE:%s", line); | |
255 | break; | |
256 | } | |
257 | } | |
258 | } | |
259 | return 0; | |
260 | } |