1*31615c96Sdholland /*-
2*31615c96Sdholland * Copyright (c) 2010 The NetBSD Foundation, Inc.
3*31615c96Sdholland * All rights reserved.
4*31615c96Sdholland *
5*31615c96Sdholland * This code is derived from software contributed to The NetBSD Foundation
6*31615c96Sdholland * by David A. Holland.
7*31615c96Sdholland *
8*31615c96Sdholland * Redistribution and use in source and binary forms, with or without
9*31615c96Sdholland * modification, are permitted provided that the following conditions
10*31615c96Sdholland * are met:
11*31615c96Sdholland * 1. Redistributions of source code must retain the above copyright
12*31615c96Sdholland * notice, this list of conditions and the following disclaimer.
13*31615c96Sdholland * 2. Redistributions in binary form must reproduce the above copyright
14*31615c96Sdholland * notice, this list of conditions and the following disclaimer in the
15*31615c96Sdholland * documentation and/or other materials provided with the distribution.
16*31615c96Sdholland *
17*31615c96Sdholland * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18*31615c96Sdholland * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19*31615c96Sdholland * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20*31615c96Sdholland * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21*31615c96Sdholland * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*31615c96Sdholland * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*31615c96Sdholland * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*31615c96Sdholland * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*31615c96Sdholland * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*31615c96Sdholland * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*31615c96Sdholland * POSSIBILITY OF SUCH DAMAGE.
28*31615c96Sdholland */
29*31615c96Sdholland
30*31615c96Sdholland #include <stdio.h>
31*31615c96Sdholland #include <stdarg.h>
32*31615c96Sdholland #include <stdlib.h>
33*31615c96Sdholland #include <string.h>
34*31615c96Sdholland #include <errno.h>
35*31615c96Sdholland
36*31615c96Sdholland #include "bool.h"
37*31615c96Sdholland #include "version.h"
38*31615c96Sdholland #include "config.h"
39*31615c96Sdholland #include "utils.h"
40*31615c96Sdholland #include "array.h"
41*31615c96Sdholland #include "mode.h"
42*31615c96Sdholland #include "place.h"
43*31615c96Sdholland #include "files.h"
44*31615c96Sdholland #include "directive.h"
45*31615c96Sdholland #include "macro.h"
46*31615c96Sdholland
47*31615c96Sdholland struct mode mode = {
48*31615c96Sdholland .werror = false,
49*31615c96Sdholland
50*31615c96Sdholland .input_allow_dollars = false,
51*31615c96Sdholland .input_tabstop = 8,
52*31615c96Sdholland
53*31615c96Sdholland .do_stdinc = true,
54*31615c96Sdholland .do_stddef = true,
55*31615c96Sdholland
56*31615c96Sdholland .do_output = true,
57*31615c96Sdholland .output_linenumbers = true,
58*31615c96Sdholland .output_cheaplinenumbers = false,
59*31615c96Sdholland .output_retain_comments = false,
60*31615c96Sdholland .output_file = NULL,
61*31615c96Sdholland
62*31615c96Sdholland .do_depend = false,
63*31615c96Sdholland .depend_report_system = false,
64*31615c96Sdholland .depend_assume_generated = false,
65*31615c96Sdholland .depend_issue_fakerules = false,
66*31615c96Sdholland .depend_quote_target = true,
67*31615c96Sdholland .depend_target = NULL,
68*31615c96Sdholland .depend_file = NULL,
69*31615c96Sdholland
70*31615c96Sdholland .do_macrolist = false,
71*31615c96Sdholland .macrolist_include_stddef = false,
72*31615c96Sdholland .macrolist_include_expansions = false,
73*31615c96Sdholland
74*31615c96Sdholland .do_trace = false,
75*31615c96Sdholland .trace_namesonly = false,
76*31615c96Sdholland .trace_indented = false,
77*31615c96Sdholland };
78*31615c96Sdholland
79*31615c96Sdholland struct warns warns = {
80*31615c96Sdholland .endiflabels = true,
81*31615c96Sdholland .nestcomment = false,
82*31615c96Sdholland .undef = false,
83*31615c96Sdholland .unused = false,
84*31615c96Sdholland };
85*31615c96Sdholland
86*31615c96Sdholland ////////////////////////////////////////////////////////////
87*31615c96Sdholland // commandline macros
88*31615c96Sdholland
89*31615c96Sdholland struct commandline_macro {
90*31615c96Sdholland struct place where;
91*31615c96Sdholland struct place where2;
92*31615c96Sdholland const char *macro;
93*31615c96Sdholland const char *expansion;
94*31615c96Sdholland };
95*31615c96Sdholland
96*31615c96Sdholland static struct array commandline_macros;
97*31615c96Sdholland
98*31615c96Sdholland static
99*31615c96Sdholland void
commandline_macros_init(void)100*31615c96Sdholland commandline_macros_init(void)
101*31615c96Sdholland {
102*31615c96Sdholland array_init(&commandline_macros);
103*31615c96Sdholland }
104*31615c96Sdholland
105*31615c96Sdholland static
106*31615c96Sdholland void
commandline_macros_cleanup(void)107*31615c96Sdholland commandline_macros_cleanup(void)
108*31615c96Sdholland {
109*31615c96Sdholland unsigned i, num;
110*31615c96Sdholland struct commandline_macro *cm;
111*31615c96Sdholland
112*31615c96Sdholland num = array_num(&commandline_macros);
113*31615c96Sdholland for (i=0; i<num; i++) {
114*31615c96Sdholland cm = array_get(&commandline_macros, i);
115*31615c96Sdholland dofree(cm, sizeof(*cm));
116*31615c96Sdholland }
117*31615c96Sdholland array_setsize(&commandline_macros, 0);
118*31615c96Sdholland
119*31615c96Sdholland array_cleanup(&commandline_macros);
120*31615c96Sdholland }
121*31615c96Sdholland
122*31615c96Sdholland static
123*31615c96Sdholland void
commandline_macro_add(const struct place * p,const char * macro,const struct place * p2,const char * expansion)124*31615c96Sdholland commandline_macro_add(const struct place *p, const char *macro,
125*31615c96Sdholland const struct place *p2, const char *expansion)
126*31615c96Sdholland {
127*31615c96Sdholland struct commandline_macro *cm;
128*31615c96Sdholland
129*31615c96Sdholland cm = domalloc(sizeof(*cm));
130*31615c96Sdholland cm->where = *p;
131*31615c96Sdholland cm->where2 = *p2;
132*31615c96Sdholland cm->macro = macro;
133*31615c96Sdholland cm->expansion = expansion;
134*31615c96Sdholland
135*31615c96Sdholland array_add(&commandline_macros, cm, NULL);
136*31615c96Sdholland }
137*31615c96Sdholland
138*31615c96Sdholland static
139*31615c96Sdholland void
commandline_def(const struct place * p,char * str)140*31615c96Sdholland commandline_def(const struct place *p, char *str)
141*31615c96Sdholland {
142*31615c96Sdholland struct place p2;
143*31615c96Sdholland char *val;
144*31615c96Sdholland
145*31615c96Sdholland if (*str == '\0') {
146*31615c96Sdholland complain(NULL, "-D: macro name expected");
147*31615c96Sdholland die();
148*31615c96Sdholland }
149*31615c96Sdholland
150*31615c96Sdholland val = strchr(str, '=');
151*31615c96Sdholland if (val != NULL) {
152*31615c96Sdholland *val = '\0';
153*31615c96Sdholland val++;
154*31615c96Sdholland }
155*31615c96Sdholland
156*31615c96Sdholland if (val) {
157*31615c96Sdholland p2 = *p;
158*31615c96Sdholland place_addcolumns(&p2, strlen(str));
159*31615c96Sdholland } else {
160*31615c96Sdholland place_setbuiltin(&p2, 1);
161*31615c96Sdholland }
162*31615c96Sdholland commandline_macro_add(p, str, &p2, val ? val : "1");
163*31615c96Sdholland }
164*31615c96Sdholland
165*31615c96Sdholland static
166*31615c96Sdholland void
commandline_undef(const struct place * p,char * str)167*31615c96Sdholland commandline_undef(const struct place *p, char *str)
168*31615c96Sdholland {
169*31615c96Sdholland if (*str == '\0') {
170*31615c96Sdholland complain(NULL, "-U: macro name expected");
171*31615c96Sdholland die();
172*31615c96Sdholland }
173*31615c96Sdholland commandline_macro_add(p, str, p, NULL);
174*31615c96Sdholland }
175*31615c96Sdholland
176*31615c96Sdholland static
177*31615c96Sdholland void
apply_commandline_macros(void)178*31615c96Sdholland apply_commandline_macros(void)
179*31615c96Sdholland {
180*31615c96Sdholland struct commandline_macro *cm;
181*31615c96Sdholland unsigned i, num;
182*31615c96Sdholland
183*31615c96Sdholland num = array_num(&commandline_macros);
184*31615c96Sdholland for (i=0; i<num; i++) {
185*31615c96Sdholland cm = array_get(&commandline_macros, i);
186*31615c96Sdholland if (cm->expansion != NULL) {
187*31615c96Sdholland macro_define_plain(&cm->where, cm->macro,
188*31615c96Sdholland &cm->where2, cm->expansion);
189*31615c96Sdholland } else {
190*31615c96Sdholland macro_undef(cm->macro);
191*31615c96Sdholland }
192*31615c96Sdholland dofree(cm, sizeof(*cm));
193*31615c96Sdholland }
194*31615c96Sdholland array_setsize(&commandline_macros, 0);
195*31615c96Sdholland }
196*31615c96Sdholland
197*31615c96Sdholland static
198*31615c96Sdholland void
apply_magic_macro(unsigned num,const char * name)199*31615c96Sdholland apply_magic_macro(unsigned num, const char *name)
200*31615c96Sdholland {
201*31615c96Sdholland struct place p;
202*31615c96Sdholland
203*31615c96Sdholland place_setbuiltin(&p, num);
204*31615c96Sdholland macro_define_magic(&p, name);
205*31615c96Sdholland }
206*31615c96Sdholland
207*31615c96Sdholland static
208*31615c96Sdholland void
apply_builtin_macro(unsigned num,const char * name,const char * val)209*31615c96Sdholland apply_builtin_macro(unsigned num, const char *name, const char *val)
210*31615c96Sdholland {
211*31615c96Sdholland struct place p;
212*31615c96Sdholland
213*31615c96Sdholland place_setbuiltin(&p, num);
214*31615c96Sdholland macro_define_plain(&p, name, &p, val);
215*31615c96Sdholland }
216*31615c96Sdholland
217*31615c96Sdholland static
218*31615c96Sdholland void
apply_builtin_macros(void)219*31615c96Sdholland apply_builtin_macros(void)
220*31615c96Sdholland {
221*31615c96Sdholland unsigned n = 1;
222*31615c96Sdholland
223*31615c96Sdholland apply_magic_macro(n++, "__FILE__");
224*31615c96Sdholland apply_magic_macro(n++, "__LINE__");
225*31615c96Sdholland
226*31615c96Sdholland #ifdef CONFIG_OS
227*31615c96Sdholland apply_builtin_macro(n++, CONFIG_OS, "1");
228*31615c96Sdholland #endif
229*31615c96Sdholland #ifdef CONFIG_OS_2
230*31615c96Sdholland apply_builtin_macro(n++, CONFIG_OS_2, "1");
231*31615c96Sdholland #endif
232*31615c96Sdholland
233*31615c96Sdholland #ifdef CONFIG_CPU
234*31615c96Sdholland apply_builtin_macro(n++, CONFIG_CPU, "1");
235*31615c96Sdholland #endif
236*31615c96Sdholland #ifdef CONFIG_CPU_2
237*31615c96Sdholland apply_builtin_macro(n++, CONFIG_CPU_2, "1");
238*31615c96Sdholland #endif
239*31615c96Sdholland
240*31615c96Sdholland #ifdef CONFIG_SIZE
241*31615c96Sdholland apply_builtin_macro(n++, CONFIG_SIZE, "1");
242*31615c96Sdholland #endif
243*31615c96Sdholland #ifdef CONFIG_BINFMT
244*31615c96Sdholland apply_builtin_macro(n++, CONFIG_BINFMT, "1");
245*31615c96Sdholland #endif
246*31615c96Sdholland
247*31615c96Sdholland #ifdef CONFIG_COMPILER
248*31615c96Sdholland apply_builtin_macro(n++, CONFIG_COMPILER, VERSION_MAJOR);
249*31615c96Sdholland apply_builtin_macro(n++, CONFIG_COMPILER_MINOR, VERSION_MINOR);
250*31615c96Sdholland apply_builtin_macro(n++, "__VERSION__", VERSION_LONG);
251*31615c96Sdholland #endif
252*31615c96Sdholland }
253*31615c96Sdholland
254*31615c96Sdholland ////////////////////////////////////////////////////////////
255*31615c96Sdholland // extra included files
256*31615c96Sdholland
257*31615c96Sdholland struct commandline_file {
258*31615c96Sdholland struct place where;
259*31615c96Sdholland char *name;
260*31615c96Sdholland bool suppress_output;
261*31615c96Sdholland };
262*31615c96Sdholland
263*31615c96Sdholland static struct array commandline_files;
264*31615c96Sdholland
265*31615c96Sdholland static
266*31615c96Sdholland void
commandline_files_init(void)267*31615c96Sdholland commandline_files_init(void)
268*31615c96Sdholland {
269*31615c96Sdholland array_init(&commandline_files);
270*31615c96Sdholland }
271*31615c96Sdholland
272*31615c96Sdholland static
273*31615c96Sdholland void
commandline_files_cleanup(void)274*31615c96Sdholland commandline_files_cleanup(void)
275*31615c96Sdholland {
276*31615c96Sdholland unsigned i, num;
277*31615c96Sdholland struct commandline_file *cf;
278*31615c96Sdholland
279*31615c96Sdholland num = array_num(&commandline_files);
280*31615c96Sdholland for (i=0; i<num; i++) {
281*31615c96Sdholland cf = array_get(&commandline_files, i);
282*31615c96Sdholland if (cf != NULL) {
283*31615c96Sdholland dofree(cf, sizeof(*cf));
284*31615c96Sdholland }
285*31615c96Sdholland }
286*31615c96Sdholland array_setsize(&commandline_files, 0);
287*31615c96Sdholland
288*31615c96Sdholland array_cleanup(&commandline_files);
289*31615c96Sdholland }
290*31615c96Sdholland
291*31615c96Sdholland static
292*31615c96Sdholland void
commandline_addfile(const struct place * p,char * name,bool suppress_output)293*31615c96Sdholland commandline_addfile(const struct place *p, char *name, bool suppress_output)
294*31615c96Sdholland {
295*31615c96Sdholland struct commandline_file *cf;
296*31615c96Sdholland
297*31615c96Sdholland cf = domalloc(sizeof(*cf));
298*31615c96Sdholland cf->where = *p;
299*31615c96Sdholland cf->name = name;
300*31615c96Sdholland cf->suppress_output = suppress_output;
301*31615c96Sdholland array_add(&commandline_files, cf, NULL);
302*31615c96Sdholland }
303*31615c96Sdholland
304*31615c96Sdholland static
305*31615c96Sdholland void
commandline_addfile_output(const struct place * p,char * name)306*31615c96Sdholland commandline_addfile_output(const struct place *p, char *name)
307*31615c96Sdholland {
308*31615c96Sdholland commandline_addfile(p, name, false);
309*31615c96Sdholland }
310*31615c96Sdholland
311*31615c96Sdholland static
312*31615c96Sdholland void
commandline_addfile_nooutput(const struct place * p,char * name)313*31615c96Sdholland commandline_addfile_nooutput(const struct place *p, char *name)
314*31615c96Sdholland {
315*31615c96Sdholland commandline_addfile(p, name, true);
316*31615c96Sdholland }
317*31615c96Sdholland
318*31615c96Sdholland static
319*31615c96Sdholland void
read_commandline_files(void)320*31615c96Sdholland read_commandline_files(void)
321*31615c96Sdholland {
322*31615c96Sdholland struct commandline_file *cf;
323*31615c96Sdholland unsigned i, num;
324*31615c96Sdholland bool save = false;
325*31615c96Sdholland
326*31615c96Sdholland num = array_num(&commandline_files);
327*31615c96Sdholland for (i=0; i<num; i++) {
328*31615c96Sdholland cf = array_get(&commandline_files, i);
329*31615c96Sdholland array_set(&commandline_files, i, NULL);
330*31615c96Sdholland if (cf->suppress_output) {
331*31615c96Sdholland save = mode.do_output;
332*31615c96Sdholland mode.do_output = false;
333*31615c96Sdholland file_readquote(&cf->where, cf->name);
334*31615c96Sdholland mode.do_output = save;
335*31615c96Sdholland } else {
336*31615c96Sdholland file_readquote(&cf->where, cf->name);
337*31615c96Sdholland }
338*31615c96Sdholland dofree(cf, sizeof(*cf));
339*31615c96Sdholland }
340*31615c96Sdholland array_setsize(&commandline_files, 0);
341*31615c96Sdholland }
342*31615c96Sdholland
343*31615c96Sdholland ////////////////////////////////////////////////////////////
344*31615c96Sdholland // include path accumulation
345*31615c96Sdholland
346*31615c96Sdholland static struct stringarray incpath_quote;
347*31615c96Sdholland static struct stringarray incpath_user;
348*31615c96Sdholland static struct stringarray incpath_system;
349*31615c96Sdholland static struct stringarray incpath_late;
350*31615c96Sdholland static const char *sysroot;
351*31615c96Sdholland
352*31615c96Sdholland static
353*31615c96Sdholland void
incpath_init(void)354*31615c96Sdholland incpath_init(void)
355*31615c96Sdholland {
356*31615c96Sdholland stringarray_init(&incpath_quote);
357*31615c96Sdholland stringarray_init(&incpath_user);
358*31615c96Sdholland stringarray_init(&incpath_system);
359*31615c96Sdholland stringarray_init(&incpath_late);
360*31615c96Sdholland }
361*31615c96Sdholland
362*31615c96Sdholland static
363*31615c96Sdholland void
incpath_cleanup(void)364*31615c96Sdholland incpath_cleanup(void)
365*31615c96Sdholland {
366*31615c96Sdholland stringarray_setsize(&incpath_quote, 0);
367*31615c96Sdholland stringarray_setsize(&incpath_user, 0);
368*31615c96Sdholland stringarray_setsize(&incpath_system, 0);
369*31615c96Sdholland stringarray_setsize(&incpath_late, 0);
370*31615c96Sdholland
371*31615c96Sdholland stringarray_cleanup(&incpath_quote);
372*31615c96Sdholland stringarray_cleanup(&incpath_user);
373*31615c96Sdholland stringarray_cleanup(&incpath_system);
374*31615c96Sdholland stringarray_cleanup(&incpath_late);
375*31615c96Sdholland }
376*31615c96Sdholland
377*31615c96Sdholland static
378*31615c96Sdholland void
commandline_isysroot(const struct place * p,char * dir)379*31615c96Sdholland commandline_isysroot(const struct place *p, char *dir)
380*31615c96Sdholland {
381*31615c96Sdholland (void)p;
382*31615c96Sdholland sysroot = dir;
383*31615c96Sdholland }
384*31615c96Sdholland
385*31615c96Sdholland static
386*31615c96Sdholland void
commandline_addincpath(struct stringarray * arr,char * s)387*31615c96Sdholland commandline_addincpath(struct stringarray *arr, char *s)
388*31615c96Sdholland {
389*31615c96Sdholland if (*s == '\0') {
390*31615c96Sdholland complain(NULL, "Empty include directory");
391*31615c96Sdholland die();
392*31615c96Sdholland }
393*31615c96Sdholland stringarray_add(arr, s, NULL);
394*31615c96Sdholland }
395*31615c96Sdholland
396*31615c96Sdholland static
397*31615c96Sdholland void
commandline_addincpath_quote(const struct place * p,char * dir)398*31615c96Sdholland commandline_addincpath_quote(const struct place *p, char *dir)
399*31615c96Sdholland {
400*31615c96Sdholland (void)p;
401*31615c96Sdholland commandline_addincpath(&incpath_quote, dir);
402*31615c96Sdholland }
403*31615c96Sdholland
404*31615c96Sdholland static
405*31615c96Sdholland void
commandline_addincpath_user(const struct place * p,char * dir)406*31615c96Sdholland commandline_addincpath_user(const struct place *p, char *dir)
407*31615c96Sdholland {
408*31615c96Sdholland (void)p;
409*31615c96Sdholland commandline_addincpath(&incpath_user, dir);
410*31615c96Sdholland }
411*31615c96Sdholland
412*31615c96Sdholland static
413*31615c96Sdholland void
commandline_addincpath_system(const struct place * p,char * dir)414*31615c96Sdholland commandline_addincpath_system(const struct place *p, char *dir)
415*31615c96Sdholland {
416*31615c96Sdholland (void)p;
417*31615c96Sdholland commandline_addincpath(&incpath_system, dir);
418*31615c96Sdholland }
419*31615c96Sdholland
420*31615c96Sdholland static
421*31615c96Sdholland void
commandline_addincpath_late(const struct place * p,char * dir)422*31615c96Sdholland commandline_addincpath_late(const struct place *p, char *dir)
423*31615c96Sdholland {
424*31615c96Sdholland (void)p;
425*31615c96Sdholland commandline_addincpath(&incpath_late, dir);
426*31615c96Sdholland }
427*31615c96Sdholland
428*31615c96Sdholland static
429*31615c96Sdholland void
loadincludepath(void)430*31615c96Sdholland loadincludepath(void)
431*31615c96Sdholland {
432*31615c96Sdholland unsigned i, num;
433*31615c96Sdholland const char *dir;
434*31615c96Sdholland char *t;
435*31615c96Sdholland
436*31615c96Sdholland num = stringarray_num(&incpath_quote);
437*31615c96Sdholland for (i=0; i<num; i++) {
438*31615c96Sdholland dir = stringarray_get(&incpath_quote, i);
439*31615c96Sdholland files_addquotepath(dir, false);
440*31615c96Sdholland }
441*31615c96Sdholland files_addquotepath(NULL, false);
442*31615c96Sdholland
443*31615c96Sdholland num = stringarray_num(&incpath_user);
444*31615c96Sdholland for (i=0; i<num; i++) {
445*31615c96Sdholland dir = stringarray_get(&incpath_user, i);
446*31615c96Sdholland files_addquotepath(dir, false);
447*31615c96Sdholland files_addbracketpath(dir, false);
448*31615c96Sdholland }
449*31615c96Sdholland
450*31615c96Sdholland if (mode.do_stdinc) {
451*31615c96Sdholland if (sysroot != NULL) {
452*31615c96Sdholland t = dostrdup3(sysroot, "/", CONFIG_LOCALINCLUDE);
453*31615c96Sdholland freestringlater(t);
454*31615c96Sdholland dir = t;
455*31615c96Sdholland } else {
456*31615c96Sdholland dir = CONFIG_LOCALINCLUDE;
457*31615c96Sdholland }
458*31615c96Sdholland files_addquotepath(dir, true);
459*31615c96Sdholland files_addbracketpath(dir, true);
460*31615c96Sdholland
461*31615c96Sdholland if (sysroot != NULL) {
462*31615c96Sdholland t = dostrdup3(sysroot, "/", CONFIG_SYSTEMINCLUDE);
463*31615c96Sdholland freestringlater(t);
464*31615c96Sdholland dir = t;
465*31615c96Sdholland } else {
466*31615c96Sdholland dir = CONFIG_SYSTEMINCLUDE;
467*31615c96Sdholland }
468*31615c96Sdholland files_addquotepath(dir, true);
469*31615c96Sdholland files_addbracketpath(dir, true);
470*31615c96Sdholland }
471*31615c96Sdholland
472*31615c96Sdholland num = stringarray_num(&incpath_system);
473*31615c96Sdholland for (i=0; i<num; i++) {
474*31615c96Sdholland dir = stringarray_get(&incpath_system, i);
475*31615c96Sdholland files_addquotepath(dir, true);
476*31615c96Sdholland files_addbracketpath(dir, true);
477*31615c96Sdholland }
478*31615c96Sdholland
479*31615c96Sdholland num = stringarray_num(&incpath_late);
480*31615c96Sdholland for (i=0; i<num; i++) {
481*31615c96Sdholland dir = stringarray_get(&incpath_late, i);
482*31615c96Sdholland files_addquotepath(dir, false);
483*31615c96Sdholland files_addbracketpath(dir, false);
484*31615c96Sdholland }
485*31615c96Sdholland }
486*31615c96Sdholland
487*31615c96Sdholland ////////////////////////////////////////////////////////////
488*31615c96Sdholland // silly commandline stuff
489*31615c96Sdholland
490*31615c96Sdholland static const char *commandline_prefix;
491*31615c96Sdholland
492*31615c96Sdholland static
493*31615c96Sdholland void
commandline_setprefix(const struct place * p,char * prefix)494*31615c96Sdholland commandline_setprefix(const struct place *p, char *prefix)
495*31615c96Sdholland {
496*31615c96Sdholland (void)p;
497*31615c96Sdholland commandline_prefix = prefix;
498*31615c96Sdholland }
499*31615c96Sdholland
500*31615c96Sdholland static
501*31615c96Sdholland void
commandline_addincpath_user_withprefix(const struct place * p,char * dir)502*31615c96Sdholland commandline_addincpath_user_withprefix(const struct place *p, char *dir)
503*31615c96Sdholland {
504*31615c96Sdholland char *s;
505*31615c96Sdholland
506*31615c96Sdholland if (commandline_prefix == NULL) {
507*31615c96Sdholland complain(NULL, "-iprefix needed");
508*31615c96Sdholland die();
509*31615c96Sdholland }
510*31615c96Sdholland s = dostrdup3(commandline_prefix, "/", dir);
511*31615c96Sdholland freestringlater(s);
512*31615c96Sdholland commandline_addincpath_user(p, s);
513*31615c96Sdholland }
514*31615c96Sdholland
515*31615c96Sdholland static
516*31615c96Sdholland void
commandline_addincpath_late_withprefix(const struct place * p,char * dir)517*31615c96Sdholland commandline_addincpath_late_withprefix(const struct place *p, char *dir)
518*31615c96Sdholland {
519*31615c96Sdholland char *s;
520*31615c96Sdholland
521*31615c96Sdholland if (commandline_prefix == NULL) {
522*31615c96Sdholland complain(NULL, "-iprefix needed");
523*31615c96Sdholland die();
524*31615c96Sdholland }
525*31615c96Sdholland s = dostrdup3(commandline_prefix, "/", dir);
526*31615c96Sdholland freestringlater(s);
527*31615c96Sdholland commandline_addincpath_late(p, s);
528*31615c96Sdholland }
529*31615c96Sdholland
530*31615c96Sdholland static
531*31615c96Sdholland void
commandline_setstd(const struct place * p,char * std)532*31615c96Sdholland commandline_setstd(const struct place *p, char *std)
533*31615c96Sdholland {
534*31615c96Sdholland (void)p;
535*31615c96Sdholland
536*31615c96Sdholland if (!strcmp(std, "krc")) {
537*31615c96Sdholland return;
538*31615c96Sdholland }
539*31615c96Sdholland complain(NULL, "Standard %s not supported by this preprocessor", std);
540*31615c96Sdholland die();
541*31615c96Sdholland }
542*31615c96Sdholland
543*31615c96Sdholland static
544*31615c96Sdholland void
commandline_setlang(const struct place * p,char * lang)545*31615c96Sdholland commandline_setlang(const struct place *p, char *lang)
546*31615c96Sdholland {
547*31615c96Sdholland (void)p;
548*31615c96Sdholland
549*31615c96Sdholland if (!strcmp(lang, "c") || !strcmp(lang, "assembler-with-cpp")) {
550*31615c96Sdholland return;
551*31615c96Sdholland }
552*31615c96Sdholland complain(NULL, "Language %s not supported by this preprocessor", lang);
553*31615c96Sdholland die();
554*31615c96Sdholland }
555*31615c96Sdholland
556*31615c96Sdholland ////////////////////////////////////////////////////////////
557*31615c96Sdholland // complex modes
558*31615c96Sdholland
559*31615c96Sdholland DEAD static
560*31615c96Sdholland void
commandline_iremap(const struct place * p,char * str)561*31615c96Sdholland commandline_iremap(const struct place *p, char *str)
562*31615c96Sdholland {
563*31615c96Sdholland (void)p;
564*31615c96Sdholland /* XXX */
565*31615c96Sdholland (void)str;
566*31615c96Sdholland complain(NULL, "-iremap not supported");
567*31615c96Sdholland die();
568*31615c96Sdholland }
569*31615c96Sdholland
570*31615c96Sdholland static
571*31615c96Sdholland void
commandline_tabstop(const struct place * p,char * s)572*31615c96Sdholland commandline_tabstop(const struct place *p, char *s)
573*31615c96Sdholland {
574*31615c96Sdholland char *t;
575*31615c96Sdholland unsigned long val;
576*31615c96Sdholland
577*31615c96Sdholland (void)p;
578*31615c96Sdholland
579*31615c96Sdholland t = strchr(s, '=');
580*31615c96Sdholland if (t == NULL) {
581*31615c96Sdholland /* should not happen */
582*31615c96Sdholland complain(NULL, "Invalid tabstop");
583*31615c96Sdholland die();
584*31615c96Sdholland }
585*31615c96Sdholland t++;
586*31615c96Sdholland errno = 0;
587*31615c96Sdholland val = strtoul(t, &t, 10);
588*31615c96Sdholland if (errno || *t != '\0') {
589*31615c96Sdholland complain(NULL, "Invalid tabstop");
590*31615c96Sdholland die();
591*31615c96Sdholland }
592*31615c96Sdholland if (val > 64) {
593*31615c96Sdholland complain(NULL, "Preposterously large tabstop");
594*31615c96Sdholland die();
595*31615c96Sdholland }
596*31615c96Sdholland mode.input_tabstop = val;
597*31615c96Sdholland }
598*31615c96Sdholland
599*31615c96Sdholland /*
600*31615c96Sdholland * macrolist
601*31615c96Sdholland */
602*31615c96Sdholland
603*31615c96Sdholland static
604*31615c96Sdholland void
commandline_dD(void)605*31615c96Sdholland commandline_dD(void)
606*31615c96Sdholland {
607*31615c96Sdholland mode.do_macrolist = true;
608*31615c96Sdholland mode.macrolist_include_stddef = false;
609*31615c96Sdholland mode.macrolist_include_expansions = true;
610*31615c96Sdholland }
611*31615c96Sdholland
612*31615c96Sdholland static
613*31615c96Sdholland void
commandline_dM(void)614*31615c96Sdholland commandline_dM(void)
615*31615c96Sdholland {
616*31615c96Sdholland mode.do_macrolist = true;
617*31615c96Sdholland mode.macrolist_include_stddef = true;
618*31615c96Sdholland mode.macrolist_include_expansions = true;
619*31615c96Sdholland mode.do_output = false;
620*31615c96Sdholland }
621*31615c96Sdholland
622*31615c96Sdholland static
623*31615c96Sdholland void
commandline_dN(void)624*31615c96Sdholland commandline_dN(void)
625*31615c96Sdholland {
626*31615c96Sdholland mode.do_macrolist = true;
627*31615c96Sdholland mode.macrolist_include_stddef = false;
628*31615c96Sdholland mode.macrolist_include_expansions = false;
629*31615c96Sdholland }
630*31615c96Sdholland
631*31615c96Sdholland /*
632*31615c96Sdholland * include trace
633*31615c96Sdholland */
634*31615c96Sdholland
635*31615c96Sdholland static
636*31615c96Sdholland void
commandline_dI(void)637*31615c96Sdholland commandline_dI(void)
638*31615c96Sdholland {
639*31615c96Sdholland mode.do_trace = true;
640*31615c96Sdholland mode.trace_namesonly = false;
641*31615c96Sdholland mode.trace_indented = false;
642*31615c96Sdholland }
643*31615c96Sdholland
644*31615c96Sdholland static
645*31615c96Sdholland void
commandline_H(void)646*31615c96Sdholland commandline_H(void)
647*31615c96Sdholland {
648*31615c96Sdholland mode.do_trace = true;
649*31615c96Sdholland mode.trace_namesonly = true;
650*31615c96Sdholland mode.trace_indented = true;
651*31615c96Sdholland }
652*31615c96Sdholland
653*31615c96Sdholland /*
654*31615c96Sdholland * depend
655*31615c96Sdholland */
656*31615c96Sdholland
657*31615c96Sdholland static
658*31615c96Sdholland void
commandline_setdependtarget(const struct place * p,char * str)659*31615c96Sdholland commandline_setdependtarget(const struct place *p, char *str)
660*31615c96Sdholland {
661*31615c96Sdholland (void)p;
662*31615c96Sdholland mode.depend_target = str;
663*31615c96Sdholland mode.depend_quote_target = false;
664*31615c96Sdholland }
665*31615c96Sdholland
666*31615c96Sdholland static
667*31615c96Sdholland void
commandline_setdependtarget_quoted(const struct place * p,char * str)668*31615c96Sdholland commandline_setdependtarget_quoted(const struct place *p, char *str)
669*31615c96Sdholland {
670*31615c96Sdholland (void)p;
671*31615c96Sdholland mode.depend_target = str;
672*31615c96Sdholland mode.depend_quote_target = true;
673*31615c96Sdholland }
674*31615c96Sdholland
675*31615c96Sdholland static
676*31615c96Sdholland void
commandline_setdependoutput(const struct place * p,char * str)677*31615c96Sdholland commandline_setdependoutput(const struct place *p, char *str)
678*31615c96Sdholland {
679*31615c96Sdholland (void)p;
680*31615c96Sdholland mode.depend_file = str;
681*31615c96Sdholland }
682*31615c96Sdholland
683*31615c96Sdholland static
684*31615c96Sdholland void
commandline_M(void)685*31615c96Sdholland commandline_M(void)
686*31615c96Sdholland {
687*31615c96Sdholland mode.do_depend = true;
688*31615c96Sdholland mode.depend_report_system = true;
689*31615c96Sdholland mode.do_output = false;
690*31615c96Sdholland }
691*31615c96Sdholland
692*31615c96Sdholland static
693*31615c96Sdholland void
commandline_MM(void)694*31615c96Sdholland commandline_MM(void)
695*31615c96Sdholland {
696*31615c96Sdholland mode.do_depend = true;
697*31615c96Sdholland mode.depend_report_system = false;
698*31615c96Sdholland mode.do_output = false;
699*31615c96Sdholland }
700*31615c96Sdholland
701*31615c96Sdholland static
702*31615c96Sdholland void
commandline_MD(void)703*31615c96Sdholland commandline_MD(void)
704*31615c96Sdholland {
705*31615c96Sdholland mode.do_depend = true;
706*31615c96Sdholland mode.depend_report_system = true;
707*31615c96Sdholland }
708*31615c96Sdholland
709*31615c96Sdholland static
710*31615c96Sdholland void
commandline_MMD(void)711*31615c96Sdholland commandline_MMD(void)
712*31615c96Sdholland {
713*31615c96Sdholland mode.do_depend = true;
714*31615c96Sdholland mode.depend_report_system = false;
715*31615c96Sdholland }
716*31615c96Sdholland
717*31615c96Sdholland static
718*31615c96Sdholland void
commandline_wall(void)719*31615c96Sdholland commandline_wall(void)
720*31615c96Sdholland {
721*31615c96Sdholland warns.nestcomment = true;
722*31615c96Sdholland warns.undef = true;
723*31615c96Sdholland warns.unused = true;
724*31615c96Sdholland }
725*31615c96Sdholland
726*31615c96Sdholland static
727*31615c96Sdholland void
commandline_wnoall(void)728*31615c96Sdholland commandline_wnoall(void)
729*31615c96Sdholland {
730*31615c96Sdholland warns.nestcomment = false;
731*31615c96Sdholland warns.undef = false;
732*31615c96Sdholland warns.unused = false;
733*31615c96Sdholland }
734*31615c96Sdholland
735*31615c96Sdholland static
736*31615c96Sdholland void
commandline_wnone(void)737*31615c96Sdholland commandline_wnone(void)
738*31615c96Sdholland {
739*31615c96Sdholland warns.nestcomment = false;
740*31615c96Sdholland warns.endiflabels = false;
741*31615c96Sdholland warns.undef = false;
742*31615c96Sdholland warns.unused = false;
743*31615c96Sdholland }
744*31615c96Sdholland
745*31615c96Sdholland ////////////////////////////////////////////////////////////
746*31615c96Sdholland // options
747*31615c96Sdholland
748*31615c96Sdholland struct ignore_option {
749*31615c96Sdholland const char *string;
750*31615c96Sdholland };
751*31615c96Sdholland
752*31615c96Sdholland struct flag_option {
753*31615c96Sdholland const char *string;
754*31615c96Sdholland bool *flag;
755*31615c96Sdholland bool setto;
756*31615c96Sdholland };
757*31615c96Sdholland
758*31615c96Sdholland struct act_option {
759*31615c96Sdholland const char *string;
760*31615c96Sdholland void (*func)(void);
761*31615c96Sdholland };
762*31615c96Sdholland
763*31615c96Sdholland struct prefix_option {
764*31615c96Sdholland const char *string;
765*31615c96Sdholland void (*func)(const struct place *, char *);
766*31615c96Sdholland };
767*31615c96Sdholland
768*31615c96Sdholland struct arg_option {
769*31615c96Sdholland const char *string;
770*31615c96Sdholland void (*func)(const struct place *, char *);
771*31615c96Sdholland };
772*31615c96Sdholland
773*31615c96Sdholland static const struct ignore_option ignore_options[] = {
774*31615c96Sdholland { "m32" },
775*31615c96Sdholland { "traditional" },
776*31615c96Sdholland };
777*31615c96Sdholland static const unsigned num_ignore_options = HOWMANY(ignore_options);
778*31615c96Sdholland
779*31615c96Sdholland static const struct flag_option flag_options[] = {
780*31615c96Sdholland { "C", &mode.output_retain_comments, true },
781*31615c96Sdholland { "CC", &mode.output_retain_comments, true },
782*31615c96Sdholland { "MG", &mode.depend_assume_generated, true },
783*31615c96Sdholland { "MP", &mode.depend_issue_fakerules, true },
784*31615c96Sdholland { "P", &mode.output_linenumbers, false },
785*31615c96Sdholland { "Wcomment", &warns.nestcomment, true },
786*31615c96Sdholland { "Wendif-labels", &warns.endiflabels, true },
787*31615c96Sdholland { "Werror", &mode.werror, true },
788*31615c96Sdholland { "Wno-comment", &warns.nestcomment, false },
789*31615c96Sdholland { "Wno-endif-labels", &warns.endiflabels, false },
790*31615c96Sdholland { "Wno-error", &mode.werror, false },
791*31615c96Sdholland { "Wno-undef", &warns.undef, false },
792*31615c96Sdholland { "Wno-unused-macros", &warns.unused, false },
793*31615c96Sdholland { "Wundef", &warns.undef, true },
794*31615c96Sdholland { "Wunused-macros", &warns.unused, true },
795*31615c96Sdholland { "fdollars-in-identifiers", &mode.input_allow_dollars, true },
796*31615c96Sdholland { "fno-dollars-in-identifiers", &mode.input_allow_dollars, false },
797*31615c96Sdholland { "nostdinc", &mode.do_stdinc, false },
798*31615c96Sdholland { "p", &mode.output_cheaplinenumbers, true },
799*31615c96Sdholland { "undef", &mode.do_stddef, false },
800*31615c96Sdholland };
801*31615c96Sdholland static const unsigned num_flag_options = HOWMANY(flag_options);
802*31615c96Sdholland
803*31615c96Sdholland static const struct act_option act_options[] = {
804*31615c96Sdholland { "H", commandline_H },
805*31615c96Sdholland { "M", commandline_M },
806*31615c96Sdholland { "MD", commandline_MD },
807*31615c96Sdholland { "MM", commandline_MM },
808*31615c96Sdholland { "MMD", commandline_MMD },
809*31615c96Sdholland { "Wall", commandline_wall },
810*31615c96Sdholland { "Wno-all", commandline_wnoall },
811*31615c96Sdholland { "dD", commandline_dD },
812*31615c96Sdholland { "dI", commandline_dI },
813*31615c96Sdholland { "dM", commandline_dM },
814*31615c96Sdholland { "dN", commandline_dN },
815*31615c96Sdholland { "w", commandline_wnone },
816*31615c96Sdholland };
817*31615c96Sdholland static const unsigned num_act_options = HOWMANY(act_options);
818*31615c96Sdholland
819*31615c96Sdholland static const struct prefix_option prefix_options[] = {
820*31615c96Sdholland { "D", commandline_def },
821*31615c96Sdholland { "I", commandline_addincpath_user },
822*31615c96Sdholland { "U", commandline_undef },
823*31615c96Sdholland { "ftabstop=", commandline_tabstop },
824*31615c96Sdholland { "std=", commandline_setstd },
825*31615c96Sdholland };
826*31615c96Sdholland static const unsigned num_prefix_options = HOWMANY(prefix_options);
827*31615c96Sdholland
828*31615c96Sdholland static const struct arg_option arg_options[] = {
829*31615c96Sdholland { "MF", commandline_setdependoutput },
830*31615c96Sdholland { "MQ", commandline_setdependtarget_quoted },
831*31615c96Sdholland { "MT", commandline_setdependtarget },
832*31615c96Sdholland { "debuglog", debuglog_open },
833*31615c96Sdholland { "idirafter", commandline_addincpath_late },
834*31615c96Sdholland { "imacros", commandline_addfile_nooutput },
835*31615c96Sdholland { "include", commandline_addfile_output },
836*31615c96Sdholland { "iprefix", commandline_setprefix },
837*31615c96Sdholland { "iquote", commandline_addincpath_quote },
838*31615c96Sdholland { "iremap", commandline_iremap },
839*31615c96Sdholland { "isysroot", commandline_isysroot },
840*31615c96Sdholland { "isystem", commandline_addincpath_system },
841*31615c96Sdholland { "iwithprefix", commandline_addincpath_late_withprefix },
842*31615c96Sdholland { "iwithprefixbefore", commandline_addincpath_user_withprefix },
843*31615c96Sdholland { "x", commandline_setlang },
844*31615c96Sdholland };
845*31615c96Sdholland static const unsigned num_arg_options = HOWMANY(arg_options);
846*31615c96Sdholland
847*31615c96Sdholland static
848*31615c96Sdholland bool
check_ignore_option(const char * opt)849*31615c96Sdholland check_ignore_option(const char *opt)
850*31615c96Sdholland {
851*31615c96Sdholland unsigned i;
852*31615c96Sdholland int r;
853*31615c96Sdholland
854*31615c96Sdholland for (i=0; i<num_ignore_options; i++) {
855*31615c96Sdholland r = strcmp(opt, ignore_options[i].string);
856*31615c96Sdholland if (r == 0) {
857*31615c96Sdholland return true;
858*31615c96Sdholland }
859*31615c96Sdholland if (r < 0) {
860*31615c96Sdholland break;
861*31615c96Sdholland }
862*31615c96Sdholland }
863*31615c96Sdholland return false;
864*31615c96Sdholland }
865*31615c96Sdholland
866*31615c96Sdholland static
867*31615c96Sdholland bool
check_flag_option(const char * opt)868*31615c96Sdholland check_flag_option(const char *opt)
869*31615c96Sdholland {
870*31615c96Sdholland unsigned i;
871*31615c96Sdholland int r;
872*31615c96Sdholland
873*31615c96Sdholland for (i=0; i<num_flag_options; i++) {
874*31615c96Sdholland r = strcmp(opt, flag_options[i].string);
875*31615c96Sdholland if (r == 0) {
876*31615c96Sdholland *flag_options[i].flag = flag_options[i].setto;
877*31615c96Sdholland return true;
878*31615c96Sdholland }
879*31615c96Sdholland if (r < 0) {
880*31615c96Sdholland break;
881*31615c96Sdholland }
882*31615c96Sdholland }
883*31615c96Sdholland return false;
884*31615c96Sdholland }
885*31615c96Sdholland
886*31615c96Sdholland static
887*31615c96Sdholland bool
check_act_option(const char * opt)888*31615c96Sdholland check_act_option(const char *opt)
889*31615c96Sdholland {
890*31615c96Sdholland unsigned i;
891*31615c96Sdholland int r;
892*31615c96Sdholland
893*31615c96Sdholland for (i=0; i<num_act_options; i++) {
894*31615c96Sdholland r = strcmp(opt, act_options[i].string);
895*31615c96Sdholland if (r == 0) {
896*31615c96Sdholland act_options[i].func();
897*31615c96Sdholland return true;
898*31615c96Sdholland }
899*31615c96Sdholland if (r < 0) {
900*31615c96Sdholland break;
901*31615c96Sdholland }
902*31615c96Sdholland }
903*31615c96Sdholland return false;
904*31615c96Sdholland }
905*31615c96Sdholland
906*31615c96Sdholland static
907*31615c96Sdholland bool
check_prefix_option(const struct place * p,char * opt)908*31615c96Sdholland check_prefix_option(const struct place *p, char *opt)
909*31615c96Sdholland {
910*31615c96Sdholland unsigned i, len;
911*31615c96Sdholland int r;
912*31615c96Sdholland
913*31615c96Sdholland for (i=0; i<num_prefix_options; i++) {
914*31615c96Sdholland len = strlen(prefix_options[i].string);
915*31615c96Sdholland r = strncmp(opt, prefix_options[i].string, len);
916*31615c96Sdholland if (r == 0) {
917*31615c96Sdholland prefix_options[i].func(p, opt + len);
918*31615c96Sdholland return true;
919*31615c96Sdholland }
920*31615c96Sdholland if (r < 0) {
921*31615c96Sdholland break;
922*31615c96Sdholland }
923*31615c96Sdholland }
924*31615c96Sdholland return false;
925*31615c96Sdholland }
926*31615c96Sdholland
927*31615c96Sdholland static
928*31615c96Sdholland bool
check_arg_option(const char * opt,const struct place * argplace,char * arg)929*31615c96Sdholland check_arg_option(const char *opt, const struct place *argplace, char *arg)
930*31615c96Sdholland {
931*31615c96Sdholland unsigned i;
932*31615c96Sdholland int r;
933*31615c96Sdholland
934*31615c96Sdholland for (i=0; i<num_arg_options; i++) {
935*31615c96Sdholland r = strcmp(opt, arg_options[i].string);
936*31615c96Sdholland if (r == 0) {
937*31615c96Sdholland if (arg == NULL) {
938*31615c96Sdholland complain(NULL,
939*31615c96Sdholland "Option -%s requires an argument",
940*31615c96Sdholland opt);
941*31615c96Sdholland die();
942*31615c96Sdholland }
943*31615c96Sdholland arg_options[i].func(argplace, arg);
944*31615c96Sdholland return true;
945*31615c96Sdholland }
946*31615c96Sdholland if (r < 0) {
947*31615c96Sdholland break;
948*31615c96Sdholland }
949*31615c96Sdholland }
950*31615c96Sdholland return false;
951*31615c96Sdholland }
952*31615c96Sdholland
953*31615c96Sdholland DEAD PF(2, 3) static
954*31615c96Sdholland void
usage(const char * progname,const char * fmt,...)955*31615c96Sdholland usage(const char *progname, const char *fmt, ...)
956*31615c96Sdholland {
957*31615c96Sdholland va_list ap;
958*31615c96Sdholland
959*31615c96Sdholland fprintf(stderr, "%s: ", progname);
960*31615c96Sdholland va_start(ap, fmt);
961*31615c96Sdholland vfprintf(stderr, fmt, ap);
962*31615c96Sdholland va_end(ap);
963*31615c96Sdholland fprintf(stderr, "\n");
964*31615c96Sdholland
965*31615c96Sdholland fprintf(stderr, "usage: %s [options] [infile [outfile]]\n", progname);
966*31615c96Sdholland fprintf(stderr, "Common options:\n");
967*31615c96Sdholland fprintf(stderr, " -C Retain comments\n");
968*31615c96Sdholland fprintf(stderr, " -Dmacro[=def] Predefine macro\n");
969*31615c96Sdholland fprintf(stderr, " -Idir Add to include path\n");
970*31615c96Sdholland fprintf(stderr, " -M Issue depend info\n");
971*31615c96Sdholland fprintf(stderr, " -MD Issue depend info and output\n");
972*31615c96Sdholland fprintf(stderr, " -MM -M w/o system headers\n");
973*31615c96Sdholland fprintf(stderr, " -MMD -MD w/o system headers\n");
974*31615c96Sdholland fprintf(stderr, " -nostdinc Drop default include path\n");
975*31615c96Sdholland fprintf(stderr, " -Umacro Undefine macro\n");
976*31615c96Sdholland fprintf(stderr, " -undef Undefine everything\n");
977*31615c96Sdholland fprintf(stderr, " -Wall Enable all warnings\n");
978*31615c96Sdholland fprintf(stderr, " -Werror Make warnings into errors\n");
979*31615c96Sdholland fprintf(stderr, " -w Disable all warnings\n");
980*31615c96Sdholland die();
981*31615c96Sdholland }
982*31615c96Sdholland
983*31615c96Sdholland ////////////////////////////////////////////////////////////
984*31615c96Sdholland // exit and cleanup
985*31615c96Sdholland
986*31615c96Sdholland static struct stringarray freestrings;
987*31615c96Sdholland
988*31615c96Sdholland static
989*31615c96Sdholland void
init(void)990*31615c96Sdholland init(void)
991*31615c96Sdholland {
992*31615c96Sdholland stringarray_init(&freestrings);
993*31615c96Sdholland
994*31615c96Sdholland incpath_init();
995*31615c96Sdholland commandline_macros_init();
996*31615c96Sdholland commandline_files_init();
997*31615c96Sdholland
998*31615c96Sdholland place_init();
999*31615c96Sdholland files_init();
1000*31615c96Sdholland directive_init();
1001*31615c96Sdholland macros_init();
1002*31615c96Sdholland }
1003*31615c96Sdholland
1004*31615c96Sdholland static
1005*31615c96Sdholland void
cleanup(void)1006*31615c96Sdholland cleanup(void)
1007*31615c96Sdholland {
1008*31615c96Sdholland unsigned i, num;
1009*31615c96Sdholland
1010*31615c96Sdholland macros_cleanup();
1011*31615c96Sdholland directive_cleanup();
1012*31615c96Sdholland files_cleanup();
1013*31615c96Sdholland place_cleanup();
1014*31615c96Sdholland
1015*31615c96Sdholland commandline_files_cleanup();
1016*31615c96Sdholland commandline_macros_cleanup();
1017*31615c96Sdholland incpath_cleanup();
1018*31615c96Sdholland debuglog_close();
1019*31615c96Sdholland
1020*31615c96Sdholland num = stringarray_num(&freestrings);
1021*31615c96Sdholland for (i=0; i<num; i++) {
1022*31615c96Sdholland dostrfree(stringarray_get(&freestrings, i));
1023*31615c96Sdholland }
1024*31615c96Sdholland stringarray_setsize(&freestrings, 0);
1025*31615c96Sdholland stringarray_cleanup(&freestrings);
1026*31615c96Sdholland }
1027*31615c96Sdholland
1028*31615c96Sdholland void
die(void)1029*31615c96Sdholland die(void)
1030*31615c96Sdholland {
1031*31615c96Sdholland cleanup();
1032*31615c96Sdholland exit(EXIT_FAILURE);
1033*31615c96Sdholland }
1034*31615c96Sdholland
1035*31615c96Sdholland void
freestringlater(char * s)1036*31615c96Sdholland freestringlater(char *s)
1037*31615c96Sdholland {
1038*31615c96Sdholland stringarray_add(&freestrings, s, NULL);
1039*31615c96Sdholland }
1040*31615c96Sdholland
1041*31615c96Sdholland ////////////////////////////////////////////////////////////
1042*31615c96Sdholland // main
1043*31615c96Sdholland
1044*31615c96Sdholland int
main(int argc,char * argv[])1045*31615c96Sdholland main(int argc, char *argv[])
1046*31615c96Sdholland {
1047*31615c96Sdholland const char *progname;
1048*31615c96Sdholland const char *inputfile = NULL;
1049*31615c96Sdholland const char *outputfile = NULL;
1050*31615c96Sdholland struct place cmdplace;
1051*31615c96Sdholland int i;
1052*31615c96Sdholland
1053*31615c96Sdholland progname = strrchr(argv[0], '/');
1054*31615c96Sdholland progname = progname == NULL ? argv[0] : progname + 1;
1055*31615c96Sdholland complain_init(progname);
1056*31615c96Sdholland
1057*31615c96Sdholland init();
1058*31615c96Sdholland
1059*31615c96Sdholland for (i=1; i<argc; i++) {
1060*31615c96Sdholland if (argv[i][0] != '-' || argv[i][1] == 0) {
1061*31615c96Sdholland break;
1062*31615c96Sdholland }
1063*31615c96Sdholland place_setcommandline(&cmdplace, i, 1);
1064*31615c96Sdholland if (check_ignore_option(argv[i]+1)) {
1065*31615c96Sdholland continue;
1066*31615c96Sdholland }
1067*31615c96Sdholland if (check_flag_option(argv[i]+1)) {
1068*31615c96Sdholland continue;
1069*31615c96Sdholland }
1070*31615c96Sdholland if (check_act_option(argv[i]+1)) {
1071*31615c96Sdholland continue;
1072*31615c96Sdholland }
1073*31615c96Sdholland if (check_prefix_option(&cmdplace, argv[i]+1)) {
1074*31615c96Sdholland continue;
1075*31615c96Sdholland }
1076*31615c96Sdholland place_setcommandline(&cmdplace, i+1, 1);
1077*31615c96Sdholland if (check_arg_option(argv[i]+1, &cmdplace, argv[i+1])) {
1078*31615c96Sdholland i++;
1079*31615c96Sdholland continue;
1080*31615c96Sdholland }
1081*31615c96Sdholland usage(progname, "Invalid option %s", argv[i]);
1082*31615c96Sdholland }
1083*31615c96Sdholland if (i < argc) {
1084*31615c96Sdholland inputfile = argv[i++];
1085*31615c96Sdholland if (!strcmp(inputfile, "-")) {
1086*31615c96Sdholland inputfile = NULL;
1087*31615c96Sdholland }
1088*31615c96Sdholland }
1089*31615c96Sdholland if (i < argc) {
1090*31615c96Sdholland outputfile = argv[i++];
1091*31615c96Sdholland if (!strcmp(outputfile, "-")) {
1092*31615c96Sdholland outputfile = NULL;
1093*31615c96Sdholland }
1094*31615c96Sdholland }
1095*31615c96Sdholland if (i < argc) {
1096*31615c96Sdholland usage(progname, "Extra non-option argument %s", argv[i]);
1097*31615c96Sdholland }
1098*31615c96Sdholland
1099*31615c96Sdholland mode.output_file = outputfile;
1100*31615c96Sdholland
1101*31615c96Sdholland loadincludepath();
1102*31615c96Sdholland apply_builtin_macros();
1103*31615c96Sdholland apply_commandline_macros();
1104*31615c96Sdholland read_commandline_files();
1105*31615c96Sdholland place_setnowhere(&cmdplace);
1106*31615c96Sdholland file_readabsolute(&cmdplace, inputfile);
1107*31615c96Sdholland
1108*31615c96Sdholland cleanup();
1109*31615c96Sdholland if (complain_failed()) {
1110*31615c96Sdholland return EXIT_FAILURE;
1111*31615c96Sdholland }
1112*31615c96Sdholland return EXIT_SUCCESS;
1113*31615c96Sdholland }
1114