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