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