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