Print this page
Incorporate rmustacc's review feedback.
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/test/libc-tests/tests/symbols/symbols_test.c
+++ new/usr/src/test/libc-tests/tests/symbols/symbols_test.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2014 Garrett D'Amore <garrett@damore.org>
13 + * Copyright 2015 Garrett D'Amore <garrett@damore.org>
14 14 */
15 15
16 16 /*
17 17 * This program tests symbol visibility using the /usr/bin/c89 and
18 18 * /usr/bin/c99 programs.
19 - *
20 - * See symbols_defs.c for the actual list of symbols tested.
21 19 */
22 20
23 21 #include <stdio.h>
24 22 #include <stdlib.h>
25 23 #include <string.h>
26 24 #include <errno.h>
27 25 #include <err.h>
28 26 #include <unistd.h>
29 27 #include <sys/types.h>
30 28 #include <sys/stat.h>
31 29 #include <note.h>
32 30 #include <sys/wait.h>
33 31 #include "test_common.h"
34 32
35 33 char *dname;
36 34 char *cfile;
37 35 char *ofile;
38 36 char *lfile;
37 +char *efile;
39 38
40 39 const char *sym = NULL;
41 40
42 41 static int good_count = 0;
43 42 static int fail_count = 0;
44 43 static int full_count = 0;
45 44 static int extra_debug = 0;
46 45 static char *compilation = "compilation.cfg";
47 46
48 47 #if defined(_LP64)
49 48 #define MFLAG "-m64"
50 49 #elif defined(_ILP32)
51 50 #define MFLAG "-m32"
52 51 #endif
53 52
54 53 const char *compilers[] = {
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
55 54 "cc",
56 55 "gcc",
57 56 "/opt/SUNWspro/bin/cc",
58 57 "/opt/gcc/4.4.4/bin/gcc",
59 58 "/opt/sunstudio12.1/bin/cc",
60 59 "/opt/sfw/bin/gcc",
61 60 "/usr/local/bin/gcc",
62 61 NULL
63 62 };
64 63
65 -const char *puname[] = {
66 - "",
67 - "/usr/bin/puname -S "
68 -};
69 -
70 64 char *compiler = NULL;
71 65 const char *c89flags = NULL;
72 66 const char *c99flags = NULL;
73 67
74 -/* ====== BEGIN ======== */
75 -
76 -#include <errno.h>
77 -#include <string.h>
78 -#include <stdio.h>
79 -#include <stdlib.h>
80 -#include <ctype.h>
81 -#include <stdint.h>
82 -
83 -#define MAXENV 64 /* bits */
68 +#define MAXENV 64 /* maximum number of environments (bitmask width) */
84 69 #define MAXHDR 10 /* maximum # headers to require to access symbol */
85 70 #define MAXARG 20 /* maximum # of arguments */
86 71
87 72 #define WS " \t"
88 73
89 74 static int next_env = 0;
90 75
91 76 struct compile_env {
92 77 char *name;
93 78 char *lang;
94 79 char *defs;
95 80 int index;
96 81 };
97 82
98 83 static struct compile_env compile_env[MAXENV];
99 84
100 85 struct env_group {
101 86 char *name;
102 87 uint64_t mask;
103 88 struct env_group *next;
104 89 };
105 90
106 91 typedef enum { SYM_TYPE, SYM_VALUE, SYM_FUNC } sym_type_t;
107 92
108 93 struct sym_test {
109 94 char *name;
110 95 sym_type_t type;
111 96 char *hdrs[MAXHDR];
112 97 char *rtype;
113 98 char *atypes[MAXARG];
114 99 uint64_t test_mask;
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
115 100 uint64_t need_mask;
116 101 char *prog;
117 102 struct sym_test *next;
118 103 };
119 104
120 105 struct env_group *env_groups = NULL;
121 106
122 107 struct sym_test *sym_tests = NULL;
123 108 struct sym_test **sym_insert = &sym_tests;
124 109
110 +static char *
111 +mystrdup(const char *s)
112 +{
113 + char *r;
114 + if ((r = strdup(s)) == NULL) {
115 + perror("strdup");
116 + exit(1);
117 + }
118 + return (r);
119 +}
120 +
121 +static void *
122 +myzalloc(size_t sz)
123 +{
124 + void *buf;
125 + if ((buf = calloc(1, sz)) == NULL) {
126 + perror("calloc");
127 + exit(1);
128 + }
129 + return (buf);
130 +}
131 +
125 132 static void
133 +myasprintf(char **buf, const char *fmt, ...)
134 +{
135 + int rv;
136 + va_list va;
137 + va_start(va, fmt);
138 + rv = vasprintf(buf, fmt, va);
139 + va_end(va);
140 + if (rv < 0) {
141 + perror("vasprintf");
142 + exit(1);
143 + }
144 +}
145 +
146 +static void
126 147 append_sym_test(struct sym_test *st)
127 148 {
128 149 *sym_insert = st;
129 150 sym_insert = &st->next;
130 151 }
131 152
132 153 static int
133 154 find_env_mask(const char *name, uint64_t *mask)
134 155 {
135 156 for (int i = 0; i < 64; i++) {
136 157 if (compile_env[i].name != NULL &&
137 158 strcmp(compile_env[i].name, name) == 0) {
138 159 *mask |= (1ULL << i);
139 160 return (0);
140 161 }
141 162 }
142 163
143 164 for (struct env_group *eg = env_groups; eg != NULL; eg = eg->next) {
144 165 if (strcmp(name, eg->name) == 0) {
145 166 *mask |= eg->mask;
146 167 return (0);
147 168 }
148 169 }
149 170 return (-1);
150 171 }
151 172
152 173
153 174 static int
154 175 expand_env(char *list, uint64_t *mask, char **erritem)
155 176 {
156 177 char *item;
157 178 for (item = strtok(list, WS); item != NULL; item = strtok(NULL, WS)) {
158 179 if (find_env_mask(item, mask) < 0) {
159 180 if (erritem != NULL) {
160 181 *erritem = item;
161 182 }
162 183 return (-1);
163 184 }
164 185 }
165 186 return (0);
166 187 }
167 188
168 189 static int
169 190 expand_env_list(char *list, uint64_t *test, uint64_t *need, char **erritem)
170 191 {
171 192 uint64_t mask = 0;
172 193 int act;
173 194 char *item;
174 195 for (item = strtok(list, WS); item != NULL; item = strtok(NULL, WS)) {
175 196 switch (item[0]) {
176 197 case '+':
177 198 act = 1;
178 199 item++;
179 200 break;
180 201 case '-':
181 202 act = 0;
182 203 item++;
183 204 break;
184 205 default:
185 206 act = 1;
186 207 break;
187 208 }
188 209
189 210 mask = 0;
190 211 if (find_env_mask(item, &mask) < 0) {
191 212 if (erritem != NULL) {
192 213 *erritem = item;
193 214 }
194 215 return (-1);
195 216 }
196 217 *test |= mask;
197 218 if (act) {
198 219 *need |= mask;
199 220 } else {
200 221 *need &= ~(mask);
201 222 }
202 223 }
203 224 return (0);
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
204 225 }
205 226
206 227 static int
207 228 do_env(char **fields, int nfields, char **err)
208 229 {
209 230 char *name;
210 231 char *lang;
211 232 char *defs;
212 233
213 234 if (nfields != 3) {
214 - (void) asprintf(err, "number of fields (%d) != 3", nfields);
235 + myasprintf(err, "number of fields (%d) != 3", nfields);
215 236 return (-1);
216 237 }
217 238
218 239 if (next_env >= MAXENV) {
219 - (void) asprintf(err, "too many environments");
240 + myasprintf(err, "too many environments");
220 241 return (-1);
221 242 }
222 243
223 244 name = fields[0];
224 245 lang = fields[1];
225 246 defs = fields[2];
226 247
227 - compile_env[next_env].name = strdup(name);
228 - compile_env[next_env].lang = strdup(lang);
229 - compile_env[next_env].defs = strdup(defs);
248 + compile_env[next_env].name = mystrdup(name);
249 + compile_env[next_env].lang = mystrdup(lang);
250 + compile_env[next_env].defs = mystrdup(defs);
230 251 compile_env[next_env].index = next_env;
231 252 next_env++;
232 253 return (0);
233 254 }
234 255
235 256 static int
236 257 do_env_group(char **fields, int nfields, char **err)
237 258 {
238 259 char *name;
239 260 char *list;
240 261 struct env_group *eg;
241 262 uint64_t mask;
242 263 char *item;
243 264
244 265 if (nfields != 2) {
245 - (void) asprintf(err, "number of fields (%d) != 2", nfields);
266 + myasprintf(err, "number of fields (%d) != 2", nfields);
246 267 return (-1);
247 268 }
248 269
249 270 name = fields[0];
250 271 list = fields[1];
251 272 mask = 0;
252 273
253 274 if (expand_env(list, &mask, &item) < 0) {
254 - (void) asprintf(err, "reference to undefined env %s", item);
275 + myasprintf(err, "reference to undefined env %s", item);
255 276 return (-1);
256 277 }
257 278
258 - eg = calloc(1, sizeof (*eg));
259 - eg->name = strdup(name);
279 + eg = myzalloc(sizeof (*eg));
280 + eg->name = mystrdup(name);
260 281 eg->mask = mask;
261 282 eg->next = env_groups;
262 283 env_groups = eg;
263 284 return (0);
264 285 }
265 286
287 +static char *progbuf = NULL;
288 +size_t proglen = 0;
289 +size_t progsiz = 0;
290 +
291 +static void
292 +addprogch(char c)
293 +{
294 + while (progsiz <= (proglen + 1)) {
295 + progbuf = realloc(progbuf, progsiz + 4096);
296 + if (progbuf == NULL) {
297 + perror("realloc");
298 + exit(1);
299 + }
300 + progsiz += 1024;
301 + }
302 + progbuf[proglen++] = c;
303 + progbuf[proglen] = 0;
304 +}
305 +
266 306 static void
307 +addprogstr(char *s)
308 +{
309 + while (*s != NULL) {
310 + addprogch(*s);
311 + s++;
312 + }
313 +}
314 +
315 +static void
316 +addprogfmt(const char *fmt, ...)
317 +{
318 + va_list va;
319 + char *buf = NULL;
320 + va_start(va, fmt);
321 + if (vasprintf(&buf, fmt, va) < 0) {
322 + perror("vasprintf");
323 + exit(1);
324 + }
325 + va_end(va);
326 + addprogstr(buf);
327 + free(buf);
328 +}
329 +
330 +static void
267 331 mkprog(struct sym_test *st)
268 332 {
269 - static char buf[2048];
270 333 char *s;
271 - char *prog = buf;
272 334
273 - *prog = 0;
335 + proglen = 0;
274 336
275 -#define ADDSTR(p, str) (void) strcpy(p, str); p += strlen(p)
276 -#define ADDFMT(p, ...) \
277 - (void) snprintf(p, sizeof (buf) - (p-buf), __VA_ARGS__); \
278 - p += strlen(p)
279 -#define ADDCHR(p, c) *p++ = c; *p = 0
280 -
281 337 for (int i = 0; i < MAXHDR && st->hdrs[i] != NULL; i++) {
282 - ADDFMT(prog, "#include <%s>\n", st->hdrs[i]);
338 + addprogfmt("#include <%s>\n", st->hdrs[i]);
283 339 }
284 340
285 341 for (s = st->rtype; *s; s++) {
286 - ADDCHR(prog, *s);
342 + addprogch(*s);
287 343 if (*s == '(') {
288 344 s++;
289 - ADDCHR(prog, *s);
345 + addprogch(*s);
290 346 s++;
291 347 break;
292 348 }
293 349 }
294 - ADDCHR(prog, ' ');
350 + addprogch(' ');
295 351
296 352 /* for function pointers, s is closing suffix, otherwise empty */
297 353
298 354 switch (st->type) {
299 355 case SYM_TYPE:
300 - ADDFMT(prog, "test_type;", st->rtype);
356 + addprogstr("test_type;");
301 357 break;
302 358
303 359 case SYM_VALUE:
304 - ADDFMT(prog, "test_value%s;\n", s); /* s usually empty */
305 - ADDSTR(prog, "void\ntest_func(void)\n{\n");
306 - ADDFMT(prog, "\ttest_value = %s;\n}",
307 - st->name);
360 + addprogfmt("test_value%s;\n", s); /* s usually empty */
361 + addprogstr("void\ntest_func(void)\n{\n");
362 + addprogfmt("\ttest_value = %s;\n}", st->name);
308 363 break;
309 364
310 365 case SYM_FUNC:
311 - ADDSTR(prog, "\ntest_func(");
366 + addprogstr("\ntest_func(");
312 367 for (int i = 0; st->atypes[i] != NULL && i < MAXARG; i++) {
313 368 int didname = 0;
314 369 if (i > 0) {
315 - ADDSTR(prog, ", ");
370 + addprogstr(", ");
316 371 }
317 372 if (strcmp(st->atypes[i], "void") == 0) {
318 373 didname = 1;
319 374 }
320 375 if (strcmp(st->atypes[i], "") == 0) {
321 376 didname = 1;
322 - ADDSTR(prog, "void");
377 + addprogstr("void");
323 378 }
324 379
325 380 /* print the argument list */
326 381 for (char *a = st->atypes[i]; *a; a++) {
327 382 if (*a == '(' && a[1] == '*' && !didname) {
328 - ADDFMT(prog, "(*a%d", i);
383 + addprogfmt("(*a%d", i);
329 384 didname = 1;
330 385 a++;
331 386 } else if (*a == '[' && !didname) {
332 - ADDFMT(prog, "a%d[", i);
387 + addprogfmt("a%d[", i);
333 388 didname = 1;
334 389 } else {
335 - ADDCHR(prog, *a);
390 + addprogch(*a);
336 391 }
337 392 }
338 393 if (!didname) {
339 - ADDFMT(prog, " a%d", i);
394 + addprogfmt(" a%d", i);
340 395 }
341 396 }
342 397
343 398 if (st->atypes[0] == NULL) {
344 - ADDSTR(prog, "void");
399 + addprogstr("void");
345 400 }
346 401
347 402 /* close argument list, and closing ")" for func ptrs */
348 - ADDFMT(prog, ")%s\n{\n\t", s); /* NB: s is normally empty */
403 + addprogfmt(")%s\n{\n\t", s); /* NB: s is normally empty */
349 404
350 405 if (strcmp(st->rtype, "") != 0 &&
351 406 strcmp(st->rtype, "void") != 0) {
352 - ADDSTR(prog, "return ");
407 + addprogstr("return ");
353 408 }
354 409
355 410 /* add the function call */
356 - ADDFMT(prog, "%s(", st->name);
411 + addprogfmt("%s(", st->name);
357 412 for (int i = 0; st->atypes[i] != NULL && i < MAXARG; i++) {
358 413 if (strcmp(st->atypes[i], "") != 0 &&
359 414 strcmp(st->atypes[i], "void") != 0) {
360 - ADDFMT(prog, "%sa%d", i > 0 ? ", " : "", i);
415 + addprogfmt("%sa%d", i > 0 ? ", " : "", i);
361 416 }
362 417 }
363 418
364 - ADDSTR(prog, ");\n}");
419 + addprogstr(");\n}");
365 420 break;
366 421 }
367 422
368 - ADDCHR(prog, '\n');
423 + addprogch('\n');
369 424
370 - st->prog = strdup(buf);
425 + st->prog = progbuf;
371 426 }
372 427
373 428 static int
374 429 add_envs(struct sym_test *st, char *envs, char **err)
375 430 {
376 431 char *item;
377 432 if (expand_env_list(envs, &st->test_mask, &st->need_mask, &item) < 0) {
378 - (void) asprintf(err, "bad env action %s", item);
433 + myasprintf(err, "bad env action %s", item);
379 434 return (-1);
380 435 }
381 436 return (0);
382 437 }
383 438
384 439 static int
385 440 add_headers(struct sym_test *st, char *hdrs, char **err)
386 441 {
387 442 int i = 0;
388 443
389 444 for (char *h = strsep(&hdrs, ";"); h != NULL; h = strsep(&hdrs, ";")) {
390 445 if (i >= MAXHDR) {
391 - (void) asprintf(err, "too many headers");
446 + myasprintf(err, "too many headers");
392 447 return (-1);
393 448 }
394 449 test_trim(&h);
395 - st->hdrs[i++] = strdup(h);
450 + st->hdrs[i++] = mystrdup(h);
396 451 }
397 452
398 453 return (0);
399 454 }
400 455
401 456 static int
402 457 add_arg_types(struct sym_test *st, char *atype, char **err)
403 458 {
404 459 int i = 0;
405 460 char *a;
406 461 for (a = strsep(&atype, ";"); a != NULL; a = strsep(&atype, ";")) {
407 462 if (i >= MAXARG) {
408 - (void) asprintf(err, "too many arguments");
463 + myasprintf(err, "too many arguments");
409 464 return (-1);
410 465 }
411 466 test_trim(&a);
412 - st->atypes[i++] = strdup(a);
467 + st->atypes[i++] = mystrdup(a);
413 468 }
414 469
415 470 return (0);
416 471 }
417 472
418 473 static int
419 474 do_type(char **fields, int nfields, char **err)
420 475 {
421 476 char *decl;
422 477 char *hdrs;
423 478 char *envs;
424 479 struct sym_test *st;
425 480
426 481 if (nfields != 3) {
427 - (void) asprintf(err, "number of fields (%d) != 3", nfields);
482 + myasprintf(err, "number of fields (%d) != 3", nfields);
428 483 return (-1);
429 484 }
430 485 decl = fields[0];
431 486 hdrs = fields[1];
432 487 envs = fields[2];
433 488
434 - st = calloc(1, sizeof (*st));
489 + st = myzalloc(sizeof (*st));
435 490 st->type = SYM_TYPE;
436 - st->name = strdup(decl);
437 - st->rtype = strdup(decl);
491 + st->name = mystrdup(decl);
492 + st->rtype = mystrdup(decl);
438 493
439 494 if ((add_envs(st, envs, err) < 0) ||
440 495 (add_headers(st, hdrs, err) < 0)) {
441 496 return (-1);
442 497 }
443 498 append_sym_test(st);
444 499
445 500 return (0);
446 501 }
447 502
448 503 static int
449 504 do_value(char **fields, int nfields, char **err)
450 505 {
451 506 char *name;
452 507 char *type;
453 508 char *hdrs;
454 509 char *envs;
455 510 struct sym_test *st;
456 511
457 512 if (nfields != 4) {
458 - (void) asprintf(err, "number of fields (%d) != 4", nfields);
513 + myasprintf(err, "number of fields (%d) != 4", nfields);
459 514 return (-1);
460 515 }
461 516 name = fields[0];
462 517 type = fields[1];
463 518 hdrs = fields[2];
464 519 envs = fields[3];
465 520
466 - st = calloc(1, sizeof (*st));
521 + st = myzalloc(sizeof (*st));
467 522 st->type = SYM_VALUE;
468 - st->name = strdup(name);
469 - st->rtype = strdup(type);
523 + st->name = mystrdup(name);
524 + st->rtype = mystrdup(type);
470 525
471 526 if ((add_envs(st, envs, err) < 0) ||
472 527 (add_headers(st, hdrs, err) < 0)) {
473 528 return (-1);
474 529 }
475 530 append_sym_test(st);
476 531
477 532 return (0);
478 533 }
479 534
480 535 static int
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
481 536 do_func(char **fields, int nfields, char **err)
482 537 {
483 538 char *name;
484 539 char *rtype;
485 540 char *atype;
486 541 char *hdrs;
487 542 char *envs;
488 543 struct sym_test *st;
489 544
490 545 if (nfields != 5) {
491 - (void) asprintf(err, "number of fields (%d) != 5", nfields);
546 + myasprintf(err, "number of fields (%d) != 5", nfields);
492 547 return (-1);
493 548 }
494 549 name = fields[0];
495 550 rtype = fields[1];
496 551 atype = fields[2];
497 552 hdrs = fields[3];
498 553 envs = fields[4];
499 554
500 - st = calloc(1, sizeof (*st));
555 + st = myzalloc(sizeof (*st));
501 556 st->type = SYM_FUNC;
502 - st->name = strdup(name);
503 - st->rtype = strdup(rtype);
557 + st->name = mystrdup(name);
558 + st->rtype = mystrdup(rtype);
504 559
505 560 if ((add_envs(st, envs, err) < 0) ||
506 561 (add_headers(st, hdrs, err) < 0) ||
507 562 (add_arg_types(st, atype, err) < 0)) {
508 563 return (-1);
509 564 }
510 565 append_sym_test(st);
511 566
512 567 return (0);
513 568 }
514 569
515 570 struct sym_test *
516 571 next_sym_test(struct sym_test *st)
517 572 {
518 573 return (st == NULL ? sym_tests : st->next);
519 574 }
520 575
521 576 const char *
522 577 sym_test_prog(struct sym_test *st)
523 578 {
524 579 if (st->prog == NULL) {
525 580 mkprog(st);
526 581 }
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
527 582 return (st->prog);
528 583 }
529 584
530 585 const char *
531 586 sym_test_name(struct sym_test *st)
532 587 {
533 588 return (st->name);
534 589 }
535 590
536 591 /*
537 - * Iterate through tests. Pass NULL for cenv first time, and previous result
538 - * the next. Returns NULL when no more environments.
592 + * Iterate through tests. Pass in NULL for cenv to begin the iteration. For
593 + * subsequent iterations, use the return value from the previous iteration.
594 + * Returns NULL when there are no more environments.
539 595 */
540 596 struct compile_env *
541 597 sym_test_env(struct sym_test *st, struct compile_env *cenv, int *need)
542 598 {
543 599 int i = cenv ? cenv->index + 1: 0;
544 600 uint64_t b = 1ULL << i;
545 601
546 602 while ((i < MAXENV) && (b != 0)) {
547 603 cenv = &compile_env[i];
548 604 if (b & st->test_mask) {
549 605 *need = (st->need_mask & b) ? 1 : 0;
550 606 return (cenv);
551 607 }
552 608 b <<= 1;
553 609 i++;
554 610 }
555 611 return (NULL);
556 612 }
557 613
558 614 const char *
559 615 env_name(struct compile_env *cenv)
560 616 {
561 617 return (cenv->name);
562 618 }
563 619
564 620 const char *
565 621 env_lang(struct compile_env *cenv)
566 622 {
567 623 return (cenv->lang);
568 624 }
569 625
570 626 const char *
571 627 env_defs(struct compile_env *cenv)
572 628 {
573 629 return (cenv->defs);
574 630 }
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
575 631
576 632 static void
577 633 show_file(test_t t, const char *path)
578 634 {
579 635 FILE *f;
580 636 char *buf = NULL;
581 637 size_t cap = 0;
582 638 int line = 1;
583 639
584 640 f = fopen(path, "r");
641 + if (f == NULL) {
642 + test_debugf(t, "fopen(%s): %s", path, strerror(errno));
643 + return;
644 + }
585 645
586 646 test_debugf(t, "----->> begin (%s) <<------", path);
587 647 while (getline(&buf, &cap, f) >= 0) {
588 648 (void) strtok(buf, "\r\n");
589 649 test_debugf(t, "%d: %s", line, buf);
590 650 line++;
591 651 }
592 652 test_debugf(t, "----->> end (%s) <<------", path);
593 653 (void) fclose(f);
594 654 }
595 655
596 656 static void
597 657 cleanup(void)
598 658 {
599 659 if (ofile != NULL) {
600 660 (void) unlink(ofile);
601 661 free(ofile);
602 662 ofile = NULL;
603 663 }
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
604 664 if (lfile != NULL) {
605 665 (void) unlink(lfile);
606 666 free(lfile);
607 667 lfile = NULL;
608 668 }
609 669 if (cfile != NULL) {
610 670 (void) unlink(cfile);
611 671 free(cfile);
612 672 cfile = NULL;
613 673 }
674 + if (efile != NULL) {
675 + (void) unlink(efile);
676 + free(efile);
677 + efile = NULL;
678 + }
614 679 if (dname) {
615 680 (void) rmdir(dname);
616 681 free(dname);
617 682 dname = NULL;
618 683 }
619 684 }
620 685
621 686 static int
622 687 mkworkdir(void)
623 688 {
624 689 char b[32];
625 690 char *d;
626 691
627 692 cleanup();
628 693
629 694 (void) strlcpy(b, "/tmp/symbols_testXXXXXX", sizeof (b));
630 695 if ((d = mkdtemp(b)) == NULL) {
631 696 perror("mkdtemp");
632 697 return (-1);
633 698 }
634 - dname = strdup(d);
635 - (void) asprintf(&cfile, "%s/compile_test.c", d);
636 - (void) asprintf(&ofile, "%s/compile_test.o", d);
637 - (void) asprintf(&lfile, "%s/compile_test.log", d);
699 + dname = mystrdup(d);
700 + myasprintf(&cfile, "%s/compile_test.c", d);
701 + myasprintf(&ofile, "%s/compile_test.o", d);
702 + myasprintf(&lfile, "%s/compile_test.log", d);
703 + myasprintf(&efile, "%s/compile_test.exe", d);
638 704 return (0);
639 705 }
640 706
641 707 void
642 708 find_compiler(void)
643 709 {
644 710 test_t t;
645 711 int i;
646 712 FILE *cf;
647 713
648 714 t = test_start("finding compiler");
649 715
650 716 if ((cf = fopen(cfile, "w+")) == NULL) {
717 + test_failed(t, "Unable to open %s for write: %s", cfile,
718 + strerror(errno));
651 719 return;
652 720 }
653 721 (void) fprintf(cf, "#include <stdio.h>\n");
654 722 (void) fprintf(cf, "int main(int argc, char **argv) {\n");
655 723 (void) fprintf(cf, "#if defined(__SUNPRO_C)\n");
656 724 (void) fprintf(cf, "exit(51);\n");
657 725 (void) fprintf(cf, "#elif defined(__GNUC__)\n");
658 726 (void) fprintf(cf, "exit(52);\n");
659 727 (void) fprintf(cf, "#else\n");
660 728 (void) fprintf(cf, "exit(99)\n");
661 729 (void) fprintf(cf, "#endif\n}\n");
662 730 (void) fclose(cf);
663 731
664 - for (i = 0; compilers[i/2] != NULL; i++) {
732 + for (i = 0; compilers[i] != NULL; i++) {
665 733 char cmd[256];
666 734 int rv;
667 735
668 736 (void) snprintf(cmd, sizeof (cmd),
669 - "%s%s %s %s -o %s >/dev/null 2>&1",
670 - puname[i%2], compilers[i/2], MFLAG, cfile, ofile);
737 + "%s %s %s -o %s >/dev/null 2>&1",
738 + compilers[i], MFLAG, cfile, efile);
671 739 test_debugf(t, "trying %s", cmd);
672 740 rv = system(cmd);
673 741
674 742 test_debugf(t, "result: %d", rv);
675 743
676 744 if ((rv < 0) || !WIFEXITED(rv) || WEXITSTATUS(rv) != 0)
677 745 continue;
678 746
679 - rv = system(ofile);
747 + rv = system(efile);
680 748 if (rv >= 0 && WIFEXITED(rv)) {
681 749 rv = WEXITSTATUS(rv);
682 750 } else {
683 751 rv = -1;
684 752 }
685 753
686 754 switch (rv) {
687 755 case 51: /* STUDIO */
688 756 test_debugf(t, "Found Studio C");
689 757 c89flags = "-Xc -errwarn=%all -v -xc99=%none " MFLAG;
690 758 c99flags = "-Xc -errwarn=%all -v -xc99=%all " MFLAG;
691 759 if (extra_debug) {
692 760 test_debugf(t, "c89flags: %s", c89flags);
693 761 test_debugf(t, "c99flags: %s", c99flags);
694 762 }
695 763 test_passed(t);
696 764 break;
697 765 case 52: /* GCC */
698 766 test_debugf(t, "Found GNU C");
699 767 c89flags = "-Wall -Werror -std=c89 " MFLAG;
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
700 768 c99flags = "-Wall -Werror -std=c99 " MFLAG;
701 769 if (extra_debug) {
702 770 test_debugf(t, "c89flags: %s", c89flags);
703 771 test_debugf(t, "c99flags: %s", c99flags);
704 772 }
705 773 test_passed(t);
706 774 break;
707 775 default:
708 776 continue;
709 777 }
710 - (void) asprintf(&compiler,
711 - "%s%s", puname[i%2], compilers[i/2]);
778 + myasprintf(&compiler, "%s", compilers[i]);
712 779 test_debugf(t, "compiler: %s", compiler);
713 780 return;
714 781 }
715 782 test_failed(t, "No compiler found.");
716 783 }
717 784
718 785 int
719 786 do_compile(test_t t, struct sym_test *st, struct compile_env *cenv, int need)
720 787 {
721 788 char *cmd;
722 789 FILE *logf;
723 790 FILE *dotc;
724 791 const char *prog;
725 792
726 793 full_count++;
727 794
728 795 if ((dotc = fopen(cfile, "w+")) == NULL) {
729 796 test_failed(t, "fopen(%s): %s", cfile, strerror(errno));
730 797 return (-1);
731 798 }
732 799 prog = sym_test_prog(st);
733 800 if (fwrite(prog, 1, strlen(prog), dotc) < strlen(prog)) {
734 801 test_failed(t, "fwrite: %s", strerror(errno));
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
735 802 (void) fclose(dotc);
736 803 return (-1);
737 804 }
738 805 if (fclose(dotc) < 0) {
739 806 test_failed(t, "fclose: %s", strerror(errno));
740 807 return (-1);
741 808 }
742 809
743 810 (void) unlink(ofile);
744 811
745 - if (asprintf(&cmd, "%s %s %s -c %s -o %s >>%s 2>&1",
812 + myasprintf(&cmd, "%s %s %s -c %s -o %s >>%s 2>&1",
746 813 compiler, strcmp(env_lang(cenv), "c99") == 0 ? c99flags : c89flags,
747 - env_defs(cenv), cfile, ofile, lfile) < 0) {
748 - test_failed(t, "asprintf: %s", strerror(errno));
749 - return (-1);
750 - }
814 + env_defs(cenv), cfile, ofile, lfile);
751 815
752 816 if (extra_debug) {
753 817 test_debugf(t, "command: %s", cmd);
754 818 }
755 819
756 -
757 820 if ((logf = fopen(lfile, "w+")) == NULL) {
758 821 test_failed(t, "fopen: %s", strerror(errno));
759 822 return (-1);
760 823 }
761 824 (void) fprintf(logf, "===================\n");
762 825 (void) fprintf(logf, "PROGRAM:\n%s\n", sym_test_prog(st));
763 826 (void) fprintf(logf, "COMMAND: %s\n", cmd);
764 827 (void) fprintf(logf, "EXPECT: %s\n", need ? "OK" : "FAIL");
765 828 (void) fclose(logf);
766 829
767 - if (system(cmd) != 0) {
768 - if (need) {
830 + switch (system(cmd)) {
831 + case -1:
832 + test_failed(t, "error compiling in %s: %s", env_name(cenv),
833 + strerror(errno));
834 + return (-1);
835 + case 0:
836 + if (!need) {
769 837 fail_count++;
770 838 show_file(t, lfile);
771 - test_failed(t, "error compiling in %s", env_name(cenv));
839 + test_failed(t, "symbol visible in %s", env_name(cenv));
772 840 return (-1);
773 841 }
774 - } else {
775 - if (!need) {
842 + break;
843 + default:
844 + if (need) {
776 845 fail_count++;
777 846 show_file(t, lfile);
778 - test_failed(t, "symbol visible in %s", env_name(cenv));
847 + test_failed(t, "error compiling in %s", env_name(cenv));
779 848 return (-1);
780 849 }
850 + break;
781 851 }
782 852 good_count++;
783 853 return (0);
784 854 }
785 855
786 856 void
787 857 test_compile(void)
788 858 {
789 859 struct sym_test *st;
790 860 struct compile_env *cenv;
791 861 test_t t;
792 862 int need;
793 863
794 864 for (st = next_sym_test(NULL); st; st = next_sym_test(st)) {
795 865 if ((sym != NULL) && strcmp(sym, sym_test_name(st))) {
796 866 continue;
797 867 }
798 868 /* XXX: we really want a sym_test_desc() */
799 869 for (cenv = sym_test_env(st, NULL, &need);
800 870 cenv != NULL;
801 871 cenv = sym_test_env(st, cenv, &need)) {
802 872 t = test_start("%s : %c%s", st->name,
803 873 need ? '+' : '-', env_name(cenv));
804 874 if (do_compile(t, st, cenv, need) == 0) {
805 875 test_passed(t);
806 876 }
807 877 }
808 878 }
809 879
810 880 if (full_count > 0) {
811 881 test_summary();
812 882 }
813 883 }
814 884
815 885 int
816 886 main(int argc, char **argv)
817 887 {
818 888 int optc;
819 889 int optC = 0;
820 890
821 891 while ((optc = getopt(argc, argv, "DdfCs:c:")) != EOF) {
822 892 switch (optc) {
823 893 case 'd':
824 894 test_set_debug();
825 895 break;
826 896 case 'f':
827 897 test_set_force();
828 898 break;
829 899 case 'D':
830 900 test_set_debug();
831 901 extra_debug++;
832 902 break;
833 903 case 'c':
834 904 compilation = optarg;
835 905 break;
836 906 case 'C':
837 907 optC++;
838 908 break;
839 909 case 's':
840 910 sym = optarg;
841 911 break;
842 912 default:
843 913 (void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]);
844 914 exit(1);
845 915 }
846 916 }
847 917
848 918 if (test_load_config(NULL, compilation,
849 919 "env", do_env, "env_group", do_env_group, NULL) < 0) {
850 920 exit(1);
851 921 }
852 922
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
853 923 while (optind < argc) {
854 924 if (test_load_config(NULL, argv[optind++],
855 925 "type", do_type,
856 926 "value", do_value,
857 927 "func", do_func,
858 928 NULL) < 0) {
859 929 exit(1);
860 930 }
861 931 }
862 932
863 - (void) atexit(cleanup);
933 + if (atexit(cleanup) != 0) {
934 + perror("atexit");
935 + exit(1);
936 + }
864 937
865 938 if (mkworkdir() < 0) {
866 939 perror("mkdir");
867 940 exit(1);
868 941 }
869 942
870 943 find_compiler();
871 944 if (!optC)
872 945 test_compile();
873 946
874 947 exit(0);
875 948 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX