xref: /onnv-gate/usr/src/lib/libpp/common/ppargs.c (revision 10898:1883b621b3ea)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*10898Sroland.mainz@nrubsig.org *          Copyright (c) 1986-2009 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                                                                      *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin  * Glenn Fowler
234887Schin  * AT&T Research
244887Schin  *
254887Schin  * common preprocessor command line argument parse
264887Schin  * called by optjoin()
274887Schin  */
284887Schin 
294887Schin static const char usage[] =
30*10898Sroland.mainz@nrubsig.org "[-?\n@(#)$Id: cpp (AT&T Research) 2009-02-02 $\n]"
314887Schin USAGE_LICENSE
324887Schin "[+NAME?cpp - C language preprocessor]"
334887Schin "[+DESCRIPTION?\bcpp\b is the preprocessor for all C language dialects. It is"
344887Schin "	a standalone version of the \blibpp\b(3) preprocessor library. The"
354887Schin "	C dialect implemented by \bcpp\b is determined by probing \bcc\b(1)"
364887Schin "	using \bprobe\b(1). The path of the emulated compiler can be changed"
374887Schin "	by the \b-D-X\b command line option.]"
384887Schin "[+?If \aoutput\a is omitted then the standard output is written; if \ainput\a"
394887Schin "	is also omitted then the standard input is read. NOTE: this is an"
404887Schin "	ancient, non-standard, non-intuitiive file operand syntax that is"
414887Schin "	required by \bcc\b(1); use shell file name expansion at your peril.]"
424887Schin "[+?\bcpp\b specific options are set by the \b-D-\b and \b-I-\b options.]"
434887Schin 
444887Schin "[C:comments?Pass comments to the output. By default comments are omitted.]"
454887Schin "[D:define?Define the macro \aname\a to have \avalue\a; \b1\b is assumed if"
464887Schin "	\b=\b\avalue\a is omitted. If \aname\a begins with \b:\b then it is"
474887Schin "	interpreted as a \blibpp\b(3) \b#pragma pp:\b statement; if \aname\a"
484887Schin "	begins with \b%\b then it is interpreted as a \blibpp\b(3) \b#\b"
494887Schin "	directive statement; if \aname\a begins with \b-\b or \b+\b then it is"
504887Schin "	interpreted as a \blibpp\b(3) option; \b-\b turns the option on,"
514887Schin "	\b+\b turns it off. Most options have a \b#pragma\b counterpart that"
524887Schin "	is listed with the option definition. Right, this is ugly, but its the"
534887Schin "	only portable way to pass options through \bcc\b(1) to"
544887Schin "	\bcpp\b:]:[name[=value]]]{"
554887Schin "	[+-D-C, pp::compatibility?Preprocess for K&R compatibility.]"
564887Schin "	[+-D-D\alevel\a, \bpp::debug\b \alevel\a?Set the debug trace level."
574887Schin "		Higher levels produce more output. Levels higher than 3"
584887Schin "		enabled only in \b-g\b compiled versions.]"
594887Schin "	[+-D-F\aname\a?Set the main input file name to \aname\a. This only"
604887Schin "		affects error message and line sync output.]"
614887Schin "	[+-D-H, pp::hosted?All directories are hosted; compatibility"
624887Schin "		warning messages from hosted directory headers are suppressed.]"
634887Schin "	[+-D-I, pp::cdir?All directories contain C headers; used only with"
644887Schin "		\b-D-+\b.]"
654887Schin "	[+-D-K, pp::keyargs?Enable the non-standard \aname=value\a macro"
664887Schin "		argument mode.]"
674887Schin "	[+-D-L\b[\aid\a]], \bpp::lineid\b [\aid\a]]?Set the line sync directive"
684887Schin "		id to \aid\a or null if omitted.]"
694887Schin "	[+-D-M, pp::nomultiple?Disable multiple include detection.]"
704887Schin "	[+-D-P, pp::passthrough?Enable the non-standard passthrough mode; may"
714887Schin "		be useful for processing non-C input.]"
724887Schin "	[+-D-Q, pp::dump?Dump macro definitions to the output so that the"
734887Schin "		output may be passed through \bcpp\b again. Used for"
744887Schin "		generating precompiled headers.]"
754887Schin "	[+-D-R, pp::transition?Enable the transition preprocessing mode. Used"
764887Schin "		for compilers that can't make up their semantics between"
774887Schin "		K&R and ISO.]"
784887Schin "	[+-D-S, pp::strict?Enable strict preprocessing semantics and warnings."
794887Schin "		Works with any mode (compatibiliy, transition,"
804887Schin "		or the default ISO).]"
814887Schin "	[+-D-T\atest\a, \bpp::test\b \atest\a?Enable implementation specific"
824887Schin "		test code according to \atest\a.]"
838462SApril.Chin@Sun.COM "	[+-D-W, pp::warn?Enable warnings in non-hosted files.]"
844887Schin "	[+-D-X\b[\acc\a]]?Preprocess for the compiler \acc\a which must be"
854887Schin "		an executable path or an executable on \b$PATH\b.]"
868462SApril.Chin@Sun.COM "	[+-D-Y, pp::pedantic?Enable pedantic \bpp::warn\b warnings in"
878462SApril.Chin@Sun.COM "		non-hosted files.]"
884887Schin "	[+-D-Z, pp::pool?Enable pool mode. See \blibpp\b(3).]"
894887Schin "	[+-D-d?List canonicalized \b#define\b statements for non-predefined"
904887Schin "		macros in the output. ]"
914887Schin "	[+-D-m?List canonicalized \b#define\b statements for all macros. All"
924887Schin "		other output is disabled.]"
934887Schin "	[+-D-+, pp::plusplus?Preprocess for the C++ dialect.]"
944887Schin "}"
954887Schin "[I:include?Append \adirectory\a to the list of directories searched for"
964887Schin "	\b#include\b files. If \adirectory\a is \b-\b then: (1) \b-I\b"
974887Schin "	directories before \b-I-\b are searched only for \"...\" include"
984887Schin "	files; (2) \b-I\b directories after \b-I-\b are searched for"
994887Schin "	\"...\" and <...> include files; (3) the directory \b.\b is searched"
1004887Schin "	only if it is explicitly specified by a \b-I\b option.]:?[directory]{"
1014887Schin "	[+-I-C\adirectory\a, \bpp::cdir\b \adirectory\a?Mark \adirectory\a"
1024887Schin "		as a C header directory. Used with \bpp:plusplus\b.]"
1034887Schin "	[+-I-D[\afile\a]]?Read the default \bprobe\b(1) definitions from"
1044887Schin "		\afile\a, or ignore the default definitions if \afile\a"
1054887Schin "		is omitted.]"
1064887Schin "	[+-I-H\adirectory\a, \bpp::hostdir\b \adirectory\a?Mark \adirectory\a"
1074887Schin "		as a hosted directory. Headers from hosted directories have"
1084887Schin "		compatibility warnings disabled.]"
1094887Schin "	[+-I-I\aheader\a, \bpp::ignore\b \aheader\a?Add \aheader\a to the"
1104887Schin "		list of ignored headers.]"
1114887Schin "	[+-I-M\afile\a?\afile\a contains a sequence of \aheader\a"
1124887Schin "		[= \"\amap\a\" ]] lines, where \aheader\a is either <\aname\a>"
1134887Schin "		or \"\aname\a\", and \"\amap\a\" is an explicit binding"
1144887Schin "		for \aheader\a. \aheader\a is ignored if = \"\amap\a\" is"
1154887Schin "		omitted.]"
1164887Schin "	[+-I-R\afile\a?Include \afile\a but do not emit text or line syncs.]"
1174887Schin "	[+-I-S\adirectory\a?Add \adirectory\a to the default standard include"
1184887Schin "		directory list.]"
1194887Schin "	[+-I-T\afile\a?Include \afile\a and emit text to the output file.]"
1204887Schin "}"
1214887Schin "[M:dependencies?Generate \bmake\b(1) dependencies. Not needed with"
1224887Schin "	\bnmake\b(1). \b-M\b may be followed by optional \aflags\a to change"
1234887Schin "	dependency output styles:]{"
1244887Schin "	[+D?Generate dependencies in a separate \b.d\b file. Preprocessed"
1254887Schin "		output is still written to \aoutput\a, or the standard output"
1264887Schin "		if \aoutput\a is omitted.]"
1274887Schin "	[+G?Generate missing dependencies too.]"
1284887Schin "	[+M?Only generate local header dependencies; \ahosted\a headers are"
1294887Schin "		omitted. Note that \ahosted\a headers are determined by"
1304887Schin "		\b-I-H\b and the \bpp:hosted\b and \bpp:hostdir\b pragmas;"
1314887Schin "		no special distiction is made between \"\" and <> \binclude\b"
1324887Schin "		styles.]"
1334887Schin "}"
1344887Schin "[P!:sync?Emit line syncs.]"
1354887Schin "[U:undefine?Remove the definition for the macro \aname\a.]:[name]"
1364887Schin 
1374887Schin "[A:assert?Enter the assertion via \b#assert\b for system V"
1384887Schin "	compatibility.]:[assertion]"
1394887Schin "[E:preprocess?Ignored for compatibility with ancient compilers.]"
1404887Schin "[H:include-reference?Emit \b#include\b file paths on the standard error,"
1414887Schin "	one per line, indented to show nesting.]"
1424887Schin "[T?If not \bgcc\b(1) then truncate identifiers to \alength\a"
1434887Schin "	characters for compatibility with old AT&T (I guess only Lucent needs"
1444887Schin "	them now) compilers.]#?[length]"
1454887Schin "[V:version?Emit the \blibpp\b(3) version.]"
1464887Schin "[X:argmode?Enable \aname\a=\avalue\a macro arguments for \beasel\b(1)"
1474887Schin "	compatibility.]"
1484887Schin "[Y:standard?Add \adirectory\a to the list searched for"
1494887Schin "	\b#include\b \b<...>\b files.]:[directory]"
1504887Schin 
1514887Schin "\n"
1524887Schin "\n[ input [ output ] ]\n"
1534887Schin "\n"
1544887Schin 
1554887Schin "[+SEE ALSO?\bcc\b(1), \bgcc\b(1), \blibpp\b(3)]"
1564887Schin ;
1574887Schin 
1584887Schin #include "pplib.h"
1594887Schin 
1604887Schin #include <ctype.h>
1614887Schin 
1624887Schin /*
1634887Schin  * convert lint comments to pragmas
1644887Schin  */
1654887Schin 
1664887Schin static void
pplint(char * head,char * comment,char * tail,int line)1674887Schin pplint(char* head, char* comment, char* tail, int line)
1684887Schin {
1694887Schin 	NoP(line);
1704887Schin 	if (strmatch(comment, "(ARGSUSED|PRINTFLIKE|PROTOLIB|SCANFLIKE|VARARGS)*([0-9])|CONSTCOND|CONSTANTCOND|CONSTANTCONDITION|EMPTY|FALLTHRU|FALLTHROUGH|LINTLIBRARY|LINTED*|NOTREACHED"))
1714887Schin 	{
1724887Schin 		strncopy(pp.token, comment, MAXTOKEN);
1734887Schin 		ppprintf("\n#%s %s:%s\n", dirname(PRAGMA), pp.pass, pp.token);
1744887Schin 		ppline(error_info.line, NiL);
1754887Schin 	}
1764887Schin }
1774887Schin 
1784887Schin /*
1794887Schin  * if last!=0 then argv[opt_info.index]==0 with return(0)
1804887Schin  * else if argv[opt_info.index]==0 then return(0)
1814887Schin  * otherwise argv[opt_info.index] is the first unrecognized
1824887Schin  * option with return(1)
1834887Schin  *
1844887Schin  * use last=0 if the preprocessor is combined with other passes
1854887Schin  * so that unknown options may be interpreted for those passes
1864887Schin  */
1874887Schin 
1884887Schin int
ppargs(char ** argv,int last)1894887Schin ppargs(char** argv, int last)
1904887Schin {
1914887Schin 	register char*	s;
1924887Schin 	register int	c;
1934887Schin 	register int	n;
1944887Schin 	char*		p;
1954887Schin 
1964887Schin 	/*
1974887Schin 	 * check the args and initialize
1984887Schin 	 */
1994887Schin 
2004887Schin 	if (!error_info.id)
2014887Schin 		error_info.id = "cpp";
2024887Schin 	for (;;)
2034887Schin 	{
2044887Schin 		for (; c = optget(argv, usage); last = 0) switch (c)
2054887Schin 		{
2064887Schin 		case 'C':
2074887Schin 			ppop(PP_COMMENT, ppcomment);
2084887Schin 			break;
2094887Schin 		case 'D':
2104887Schin 			/*
2114887Schin 			 * this allows single arg pp option extensions
2124887Schin 			 * without touching cc
2134887Schin 			 * (not all cc wrappers have -W...)
2144887Schin 			 */
2154887Schin 
2164887Schin 			switch (*(s = opt_info.arg))
2174887Schin 			{
2184887Schin 			case '-':
2194887Schin 			case '+':
2204887Schin 				n = (*s++ == '-');
2214887Schin 				while (c = *s++) switch (c)
2224887Schin 				{
2234887Schin 				case 'C':
2244887Schin 					ppop(PP_COMPATIBILITY, n);
2254887Schin 					break;
2264887Schin 				case 'D':
2274887Schin 					if (n && ((c = strtol(s, &p, 0)) || p != s))
2284887Schin 					{
2294887Schin 						s = p;
2304887Schin 						n = c;
2314887Schin 					}
2324887Schin 					ppop(PP_DEBUG, -n);
2334887Schin 					break;
2344887Schin 				case 'F':
2354887Schin 					ppop(PP_FILENAME, n ? s : NiL);
2364887Schin 					goto hasarg;
2374887Schin 				case 'H':
2384887Schin 					ppop(PP_HOSTDIR, "-", n);
2394887Schin 					break;
2404887Schin 				case 'I':
2414887Schin 					ppop(PP_CDIR, "-", n);
2424887Schin 					break;
2434887Schin 				case 'K':
2444887Schin 					ppop(PP_KEYARGS, n);
2454887Schin 					break;
2464887Schin 				case 'L':
2474887Schin 					ppop(PP_LINEID, n && *s ? s : "line");
2484887Schin 					goto hasarg;
2494887Schin 				case 'M':
2504887Schin 					ppop(PP_MULTIPLE, !n);
2514887Schin 					break;
2524887Schin 				case 'P':
2534887Schin 					ppop(PP_PASSTHROUGH, n);
2544887Schin 					break;
2554887Schin 				case 'Q':
2564887Schin 					ppop(PP_DUMP, n);
2574887Schin 					break;
2584887Schin 				case 'R':
2594887Schin 					ppop(PP_TRANSITION, n);
2604887Schin 					break;
2614887Schin 				case 'S':
2624887Schin 					ppop(PP_STRICT, n);
2634887Schin 					break;
2644887Schin 				case 'T':
2654887Schin 					ppop(PP_TEST, s);
2664887Schin 					goto hasarg;
2674887Schin 				case 'V':
2684887Schin 					ppop(PP_VENDOR, "-", n);
2694887Schin 					break;
2704887Schin 				case 'W':
2714887Schin 					ppop(PP_WARN, n);
2724887Schin 					break;
2734887Schin 				case 'X':
2744887Schin 					ppop(PP_PROBE, n && *s ? s : 0);
2754887Schin 					goto hasarg;
2768462SApril.Chin@Sun.COM 				case 'Y':
2778462SApril.Chin@Sun.COM 					ppop(PP_PEDANTIC, n);
2788462SApril.Chin@Sun.COM 					break;
2794887Schin 				case 'Z':
2804887Schin 					ppop(PP_POOL, n);
2814887Schin 					break;
2824887Schin 				case 'd':
2834887Schin 					pp.option |= DEFINITIONS;
2844887Schin 					break;
2854887Schin 				case 'm':
2864887Schin 					pp.state |= NOTEXT;
2874887Schin 					pp.option |= KEEPNOTEXT|DEFINITIONS|PREDEFINITIONS;
2884887Schin 					pp.linesync = 0;
2894887Schin 					break;
2904887Schin 				case '+':
2914887Schin 					ppop(PP_PLUSPLUS, n);
2924887Schin 					break;
2934887Schin 				default:
2944887Schin 					if (pp.optarg)
2954887Schin 					{
2964887Schin 						if ((c = (*pp.optarg)(n, c, s)) > 0) goto hasarg;
2974887Schin 						else if (!c) break;
2984887Schin 					}
2994887Schin 					error(1, "%c%s: unknown -D option overload", n ? '-' : '+', s - 1);
3004887Schin 					goto hasarg;
3014887Schin 				}
3024887Schin 			hasarg:
3034887Schin 				break;
3044887Schin 			case ':':
3054887Schin 				ppop(PP_OPTION, s + 1);
3064887Schin 				break;
3074887Schin 			case '%':
3084887Schin 				ppop(PP_DIRECTIVE, s + 1);
3094887Schin 				break;
3104887Schin 			case '_':
3114887Schin 				if (strmatch(s, "__GNUC__*"))
3124887Schin 					pp.arg_style |= STYLE_gnu;
3134887Schin 				else if (strmatch(s, "__(ANSI|STDC|STRICT)__*") || !(pp.arg_style & STYLE_gnu) && strmatch(s, "__STRICT_ANSI__*"))
3144887Schin 					ppop(PP_STRICT, 1);
3154887Schin 				else if (strmatch(s, "__cplusplus*"))
3164887Schin 					ppop(PP_PLUSPLUS, 1);
3174887Schin 				/*FALLTHROUGH*/
3184887Schin 			default:
3194887Schin 				ppop(PP_DEFINE, s);
3204887Schin 				break;
3214887Schin 			}
3224887Schin 			break;
3234887Schin 		case 'E':
3244887Schin 			/* historically ignored */
3254887Schin 			break;
3264887Schin 		case 'I':
3274887Schin 			if (!(s = opt_info.arg))
3284887Schin 			{
3294887Schin 				/*
3304887Schin 				 * some compilers interpret `-I ...' as
3314887Schin 				 * `-I-S' and arg ... while others interpret
3324887Schin 				 * it as `-I...'
3334887Schin 				 */
3344887Schin 
3354887Schin 				p = "-S";
3364887Schin 				if ((s = argv[opt_info.index]) && ((n = *s++) == '-' || n == '+') && *s++ == 'D')
3374887Schin 				{
3384887Schin 					if (isalpha(*s) || *s == '_')
3394887Schin 						while (isalnum(*++s) || *s == '_');
3404887Schin 					if (*s && *s != '=' && *s != '-' && *s != '+')
3414887Schin 						p = argv[opt_info.index++];
3424887Schin 				}
3434887Schin 				s = p;
3444887Schin 			}
3454887Schin 			switch (*s)
3464887Schin 			{
3474887Schin 			case '-':
3484887Schin 			case '+':
3494887Schin 				n = *(p = s++) == '-';
3504887Schin 				c = *s++;
3514887Schin 				if (!n && !*s) s = 0;
3524887Schin 				switch (c)
3534887Schin 				{
3544887Schin 				case 0:
3554887Schin 					ppop(PP_LOCAL);
3564887Schin 					break;
3574887Schin 				case 'C':
3584887Schin 					ppop(PP_CDIR, s, n);
3594887Schin 					break;
3604887Schin 				case 'D':
3614887Schin 					ppop(PP_DEFAULT, s);
3624887Schin 					break;
3634887Schin 				case 'H':
3644887Schin 					ppop(PP_HOSTDIR, s, n);
3654887Schin 					break;
3664887Schin 				case 'I':
3674887Schin 					ppop(PP_IGNORE, s);
3684887Schin 					break;
3694887Schin 				case 'M':
3704887Schin 					ppop(PP_IGNORELIST, s);
3714887Schin 					break;
3724887Schin 				case 'R':
3734887Schin 					ppop(PP_READ, s);
3744887Schin 					break;
3754887Schin 				case 'S':
3764887Schin 					ppop(PP_STANDARD, s);
3774887Schin 					break;
3784887Schin 				case 'T':
3794887Schin 					ppop(PP_TEXT, s);
3804887Schin 					break;
3814887Schin 				case 'V':
3824887Schin 					ppop(PP_VENDOR, s, n);
3834887Schin 					break;
3844887Schin 				default:
3854887Schin 					error(1, "%s: unknown -I option overload", p);
3864887Schin 					break;
3874887Schin 				}
3884887Schin 				break;
3894887Schin 			default:
3904887Schin 				ppop(PP_INCLUDE, s);
3914887Schin 				break;
3924887Schin 			}
3934887Schin 			break;
3944887Schin 		case 'M':
3954887Schin 			for (n = PP_deps; argv[opt_info.index]; opt_info.offset++)
3964887Schin 			{
3974887Schin 				switch (argv[opt_info.index][opt_info.offset])
3984887Schin 				{
3994887Schin 				case 'D':
4004887Schin 					n |= PP_deps_file;
4014887Schin 					continue;
4024887Schin 				case 'G':
4034887Schin 					n |= PP_deps_generated;
4044887Schin 					continue;
4054887Schin 				case 'M':
4064887Schin 					n |= PP_deps_local;
4074887Schin 					continue;
4084887Schin 				}
4094887Schin 				break;
4104887Schin 			}
4114887Schin 			ppop(PP_FILEDEPS, n);
4124887Schin 			break;
4134887Schin 		case 'P':
4144887Schin 			ppop(PP_LINE, (PPLINESYNC)0);
4154887Schin 			break;
4164887Schin 		case 'U':
4174887Schin 			ppop(PP_UNDEF, opt_info.arg);
4184887Schin 			break;
4194887Schin 
4204887Schin 		/*
4214887Schin 		 * System V CCS compatibility
4224887Schin 		 */
4234887Schin 
4244887Schin 		case 'A':
4254887Schin 			if (isalpha(opt_info.arg[0]) || opt_info.arg[0] == '_' || opt_info.arg[0] == '$')
4264887Schin 				ppop(PP_ASSERT, opt_info.arg);
4274887Schin 			break;
4284887Schin 		case 'H':
4294887Schin 			ppop(PP_INCREF, ppincref);
4304887Schin 			break;
4314887Schin 		case 'T':
4324887Schin 			if (!(pp.arg_style & STYLE_gnu))
4334887Schin 				ppop(PP_TRUNCATE, TRUNCLENGTH);
4344887Schin 			/* else enable ANSI trigraphs -- default */
4354887Schin 			break;
4364887Schin 		case 'V':
4374887Schin 			error(0, "%s", pp.version);
4384887Schin 			break;
4394887Schin 		case 'X':
4404887Schin 			pp.arg_mode = (*(opt_info.arg + 1) || pp.arg_mode && pp.arg_mode != *opt_info.arg) ? '-' : *opt_info.arg;
4414887Schin 			break;
4424887Schin 		case 'Y':
4434887Schin 			if (*(s = opt_info.arg) && *(s + 1) == ',')
4444887Schin 			{
4454887Schin 				if (*s != 'I') break;
4464887Schin 				s += 2;
4474887Schin 			}
4484887Schin 			ppop(PP_STANDARD, s);
4494887Schin 			break;
4504887Schin 
4514887Schin 		/*
4524887Schin 		 * errors
4534887Schin 		 */
4544887Schin 
4554887Schin 		case '?':
4564887Schin 			error(ERROR_USAGE|4, "%s", opt_info.arg);
4574887Schin 			break;
4584887Schin 		case ':':
4594887Schin 			if (!last)
4604887Schin 			{
4614887Schin 				opt_info.again = 1;
4624887Schin 				return(1);
4634887Schin 			}
4644887Schin 
4654887Schin 			/*
4664887Schin 			 * cross your fingers
4674887Schin 			 */
4684887Schin 
4694887Schin 			if (!(s = argv[opt_info.index]))
4704887Schin 				error(3, "%s", opt_info.arg);
4714887Schin 			if (opt_info.offset == 2 && (pp.arg_style & STYLE_gnu))
4724887Schin 			{
4734887Schin 				p = argv[opt_info.index + 1];
4744887Schin 				if (streq(s, "-$"))
4754887Schin 				{
4764887Schin 					ppop(PP_OPTION, "noid \"$\"");
4774887Schin 					goto ignore;
4784887Schin 				}
4794887Schin 				else if (streq(s, "-dD"))
4804887Schin 				{
4814887Schin 					pp.option |= DEFINITIONS;
4824887Schin 					goto ignore;
4834887Schin 				}
4844887Schin 				else if (streq(s, "-dM"))
4854887Schin 				{
4864887Schin 					pp.state |= NOTEXT;
4874887Schin 					pp.option |= KEEPNOTEXT|DEFINITIONS|PREDEFINITIONS;
4884887Schin 					pp.linesync = 0;
4894887Schin 					goto ignore;
4904887Schin 				}
4914887Schin 				else if (streq(s, "-imacros"))
4924887Schin 				{
4934887Schin 					if (p)
4944887Schin 					{
4954887Schin 						ppop(PP_READ, p);
4964887Schin 						opt_info.index++;
4974887Schin 						opt_info.offset = 0;
4984887Schin 					}
4994887Schin 					goto ignore;
5004887Schin 				}
5014887Schin 				else if (streq(s, "-include"))
5024887Schin 				{
5034887Schin 					if (p)
5044887Schin 					{
5054887Schin 						ppop(PP_TEXT, p);
5064887Schin 						opt_info.index++;
5074887Schin 						opt_info.offset = 0;
5084887Schin 					}
5094887Schin 					opt_info.offset = 0;
5104887Schin 					goto ignore;
5114887Schin 				}
5124887Schin 				else if (strneq(s, "-lang-", 6))
5134887Schin 				{
5144887Schin 					s += 6;
5154887Schin 					if (streq(s, "c"))
5164887Schin 						c = 0;
5174887Schin 					else if (streq(s, "c++"))
5184887Schin 						c = 1;
5194887Schin 					else if (streq(s, "objc"))
5204887Schin 						c = 2;
5214887Schin 					else if (streq(s, "objc++"))
5224887Schin 						c = 3;
5234887Schin 					ppop(PP_PLUSPLUS, c & 1);
5244887Schin 					if (c & 2)
5254887Schin 						ppop(PP_DIRECTIVE, "pragma pp:map \"/#(pragma )?import>/\" \"/#(pragma )?import(.*)/__STDPP__IMPORT__(\\2)/\"\n\
5264887Schin #macdef __STDPP__IMPORT__(x)\n\
5274887Schin #pragma pp:noallmultiple\n\
5284887Schin #include x\n\
5294887Schin #pragma pp:allmultiple\n\
5304887Schin #endmac");
5314887Schin 					goto ignore;
5324887Schin 				}
5334887Schin 				else if (streq(s, "-lint"))
5344887Schin 				{
5354887Schin 					ppop(PP_COMMENT, pplint);
5364887Schin 					goto ignore;
5374887Schin 				}
5384887Schin 			}
5394887Schin 			s += opt_info.offset - 1;
5404887Schin 			if (strmatch(s, "i*.h"))
5414887Schin 				ppop((pp.arg_style & STYLE_gnu) || s[1] == '/' ? PP_READ : PP_TEXT, s + 1);
5424887Schin 			else if (strmatch(s, "*@(nostandard|nostdinc)*"))
5434887Schin 				ppop(PP_STANDARD, "");
5444887Schin 			else if (strmatch(s, "*@(exten|xansi)*|std"))
5454887Schin 			{
5464887Schin 				ppop(PP_COMPATIBILITY, 0);
5474887Schin 				ppop(PP_TRANSITION, 1);
5484887Schin 			}
5494887Schin 			else if (strmatch(s, "*@(ansi|conform|pedantic|stand|std1|strict[!-])*"))
5504887Schin 			{
5514887Schin 				ppop(PP_COMPATIBILITY, 0);
5524887Schin 				ppop(PP_STRICT, 1);
5534887Schin 				if (strmatch(s, "*pedantic*"))
5544887Schin 					ppop(PP_PEDANTIC, 1);
5554887Schin 			}
5564887Schin 			else if (strmatch(s, "*@(trans)*"))
5574887Schin 			{
5584887Schin 				ppop(PP_COMPATIBILITY, 1);
5594887Schin 				ppop(PP_TRANSITION, 1);
5604887Schin 			}
5614887Schin 			else if (strmatch(s, "*@(classic|compat|std0|tradition|[kK][n&+][rR])*"))
5624887Schin 			{
5634887Schin 				ppop(PP_COMPATIBILITY, 1);
5644887Schin 				ppop(PP_TRANSITION, 0);
5654887Schin 			}
5664887Schin 			else if (strmatch(s, "*@(plusplus|++)*"))
5674887Schin 				ppop(PP_PLUSPLUS, 1);
5684887Schin 			else if (strmatch(s, "*@(warn)*"))
5694887Schin 				ppop(PP_WARN, 1);
5704887Schin 
5714887Schin 			/*
5724887Schin 			 * ignore unknown options
5734887Schin 			 * the probe info takes care of these
5744887Schin 			 * fails if an option value is in the next arg
5754887Schin 			 * and this is the last option
5764887Schin 			 */
5774887Schin 
5784887Schin 			if (argv[opt_info.index + 1] && argv[opt_info.index + 1][0] != '-' && argv[opt_info.index + 2] && argv[opt_info.index + 2][0] == '-')
5794887Schin 			{
5804887Schin 				opt_info.index++;
5814887Schin 				opt_info.offset = 0;
5824887Schin 			}
5834887Schin 		ignore:
5844887Schin 			while (argv[opt_info.index][opt_info.offset]) opt_info.offset++;
5854887Schin 			break;
5864887Schin 		}
5874887Schin 		if (!(s = argv[opt_info.index])) return(0);
5884887Schin 		switch (pp.arg_file)
5894887Schin 		{
5904887Schin 		case 0:
5914887Schin 			if (*s != '-' || *(s + 1)) ppop(PP_INPUT, s);
5924887Schin 			break;
5934887Schin 		case 1:
5944887Schin 			if (*s != '-' || *(s + 1)) ppop(PP_OUTPUT, s);
5954887Schin 			break;
5964887Schin 		default:
5974887Schin 			if (!last) return(1);
5984887Schin 			error(1, "%s: extraneous argument ignored", s);
5994887Schin 			break;
6004887Schin 		}
6014887Schin 		pp.arg_file++;
6024887Schin 		if (!argv[++opt_info.index]) return(0);
6034887Schin 
6044887Schin 		/*
6054887Schin 		 * old versions allow options after file args
6064887Schin 		 */
6074887Schin 	}
6084887Schin }
609