Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison main.c @ 4:ee9a66b87c70
Initial version of toplevel and options handling.
author | David A. Holland |
---|---|
date | Sun, 19 Dec 2010 17:52:59 -0500 |
parents | |
children | 7c489c73d62b |
comparison
equal
deleted
inserted
replaced
3:bfa97d43197e | 4:ee9a66b87c70 |
---|---|
1 #include <stdbool.h> | |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
4 #include <string.h> | |
5 #include <errno.h> | |
6 #include <err.h> | |
7 | |
8 #include "inlinedefs.h" // XXX | |
9 #include "version.h" | |
10 #include "config.h" | |
11 #include "utils.h" | |
12 #include "array.h" | |
13 #include "mode.h" | |
14 #include "files.h" | |
15 #include "macro.h" | |
16 | |
17 struct mode mode = { | |
18 .werror = false, | |
19 | |
20 .input_allow_dollars = false, | |
21 .input_tabstop = 8, | |
22 | |
23 .do_stdinc = true, | |
24 .do_stddef = true, | |
25 | |
26 .do_output = true, | |
27 .output_linenumbers = true, | |
28 .output_retain_comments = false, | |
29 .output_file = NULL, | |
30 | |
31 .do_depend = false, | |
32 .depend_report_system = false, | |
33 .depend_assume_generated = false, | |
34 .depend_issue_fakerules = false, | |
35 .depend_quote_target = true, | |
36 .depend_target = NULL, | |
37 .depend_file = NULL, | |
38 | |
39 .do_macrolist = false, | |
40 .macrolist_include_stddef = false, | |
41 .macrolist_include_expansions = false, | |
42 | |
43 .do_trace = false, | |
44 .trace_namesonly = false, | |
45 .trace_indented = false, | |
46 }; | |
47 | |
48 struct warns warns = { | |
49 .endiflabels = true, | |
50 .nestcomment = false, | |
51 .undef = false, | |
52 .unused = false, | |
53 }; | |
54 | |
55 //////////////////////////////////////////////////////////// | |
56 // commandline macros | |
57 | |
58 struct commandline_macro { | |
59 const char *macro; | |
60 const char *expansion; | |
61 }; | |
62 | |
63 static struct array commandline_macros; | |
64 | |
65 static | |
66 void | |
67 commandline_macros_init(void) | |
68 { | |
69 array_init(&commandline_macros); | |
70 } | |
71 | |
72 static | |
73 void | |
74 commandline_macros_cleanup(void) | |
75 { | |
76 array_cleanup(&commandline_macros); | |
77 } | |
78 | |
79 static | |
80 void | |
81 commandline_macro_add(const char *macro, const char *expansion) | |
82 { | |
83 struct commandline_macro *cm; | |
84 | |
85 cm = domalloc(sizeof(*cm)); | |
86 cm->macro = macro; | |
87 cm->expansion = expansion; | |
88 } | |
89 | |
90 static | |
91 void | |
92 commandline_def(char *str) | |
93 { | |
94 char *val; | |
95 | |
96 val = strchr(str, '='); | |
97 if (val != NULL) { | |
98 *val = '\0'; | |
99 val++; | |
100 } | |
101 commandline_macro_add(str, val ? val : "1"); | |
102 } | |
103 | |
104 static | |
105 void | |
106 commandline_undef(char *str) | |
107 { | |
108 commandline_macro_add(str, NULL); | |
109 } | |
110 | |
111 static | |
112 void | |
113 apply_commandline_macros(void) | |
114 { | |
115 struct commandline_macro *cm; | |
116 unsigned i, num; | |
117 | |
118 num = array_num(&commandline_macros); | |
119 for (i=0; i<num; i++) { | |
120 cm = array_get(&commandline_macros, i); | |
121 if (cm->expansion != NULL) { | |
122 macro_define(NULL, cm->macro, cm->expansion); | |
123 } else { | |
124 macro_undef(cm->macro); | |
125 } | |
126 free(cm); | |
127 } | |
128 array_setsize(&commandline_macros, 0); | |
129 } | |
130 | |
131 static | |
132 void | |
133 apply_builtin_macro(const char *name, const char *val) | |
134 { | |
135 /* XXX distinguish builtin-place and commandline-place and nowhere */ | |
136 macro_define(NULL, name, val); | |
137 } | |
138 | |
139 static | |
140 void | |
141 apply_builtin_macros(void) | |
142 { | |
143 #ifdef CONFIG_OS | |
144 apply_builtin_macro(CONFIG_OS, "1"); | |
145 #endif | |
146 #ifdef CONFIG_OS_2 | |
147 apply_builtin_macro(CONFIG_OS_2, "1"); | |
148 #endif | |
149 | |
150 #ifdef CONFIG_CPU | |
151 apply_builtin_macro(CONFIG_CPU, "1"); | |
152 #endif | |
153 #ifdef CONFIG_CPU_2 | |
154 apply_builtin_macro(CONFIG_CPU_2, "1"); | |
155 #endif | |
156 | |
157 #ifdef CONFIG_SIZE | |
158 apply_builtin_macro(CONFIG_SIZE, "1"); | |
159 #endif | |
160 #ifdef CONFIG_BINFMT | |
161 apply_builtin_macro(CONFIG_BINFMT, "1"); | |
162 #endif | |
163 | |
164 #ifdef CONFIG_COMPILER | |
165 apply_builtin_macro(CONFIG_COMPILER, VERSION_MAJOR); | |
166 apply_builtin_macro(CONFIG_COMPILER_MINOR, VERSION_MINOR); | |
167 apply_builtin_macro("__VERSION__", VERSION_LONG); | |
168 #endif | |
169 } | |
170 | |
171 //////////////////////////////////////////////////////////// | |
172 // extra included files | |
173 | |
174 struct commandline_file { | |
175 char *name; | |
176 bool suppress_output; | |
177 }; | |
178 | |
179 static struct array commandline_files; | |
180 | |
181 static | |
182 void | |
183 commandline_files_init(void) | |
184 { | |
185 array_init(&commandline_files); | |
186 } | |
187 | |
188 static | |
189 void | |
190 commandline_files_cleanup(void) | |
191 { | |
192 array_cleanup(&commandline_files); | |
193 } | |
194 | |
195 static | |
196 void | |
197 commandline_addfile(char *name, bool suppress_output) | |
198 { | |
199 struct commandline_file *cf; | |
200 | |
201 cf = domalloc(sizeof(*cf)); | |
202 cf->name = name; | |
203 cf->suppress_output = suppress_output; | |
204 array_add(&commandline_files, cf, NULL); | |
205 } | |
206 | |
207 static | |
208 void | |
209 commandline_addfile_output(char *name) | |
210 { | |
211 commandline_addfile(name, false); | |
212 } | |
213 | |
214 static | |
215 void | |
216 commandline_addfile_nooutput(char *name) | |
217 { | |
218 commandline_addfile(name, true); | |
219 } | |
220 | |
221 static | |
222 void | |
223 read_commandline_files(void) | |
224 { | |
225 struct commandline_file *cf; | |
226 unsigned i, num; | |
227 bool save = false; | |
228 | |
229 num = array_num(&commandline_files); | |
230 for (i=0; i<num; i++) { | |
231 cf = array_get(&commandline_files, i); | |
232 if (cf->suppress_output) { | |
233 save = mode.do_output; | |
234 mode.do_output = false; | |
235 files_read(NULL, cf->name); | |
236 mode.do_output = save; | |
237 } else { | |
238 files_read(NULL, cf->name); | |
239 } | |
240 } | |
241 } | |
242 | |
243 //////////////////////////////////////////////////////////// | |
244 // include path accumulation | |
245 | |
246 static struct stringarray incpath_quote; | |
247 static struct stringarray incpath_user; | |
248 static struct stringarray incpath_system; | |
249 static struct stringarray incpath_late; | |
250 static const char *sysroot; | |
251 | |
252 static | |
253 void | |
254 incpath_init(void) | |
255 { | |
256 stringarray_init(&incpath_quote); | |
257 stringarray_init(&incpath_user); | |
258 stringarray_init(&incpath_system); | |
259 stringarray_init(&incpath_late); | |
260 } | |
261 | |
262 static | |
263 void | |
264 incpath_cleanup(void) | |
265 { | |
266 stringarray_cleanup(&incpath_quote); | |
267 stringarray_cleanup(&incpath_user); | |
268 stringarray_cleanup(&incpath_system); | |
269 stringarray_cleanup(&incpath_late); | |
270 } | |
271 | |
272 static | |
273 void | |
274 commandline_isysroot(char *dir) | |
275 { | |
276 sysroot = dir; | |
277 } | |
278 | |
279 static | |
280 void | |
281 commandline_addincpath(struct stringarray *arr, char *s) | |
282 { | |
283 stringarray_add(arr, s, NULL); | |
284 } | |
285 | |
286 static | |
287 void | |
288 commandline_addincpath_quote(char *dir) | |
289 { | |
290 commandline_addincpath(&incpath_quote, dir); | |
291 } | |
292 | |
293 static | |
294 void | |
295 commandline_addincpath_user(char *dir) | |
296 { | |
297 commandline_addincpath(&incpath_user, dir); | |
298 } | |
299 | |
300 static | |
301 void | |
302 commandline_addincpath_system(char *dir) | |
303 { | |
304 commandline_addincpath(&incpath_system, dir); | |
305 } | |
306 | |
307 static | |
308 void | |
309 commandline_addincpath_late(char *dir) | |
310 { | |
311 commandline_addincpath(&incpath_late, dir); | |
312 } | |
313 | |
314 static | |
315 void | |
316 loadincludepath(void) | |
317 { | |
318 unsigned i, num; | |
319 const char *dir; | |
320 char *t; | |
321 | |
322 num = stringarray_num(&incpath_quote); | |
323 for (i=0; i<num; i++) { | |
324 dir = stringarray_get(&incpath_quote, i); | |
325 files_addquotepath(dir, false); | |
326 } | |
327 files_addquotepath(".", false); | |
328 | |
329 num = stringarray_num(&incpath_user); | |
330 for (i=0; i<num; i++) { | |
331 dir = stringarray_get(&incpath_user, i); | |
332 files_addquotepath(dir, false); | |
333 files_addbracketpath(dir, false); | |
334 } | |
335 | |
336 if (mode.do_stdinc) { | |
337 if (sysroot != NULL) { | |
338 t = dostrdup3(sysroot, "/", CONFIG_LOCALINCLUDE); | |
339 freestringlater(t); | |
340 dir = t; | |
341 } else { | |
342 dir = CONFIG_LOCALINCLUDE; | |
343 } | |
344 files_addquotepath(dir, true); | |
345 files_addbracketpath(dir, true); | |
346 | |
347 if (sysroot != NULL) { | |
348 t = dostrdup3(sysroot, "/", CONFIG_SYSTEMINCLUDE); | |
349 freestringlater(t); | |
350 dir = t; | |
351 } else { | |
352 dir = CONFIG_SYSTEMINCLUDE; | |
353 } | |
354 files_addquotepath(dir, true); | |
355 files_addbracketpath(dir, true); | |
356 } | |
357 | |
358 num = stringarray_num(&incpath_system); | |
359 for (i=0; i<num; i++) { | |
360 dir = stringarray_get(&incpath_system, i); | |
361 files_addquotepath(dir, true); | |
362 files_addbracketpath(dir, true); | |
363 } | |
364 | |
365 num = stringarray_num(&incpath_late); | |
366 for (i=0; i<num; i++) { | |
367 dir = stringarray_get(&incpath_late, i); | |
368 files_addquotepath(dir, false); | |
369 files_addbracketpath(dir, false); | |
370 } | |
371 } | |
372 | |
373 //////////////////////////////////////////////////////////// | |
374 // silly commandline stuff | |
375 | |
376 static const char *commandline_prefix; | |
377 | |
378 static | |
379 void | |
380 commandline_setprefix(char *prefix) | |
381 { | |
382 commandline_prefix = prefix; | |
383 } | |
384 | |
385 static | |
386 void | |
387 commandline_addincpath_user_withprefix(char *dir) | |
388 { | |
389 char *s; | |
390 | |
391 if (commandline_prefix == NULL) { | |
392 warnx("-iprefix needed"); | |
393 die(); | |
394 } | |
395 s = dostrdup3(commandline_prefix, "/", dir); | |
396 freestringlater(s); | |
397 commandline_addincpath_user(s); | |
398 } | |
399 | |
400 static | |
401 void | |
402 commandline_addincpath_late_withprefix(char *dir) | |
403 { | |
404 char *s; | |
405 | |
406 if (commandline_prefix == NULL) { | |
407 warnx("-iprefix needed"); | |
408 die(); | |
409 } | |
410 s = dostrdup3(commandline_prefix, "/", dir); | |
411 freestringlater(s); | |
412 commandline_addincpath_late(s); | |
413 } | |
414 | |
415 static | |
416 void | |
417 commandline_setstd(char *std) | |
418 { | |
419 if (!strcmp(std, "krc")) { | |
420 return; | |
421 } | |
422 warnx("Standard %s not supported by this preprocessor", std); | |
423 die(); | |
424 } | |
425 | |
426 static | |
427 void | |
428 commandline_setlang(char *lang) | |
429 { | |
430 if (!strcmp(lang, "c") || !strcmp(lang, "assembler-with-cpp")) { | |
431 return; | |
432 } | |
433 warnx("Language %s not supported by this preprocessor", lang); | |
434 die(); | |
435 } | |
436 | |
437 //////////////////////////////////////////////////////////// | |
438 // complex modes | |
439 | |
440 static | |
441 void | |
442 commandline_iremap(char *str) | |
443 { | |
444 /* XXX */ | |
445 warnx("-iremap not supported"); | |
446 die(); | |
447 } | |
448 | |
449 static | |
450 void | |
451 commandline_tabstop(char *s) | |
452 { | |
453 char *t; | |
454 unsigned long val; | |
455 | |
456 t = strchr(s, '='); | |
457 if (t == NULL) { | |
458 /* should not happen */ | |
459 warnx("Invalid tabstop"); | |
460 die(); | |
461 } | |
462 t++; | |
463 errno = 0; | |
464 val = strtoul(t, &t, 10); | |
465 if (errno || *t != '\0') { | |
466 warnx("Invalid tabstop"); | |
467 die(); | |
468 } | |
469 if (val > 64) { | |
470 warnx("Preposterously large tabstop"); | |
471 die(); | |
472 } | |
473 mode.input_tabstop = val; | |
474 } | |
475 | |
476 /* | |
477 * macrolist | |
478 */ | |
479 | |
480 static | |
481 void | |
482 commandline_dD(void) | |
483 { | |
484 mode.do_macrolist = true; | |
485 mode.macrolist_include_stddef = false; | |
486 mode.macrolist_include_expansions = true; | |
487 } | |
488 | |
489 static | |
490 void | |
491 commandline_dM(void) | |
492 { | |
493 mode.do_macrolist = true; | |
494 mode.macrolist_include_stddef = true; | |
495 mode.macrolist_include_expansions = true; | |
496 mode.do_output = false; | |
497 } | |
498 | |
499 static | |
500 void | |
501 commandline_dN(void) | |
502 { | |
503 mode.do_macrolist = true; | |
504 mode.macrolist_include_stddef = false; | |
505 mode.macrolist_include_expansions = false; | |
506 } | |
507 | |
508 /* | |
509 * include trace | |
510 */ | |
511 | |
512 static | |
513 void | |
514 commandline_dI(void) | |
515 { | |
516 mode.do_trace = true; | |
517 mode.trace_namesonly = false; | |
518 mode.trace_indented = false; | |
519 } | |
520 | |
521 static | |
522 void | |
523 commandline_H(void) | |
524 { | |
525 mode.do_trace = true; | |
526 mode.trace_namesonly = true; | |
527 mode.trace_indented = true; | |
528 } | |
529 | |
530 /* | |
531 * depend | |
532 */ | |
533 | |
534 static | |
535 void | |
536 commandline_setdependtarget(char *str) | |
537 { | |
538 mode.depend_target = str; | |
539 mode.depend_quote_target = false; | |
540 } | |
541 | |
542 static | |
543 void | |
544 commandline_setdependtarget_quoted(char *str) | |
545 { | |
546 mode.depend_target = str; | |
547 mode.depend_quote_target = true; | |
548 } | |
549 | |
550 static | |
551 void | |
552 commandline_setdependoutput(char *str) | |
553 { | |
554 mode.depend_file = str; | |
555 } | |
556 | |
557 static | |
558 void | |
559 commandline_M(void) | |
560 { | |
561 mode.do_depend = true; | |
562 mode.depend_report_system = true; | |
563 mode.do_output = false; | |
564 } | |
565 | |
566 static | |
567 void | |
568 commandline_MM(void) | |
569 { | |
570 mode.do_depend = true; | |
571 mode.depend_report_system = false; | |
572 mode.do_output = false; | |
573 } | |
574 | |
575 static | |
576 void | |
577 commandline_MD(void) | |
578 { | |
579 mode.do_depend = true; | |
580 mode.depend_report_system = true; | |
581 } | |
582 | |
583 static | |
584 void | |
585 commandline_MMD(void) | |
586 { | |
587 mode.do_depend = true; | |
588 mode.depend_report_system = false; | |
589 } | |
590 | |
591 static | |
592 void | |
593 commandline_wall(void) | |
594 { | |
595 warns.nestcomment = true; | |
596 warns.undef = true; | |
597 warns.unused = true; | |
598 } | |
599 | |
600 static | |
601 void | |
602 commandline_wnoall(void) | |
603 { | |
604 warns.nestcomment = false; | |
605 warns.undef = false; | |
606 warns.unused = false; | |
607 } | |
608 | |
609 static | |
610 void | |
611 commandline_wnone(void) | |
612 { | |
613 warns.nestcomment = false; | |
614 warns.endiflabels = false; | |
615 warns.undef = false; | |
616 warns.unused = false; | |
617 } | |
618 | |
619 //////////////////////////////////////////////////////////// | |
620 // options | |
621 | |
622 struct flag_option { | |
623 const char *string; | |
624 bool *flag; | |
625 bool setto; | |
626 }; | |
627 | |
628 struct act_option { | |
629 const char *string; | |
630 void (*func)(void); | |
631 }; | |
632 | |
633 struct prefix_option { | |
634 const char *string; | |
635 void (*func)(char *); | |
636 }; | |
637 | |
638 struct arg_option { | |
639 const char *string; | |
640 void (*func)(char *); | |
641 }; | |
642 | |
643 static const struct flag_option flag_options[] = { | |
644 { "C", &mode.output_retain_comments, true }, | |
645 { "CC", &mode.output_retain_comments, true }, | |
646 { "fdollars-in-identifiers", &mode.input_allow_dollars, true }, | |
647 { "fno-dollars-in-identifiers", &mode.input_allow_dollars, false }, | |
648 { "MG", &mode.depend_assume_generated, true }, | |
649 { "MP", &mode.depend_issue_fakerules, true }, | |
650 { "nostdinc", &mode.do_stdinc, false }, | |
651 { "P", &mode.output_linenumbers, false }, | |
652 { "undef", &mode.do_stddef, false }, | |
653 { "Wcomment", &warns.nestcomment, true }, | |
654 { "Wendif-labels", &warns.endiflabels, true }, | |
655 { "Werror", &mode.werror, true }, | |
656 { "Wno-comment", &warns.nestcomment, false }, | |
657 { "Wno-endif-labels", &warns.endiflabels, false }, | |
658 { "Wno-error", &mode.werror, false }, | |
659 { "Wno-undef", &warns.undef, false }, | |
660 { "Wno-unused-macros", &warns.unused, false }, | |
661 { "Wundef", &warns.undef, true }, | |
662 { "Wunused-macros", &warns.unused, true }, | |
663 }; | |
664 static const unsigned num_flag_options = HOWMANY(flag_options); | |
665 | |
666 static const struct act_option act_options[] = { | |
667 { "dD", commandline_dD }, | |
668 { "dI", commandline_dI }, | |
669 { "dM", commandline_dM }, | |
670 { "dN", commandline_dN }, | |
671 { "H", commandline_H }, | |
672 { "M", commandline_M }, | |
673 { "MD", commandline_MD }, | |
674 { "MM", commandline_MM }, | |
675 { "MMD", commandline_MMD }, | |
676 { "Wall", commandline_wall }, | |
677 { "Wno-all", commandline_wnoall }, | |
678 { "w", commandline_wnone }, | |
679 }; | |
680 static const unsigned num_act_options = HOWMANY(act_options); | |
681 | |
682 static const struct prefix_option prefix_options[] = { | |
683 { "D", commandline_def }, | |
684 { "ftabstop=", commandline_tabstop }, | |
685 { "I", commandline_addincpath_user }, | |
686 { "std=", commandline_setstd }, | |
687 { "U", commandline_undef }, | |
688 }; | |
689 static const unsigned num_prefix_options = HOWMANY(prefix_options); | |
690 | |
691 static const struct arg_option arg_options[] = { | |
692 { "idirafter", commandline_addincpath_late }, | |
693 { "imacros", commandline_addfile_nooutput }, | |
694 { "include", commandline_addfile_output }, | |
695 { "iprefix", commandline_setprefix }, | |
696 { "iquote", commandline_addincpath_quote }, | |
697 { "iremap", commandline_iremap }, | |
698 { "isysroot", commandline_isysroot }, | |
699 { "isystem", commandline_addincpath_system }, | |
700 { "iwithprefix", commandline_addincpath_late_withprefix }, | |
701 { "iwithprefixbefore", commandline_addincpath_user_withprefix }, | |
702 { "MF", commandline_setdependoutput }, | |
703 { "MT", commandline_setdependtarget }, | |
704 { "MQ", commandline_setdependtarget_quoted }, | |
705 { "x", commandline_setlang }, | |
706 }; | |
707 static const unsigned num_arg_options = HOWMANY(arg_options); | |
708 | |
709 static | |
710 bool | |
711 check_flag_option(const char *opt) | |
712 { | |
713 unsigned i; | |
714 int r; | |
715 | |
716 for (i=0; i<num_flag_options; i++) { | |
717 r = strcmp(opt, flag_options[i].string); | |
718 if (r == 0) { | |
719 *flag_options[i].flag = flag_options[i].setto; | |
720 return true; | |
721 } | |
722 if (r < 0) { | |
723 break; | |
724 } | |
725 } | |
726 return false; | |
727 } | |
728 | |
729 static | |
730 bool | |
731 check_act_option(const char *opt) | |
732 { | |
733 unsigned i; | |
734 int r; | |
735 | |
736 for (i=0; i<num_act_options; i++) { | |
737 r = strcmp(opt, act_options[i].string); | |
738 if (r == 0) { | |
739 act_options[i].func(); | |
740 return true; | |
741 } | |
742 if (r < 0) { | |
743 break; | |
744 } | |
745 } | |
746 return false; | |
747 } | |
748 | |
749 static | |
750 bool | |
751 check_prefix_option(char *opt) | |
752 { | |
753 unsigned i; | |
754 int r; | |
755 | |
756 for (i=0; i<num_prefix_options; i++) { | |
757 r = strncmp(opt, prefix_options[i].string, | |
758 strlen(prefix_options[i].string)); | |
759 if (r == 0) { | |
760 prefix_options[i].func(opt); | |
761 return true; | |
762 } | |
763 if (r < 0) { | |
764 break; | |
765 } | |
766 } | |
767 return false; | |
768 } | |
769 | |
770 static | |
771 bool | |
772 check_arg_option(const char *opt, char *arg) | |
773 { | |
774 unsigned i; | |
775 int r; | |
776 | |
777 for (i=0; i<num_arg_options; i++) { | |
778 r = strcmp(opt, arg_options[i].string); | |
779 if (r == 0) { | |
780 if (arg == NULL) { | |
781 warnx("Option -%s requires an argument", opt); | |
782 die(); | |
783 } | |
784 arg_options[i].func(arg); | |
785 return true; | |
786 } | |
787 if (r < 0) { | |
788 break; | |
789 } | |
790 } | |
791 return false; | |
792 } | |
793 | |
794 static | |
795 void | |
796 usage(void) | |
797 { | |
798 fprintf(stderr, "Usage: %s [options] [infile [outfile]]\n", | |
799 getprogname()); | |
800 fprintf(stderr, "Common options:\n"); | |
801 fprintf(stderr, " -C Retain comments\n"); | |
802 fprintf(stderr, " -Dmacro[=def] Predefine macro\n"); | |
803 fprintf(stderr, " -Idir Add to include path\n"); | |
804 fprintf(stderr, " -M Issue depend info\n"); | |
805 fprintf(stderr, " -MD Issue depend info and output\n"); | |
806 fprintf(stderr, " -MM -M w/o system headers\n"); | |
807 fprintf(stderr, " -MMD -MD w/o system headers\n"); | |
808 fprintf(stderr, " -nostdinc Drop default include path\n"); | |
809 fprintf(stderr, " -Umacro Undefine macro\n"); | |
810 fprintf(stderr, " -undef Undefine everything\n"); | |
811 fprintf(stderr, " -Wall Enable all warnings\n"); | |
812 fprintf(stderr, " -Werror Make warnings into errors\n"); | |
813 fprintf(stderr, " -w Disable all warnings\n"); | |
814 die(); | |
815 } | |
816 | |
817 //////////////////////////////////////////////////////////// | |
818 // exit and cleanup | |
819 | |
820 static struct stringarray freestrings; | |
821 | |
822 static | |
823 void | |
824 init(void) | |
825 { | |
826 stringarray_init(&freestrings); | |
827 incpath_init(); | |
828 commandline_macros_init(); | |
829 commandline_files_init(); | |
830 } | |
831 | |
832 static | |
833 void | |
834 cleanup(void) | |
835 { | |
836 unsigned i, num; | |
837 | |
838 commandline_files_cleanup(); | |
839 commandline_macros_cleanup(); | |
840 incpath_cleanup(); | |
841 | |
842 num = stringarray_num(&freestrings); | |
843 for (i=0; i<num; i++) { | |
844 free(stringarray_get(&freestrings, i)); | |
845 } | |
846 stringarray_setsize(&freestrings, 0); | |
847 stringarray_cleanup(&freestrings); | |
848 } | |
849 | |
850 void | |
851 die(void) | |
852 { | |
853 cleanup(); | |
854 exit(EXIT_FAILURE); | |
855 } | |
856 | |
857 void | |
858 freestringlater(char *s) | |
859 { | |
860 stringarray_add(&freestrings, s, NULL); | |
861 } | |
862 | |
863 //////////////////////////////////////////////////////////// | |
864 // main | |
865 | |
866 int | |
867 main(int argc, char *argv[]) | |
868 { | |
869 const char *inputfile = NULL; | |
870 const char *outputfile = NULL; | |
871 int i; | |
872 | |
873 init(); | |
874 | |
875 for (i=1; i<argc; i++) { | |
876 if (argv[i][0] != '-') { | |
877 break; | |
878 } | |
879 if (check_flag_option(argv[i]+1)) { | |
880 continue; | |
881 } | |
882 if (check_act_option(argv[i]+1)) { | |
883 continue; | |
884 } | |
885 if (check_prefix_option(argv[i]+1)) { | |
886 continue; | |
887 } | |
888 if (check_arg_option(argv[i]+1, argv[i+1])) { | |
889 i++; | |
890 continue; | |
891 } | |
892 usage(); | |
893 } | |
894 if (i < argc) { | |
895 inputfile = argv[i++]; | |
896 } | |
897 if (i < argc) { | |
898 outputfile = argv[i++]; | |
899 } | |
900 if (i < argc) { | |
901 usage(); | |
902 } | |
903 | |
904 mode.output_file = outputfile; | |
905 | |
906 loadincludepath(); | |
907 apply_builtin_macros(); | |
908 apply_commandline_macros(); | |
909 read_commandline_files(); | |
910 files_read(NULL, inputfile); | |
911 | |
912 cleanup(); | |
913 return EXIT_SUCCESS; | |
914 } |