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