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