]> git.saurik.com Git - apple/ld64.git/blob - unit-tests/src/results-to-xml.cpp
ld64-84.1.2.tar.gz
[apple/ld64.git] / unit-tests / src / results-to-xml.cpp
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("&amp;", 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 }