OSDN Git Service

* configure.in: Fix typo.
[pf3gnuchains/gcc-fork.git] / gcc / cppspec.c
1 /* Specific flags and argument handling of the C preprocessor.
2    Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "gcc.h"
26
27 /* The `cpp' executable installed in $(bindir) and $(cpp_install_dir)
28    is a customized version of the gcc driver.  It forces -E; -S and -c
29    are errors.  It defaults to -x c for files with unrecognized
30    extensions, unless -x options appear in argv, in which case we
31    assume the user knows what they're doing.  If no explicit input is
32    mentioned, it will read stdin.  */
33
34 /* Snarfed from gcc.c: */
35
36 /* This defines which switch letters take arguments.  */
37
38 #define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
39   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
40    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
41    || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
42    || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
43    || (CHAR) == 'B' || (CHAR) == 'b')
44
45 #ifndef SWITCH_TAKES_ARG
46 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
47 #endif
48
49 /* This defines which multi-letter switches take arguments.  */
50
51 #define DEFAULT_WORD_SWITCH_TAKES_ARG(STR)              \
52  (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext")      \
53   || !strcmp (STR, "Tbss") || !strcmp (STR, "include")  \
54   || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
55   || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
56   || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
57   || !strcmp (STR, "isystem") || !strcmp (STR, "specs") \
58   || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ"))
59
60 #ifndef WORD_SWITCH_TAKES_ARG
61 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
62 #endif
63
64 /* Suffixes for known sorts of input files.  Note that we do not list
65    files which are normally considered to have been preprocessed already,
66    since the user's expectation is that `cpp' always preprocesses.  */
67 static const char *const known_suffixes[] =
68 {
69   ".c",  ".C",   ".S",   ".m",
70   ".cc", ".cxx", ".cpp", ".cp",  ".c++",
71   NULL
72 };
73
74 /* Filter argc and argv before processing by the gcc driver proper.  */
75 void
76 lang_specific_driver (in_argc, in_argv, in_added_libraries)
77      int *in_argc;
78      const char *const **in_argv;
79      int *in_added_libraries ATTRIBUTE_UNUSED;
80 {
81   int argc = *in_argc;
82   const char *const *argv = *in_argv;
83
84   /* Do we need to read stdin? */
85   int read_stdin = 1;
86
87   /* Do we need to insert -E? */
88   int need_E = 1;
89
90   /* Do we need to insert -no-gcc? */
91   int need_no_gcc = 1;
92
93   /* Have we seen an input file? */
94   int seen_input = 0;
95
96   /* Positions to insert -xc, -xassembler-with-cpp, and -o, if necessary.
97      0 means unnecessary.  */
98   int lang_c_here = 0;
99   int lang_S_here = 0;
100   int o_here = 0;
101
102   /* Do we need to fix up an input file with an unrecognized suffix? */
103   int need_fixups = 1;
104
105   int i, j, quote = 0;
106   const char **new_argv;
107   int new_argc;
108   extern int is_cpp_driver;
109
110   is_cpp_driver = 1;
111
112   /* First pass.  If we see an -S or -c, barf.  If we see an input file,
113      turn off read_stdin.  If we see a second input file, it is actually
114      the output file.  If we see a third input file, barf.  */
115   for (i = 1; i < argc; i++)
116     {
117       if (quote == 1)
118         {
119           quote = 0;
120           continue;
121         }
122
123       if (argv[i][0] == '-')
124         {
125           if (argv[i][1] == '\0')
126             read_stdin = 0;
127           else if (argv[i][2] == '\0')
128             {
129               if (argv[i][1] == 'E')
130                 need_E = 0;
131               else if (argv[i][1] == 'S' || argv[i][1] == 'c')
132                 {
133                   fatal ("\"%s\" is not a valid option to the preprocessor",
134                          argv[i]);
135                   return;
136                 }
137               else if (argv[i][1] == 'x')
138                 {
139                   need_fixups = 0;
140                   quote = 1;
141                 }
142               else if (SWITCH_TAKES_ARG (argv[i][1]))
143                 quote = 1;
144             }
145           else if (argv[i][1] == 'x')
146             need_fixups = 0;
147           else if (argv[i][1] == 'g' && !strcmp(&argv[i][2], "cc"))
148             need_no_gcc = 0;
149           else if (WORD_SWITCH_TAKES_ARG (&argv[i][1]))
150             quote = 1;
151         }
152       else /* not an option */
153         {
154           seen_input++;
155           if (seen_input == 3)
156             {
157               fatal ("too many input files");
158               return;
159             }
160           else if (seen_input == 2)
161             {
162               o_here = i;
163             }
164           else
165             {
166               read_stdin = 0;
167               if (need_fixups)
168                 {
169                   int l = strlen (argv[i]);
170                   int known = 0;
171                   const char *const *suff;
172
173                   for (suff = known_suffixes; *suff; suff++)
174                     if (!strcmp (*suff, &argv[i][l - strlen(*suff)]))
175                       {
176                         known = 1;
177                         break;
178                       }
179
180                   if (! known)
181                     {
182                       /* .s files are a special case; we have to treat
183                          them like .S files so -D__ASSEMBLER__ will be
184                          in effect.  */
185                       if (!strcmp (".s", &argv[i][l - 2]))
186                         lang_S_here = i;
187                       else
188                         lang_c_here = i;
189                     }
190                 }
191             }
192         }
193     }
194
195   /* If we don't need to edit the command line, we can bail early.  */
196
197   new_argc = argc + need_E + need_no_gcc + read_stdin
198     + !!o_here + !!lang_c_here + !!lang_S_here;
199
200   if (new_argc == argc)
201     return;
202
203   /* One more slot for a terminating null.  */
204   new_argv = (const char **) xmalloc ((new_argc + 1) * sizeof(char *));
205
206   new_argv[0] = argv[0];
207   j = 1;
208
209   if (need_E)
210     new_argv[j++] = "-E";
211
212   if (need_no_gcc)
213     new_argv[j++] = "-no-gcc";
214
215   for (i = 1; i < argc; i++, j++)
216     {
217       if (i == lang_c_here)
218         new_argv[j++] = "-xc";
219       else if (i == lang_S_here)
220         new_argv[j++] = "-xassembler-with-cpp";
221       else if (i == o_here)
222         new_argv[j++] = "-o";
223
224       new_argv[j] = argv[i];
225     }
226
227   if (read_stdin)
228     new_argv[j++] = "-";
229
230   new_argv[j] = NULL;
231   *in_argc = new_argc;
232   *in_argv = new_argv;
233 }
234
235 /* Called before linking.  Returns 0 on success and -1 on failure.  */
236 int lang_specific_pre_link ()
237 {
238   return 0;  /* Not used for cpp.  */
239 }
240
241 /* Number of extra output files that lang_specific_pre_link may generate.  */
242 int lang_specific_extra_outfiles = 0;  /* Not used for cpp.  */
243
244 /* Table of language-specific spec functions.  */
245 const struct spec_function lang_specific_spec_functions[] =
246 {
247   { 0, 0 }
248 };