xref: /illumos-gate/usr/src/contrib/ast/src/lib/libpp/ppargs.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1986-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman  * Glenn Fowler
23*b30d1939SAndy Fiddaman  * AT&T Research
24*b30d1939SAndy Fiddaman  *
25*b30d1939SAndy Fiddaman  * common preprocessor command line argument parse
26*b30d1939SAndy Fiddaman  * called by optjoin()
27*b30d1939SAndy Fiddaman  */
28*b30d1939SAndy Fiddaman 
29*b30d1939SAndy Fiddaman static const char usage[] =
30*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: cpp (AT&T Research) 2009-02-02 $\n]"
31*b30d1939SAndy Fiddaman USAGE_LICENSE
32*b30d1939SAndy Fiddaman "[+NAME?cpp - C language preprocessor]"
33*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bcpp\b is the preprocessor for all C language dialects. It is"
34*b30d1939SAndy Fiddaman "	a standalone version of the \blibpp\b(3) preprocessor library. The"
35*b30d1939SAndy Fiddaman "	C dialect implemented by \bcpp\b is determined by probing \bcc\b(1)"
36*b30d1939SAndy Fiddaman "	using \bprobe\b(1). The path of the emulated compiler can be changed"
37*b30d1939SAndy Fiddaman "	by the \b-D-X\b command line option.]"
38*b30d1939SAndy Fiddaman "[+?If \aoutput\a is omitted then the standard output is written; if \ainput\a"
39*b30d1939SAndy Fiddaman "	is also omitted then the standard input is read. NOTE: this is an"
40*b30d1939SAndy Fiddaman "	ancient, non-standard, non-intuitiive file operand syntax that is"
41*b30d1939SAndy Fiddaman "	required by \bcc\b(1); use shell file name expansion at your peril.]"
42*b30d1939SAndy Fiddaman "[+?\bcpp\b specific options are set by the \b-D-\b and \b-I-\b options.]"
43*b30d1939SAndy Fiddaman 
44*b30d1939SAndy Fiddaman "[C:comments?Pass comments to the output. By default comments are omitted.]"
45*b30d1939SAndy Fiddaman "[D:define?Define the macro \aname\a to have \avalue\a; \b1\b is assumed if"
46*b30d1939SAndy Fiddaman "	\b=\b\avalue\a is omitted. If \aname\a begins with \b:\b then it is"
47*b30d1939SAndy Fiddaman "	interpreted as a \blibpp\b(3) \b#pragma pp:\b statement; if \aname\a"
48*b30d1939SAndy Fiddaman "	begins with \b%\b then it is interpreted as a \blibpp\b(3) \b#\b"
49*b30d1939SAndy Fiddaman "	directive statement; if \aname\a begins with \b-\b or \b+\b then it is"
50*b30d1939SAndy Fiddaman "	interpreted as a \blibpp\b(3) option; \b-\b turns the option on,"
51*b30d1939SAndy Fiddaman "	\b+\b turns it off. Most options have a \b#pragma\b counterpart that"
52*b30d1939SAndy Fiddaman "	is listed with the option definition. Right, this is ugly, but its the"
53*b30d1939SAndy Fiddaman "	only portable way to pass options through \bcc\b(1) to"
54*b30d1939SAndy Fiddaman "	\bcpp\b:]:[name[=value]]]{"
55*b30d1939SAndy Fiddaman "	[+-D-C, pp::compatibility?Preprocess for K&R compatibility.]"
56*b30d1939SAndy Fiddaman "	[+-D-D\alevel\a, \bpp::debug\b \alevel\a?Set the debug trace level."
57*b30d1939SAndy Fiddaman "		Higher levels produce more output. Levels higher than 3"
58*b30d1939SAndy Fiddaman "		enabled only in \b-g\b compiled versions.]"
59*b30d1939SAndy Fiddaman "	[+-D-F\aname\a?Set the main input file name to \aname\a. This only"
60*b30d1939SAndy Fiddaman "		affects error message and line sync output.]"
61*b30d1939SAndy Fiddaman "	[+-D-H, pp::hosted?All directories are hosted; compatibility"
62*b30d1939SAndy Fiddaman "		warning messages from hosted directory headers are suppressed.]"
63*b30d1939SAndy Fiddaman "	[+-D-I, pp::cdir?All directories contain C headers; used only with"
64*b30d1939SAndy Fiddaman "		\b-D-+\b.]"
65*b30d1939SAndy Fiddaman "	[+-D-K, pp::keyargs?Enable the non-standard \aname=value\a macro"
66*b30d1939SAndy Fiddaman "		argument mode.]"
67*b30d1939SAndy Fiddaman "	[+-D-L\b[\aid\a]], \bpp::lineid\b [\aid\a]]?Set the line sync directive"
68*b30d1939SAndy Fiddaman "		id to \aid\a or null if omitted.]"
69*b30d1939SAndy Fiddaman "	[+-D-M, pp::nomultiple?Disable multiple include detection.]"
70*b30d1939SAndy Fiddaman "	[+-D-P, pp::passthrough?Enable the non-standard passthrough mode; may"
71*b30d1939SAndy Fiddaman "		be useful for processing non-C input.]"
72*b30d1939SAndy Fiddaman "	[+-D-Q, pp::dump?Dump macro definitions to the output so that the"
73*b30d1939SAndy Fiddaman "		output may be passed through \bcpp\b again. Used for"
74*b30d1939SAndy Fiddaman "		generating precompiled headers.]"
75*b30d1939SAndy Fiddaman "	[+-D-R, pp::transition?Enable the transition preprocessing mode. Used"
76*b30d1939SAndy Fiddaman "		for compilers that can't make up their semantics between"
77*b30d1939SAndy Fiddaman "		K&R and ISO.]"
78*b30d1939SAndy Fiddaman "	[+-D-S, pp::strict?Enable strict preprocessing semantics and warnings."
79*b30d1939SAndy Fiddaman "		Works with any mode (compatibiliy, transition,"
80*b30d1939SAndy Fiddaman "		or the default ISO).]"
81*b30d1939SAndy Fiddaman "	[+-D-T\atest\a, \bpp::test\b \atest\a?Enable implementation specific"
82*b30d1939SAndy Fiddaman "		test code according to \atest\a.]"
83*b30d1939SAndy Fiddaman "	[+-D-W, pp::warn?Enable warnings in non-hosted files.]"
84*b30d1939SAndy Fiddaman "	[+-D-X\b[\acc\a]]?Preprocess for the compiler \acc\a which must be"
85*b30d1939SAndy Fiddaman "		an executable path or an executable on \b$PATH\b.]"
86*b30d1939SAndy Fiddaman "	[+-D-Y, pp::pedantic?Enable pedantic \bpp::warn\b warnings in"
87*b30d1939SAndy Fiddaman "		non-hosted files.]"
88*b30d1939SAndy Fiddaman "	[+-D-Z, pp::pool?Enable pool mode. See \blibpp\b(3).]"
89*b30d1939SAndy Fiddaman "	[+-D-d?List canonicalized \b#define\b statements for non-predefined"
90*b30d1939SAndy Fiddaman "		macros in the output. ]"
91*b30d1939SAndy Fiddaman "	[+-D-m?List canonicalized \b#define\b statements for all macros. All"
92*b30d1939SAndy Fiddaman "		other output is disabled.]"
93*b30d1939SAndy Fiddaman "	[+-D-+, pp::plusplus?Preprocess for the C++ dialect.]"
94*b30d1939SAndy Fiddaman "}"
95*b30d1939SAndy Fiddaman "[I:include?Append \adirectory\a to the list of directories searched for"
96*b30d1939SAndy Fiddaman "	\b#include\b files. If \adirectory\a is \b-\b then: (1) \b-I\b"
97*b30d1939SAndy Fiddaman "	directories before \b-I-\b are searched only for \"...\" include"
98*b30d1939SAndy Fiddaman "	files; (2) \b-I\b directories after \b-I-\b are searched for"
99*b30d1939SAndy Fiddaman "	\"...\" and <...> include files; (3) the directory \b.\b is searched"
100*b30d1939SAndy Fiddaman "	only if it is explicitly specified by a \b-I\b option.]:?[directory]{"
101*b30d1939SAndy Fiddaman "	[+-I-C\adirectory\a, \bpp::cdir\b \adirectory\a?Mark \adirectory\a"
102*b30d1939SAndy Fiddaman "		as a C header directory. Used with \bpp:plusplus\b.]"
103*b30d1939SAndy Fiddaman "	[+-I-D[\afile\a]]?Read the default \bprobe\b(1) definitions from"
104*b30d1939SAndy Fiddaman "		\afile\a, or ignore the default definitions if \afile\a"
105*b30d1939SAndy Fiddaman "		is omitted.]"
106*b30d1939SAndy Fiddaman "	[+-I-H\adirectory\a, \bpp::hostdir\b \adirectory\a?Mark \adirectory\a"
107*b30d1939SAndy Fiddaman "		as a hosted directory. Headers from hosted directories have"
108*b30d1939SAndy Fiddaman "		compatibility warnings disabled.]"
109*b30d1939SAndy Fiddaman "	[+-I-I\aheader\a, \bpp::ignore\b \aheader\a?Add \aheader\a to the"
110*b30d1939SAndy Fiddaman "		list of ignored headers.]"
111*b30d1939SAndy Fiddaman "	[+-I-M\afile\a?\afile\a contains a sequence of \aheader\a"
112*b30d1939SAndy Fiddaman "		[= \"\amap\a\" ]] lines, where \aheader\a is either <\aname\a>"
113*b30d1939SAndy Fiddaman "		or \"\aname\a\", and \"\amap\a\" is an explicit binding"
114*b30d1939SAndy Fiddaman "		for \aheader\a. \aheader\a is ignored if = \"\amap\a\" is"
115*b30d1939SAndy Fiddaman "		omitted.]"
116*b30d1939SAndy Fiddaman "	[+-I-R\afile\a?Include \afile\a but do not emit text or line syncs.]"
117*b30d1939SAndy Fiddaman "	[+-I-S\adirectory\a?Add \adirectory\a to the default standard include"
118*b30d1939SAndy Fiddaman "		directory list.]"
119*b30d1939SAndy Fiddaman "	[+-I-T\afile\a?Include \afile\a and emit text to the output file.]"
120*b30d1939SAndy Fiddaman "}"
121*b30d1939SAndy Fiddaman "[M:dependencies?Generate \bmake\b(1) dependencies. Not needed with"
122*b30d1939SAndy Fiddaman "	\bnmake\b(1). \b-M\b may be followed by optional \aflags\a to change"
123*b30d1939SAndy Fiddaman "	dependency output styles:]{"
124*b30d1939SAndy Fiddaman "	[+D?Generate dependencies in a separate \b.d\b file. Preprocessed"
125*b30d1939SAndy Fiddaman "		output is still written to \aoutput\a, or the standard output"
126*b30d1939SAndy Fiddaman "		if \aoutput\a is omitted.]"
127*b30d1939SAndy Fiddaman "	[+G?Generate missing dependencies too.]"
128*b30d1939SAndy Fiddaman "	[+M?Only generate local header dependencies; \ahosted\a headers are"
129*b30d1939SAndy Fiddaman "		omitted. Note that \ahosted\a headers are determined by"
130*b30d1939SAndy Fiddaman "		\b-I-H\b and the \bpp:hosted\b and \bpp:hostdir\b pragmas;"
131*b30d1939SAndy Fiddaman "		no special distiction is made between \"\" and <> \binclude\b"
132*b30d1939SAndy Fiddaman "		styles.]"
133*b30d1939SAndy Fiddaman "}"
134*b30d1939SAndy Fiddaman "[P!:sync?Emit line syncs.]"
135*b30d1939SAndy Fiddaman "[U:undefine?Remove the definition for the macro \aname\a.]:[name]"
136*b30d1939SAndy Fiddaman 
137*b30d1939SAndy Fiddaman "[A:assert?Enter the assertion via \b#assert\b for system V"
138*b30d1939SAndy Fiddaman "	compatibility.]:[assertion]"
139*b30d1939SAndy Fiddaman "[E:preprocess?Ignored for compatibility with ancient compilers.]"
140*b30d1939SAndy Fiddaman "[H:include-reference?Emit \b#include\b file paths on the standard error,"
141*b30d1939SAndy Fiddaman "	one per line, indented to show nesting. If the optional \asize\a"
142*b30d1939SAndy Fiddaman "	argument is specified then the entire \b-H\b option is"
143*b30d1939SAndy Fiddaman "	ignored.]#?[size]"
144*b30d1939SAndy Fiddaman "[T?If not \bgcc\b(1) then truncate identifiers to \alength\a"
145*b30d1939SAndy Fiddaman "	characters for compatibility with old AT&T (I guess only Lucent needs"
146*b30d1939SAndy Fiddaman "	them now) compilers.]#?[length]"
147*b30d1939SAndy Fiddaman "[V:version?Emit the \blibpp\b(3) version.]"
148*b30d1939SAndy Fiddaman "[X:argmode?Enable \aname\a=\avalue\a macro arguments for \beasel\b(1)"
149*b30d1939SAndy Fiddaman "	compatibility.]"
150*b30d1939SAndy Fiddaman "[Y:standard?Add \adirectory\a to the list searched for"
151*b30d1939SAndy Fiddaman "	\b#include\b \b<...>\b files.]:[directory]"
152*b30d1939SAndy Fiddaman 
153*b30d1939SAndy Fiddaman "\n"
154*b30d1939SAndy Fiddaman "\n[ input [ output ] ]\n"
155*b30d1939SAndy Fiddaman "\n"
156*b30d1939SAndy Fiddaman 
157*b30d1939SAndy Fiddaman "[+SEE ALSO?\bcc\b(1), \bgcc\b(1), \blibpp\b(3)]"
158*b30d1939SAndy Fiddaman ;
159*b30d1939SAndy Fiddaman 
160*b30d1939SAndy Fiddaman #include "pplib.h"
161*b30d1939SAndy Fiddaman 
162*b30d1939SAndy Fiddaman #include <ctype.h>
163*b30d1939SAndy Fiddaman 
164*b30d1939SAndy Fiddaman /*
165*b30d1939SAndy Fiddaman  * convert lint comments to pragmas
166*b30d1939SAndy Fiddaman  */
167*b30d1939SAndy Fiddaman 
168*b30d1939SAndy Fiddaman static void
pplint(char * head,char * comment,char * tail,int line)169*b30d1939SAndy Fiddaman pplint(char* head, char* comment, char* tail, int line)
170*b30d1939SAndy Fiddaman {
171*b30d1939SAndy Fiddaman 	NoP(line);
172*b30d1939SAndy Fiddaman 	if (strmatch(comment, "(ARGSUSED|PRINTFLIKE|PROTOLIB|SCANFLIKE|VARARGS)*([0-9])|CONSTCOND|CONSTANTCOND|CONSTANTCONDITION|EMPTY|FALLTHRU|FALLTHROUGH|LINTLIBRARY|LINTED*|NOTREACHED"))
173*b30d1939SAndy Fiddaman 	{
174*b30d1939SAndy Fiddaman 		strncopy(pp.token, comment, MAXTOKEN);
175*b30d1939SAndy Fiddaman 		ppprintf("\n#%s %s:%s\n", dirname(PRAGMA), pp.pass, pp.token);
176*b30d1939SAndy Fiddaman 		ppline(error_info.line, NiL);
177*b30d1939SAndy Fiddaman 	}
178*b30d1939SAndy Fiddaman }
179*b30d1939SAndy Fiddaman 
180*b30d1939SAndy Fiddaman /*
181*b30d1939SAndy Fiddaman  * if last!=0 then argv[opt_info.index]==0 with return(0)
182*b30d1939SAndy Fiddaman  * else if argv[opt_info.index]==0 then return(0)
183*b30d1939SAndy Fiddaman  * otherwise argv[opt_info.index] is the first unrecognized
184*b30d1939SAndy Fiddaman  * option with return(1)
185*b30d1939SAndy Fiddaman  *
186*b30d1939SAndy Fiddaman  * use last=0 if the preprocessor is combined with other passes
187*b30d1939SAndy Fiddaman  * so that unknown options may be interpreted for those passes
188*b30d1939SAndy Fiddaman  */
189*b30d1939SAndy Fiddaman 
190*b30d1939SAndy Fiddaman int
ppargs(char ** argv,int last)191*b30d1939SAndy Fiddaman ppargs(char** argv, int last)
192*b30d1939SAndy Fiddaman {
193*b30d1939SAndy Fiddaman 	register char*	s;
194*b30d1939SAndy Fiddaman 	register int	c;
195*b30d1939SAndy Fiddaman 	register int	n;
196*b30d1939SAndy Fiddaman 	char*		p;
197*b30d1939SAndy Fiddaman 
198*b30d1939SAndy Fiddaman 	/*
199*b30d1939SAndy Fiddaman 	 * check the args and initialize
200*b30d1939SAndy Fiddaman 	 */
201*b30d1939SAndy Fiddaman 
202*b30d1939SAndy Fiddaman 	if (!error_info.id)
203*b30d1939SAndy Fiddaman 		error_info.id = "cpp";
204*b30d1939SAndy Fiddaman 	for (;;)
205*b30d1939SAndy Fiddaman 	{
206*b30d1939SAndy Fiddaman 		for (; c = optget(argv, usage); last = 0) switch (c)
207*b30d1939SAndy Fiddaman 		{
208*b30d1939SAndy Fiddaman 		case 'C':
209*b30d1939SAndy Fiddaman 			ppop(PP_COMMENT, ppcomment);
210*b30d1939SAndy Fiddaman 			break;
211*b30d1939SAndy Fiddaman 		case 'D':
212*b30d1939SAndy Fiddaman 			/*
213*b30d1939SAndy Fiddaman 			 * this allows single arg pp option extensions
214*b30d1939SAndy Fiddaman 			 * without touching cc
215*b30d1939SAndy Fiddaman 			 * (not all cc wrappers have -W...)
216*b30d1939SAndy Fiddaman 			 */
217*b30d1939SAndy Fiddaman 
218*b30d1939SAndy Fiddaman 			switch (*(s = opt_info.arg))
219*b30d1939SAndy Fiddaman 			{
220*b30d1939SAndy Fiddaman 			case '-':
221*b30d1939SAndy Fiddaman 			case '+':
222*b30d1939SAndy Fiddaman 				n = (*s++ == '-');
223*b30d1939SAndy Fiddaman 				while (c = *s++) switch (c)
224*b30d1939SAndy Fiddaman 				{
225*b30d1939SAndy Fiddaman 				case 'C':
226*b30d1939SAndy Fiddaman 					ppop(PP_COMPATIBILITY, n);
227*b30d1939SAndy Fiddaman 					break;
228*b30d1939SAndy Fiddaman 				case 'D':
229*b30d1939SAndy Fiddaman 					if (n && ((c = strtol(s, &p, 0)) || p != s))
230*b30d1939SAndy Fiddaman 					{
231*b30d1939SAndy Fiddaman 						s = p;
232*b30d1939SAndy Fiddaman 						n = c;
233*b30d1939SAndy Fiddaman 					}
234*b30d1939SAndy Fiddaman 					ppop(PP_DEBUG, -n);
235*b30d1939SAndy Fiddaman 					break;
236*b30d1939SAndy Fiddaman 				case 'F':
237*b30d1939SAndy Fiddaman 					ppop(PP_FILENAME, n ? s : NiL);
238*b30d1939SAndy Fiddaman 					goto hasarg;
239*b30d1939SAndy Fiddaman 				case 'H':
240*b30d1939SAndy Fiddaman 					ppop(PP_HOSTDIR, "-", n);
241*b30d1939SAndy Fiddaman 					break;
242*b30d1939SAndy Fiddaman 				case 'I':
243*b30d1939SAndy Fiddaman 					ppop(PP_CDIR, "-", n);
244*b30d1939SAndy Fiddaman 					break;
245*b30d1939SAndy Fiddaman 				case 'K':
246*b30d1939SAndy Fiddaman 					ppop(PP_KEYARGS, n);
247*b30d1939SAndy Fiddaman 					break;
248*b30d1939SAndy Fiddaman 				case 'L':
249*b30d1939SAndy Fiddaman 					ppop(PP_LINEID, n && *s ? s : "line");
250*b30d1939SAndy Fiddaman 					goto hasarg;
251*b30d1939SAndy Fiddaman 				case 'M':
252*b30d1939SAndy Fiddaman 					ppop(PP_MULTIPLE, !n);
253*b30d1939SAndy Fiddaman 					break;
254*b30d1939SAndy Fiddaman 				case 'P':
255*b30d1939SAndy Fiddaman 					ppop(PP_PASSTHROUGH, n);
256*b30d1939SAndy Fiddaman 					break;
257*b30d1939SAndy Fiddaman 				case 'Q':
258*b30d1939SAndy Fiddaman 					ppop(PP_DUMP, n);
259*b30d1939SAndy Fiddaman 					break;
260*b30d1939SAndy Fiddaman 				case 'R':
261*b30d1939SAndy Fiddaman 					ppop(PP_TRANSITION, n);
262*b30d1939SAndy Fiddaman 					break;
263*b30d1939SAndy Fiddaman 				case 'S':
264*b30d1939SAndy Fiddaman 					ppop(PP_STRICT, n);
265*b30d1939SAndy Fiddaman 					break;
266*b30d1939SAndy Fiddaman 				case 'T':
267*b30d1939SAndy Fiddaman 					ppop(PP_TEST, s);
268*b30d1939SAndy Fiddaman 					goto hasarg;
269*b30d1939SAndy Fiddaman 				case 'V':
270*b30d1939SAndy Fiddaman 					ppop(PP_VENDOR, "-", n);
271*b30d1939SAndy Fiddaman 					break;
272*b30d1939SAndy Fiddaman 				case 'W':
273*b30d1939SAndy Fiddaman 					ppop(PP_WARN, n);
274*b30d1939SAndy Fiddaman 					break;
275*b30d1939SAndy Fiddaman 				case 'X':
276*b30d1939SAndy Fiddaman 					ppop(PP_PROBE, n && *s ? s : 0);
277*b30d1939SAndy Fiddaman 					goto hasarg;
278*b30d1939SAndy Fiddaman 				case 'Y':
279*b30d1939SAndy Fiddaman 					ppop(PP_PEDANTIC, n);
280*b30d1939SAndy Fiddaman 					break;
281*b30d1939SAndy Fiddaman 				case 'Z':
282*b30d1939SAndy Fiddaman 					ppop(PP_POOL, n);
283*b30d1939SAndy Fiddaman 					break;
284*b30d1939SAndy Fiddaman 				case 'd':
285*b30d1939SAndy Fiddaman 					pp.option |= DEFINITIONS;
286*b30d1939SAndy Fiddaman 					break;
287*b30d1939SAndy Fiddaman 				case 'm':
288*b30d1939SAndy Fiddaman 					pp.state |= NOTEXT;
289*b30d1939SAndy Fiddaman 					pp.option |= KEEPNOTEXT|DEFINITIONS|PREDEFINITIONS;
290*b30d1939SAndy Fiddaman 					pp.linesync = 0;
291*b30d1939SAndy Fiddaman 					break;
292*b30d1939SAndy Fiddaman 				case '+':
293*b30d1939SAndy Fiddaman 					ppop(PP_PLUSPLUS, n);
294*b30d1939SAndy Fiddaman 					break;
295*b30d1939SAndy Fiddaman 				default:
296*b30d1939SAndy Fiddaman 					if (pp.optarg)
297*b30d1939SAndy Fiddaman 					{
298*b30d1939SAndy Fiddaman 						if ((c = (*pp.optarg)(n, c, s)) > 0) goto hasarg;
299*b30d1939SAndy Fiddaman 						else if (!c) break;
300*b30d1939SAndy Fiddaman 					}
301*b30d1939SAndy Fiddaman 					error(1, "%c%s: unknown -D option overload", n ? '-' : '+', s - 1);
302*b30d1939SAndy Fiddaman 					goto hasarg;
303*b30d1939SAndy Fiddaman 				}
304*b30d1939SAndy Fiddaman 			hasarg:
305*b30d1939SAndy Fiddaman 				break;
306*b30d1939SAndy Fiddaman 			case ':':
307*b30d1939SAndy Fiddaman 				ppop(PP_OPTION, s + 1);
308*b30d1939SAndy Fiddaman 				break;
309*b30d1939SAndy Fiddaman 			case '%':
310*b30d1939SAndy Fiddaman 				ppop(PP_DIRECTIVE, s + 1);
311*b30d1939SAndy Fiddaman 				break;
312*b30d1939SAndy Fiddaman 			case '_':
313*b30d1939SAndy Fiddaman 				if (strmatch(s, "__GNUC__*"))
314*b30d1939SAndy Fiddaman 					pp.arg_style |= STYLE_gnu;
315*b30d1939SAndy Fiddaman 				else if (strmatch(s, "__(ANSI|STDC|STRICT)__*") || !(pp.arg_style & STYLE_gnu) && strmatch(s, "__STRICT_ANSI__*"))
316*b30d1939SAndy Fiddaman 					ppop(PP_STRICT, 1);
317*b30d1939SAndy Fiddaman 				else if (strmatch(s, "__cplusplus*"))
318*b30d1939SAndy Fiddaman 					ppop(PP_PLUSPLUS, 1);
319*b30d1939SAndy Fiddaman 				/*FALLTHROUGH*/
320*b30d1939SAndy Fiddaman 			default:
321*b30d1939SAndy Fiddaman 				ppop(PP_DEFINE, s);
322*b30d1939SAndy Fiddaman 				break;
323*b30d1939SAndy Fiddaman 			}
324*b30d1939SAndy Fiddaman 			break;
325*b30d1939SAndy Fiddaman 		case 'E':
326*b30d1939SAndy Fiddaman 			/* historically ignored */
327*b30d1939SAndy Fiddaman 			break;
328*b30d1939SAndy Fiddaman 		case 'I':
329*b30d1939SAndy Fiddaman 			if (!(s = opt_info.arg))
330*b30d1939SAndy Fiddaman 			{
331*b30d1939SAndy Fiddaman 				/*
332*b30d1939SAndy Fiddaman 				 * some compilers interpret `-I ...' as
333*b30d1939SAndy Fiddaman 				 * `-I-S' and arg ... while others interpret
334*b30d1939SAndy Fiddaman 				 * it as `-I...'
335*b30d1939SAndy Fiddaman 				 */
336*b30d1939SAndy Fiddaman 
337*b30d1939SAndy Fiddaman 				p = "-S";
338*b30d1939SAndy Fiddaman 				if ((s = argv[opt_info.index]) && ((n = *s++) == '-' || n == '+') && *s++ == 'D')
339*b30d1939SAndy Fiddaman 				{
340*b30d1939SAndy Fiddaman 					if (isalpha(*s) || *s == '_')
341*b30d1939SAndy Fiddaman 						while (isalnum(*++s) || *s == '_');
342*b30d1939SAndy Fiddaman 					if (*s && *s != '=' && *s != '-' && *s != '+')
343*b30d1939SAndy Fiddaman 						p = argv[opt_info.index++];
344*b30d1939SAndy Fiddaman 				}
345*b30d1939SAndy Fiddaman 				s = p;
346*b30d1939SAndy Fiddaman 			}
347*b30d1939SAndy Fiddaman 			switch (*s)
348*b30d1939SAndy Fiddaman 			{
349*b30d1939SAndy Fiddaman 			case '-':
350*b30d1939SAndy Fiddaman 			case '+':
351*b30d1939SAndy Fiddaman 				n = *(p = s++) == '-';
352*b30d1939SAndy Fiddaman 				c = *s++;
353*b30d1939SAndy Fiddaman 				if (!n && !*s) s = 0;
354*b30d1939SAndy Fiddaman 				switch (c)
355*b30d1939SAndy Fiddaman 				{
356*b30d1939SAndy Fiddaman 				case 0:
357*b30d1939SAndy Fiddaman 					ppop(PP_LOCAL);
358*b30d1939SAndy Fiddaman 					break;
359*b30d1939SAndy Fiddaman 				case 'C':
360*b30d1939SAndy Fiddaman 					ppop(PP_CDIR, s, n);
361*b30d1939SAndy Fiddaman 					break;
362*b30d1939SAndy Fiddaman 				case 'D':
363*b30d1939SAndy Fiddaman 					ppop(PP_DEFAULT, s);
364*b30d1939SAndy Fiddaman 					break;
365*b30d1939SAndy Fiddaman 				case 'H':
366*b30d1939SAndy Fiddaman 					ppop(PP_HOSTDIR, s, n);
367*b30d1939SAndy Fiddaman 					break;
368*b30d1939SAndy Fiddaman 				case 'I':
369*b30d1939SAndy Fiddaman 					ppop(PP_IGNORE, s);
370*b30d1939SAndy Fiddaman 					break;
371*b30d1939SAndy Fiddaman 				case 'M':
372*b30d1939SAndy Fiddaman 					ppop(PP_IGNORELIST, s);
373*b30d1939SAndy Fiddaman 					break;
374*b30d1939SAndy Fiddaman 				case 'R':
375*b30d1939SAndy Fiddaman 					ppop(PP_READ, s);
376*b30d1939SAndy Fiddaman 					break;
377*b30d1939SAndy Fiddaman 				case 'S':
378*b30d1939SAndy Fiddaman 					ppop(PP_STANDARD, s);
379*b30d1939SAndy Fiddaman 					break;
380*b30d1939SAndy Fiddaman 				case 'T':
381*b30d1939SAndy Fiddaman 					ppop(PP_TEXT, s);
382*b30d1939SAndy Fiddaman 					break;
383*b30d1939SAndy Fiddaman 				case 'V':
384*b30d1939SAndy Fiddaman 					ppop(PP_VENDOR, s, n);
385*b30d1939SAndy Fiddaman 					break;
386*b30d1939SAndy Fiddaman 				default:
387*b30d1939SAndy Fiddaman 					error(1, "%s: unknown -I option overload", p);
388*b30d1939SAndy Fiddaman 					break;
389*b30d1939SAndy Fiddaman 				}
390*b30d1939SAndy Fiddaman 				break;
391*b30d1939SAndy Fiddaman 			default:
392*b30d1939SAndy Fiddaman 				ppop(PP_INCLUDE, s);
393*b30d1939SAndy Fiddaman 				break;
394*b30d1939SAndy Fiddaman 			}
395*b30d1939SAndy Fiddaman 			break;
396*b30d1939SAndy Fiddaman 		case 'M':
397*b30d1939SAndy Fiddaman 			for (n = PP_deps; argv[opt_info.index]; opt_info.offset++)
398*b30d1939SAndy Fiddaman 			{
399*b30d1939SAndy Fiddaman 				switch (argv[opt_info.index][opt_info.offset])
400*b30d1939SAndy Fiddaman 				{
401*b30d1939SAndy Fiddaman 				case 'D':
402*b30d1939SAndy Fiddaman 					n |= PP_deps_file;
403*b30d1939SAndy Fiddaman 					continue;
404*b30d1939SAndy Fiddaman 				case 'G':
405*b30d1939SAndy Fiddaman 					n |= PP_deps_generated;
406*b30d1939SAndy Fiddaman 					continue;
407*b30d1939SAndy Fiddaman 				case 'M':
408*b30d1939SAndy Fiddaman 					n |= PP_deps_local;
409*b30d1939SAndy Fiddaman 					continue;
410*b30d1939SAndy Fiddaman 				}
411*b30d1939SAndy Fiddaman 				break;
412*b30d1939SAndy Fiddaman 			}
413*b30d1939SAndy Fiddaman 			ppop(PP_FILEDEPS, n);
414*b30d1939SAndy Fiddaman 			break;
415*b30d1939SAndy Fiddaman 		case 'P':
416*b30d1939SAndy Fiddaman 			ppop(PP_LINE, (PPLINESYNC)0);
417*b30d1939SAndy Fiddaman 			break;
418*b30d1939SAndy Fiddaman 		case 'U':
419*b30d1939SAndy Fiddaman 			ppop(PP_UNDEF, opt_info.arg);
420*b30d1939SAndy Fiddaman 			break;
421*b30d1939SAndy Fiddaman 
422*b30d1939SAndy Fiddaman 		/*
423*b30d1939SAndy Fiddaman 		 * System V CCS compatibility
424*b30d1939SAndy Fiddaman 		 */
425*b30d1939SAndy Fiddaman 
426*b30d1939SAndy Fiddaman 		case 'A':
427*b30d1939SAndy Fiddaman 			if (isalpha(opt_info.arg[0]) || opt_info.arg[0] == '_' || opt_info.arg[0] == '$')
428*b30d1939SAndy Fiddaman 				ppop(PP_ASSERT, opt_info.arg);
429*b30d1939SAndy Fiddaman 			break;
430*b30d1939SAndy Fiddaman 		case 'H':
431*b30d1939SAndy Fiddaman 			if (!opt_info.arg)
432*b30d1939SAndy Fiddaman 				ppop(PP_INCREF, ppincref);
433*b30d1939SAndy Fiddaman 			break;
434*b30d1939SAndy Fiddaman 		case 'T':
435*b30d1939SAndy Fiddaman 			if (!(pp.arg_style & STYLE_gnu))
436*b30d1939SAndy Fiddaman 				ppop(PP_TRUNCATE, TRUNCLENGTH);
437*b30d1939SAndy Fiddaman 			/* else enable ANSI trigraphs -- default */
438*b30d1939SAndy Fiddaman 			break;
439*b30d1939SAndy Fiddaman 		case 'V':
440*b30d1939SAndy Fiddaman 			error(0, "%s", pp.version);
441*b30d1939SAndy Fiddaman 			break;
442*b30d1939SAndy Fiddaman 		case 'X':
443*b30d1939SAndy Fiddaman 			pp.arg_mode = (*(opt_info.arg + 1) || pp.arg_mode && pp.arg_mode != *opt_info.arg) ? '-' : *opt_info.arg;
444*b30d1939SAndy Fiddaman 			break;
445*b30d1939SAndy Fiddaman 		case 'Y':
446*b30d1939SAndy Fiddaman 			if (*(s = opt_info.arg) && *(s + 1) == ',')
447*b30d1939SAndy Fiddaman 			{
448*b30d1939SAndy Fiddaman 				if (*s != 'I') break;
449*b30d1939SAndy Fiddaman 				s += 2;
450*b30d1939SAndy Fiddaman 			}
451*b30d1939SAndy Fiddaman 			ppop(PP_STANDARD, s);
452*b30d1939SAndy Fiddaman 			break;
453*b30d1939SAndy Fiddaman 
454*b30d1939SAndy Fiddaman 		/*
455*b30d1939SAndy Fiddaman 		 * errors
456*b30d1939SAndy Fiddaman 		 */
457*b30d1939SAndy Fiddaman 
458*b30d1939SAndy Fiddaman 		case '?':
459*b30d1939SAndy Fiddaman 			error(ERROR_USAGE|4, "%s", opt_info.arg);
460*b30d1939SAndy Fiddaman 			break;
461*b30d1939SAndy Fiddaman 		case ':':
462*b30d1939SAndy Fiddaman 			if (!last)
463*b30d1939SAndy Fiddaman 			{
464*b30d1939SAndy Fiddaman 				opt_info.again = 1;
465*b30d1939SAndy Fiddaman 				return(1);
466*b30d1939SAndy Fiddaman 			}
467*b30d1939SAndy Fiddaman 
468*b30d1939SAndy Fiddaman 			/*
469*b30d1939SAndy Fiddaman 			 * cross your fingers
470*b30d1939SAndy Fiddaman 			 */
471*b30d1939SAndy Fiddaman 
472*b30d1939SAndy Fiddaman 			if (!(s = argv[opt_info.index]))
473*b30d1939SAndy Fiddaman 				error(3, "%s", opt_info.arg);
474*b30d1939SAndy Fiddaman 			if (opt_info.offset == 2 && (pp.arg_style & STYLE_gnu))
475*b30d1939SAndy Fiddaman 			{
476*b30d1939SAndy Fiddaman 				p = argv[opt_info.index + 1];
477*b30d1939SAndy Fiddaman 				if (streq(s, "-$"))
478*b30d1939SAndy Fiddaman 				{
479*b30d1939SAndy Fiddaman 					ppop(PP_OPTION, "noid \"$\"");
480*b30d1939SAndy Fiddaman 					goto ignore;
481*b30d1939SAndy Fiddaman 				}
482*b30d1939SAndy Fiddaman 				else if (streq(s, "-dD"))
483*b30d1939SAndy Fiddaman 				{
484*b30d1939SAndy Fiddaman 					pp.option |= DEFINITIONS;
485*b30d1939SAndy Fiddaman 					goto ignore;
486*b30d1939SAndy Fiddaman 				}
487*b30d1939SAndy Fiddaman 				else if (streq(s, "-dM"))
488*b30d1939SAndy Fiddaman 				{
489*b30d1939SAndy Fiddaman 					pp.state |= NOTEXT;
490*b30d1939SAndy Fiddaman 					pp.option |= KEEPNOTEXT|DEFINITIONS|PREDEFINITIONS;
491*b30d1939SAndy Fiddaman 					pp.linesync = 0;
492*b30d1939SAndy Fiddaman 					goto ignore;
493*b30d1939SAndy Fiddaman 				}
494*b30d1939SAndy Fiddaman 				else if (streq(s, "-imacros"))
495*b30d1939SAndy Fiddaman 				{
496*b30d1939SAndy Fiddaman 					if (p)
497*b30d1939SAndy Fiddaman 					{
498*b30d1939SAndy Fiddaman 						ppop(PP_READ, p);
499*b30d1939SAndy Fiddaman 						opt_info.index++;
500*b30d1939SAndy Fiddaman 						opt_info.offset = 0;
501*b30d1939SAndy Fiddaman 					}
502*b30d1939SAndy Fiddaman 					goto ignore;
503*b30d1939SAndy Fiddaman 				}
504*b30d1939SAndy Fiddaman 				else if (streq(s, "-include"))
505*b30d1939SAndy Fiddaman 				{
506*b30d1939SAndy Fiddaman 					if (p)
507*b30d1939SAndy Fiddaman 					{
508*b30d1939SAndy Fiddaman 						ppop(PP_TEXT, p);
509*b30d1939SAndy Fiddaman 						opt_info.index++;
510*b30d1939SAndy Fiddaman 						opt_info.offset = 0;
511*b30d1939SAndy Fiddaman 					}
512*b30d1939SAndy Fiddaman 					opt_info.offset = 0;
513*b30d1939SAndy Fiddaman 					goto ignore;
514*b30d1939SAndy Fiddaman 				}
515*b30d1939SAndy Fiddaman 				else if (strneq(s, "-lang-", 6))
516*b30d1939SAndy Fiddaman 				{
517*b30d1939SAndy Fiddaman 					s += 6;
518*b30d1939SAndy Fiddaman 					if (streq(s, "c"))
519*b30d1939SAndy Fiddaman 						c = 0;
520*b30d1939SAndy Fiddaman 					else if (streq(s, "c++"))
521*b30d1939SAndy Fiddaman 						c = 1;
522*b30d1939SAndy Fiddaman 					else if (streq(s, "objc"))
523*b30d1939SAndy Fiddaman 						c = 2;
524*b30d1939SAndy Fiddaman 					else if (streq(s, "objc++"))
525*b30d1939SAndy Fiddaman 						c = 3;
526*b30d1939SAndy Fiddaman 					ppop(PP_PLUSPLUS, c & 1);
527*b30d1939SAndy Fiddaman 					if (c & 2)
528*b30d1939SAndy Fiddaman 						ppop(PP_DIRECTIVE, "pragma pp:map \"/#(pragma )?import>/\" \"/#(pragma )?import(.*)/__STDPP__IMPORT__(\\2)/\"\n\
529*b30d1939SAndy Fiddaman #macdef __STDPP__IMPORT__(x)\n\
530*b30d1939SAndy Fiddaman #pragma pp:noallmultiple\n\
531*b30d1939SAndy Fiddaman #include x\n\
532*b30d1939SAndy Fiddaman #pragma pp:allmultiple\n\
533*b30d1939SAndy Fiddaman #endmac");
534*b30d1939SAndy Fiddaman 					goto ignore;
535*b30d1939SAndy Fiddaman 				}
536*b30d1939SAndy Fiddaman 				else if (streq(s, "-lint"))
537*b30d1939SAndy Fiddaman 				{
538*b30d1939SAndy Fiddaman 					ppop(PP_COMMENT, pplint);
539*b30d1939SAndy Fiddaman 					goto ignore;
540*b30d1939SAndy Fiddaman 				}
541*b30d1939SAndy Fiddaman 			}
542*b30d1939SAndy Fiddaman 			s += opt_info.offset - 1;
543*b30d1939SAndy Fiddaman 			if (strmatch(s, "i*.h"))
544*b30d1939SAndy Fiddaman 				ppop((pp.arg_style & STYLE_gnu) || s[1] == '/' ? PP_READ : PP_TEXT, s + 1);
545*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(nostandard|nostdinc)*"))
546*b30d1939SAndy Fiddaman 				ppop(PP_STANDARD, "");
547*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(exten|xansi)*|std"))
548*b30d1939SAndy Fiddaman 			{
549*b30d1939SAndy Fiddaman 				ppop(PP_COMPATIBILITY, 0);
550*b30d1939SAndy Fiddaman 				ppop(PP_TRANSITION, 1);
551*b30d1939SAndy Fiddaman 			}
552*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(ansi|conform|pedantic|stand|std1|strict[!-])*"))
553*b30d1939SAndy Fiddaman 			{
554*b30d1939SAndy Fiddaman 				ppop(PP_COMPATIBILITY, 0);
555*b30d1939SAndy Fiddaman 				ppop(PP_STRICT, 1);
556*b30d1939SAndy Fiddaman 				if (strmatch(s, "*pedantic*"))
557*b30d1939SAndy Fiddaman 					ppop(PP_PEDANTIC, 1);
558*b30d1939SAndy Fiddaman 			}
559*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(trans)*"))
560*b30d1939SAndy Fiddaman 			{
561*b30d1939SAndy Fiddaman 				ppop(PP_COMPATIBILITY, 1);
562*b30d1939SAndy Fiddaman 				ppop(PP_TRANSITION, 1);
563*b30d1939SAndy Fiddaman 			}
564*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(classic|compat|std0|tradition|[kK][n&+][rR])*"))
565*b30d1939SAndy Fiddaman 			{
566*b30d1939SAndy Fiddaman 				ppop(PP_COMPATIBILITY, 1);
567*b30d1939SAndy Fiddaman 				ppop(PP_TRANSITION, 0);
568*b30d1939SAndy Fiddaman 			}
569*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(plusplus|++)*"))
570*b30d1939SAndy Fiddaman 				ppop(PP_PLUSPLUS, 1);
571*b30d1939SAndy Fiddaman 			else if (strmatch(s, "*@(warn)*"))
572*b30d1939SAndy Fiddaman 				ppop(PP_WARN, 1);
573*b30d1939SAndy Fiddaman 
574*b30d1939SAndy Fiddaman 			/*
575*b30d1939SAndy Fiddaman 			 * ignore unknown options
576*b30d1939SAndy Fiddaman 			 * the probe info takes care of these
577*b30d1939SAndy Fiddaman 			 * fails if an option value is in the next arg
578*b30d1939SAndy Fiddaman 			 * and this is the last option
579*b30d1939SAndy Fiddaman 			 */
580*b30d1939SAndy Fiddaman 
581*b30d1939SAndy Fiddaman 			if (argv[opt_info.index + 1] && argv[opt_info.index + 1][0] != '-' && argv[opt_info.index + 2] && argv[opt_info.index + 2][0] == '-')
582*b30d1939SAndy Fiddaman 			{
583*b30d1939SAndy Fiddaman 				opt_info.index++;
584*b30d1939SAndy Fiddaman 				opt_info.offset = 0;
585*b30d1939SAndy Fiddaman 			}
586*b30d1939SAndy Fiddaman 		ignore:
587*b30d1939SAndy Fiddaman 			while (argv[opt_info.index][opt_info.offset]) opt_info.offset++;
588*b30d1939SAndy Fiddaman 			break;
589*b30d1939SAndy Fiddaman 		}
590*b30d1939SAndy Fiddaman 		if (!(s = argv[opt_info.index])) return(0);
591*b30d1939SAndy Fiddaman 		switch (pp.arg_file)
592*b30d1939SAndy Fiddaman 		{
593*b30d1939SAndy Fiddaman 		case 0:
594*b30d1939SAndy Fiddaman 			if (*s != '-' || *(s + 1)) ppop(PP_INPUT, s);
595*b30d1939SAndy Fiddaman 			break;
596*b30d1939SAndy Fiddaman 		case 1:
597*b30d1939SAndy Fiddaman 			if (*s != '-' || *(s + 1)) ppop(PP_OUTPUT, s);
598*b30d1939SAndy Fiddaman 			break;
599*b30d1939SAndy Fiddaman 		default:
600*b30d1939SAndy Fiddaman 			if (!last) return(1);
601*b30d1939SAndy Fiddaman 			error(1, "%s: extraneous argument ignored", s);
602*b30d1939SAndy Fiddaman 			break;
603*b30d1939SAndy Fiddaman 		}
604*b30d1939SAndy Fiddaman 		pp.arg_file++;
605*b30d1939SAndy Fiddaman 		if (!argv[++opt_info.index]) return(0);
606*b30d1939SAndy Fiddaman 
607*b30d1939SAndy Fiddaman 		/*
608*b30d1939SAndy Fiddaman 		 * old versions allow options after file args
609*b30d1939SAndy Fiddaman 		 */
610*b30d1939SAndy Fiddaman 	}
611*b30d1939SAndy Fiddaman }
612