OSDN Git Service

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