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