11556Srgrimes/* Specific flags and argument handling of the C preprocessor. 21556Srgrimes Copyright (C) 1999 Free Software Foundation, Inc. 31556Srgrimes 41556SrgrimesThis file is part of GCC. 51556Srgrimes 61556SrgrimesGCC is free software; you can redistribute it and/or modify it under 71556Srgrimesthe terms of the GNU General Public License as published by the Free 81556SrgrimesSoftware Foundation; either version 2, or (at your option) any later 91556Srgrimesversion. 101556Srgrimes 111556SrgrimesGCC is distributed in the hope that it will be useful, but WITHOUT ANY 121556SrgrimesWARRANTY; without even the implied warranty of MERCHANTABILITY or 131556SrgrimesFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141556Srgrimesfor more details. 151556Srgrimes 161556SrgrimesYou should have received a copy of the GNU General Public License 171556Srgrimesalong with GCC; see the file COPYING. If not, write to the Free 181556SrgrimesSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 191556Srgrimes02110-1301, USA. */ 201556Srgrimes 211556Srgrimes#include "config.h" 221556Srgrimes#include "system.h" 231556Srgrimes#include "coretypes.h" 241556Srgrimes#include "tm.h" 251556Srgrimes#include "gcc.h" 261556Srgrimes 271556Srgrimes/* The `cpp' executable installed in $(bindir) and $(cpp_install_dir) 281556Srgrimes is a customized version of the gcc driver. It forces -E; -S and -c 291556Srgrimes are errors. It defaults to -x c for files with unrecognized 301556Srgrimes extensions, unless -x options appear in argv, in which case we 311556Srgrimes assume the user knows what they're doing. If no explicit input is 321556Srgrimes mentioned, it will read stdin. */ 331556Srgrimes 341556Srgrimes#ifndef SWITCH_TAKES_ARG 351556Srgrimes#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) 361556Srgrimes#endif 371556Srgrimes 381556Srgrimes#ifndef WORD_SWITCH_TAKES_ARG 3936049Scharnier#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) 4036049Scharnier#endif 4136049Scharnier 4236049Scharnier/* Suffixes for known sorts of input files. Note that we do not list 4350471Speter files which are normally considered to have been preprocessed already, 441556Srgrimes since the user's expectation is that `cpp' always preprocesses. */ 451556Srgrimesstatic const char *const known_suffixes[] = 461556Srgrimes{ 471556Srgrimes ".c", ".C", ".S", ".m", 481556Srgrimes ".cc", ".cxx", ".cpp", ".cp", ".c++", 491556Srgrimes NULL 501556Srgrimes}; 511556Srgrimes 521556Srgrimes/* Filter argc and argv before processing by the gcc driver proper. */ 531556Srgrimesvoid 541556Srgrimeslang_specific_driver (int *in_argc, const char *const **in_argv, 551556Srgrimes int *in_added_libraries ATTRIBUTE_UNUSED) 561556Srgrimes{ 571556Srgrimes int argc = *in_argc; 581556Srgrimes const char *const *argv = *in_argv; 591556Srgrimes 601556Srgrimes /* Do we need to read stdin? */ 611556Srgrimes int read_stdin = 1; 621556Srgrimes 631556Srgrimes /* Do we need to insert -E? */ 641556Srgrimes int need_E = 1; 651556Srgrimes 661556Srgrimes /* Have we seen an input file? */ 671556Srgrimes int seen_input = 0; 681556Srgrimes 691556Srgrimes /* Positions to insert -xc, -xassembler-with-cpp, and -o, if necessary. 701556Srgrimes 0 means unnecessary. */ 711556Srgrimes int lang_c_here = 0; 721556Srgrimes int lang_S_here = 0; 731556Srgrimes int o_here = 0; 741556Srgrimes 751556Srgrimes /* Do we need to fix up an input file with an unrecognized suffix? */ 761556Srgrimes int need_fixups = 1; 771556Srgrimes 781556Srgrimes int i, j, quote = 0; 7976017Skris const char **new_argv; 801556Srgrimes int new_argc; 811556Srgrimes extern int is_cpp_driver; 821556Srgrimes 831556Srgrimes is_cpp_driver = 1; 841556Srgrimes 851556Srgrimes /* First pass. If we see an -S or -c, barf. If we see an input file, 861556Srgrimes turn off read_stdin. If we see a second input file, it is actually 871556Srgrimes the output file. If we see a third input file, barf. */ 881556Srgrimes for (i = 1; i < argc; i++) 891556Srgrimes { 901556Srgrimes if (quote == 1) 911556Srgrimes { 921556Srgrimes quote = 0; 931556Srgrimes continue; 941556Srgrimes } 9576017Skris 961556Srgrimes if (argv[i][0] == '-') 971556Srgrimes { 981556Srgrimes if (argv[i][1] == '\0') 991556Srgrimes read_stdin = 0; 1001556Srgrimes else if (argv[i][2] == '\0') 1011556Srgrimes { 1021556Srgrimes if (argv[i][1] == 'E') 1031556Srgrimes need_E = 0; 1041556Srgrimes else if (argv[i][1] == 'S' || argv[i][1] == 'c') 1051556Srgrimes { 1061556Srgrimes fatal ("\"%s\" is not a valid option to the preprocessor", 1071556Srgrimes argv[i]); 10876017Skris return; 1091556Srgrimes } 1101556Srgrimes else if (argv[i][1] == 'x') 1111556Srgrimes { 1121556Srgrimes need_fixups = 0; 1131556Srgrimes quote = 1; 1141556Srgrimes } 1151556Srgrimes else if (SWITCH_TAKES_ARG (argv[i][1])) 1161556Srgrimes quote = 1; 1171556Srgrimes } 1181556Srgrimes else if (argv[i][1] == 'x') 1191556Srgrimes need_fixups = 0; 1201556Srgrimes else if (WORD_SWITCH_TAKES_ARG (&argv[i][1])) 1211556Srgrimes quote = 1; 1221556Srgrimes } 1231556Srgrimes else /* not an option */ 12476017Skris { 1251556Srgrimes seen_input++; 1261556Srgrimes if (seen_input == 3) 1271556Srgrimes { 1281556Srgrimes fatal ("too many input files"); 1291556Srgrimes return; 1301556Srgrimes } 1311556Srgrimes else if (seen_input == 2) 1321556Srgrimes { 1331556Srgrimes o_here = i; 1341556Srgrimes } 1351556Srgrimes else 1361556Srgrimes { 13776017Skris read_stdin = 0; 1381556Srgrimes if (need_fixups) 1391556Srgrimes { 1401556Srgrimes int l = strlen (argv[i]); 1411556Srgrimes int known = 0; 1421556Srgrimes const char *const *suff; 1431556Srgrimes 1441556Srgrimes for (suff = known_suffixes; *suff; suff++) 1451556Srgrimes if (!strcmp (*suff, &argv[i][l - strlen(*suff)])) 1461556Srgrimes { 1471556Srgrimes known = 1; 1481556Srgrimes break; 1491556Srgrimes } 1501556Srgrimes 1511556Srgrimes if (! known) 1521556Srgrimes { 15376017Skris /* .s files are a special case; we have to treat 1541556Srgrimes them like .S files so -D__ASSEMBLER__ will be 1551556Srgrimes in effect. */ 1561556Srgrimes if (!strcmp (".s", &argv[i][l - 2])) 1571556Srgrimes lang_S_here = i; 1581556Srgrimes else 1591556Srgrimes lang_c_here = i; 1601556Srgrimes } 1611556Srgrimes } 1621556Srgrimes } 1631556Srgrimes } 1641556Srgrimes } 1651556Srgrimes 16676017Skris /* If we don't need to edit the command line, we can bail early. */ 1671556Srgrimes 1681556Srgrimes new_argc = argc + need_E + read_stdin 1691556Srgrimes + !!o_here + !!lang_c_here + !!lang_S_here; 1701556Srgrimes 1711556Srgrimes if (new_argc == argc) 1721556Srgrimes return; 1731556Srgrimes 1741556Srgrimes /* One more slot for a terminating null. */ 1751556Srgrimes new_argv = XNEWVEC (const char *, new_argc + 1); 1761556Srgrimes 1771556Srgrimes new_argv[0] = argv[0]; 1781556Srgrimes j = 1; 1791556Srgrimes 1801556Srgrimes if (need_E) 1811556Srgrimes new_argv[j++] = "-E"; 18276017Skris 1831556Srgrimes for (i = 1; i < argc; i++, j++) 1841556Srgrimes { 1851556Srgrimes if (i == lang_c_here) 1861556Srgrimes new_argv[j++] = "-xc"; 1871556Srgrimes else if (i == lang_S_here) 1881556Srgrimes new_argv[j++] = "-xassembler-with-cpp"; 1891556Srgrimes else if (i == o_here) 1901556Srgrimes new_argv[j++] = "-o"; 1911556Srgrimes 1921556Srgrimes new_argv[j] = argv[i]; 1931556Srgrimes } 1941556Srgrimes 1951556Srgrimes if (read_stdin) 19676017Skris new_argv[j++] = "-"; 1971556Srgrimes 1981556Srgrimes new_argv[j] = NULL; 1991556Srgrimes *in_argc = new_argc; 2001556Srgrimes *in_argv = new_argv; 2011556Srgrimes} 2021556Srgrimes 2031556Srgrimes/* Called before linking. Returns 0 on success and -1 on failure. */ 2041556Srgrimesint lang_specific_pre_link (void) 2051556Srgrimes{ 2061556Srgrimes return 0; /* Not used for cpp. */ 2071556Srgrimes} 2081556Srgrimes 2091556Srgrimes/* Number of extra output files that lang_specific_pre_link may generate. */ 2101556Srgrimesint lang_specific_extra_outfiles = 0; /* Not used for cpp. */ 2111556Srgrimes