xref: /freebsd-12.1/contrib/gcc/cppspec.c (revision 6b834ef1)
1f2c57ef8SDavid E. O'Brien /* Specific flags and argument handling of the C preprocessor.
2f2c57ef8SDavid E. O'Brien    Copyright (C) 1999 Free Software Foundation, Inc.
3f2c57ef8SDavid E. O'Brien 
41952e2e1SDavid E. O'Brien This file is part of GCC.
5f2c57ef8SDavid E. O'Brien 
61952e2e1SDavid E. O'Brien GCC is free software; you can redistribute it and/or modify it under
71952e2e1SDavid E. O'Brien the terms of the GNU General Public License as published by the Free
81952e2e1SDavid E. O'Brien Software Foundation; either version 2, or (at your option) any later
91952e2e1SDavid E. O'Brien version.
10f2c57ef8SDavid E. O'Brien 
111952e2e1SDavid E. O'Brien GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121952e2e1SDavid E. O'Brien WARRANTY; without even the implied warranty of MERCHANTABILITY or
131952e2e1SDavid E. O'Brien FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141952e2e1SDavid E. O'Brien for more details.
15f2c57ef8SDavid E. O'Brien 
16f2c57ef8SDavid E. O'Brien You should have received a copy of the GNU General Public License
171952e2e1SDavid E. O'Brien along with GCC; see the file COPYING.  If not, write to the Free
18*6b834ef1SAlexander Kabaev Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19*6b834ef1SAlexander Kabaev 02110-1301, USA.  */
20f2c57ef8SDavid E. O'Brien 
21f2c57ef8SDavid E. O'Brien #include "config.h"
22f2c57ef8SDavid E. O'Brien #include "system.h"
239a63ad92SAlexander Kabaev #include "coretypes.h"
249a63ad92SAlexander Kabaev #include "tm.h"
251952e2e1SDavid E. O'Brien #include "gcc.h"
26f2c57ef8SDavid E. O'Brien 
27f2c57ef8SDavid E. O'Brien /* The `cpp' executable installed in $(bindir) and $(cpp_install_dir)
28f2c57ef8SDavid E. O'Brien    is a customized version of the gcc driver.  It forces -E; -S and -c
29f2c57ef8SDavid E. O'Brien    are errors.  It defaults to -x c for files with unrecognized
30f2c57ef8SDavid E. O'Brien    extensions, unless -x options appear in argv, in which case we
31f2c57ef8SDavid E. O'Brien    assume the user knows what they're doing.  If no explicit input is
32f2c57ef8SDavid E. O'Brien    mentioned, it will read stdin.  */
33f2c57ef8SDavid E. O'Brien 
34f2c57ef8SDavid E. O'Brien #ifndef SWITCH_TAKES_ARG
35f2c57ef8SDavid E. O'Brien #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
36f2c57ef8SDavid E. O'Brien #endif
37f2c57ef8SDavid E. O'Brien 
38f2c57ef8SDavid E. O'Brien #ifndef WORD_SWITCH_TAKES_ARG
39f2c57ef8SDavid E. O'Brien #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
40f2c57ef8SDavid E. O'Brien #endif
41f2c57ef8SDavid E. O'Brien 
42f2c57ef8SDavid E. O'Brien /* Suffixes for known sorts of input files.  Note that we do not list
43f2c57ef8SDavid E. O'Brien    files which are normally considered to have been preprocessed already,
44f2c57ef8SDavid E. O'Brien    since the user's expectation is that `cpp' always preprocesses.  */
45f2c57ef8SDavid E. O'Brien static const char *const known_suffixes[] =
46f2c57ef8SDavid E. O'Brien {
47f2c57ef8SDavid E. O'Brien   ".c",  ".C",   ".S",   ".m",
48f2c57ef8SDavid E. O'Brien   ".cc", ".cxx", ".cpp", ".cp",  ".c++",
49f2c57ef8SDavid E. O'Brien   NULL
50f2c57ef8SDavid E. O'Brien };
51f2c57ef8SDavid E. O'Brien 
52f2c57ef8SDavid E. O'Brien /* Filter argc and argv before processing by the gcc driver proper.  */
53f2c57ef8SDavid E. O'Brien void
lang_specific_driver(int * in_argc,const char * const ** in_argv,int * in_added_libraries ATTRIBUTE_UNUSED)549a63ad92SAlexander Kabaev lang_specific_driver (int *in_argc, const char *const **in_argv,
559a63ad92SAlexander Kabaev 		      int *in_added_libraries ATTRIBUTE_UNUSED)
56f2c57ef8SDavid E. O'Brien {
57f2c57ef8SDavid E. O'Brien   int argc = *in_argc;
581952e2e1SDavid E. O'Brien   const char *const *argv = *in_argv;
59f2c57ef8SDavid E. O'Brien 
60f2c57ef8SDavid E. O'Brien   /* Do we need to read stdin? */
61f2c57ef8SDavid E. O'Brien   int read_stdin = 1;
62f2c57ef8SDavid E. O'Brien 
63f2c57ef8SDavid E. O'Brien   /* Do we need to insert -E? */
64f2c57ef8SDavid E. O'Brien   int need_E = 1;
65f2c57ef8SDavid E. O'Brien 
66f2c57ef8SDavid E. O'Brien   /* Have we seen an input file? */
67f2c57ef8SDavid E. O'Brien   int seen_input = 0;
68f2c57ef8SDavid E. O'Brien 
69f2c57ef8SDavid E. O'Brien   /* Positions to insert -xc, -xassembler-with-cpp, and -o, if necessary.
70f2c57ef8SDavid E. O'Brien      0 means unnecessary.  */
71f2c57ef8SDavid E. O'Brien   int lang_c_here = 0;
72f2c57ef8SDavid E. O'Brien   int lang_S_here = 0;
73f2c57ef8SDavid E. O'Brien   int o_here = 0;
74f2c57ef8SDavid E. O'Brien 
75f2c57ef8SDavid E. O'Brien   /* Do we need to fix up an input file with an unrecognized suffix? */
76f2c57ef8SDavid E. O'Brien   int need_fixups = 1;
77f2c57ef8SDavid E. O'Brien 
781952e2e1SDavid E. O'Brien   int i, j, quote = 0;
791952e2e1SDavid E. O'Brien   const char **new_argv;
80f2c57ef8SDavid E. O'Brien   int new_argc;
811952e2e1SDavid E. O'Brien   extern int is_cpp_driver;
821952e2e1SDavid E. O'Brien 
831952e2e1SDavid E. O'Brien   is_cpp_driver = 1;
84f2c57ef8SDavid E. O'Brien 
85f2c57ef8SDavid E. O'Brien   /* First pass.  If we see an -S or -c, barf.  If we see an input file,
86f2c57ef8SDavid E. O'Brien      turn off read_stdin.  If we see a second input file, it is actually
87f2c57ef8SDavid E. O'Brien      the output file.  If we see a third input file, barf.  */
88f2c57ef8SDavid E. O'Brien   for (i = 1; i < argc; i++)
89f2c57ef8SDavid E. O'Brien     {
90f2c57ef8SDavid E. O'Brien       if (quote == 1)
91f2c57ef8SDavid E. O'Brien 	{
92f2c57ef8SDavid E. O'Brien 	  quote = 0;
93f2c57ef8SDavid E. O'Brien 	  continue;
94f2c57ef8SDavid E. O'Brien 	}
95f2c57ef8SDavid E. O'Brien 
96f2c57ef8SDavid E. O'Brien       if (argv[i][0] == '-')
97f2c57ef8SDavid E. O'Brien 	{
98f2c57ef8SDavid E. O'Brien 	  if (argv[i][1] == '\0')
99f2c57ef8SDavid E. O'Brien 	    read_stdin = 0;
100f2c57ef8SDavid E. O'Brien 	  else if (argv[i][2] == '\0')
101f2c57ef8SDavid E. O'Brien 	    {
102f2c57ef8SDavid E. O'Brien 	      if (argv[i][1] == 'E')
103f2c57ef8SDavid E. O'Brien 		need_E = 0;
104f2c57ef8SDavid E. O'Brien 	      else if (argv[i][1] == 'S' || argv[i][1] == 'c')
105f2c57ef8SDavid E. O'Brien 		{
1061952e2e1SDavid E. O'Brien 		  fatal ("\"%s\" is not a valid option to the preprocessor",
107f2c57ef8SDavid E. O'Brien 			 argv[i]);
108f2c57ef8SDavid E. O'Brien 		  return;
109f2c57ef8SDavid E. O'Brien 		}
110f2c57ef8SDavid E. O'Brien 	      else if (argv[i][1] == 'x')
111f2c57ef8SDavid E. O'Brien 		{
112f2c57ef8SDavid E. O'Brien 		  need_fixups = 0;
113f2c57ef8SDavid E. O'Brien 		  quote = 1;
114f2c57ef8SDavid E. O'Brien 		}
115f2c57ef8SDavid E. O'Brien 	      else if (SWITCH_TAKES_ARG (argv[i][1]))
116f2c57ef8SDavid E. O'Brien 		quote = 1;
117f2c57ef8SDavid E. O'Brien 	    }
118f2c57ef8SDavid E. O'Brien 	  else if (argv[i][1] == 'x')
119f2c57ef8SDavid E. O'Brien 	    need_fixups = 0;
120f2c57ef8SDavid E. O'Brien 	  else if (WORD_SWITCH_TAKES_ARG (&argv[i][1]))
121f2c57ef8SDavid E. O'Brien 	    quote = 1;
122f2c57ef8SDavid E. O'Brien 	}
123f2c57ef8SDavid E. O'Brien       else /* not an option */
124f2c57ef8SDavid E. O'Brien 	{
125f2c57ef8SDavid E. O'Brien 	  seen_input++;
126f2c57ef8SDavid E. O'Brien 	  if (seen_input == 3)
127f2c57ef8SDavid E. O'Brien 	    {
1281952e2e1SDavid E. O'Brien 	      fatal ("too many input files");
129f2c57ef8SDavid E. O'Brien 	      return;
130f2c57ef8SDavid E. O'Brien 	    }
131f2c57ef8SDavid E. O'Brien 	  else if (seen_input == 2)
132f2c57ef8SDavid E. O'Brien 	    {
133f2c57ef8SDavid E. O'Brien 	      o_here = i;
134f2c57ef8SDavid E. O'Brien 	    }
135f2c57ef8SDavid E. O'Brien 	  else
136f2c57ef8SDavid E. O'Brien 	    {
137f2c57ef8SDavid E. O'Brien 	      read_stdin = 0;
138f2c57ef8SDavid E. O'Brien 	      if (need_fixups)
139f2c57ef8SDavid E. O'Brien 		{
140f2c57ef8SDavid E. O'Brien 		  int l = strlen (argv[i]);
141f2c57ef8SDavid E. O'Brien 		  int known = 0;
142f2c57ef8SDavid E. O'Brien 		  const char *const *suff;
143f2c57ef8SDavid E. O'Brien 
144f2c57ef8SDavid E. O'Brien 		  for (suff = known_suffixes; *suff; suff++)
145f2c57ef8SDavid E. O'Brien 		    if (!strcmp (*suff, &argv[i][l - strlen(*suff)]))
146f2c57ef8SDavid E. O'Brien 		      {
147f2c57ef8SDavid E. O'Brien 			known = 1;
148f2c57ef8SDavid E. O'Brien 			break;
149f2c57ef8SDavid E. O'Brien 		      }
150f2c57ef8SDavid E. O'Brien 
151f2c57ef8SDavid E. O'Brien 		  if (! known)
152f2c57ef8SDavid E. O'Brien 		    {
153f2c57ef8SDavid E. O'Brien 		      /* .s files are a special case; we have to treat
154f2c57ef8SDavid E. O'Brien 			 them like .S files so -D__ASSEMBLER__ will be
155f2c57ef8SDavid E. O'Brien 			 in effect.  */
156f2c57ef8SDavid E. O'Brien 		      if (!strcmp (".s", &argv[i][l - 2]))
157f2c57ef8SDavid E. O'Brien 			lang_S_here = i;
158f2c57ef8SDavid E. O'Brien 		      else
159f2c57ef8SDavid E. O'Brien 			lang_c_here = i;
160f2c57ef8SDavid E. O'Brien 		    }
161f2c57ef8SDavid E. O'Brien 		}
162f2c57ef8SDavid E. O'Brien 	    }
163f2c57ef8SDavid E. O'Brien 	}
164f2c57ef8SDavid E. O'Brien     }
165f2c57ef8SDavid E. O'Brien 
166f2c57ef8SDavid E. O'Brien   /* If we don't need to edit the command line, we can bail early.  */
167f2c57ef8SDavid E. O'Brien 
1689a63ad92SAlexander Kabaev   new_argc = argc + need_E + read_stdin
169f2c57ef8SDavid E. O'Brien     + !!o_here + !!lang_c_here + !!lang_S_here;
170f2c57ef8SDavid E. O'Brien 
171f2c57ef8SDavid E. O'Brien   if (new_argc == argc)
172f2c57ef8SDavid E. O'Brien     return;
173f2c57ef8SDavid E. O'Brien 
1741952e2e1SDavid E. O'Brien   /* One more slot for a terminating null.  */
175*6b834ef1SAlexander Kabaev   new_argv = XNEWVEC (const char *, new_argc + 1);
176f2c57ef8SDavid E. O'Brien 
177f2c57ef8SDavid E. O'Brien   new_argv[0] = argv[0];
178f2c57ef8SDavid E. O'Brien   j = 1;
179f2c57ef8SDavid E. O'Brien 
180f2c57ef8SDavid E. O'Brien   if (need_E)
181f2c57ef8SDavid E. O'Brien     new_argv[j++] = "-E";
182f2c57ef8SDavid E. O'Brien 
183f2c57ef8SDavid E. O'Brien   for (i = 1; i < argc; i++, j++)
184f2c57ef8SDavid E. O'Brien     {
185f2c57ef8SDavid E. O'Brien       if (i == lang_c_here)
186f2c57ef8SDavid E. O'Brien 	new_argv[j++] = "-xc";
187f2c57ef8SDavid E. O'Brien       else if (i == lang_S_here)
188f2c57ef8SDavid E. O'Brien 	new_argv[j++] = "-xassembler-with-cpp";
189f2c57ef8SDavid E. O'Brien       else if (i == o_here)
190f2c57ef8SDavid E. O'Brien 	new_argv[j++] = "-o";
191f2c57ef8SDavid E. O'Brien 
192f2c57ef8SDavid E. O'Brien       new_argv[j] = argv[i];
193f2c57ef8SDavid E. O'Brien     }
194f2c57ef8SDavid E. O'Brien 
195f2c57ef8SDavid E. O'Brien   if (read_stdin)
1961952e2e1SDavid E. O'Brien     new_argv[j++] = "-";
197f2c57ef8SDavid E. O'Brien 
1981952e2e1SDavid E. O'Brien   new_argv[j] = NULL;
199f2c57ef8SDavid E. O'Brien   *in_argc = new_argc;
200f2c57ef8SDavid E. O'Brien   *in_argv = new_argv;
201f2c57ef8SDavid E. O'Brien }
202f2c57ef8SDavid E. O'Brien 
203f2c57ef8SDavid E. O'Brien /* Called before linking.  Returns 0 on success and -1 on failure.  */
lang_specific_pre_link(void)2049a63ad92SAlexander Kabaev int lang_specific_pre_link (void)
205f2c57ef8SDavid E. O'Brien {
206f2c57ef8SDavid E. O'Brien   return 0;  /* Not used for cpp.  */
207f2c57ef8SDavid E. O'Brien }
208f2c57ef8SDavid E. O'Brien 
209f2c57ef8SDavid E. O'Brien /* Number of extra output files that lang_specific_pre_link may generate.  */
210f2c57ef8SDavid E. O'Brien int lang_specific_extra_outfiles = 0;  /* Not used for cpp.  */
211