152284Sobrien/* Specific flags and argument handling of the C preprocessor. 252284Sobrien Copyright (C) 1999 Free Software Foundation, Inc. 352284Sobrien 490075SobrienThis file is part of GCC. 552284Sobrien 690075SobrienGCC is free software; you can redistribute it and/or modify it under 790075Sobrienthe terms of the GNU General Public License as published by the Free 890075SobrienSoftware Foundation; either version 2, or (at your option) any later 990075Sobrienversion. 1052284Sobrien 1190075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1290075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1390075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1490075Sobrienfor more details. 1552284Sobrien 1652284SobrienYou should have received a copy of the GNU General Public License 1790075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 19169689Skan02110-1301, USA. */ 2052284Sobrien 2152284Sobrien#include "config.h" 2252284Sobrien#include "system.h" 23132718Skan#include "coretypes.h" 24132718Skan#include "tm.h" 2590075Sobrien#include "gcc.h" 2652284Sobrien 2752284Sobrien/* The `cpp' executable installed in $(bindir) and $(cpp_install_dir) 2852284Sobrien is a customized version of the gcc driver. It forces -E; -S and -c 2952284Sobrien are errors. It defaults to -x c for files with unrecognized 3052284Sobrien extensions, unless -x options appear in argv, in which case we 3152284Sobrien assume the user knows what they're doing. If no explicit input is 3290075Sobrien mentioned, it will read stdin. */ 3352284Sobrien 3452284Sobrien#ifndef SWITCH_TAKES_ARG 3552284Sobrien#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) 3652284Sobrien#endif 3752284Sobrien 3852284Sobrien#ifndef WORD_SWITCH_TAKES_ARG 3952284Sobrien#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) 4052284Sobrien#endif 4152284Sobrien 4252284Sobrien/* Suffixes for known sorts of input files. Note that we do not list 4352284Sobrien files which are normally considered to have been preprocessed already, 4452284Sobrien since the user's expectation is that `cpp' always preprocesses. */ 4552284Sobrienstatic const char *const known_suffixes[] = 4652284Sobrien{ 4752284Sobrien ".c", ".C", ".S", ".m", 4852284Sobrien ".cc", ".cxx", ".cpp", ".cp", ".c++", 4952284Sobrien NULL 5052284Sobrien}; 5152284Sobrien 5290075Sobrien/* Filter argc and argv before processing by the gcc driver proper. */ 5352284Sobrienvoid 54132718Skanlang_specific_driver (int *in_argc, const char *const **in_argv, 55132718Skan int *in_added_libraries ATTRIBUTE_UNUSED) 5652284Sobrien{ 5752284Sobrien int argc = *in_argc; 5890075Sobrien const char *const *argv = *in_argv; 5990075Sobrien 6052284Sobrien /* Do we need to read stdin? */ 6152284Sobrien int read_stdin = 1; 6252284Sobrien 6352284Sobrien /* Do we need to insert -E? */ 6452284Sobrien int need_E = 1; 6552284Sobrien 6652284Sobrien /* Have we seen an input file? */ 6752284Sobrien int seen_input = 0; 68117395Skan 6952284Sobrien /* Positions to insert -xc, -xassembler-with-cpp, and -o, if necessary. 7090075Sobrien 0 means unnecessary. */ 7152284Sobrien int lang_c_here = 0; 7252284Sobrien int lang_S_here = 0; 7352284Sobrien int o_here = 0; 7452284Sobrien 7552284Sobrien /* Do we need to fix up an input file with an unrecognized suffix? */ 7652284Sobrien int need_fixups = 1; 77117395Skan 7890075Sobrien int i, j, quote = 0; 7990075Sobrien const char **new_argv; 8052284Sobrien int new_argc; 8190075Sobrien extern int is_cpp_driver; 8252284Sobrien 8390075Sobrien is_cpp_driver = 1; 8490075Sobrien 8552284Sobrien /* First pass. If we see an -S or -c, barf. If we see an input file, 8652284Sobrien turn off read_stdin. If we see a second input file, it is actually 8752284Sobrien the output file. If we see a third input file, barf. */ 8852284Sobrien for (i = 1; i < argc; i++) 8952284Sobrien { 9052284Sobrien if (quote == 1) 9152284Sobrien { 9252284Sobrien quote = 0; 9352284Sobrien continue; 9452284Sobrien } 95117395Skan 9652284Sobrien if (argv[i][0] == '-') 9752284Sobrien { 9852284Sobrien if (argv[i][1] == '\0') 9952284Sobrien read_stdin = 0; 10052284Sobrien else if (argv[i][2] == '\0') 10152284Sobrien { 10252284Sobrien if (argv[i][1] == 'E') 10352284Sobrien need_E = 0; 10452284Sobrien else if (argv[i][1] == 'S' || argv[i][1] == 'c') 10552284Sobrien { 10690075Sobrien fatal ("\"%s\" is not a valid option to the preprocessor", 10790075Sobrien argv[i]); 10852284Sobrien return; 10952284Sobrien } 11052284Sobrien else if (argv[i][1] == 'x') 11152284Sobrien { 11252284Sobrien need_fixups = 0; 11352284Sobrien quote = 1; 11452284Sobrien } 11552284Sobrien else if (SWITCH_TAKES_ARG (argv[i][1])) 11652284Sobrien quote = 1; 11752284Sobrien } 11852284Sobrien else if (argv[i][1] == 'x') 11952284Sobrien need_fixups = 0; 12052284Sobrien else if (WORD_SWITCH_TAKES_ARG (&argv[i][1])) 12152284Sobrien quote = 1; 12252284Sobrien } 12352284Sobrien else /* not an option */ 12452284Sobrien { 12552284Sobrien seen_input++; 12652284Sobrien if (seen_input == 3) 12752284Sobrien { 12890075Sobrien fatal ("too many input files"); 12952284Sobrien return; 13052284Sobrien } 13152284Sobrien else if (seen_input == 2) 13252284Sobrien { 13352284Sobrien o_here = i; 13452284Sobrien } 13552284Sobrien else 13652284Sobrien { 13752284Sobrien read_stdin = 0; 13852284Sobrien if (need_fixups) 13952284Sobrien { 14052284Sobrien int l = strlen (argv[i]); 14152284Sobrien int known = 0; 14252284Sobrien const char *const *suff; 14352284Sobrien 14452284Sobrien for (suff = known_suffixes; *suff; suff++) 14552284Sobrien if (!strcmp (*suff, &argv[i][l - strlen(*suff)])) 14652284Sobrien { 14752284Sobrien known = 1; 14852284Sobrien break; 14952284Sobrien } 15052284Sobrien 15152284Sobrien if (! known) 15252284Sobrien { 15352284Sobrien /* .s files are a special case; we have to treat 15452284Sobrien them like .S files so -D__ASSEMBLER__ will be 15552284Sobrien in effect. */ 15652284Sobrien if (!strcmp (".s", &argv[i][l - 2])) 15752284Sobrien lang_S_here = i; 15852284Sobrien else 15952284Sobrien lang_c_here = i; 16052284Sobrien } 16152284Sobrien } 16252284Sobrien } 16352284Sobrien } 16452284Sobrien } 16552284Sobrien 16652284Sobrien /* If we don't need to edit the command line, we can bail early. */ 16752284Sobrien 168132718Skan new_argc = argc + need_E + read_stdin 16952284Sobrien + !!o_here + !!lang_c_here + !!lang_S_here; 17052284Sobrien 17152284Sobrien if (new_argc == argc) 17252284Sobrien return; 17352284Sobrien 17490075Sobrien /* One more slot for a terminating null. */ 175169689Skan new_argv = XNEWVEC (const char *, new_argc + 1); 17652284Sobrien 17752284Sobrien new_argv[0] = argv[0]; 17852284Sobrien j = 1; 17952284Sobrien 18052284Sobrien if (need_E) 18152284Sobrien new_argv[j++] = "-E"; 18252284Sobrien 18352284Sobrien for (i = 1; i < argc; i++, j++) 18452284Sobrien { 18552284Sobrien if (i == lang_c_here) 18652284Sobrien new_argv[j++] = "-xc"; 18752284Sobrien else if (i == lang_S_here) 18852284Sobrien new_argv[j++] = "-xassembler-with-cpp"; 18952284Sobrien else if (i == o_here) 19052284Sobrien new_argv[j++] = "-o"; 19152284Sobrien 19252284Sobrien new_argv[j] = argv[i]; 19352284Sobrien } 19452284Sobrien 19552284Sobrien if (read_stdin) 19690075Sobrien new_argv[j++] = "-"; 19752284Sobrien 19890075Sobrien new_argv[j] = NULL; 19952284Sobrien *in_argc = new_argc; 20052284Sobrien *in_argv = new_argv; 201117395Skan} 20252284Sobrien 20390075Sobrien/* Called before linking. Returns 0 on success and -1 on failure. */ 204132718Skanint lang_specific_pre_link (void) 20552284Sobrien{ 20690075Sobrien return 0; /* Not used for cpp. */ 20752284Sobrien} 20852284Sobrien 20990075Sobrien/* Number of extra output files that lang_specific_pre_link may generate. */ 21090075Sobrienint lang_specific_extra_outfiles = 0; /* Not used for cpp. */ 211