]> gcc.gnu.org Git - gcc.git/blame - gcc/cppmain.c
genoutput.c (validate_insn_operands): New.
[gcc.git] / gcc / cppmain.c
CommitLineData
7f2935c7 1/* CPP main program, using CPP Library.
5e7b4e25 2 Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
7f2935c7
PB
3 Written by Per Bothner, 1994-95.
4
5This program is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
940d9d63 17Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
7f2935c7
PB
18
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding! */
22
84ee6fd4 23#include "config.h"
b04cd507 24#include "system.h"
b04cd507 25#include "cpplib.h"
ab87f8c8 26#include "intl.h"
7f2935c7 27
93c80368
NB
28/* Encapsulates state used to convert the stream of tokens coming from
29 cpp_get_token back into a text file. */
30struct printer
31{
32 FILE *outf; /* stream to write to. */
33 const char *last_fname; /* previous file name. */
34 const char *syshdr_flags; /* system header flags, if any. */
35 unsigned int lineno; /* line currently being written. */
36 unsigned char printed; /* nonzero if something output at lineno. */
37 unsigned char no_line_dirs; /* nonzero to output no line directives. */
38};
7f2935c7 39
58fea6af 40int main PARAMS ((int, char **));
cf44ea52
NB
41static void general_init PARAMS ((const char *));
42static void setup_callbacks PARAMS ((void));
58fea6af 43
93c80368
NB
44/* General output routines. */
45static void scan_buffer PARAMS ((cpp_reader *));
46static int printer_init PARAMS ((cpp_reader *));
926c5678 47static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
93c80368
NB
48
49static void print_line PARAMS ((const char *));
50static void maybe_print_line PARAMS ((unsigned int));
93c80368 51
58fea6af
ZW
52/* Callback routines for the parser. Most of these are active only
53 in specific modes. */
54static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *));
55static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
56static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
93c80368
NB
57 const cpp_token *));
58static void cb_ident PARAMS ((cpp_reader *, const cpp_string *));
27e2564a 59static void cb_change_file PARAMS ((cpp_reader *, const cpp_file_change *));
58fea6af 60static void cb_def_pragma PARAMS ((cpp_reader *));
58fea6af 61static void do_pragma_implementation PARAMS ((cpp_reader *));
93c80368 62
cf44ea52
NB
63const char *progname; /* Needs to be global. */
64static cpp_reader *pfile;
926c5678 65static struct printer print;
58fea6af 66
7f2935c7
PB
67int
68main (argc, argv)
69 int argc;
70 char **argv;
71{
0f41302f 72 int argi = 1; /* Next argument to handle. */
7f2935c7 73
cf44ea52 74 general_init (argv[0]);
dd07b884 75 /* Default language is GNU C89. */
cf44ea52 76 pfile = cpp_create_reader (CLK_GNUC89);
7f2935c7 77
ae79697b
ZW
78 argi += cpp_handle_options (pfile, argc - argi , argv + argi);
79 if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
80 cpp_fatal (pfile, "Invalid option %s", argv[argi]);
81 if (CPP_FATAL_ERRORS (pfile))
bcc5cac9 82 return (FATAL_EXIT_CODE);
7f2935c7 83
f2d5f0cc
ZW
84 /* Open the output now. We must do so even if no_output is on,
85 because there may be other output than from the actual
86 preprocessing (e.g. from -dM). */
93c80368 87 if (printer_init (pfile))
bcc5cac9 88 return (FATAL_EXIT_CODE);
58fea6af 89
cf44ea52 90 setup_callbacks ();
7f2935c7 91
93c80368 92 if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
f2d5f0cc
ZW
93 return (FATAL_EXIT_CODE);
94
93c80368
NB
95 if (CPP_BUFFER (pfile))
96 {
97 if (CPP_OPTION (pfile, no_output))
98 cpp_scan_buffer_nooutput (pfile);
99 else
100 scan_buffer (pfile);
101 }
7f2935c7 102
93c80368 103 /* -dM command line option. */
58fea6af 104 if (CPP_OPTION (pfile, dump_macros) == dump_only)
926c5678 105 cpp_forall_identifiers (pfile, dump_macro, NULL);
93c80368
NB
106
107 cpp_finish (pfile);
ae79697b 108 cpp_cleanup (pfile);
a9ae4483 109
93c80368
NB
110 /* Flush any pending output. */
111 if (print.printed)
112 putc ('\n', print.outf);
113 if (ferror (print.outf) || fclose (print.outf))
114 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
115
cf44ea52 116 if (pfile->errors)
bcc5cac9
KG
117 return (FATAL_EXIT_CODE);
118 return (SUCCESS_EXIT_CODE);
7f2935c7 119}
58fea6af 120
cf44ea52
NB
121/* Store the program name, and set the locale. */
122static void
123general_init (const char *argv0)
124{
125 progname = argv0 + strlen (argv0);
126
127 while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
128 --progname;
129
130 xmalloc_set_program_name (progname);
131
132#ifdef HAVE_LC_MESSAGES
133 setlocale (LC_MESSAGES, "");
134#endif
135 (void) bindtextdomain (PACKAGE, localedir);
136 (void) textdomain (PACKAGE);
137}
138
139/* Set up the callbacks and register the pragmas we handle. */
140static void
141setup_callbacks ()
142{
143 /* Set callbacks. */
144 if (! CPP_OPTION (pfile, no_output))
145 {
146 pfile->cb.ident = cb_ident;
147 pfile->cb.def_pragma = cb_def_pragma;
148 if (! CPP_OPTION (pfile, no_line_commands))
149 pfile->cb.change_file = cb_change_file;
150 }
151
152 if (CPP_OPTION (pfile, dump_includes))
153 pfile->cb.include = cb_include;
154
155 if (CPP_OPTION (pfile, debug_output)
156 || CPP_OPTION (pfile, dump_macros) == dump_names
157 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
158 {
159 pfile->cb.define = cb_define;
160 pfile->cb.undef = cb_undef;
161 pfile->cb.poison = cb_def_pragma;
162 }
163
164 /* Register one #pragma which needs special handling. */
165 cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
166 cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
167}
168
93c80368
NB
169/* Writes out the preprocessed file. Alternates between two tokens,
170 so that we can avoid accidental token pasting. */
171static void
172scan_buffer (pfile)
173 cpp_reader *pfile;
174{
175 unsigned int index, line;
176 cpp_token tokens[2], *token;
58fea6af 177
93c80368
NB
178 do
179 {
180 for (index = 0;; index = 1 - index)
181 {
182 token = &tokens[index];
183 cpp_get_token (pfile, token);
184
185 if (token->type == CPP_EOF)
186 break;
187
188 line = cpp_get_line (pfile)->output_line;
189 if (print.lineno != line)
190 {
191 unsigned int col = cpp_get_line (pfile)->col;
192
193 /* Supply enough whitespace to put this token in its original
194 column. Don't bother trying to reconstruct tabs; we can't
195 get it right in general, and nothing ought to care. (Yes,
196 some things do care; the fault lies with them.) */
197 maybe_print_line (line);
198 if (col > 1)
199 {
200 if (token->flags & PREV_WHITE)
201 col--;
202 while (--col)
203 putc (' ', print.outf);
204 }
205 }
3a59c77c
RH
206 else if (print.printed
207 && ! (token->flags & PREV_WHITE)
bdb05a7b 208 && CPP_OPTION (pfile, lang) != CLK_ASM
93c80368
NB
209 && cpp_avoid_paste (pfile, &tokens[1 - index], token))
210 token->flags |= PREV_WHITE;
211
212 cpp_output_token (token, print.outf);
213 print.printed = 1;
214 }
215 }
216 while (cpp_pop_buffer (pfile) != 0);
217}
218
219/* Initialize a cpp_printer structure. As a side effect, open the
220 output file. */
221static int
222printer_init (pfile)
223 cpp_reader *pfile;
224{
225 print.last_fname = 0;
226 print.lineno = 0;
227 print.printed = 0;
228 print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
229
230 if (CPP_OPTION (pfile, out_fname) == NULL)
231 CPP_OPTION (pfile, out_fname) = "";
232
233 if (CPP_OPTION (pfile, out_fname)[0] == '\0')
234 print.outf = stdout;
235 else
236 {
237 print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
238 if (! print.outf)
239 {
240 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
241 return 1;
242 }
243 }
244 return 0;
245}
246
247/* Newline-terminate any output line currently in progress. If
248 appropriate, write the current line number to the output, or pad
249 with newlines so the output line matches the current line. */
58fea6af 250static void
93c80368
NB
251maybe_print_line (line)
252 unsigned int line;
253{
254 /* End the previous line of text (probably only needed until we get
255 multi-line tokens fixed). */
256 if (print.printed)
257 {
258 putc ('\n', print.outf);
259 print.lineno++;
260 print.printed = 0;
261 }
262
263 if (print.no_line_dirs)
264 return;
265
266 if (line >= print.lineno && line < print.lineno + 8)
267 {
268 while (line > print.lineno)
269 {
270 putc ('\n', print.outf);
271 print.lineno++;
272 }
273 }
274 else
275 {
276 print.lineno = line;
277 print_line ("");
278 }
279}
280
281static void
282print_line (special_flags)
283 const char *special_flags;
284{
285 /* End any previous line of text. */
286 if (print.printed)
287 putc ('\n', print.outf);
288 print.printed = 0;
289
290 fprintf (print.outf, "# %u \"%s\"%s%s\n",
291 print.lineno, print.last_fname, special_flags, print.syshdr_flags);
292}
293
93c80368
NB
294/* Callbacks */
295
296static void
297cb_ident (pfile, str)
298 cpp_reader *pfile ATTRIBUTE_UNUSED;
299 const cpp_string * str;
58fea6af 300{
93c80368
NB
301 maybe_print_line (cpp_get_line (pfile)->output_line);
302 fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
303 print.lineno++;
58fea6af
ZW
304}
305
306static void
93c80368 307cb_define (pfile, node)
58fea6af 308 cpp_reader *pfile;
93c80368 309 cpp_hashnode *node;
58fea6af 310{
5ef865d5
ZW
311 if (pfile->done_initializing)
312 {
93c80368
NB
313 maybe_print_line (cpp_get_line (pfile)->output_line);
314 fprintf (print.outf, "#define %s", node->name);
315
316 /* -dD or -g3 command line options. */
5ef865d5
ZW
317 if (CPP_OPTION (pfile, debug_output)
318 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
93c80368
NB
319 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
320
321 putc ('\n', print.outf);
322 print.lineno++;
5ef865d5 323 }
58fea6af
ZW
324}
325
326static void
93c80368 327cb_undef (pfile, node)
58fea6af 328 cpp_reader *pfile;
93c80368 329 cpp_hashnode *node;
58fea6af 330{
5ef865d5 331 if (pfile->done_initializing)
3cb553b4 332 {
93c80368
NB
333 maybe_print_line (cpp_get_line (pfile)->output_line);
334 fprintf (print.outf, "#undef %s\n", node->name);
335 print.lineno++;
3cb553b4 336 }
58fea6af
ZW
337}
338
339static void
93c80368
NB
340cb_include (pfile, dir, header)
341 cpp_reader *pfile ATTRIBUTE_UNUSED;
58fea6af 342 const unsigned char *dir;
93c80368 343 const cpp_token *header;
58fea6af 344{
93c80368
NB
345 maybe_print_line (cpp_get_line (pfile)->output_line);
346 fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
347 print.lineno++;
58fea6af
ZW
348}
349
350static void
27e2564a
NB
351cb_change_file (pfile, fc)
352 cpp_reader *pfile ATTRIBUTE_UNUSED;
353 const cpp_file_change *fc;
58fea6af 354{
27e2564a
NB
355 const char *flags;
356
357 /* Bring current file to correct line (except first file). */
358 if (fc->reason == FC_ENTER && fc->from.filename)
359 maybe_print_line (fc->from.lineno);
360
361 print.lineno = fc->to.lineno;
362 print.last_fname = fc->to.filename;
363 if (fc->externc)
364 print.syshdr_flags = " 3 4";
365 else if (fc->sysp)
366 print.syshdr_flags = " 3";
367 else
368 print.syshdr_flags = "";
58fea6af 369
27e2564a
NB
370 switch (fc->reason)
371 {
372 case FC_ENTER : flags = fc->from.filename ? " 1": ""; break;
373 case FC_LEAVE : flags = " 2"; break;
374 case FC_RENAME: flags = ""; break;
375 }
58fea6af 376
27e2564a 377 print_line (flags);
9ec7291f
ZW
378}
379
58fea6af
ZW
380static void
381cb_def_pragma (pfile)
382 cpp_reader *pfile;
383{
93c80368
NB
384 maybe_print_line (cpp_get_line (pfile)->output_line);
385 fputs ("#pragma ", print.outf);
386 cpp_output_line (pfile, print.outf);
387 print.lineno++;
58fea6af
ZW
388}
389
390static void
391do_pragma_implementation (pfile)
392 cpp_reader *pfile;
393{
394 /* Be quiet about `#pragma implementation' for a file only if it hasn't
395 been included yet. */
93c80368 396 cpp_token token;
58fea6af 397
93c80368
NB
398 cpp_start_lookahead (pfile);
399 cpp_get_token (pfile, &token);
400 cpp_stop_lookahead (pfile, 0);
58fea6af 401
93c80368
NB
402 /* If it's not a string, pass it through and let the front end complain. */
403 if (token.type == CPP_STRING)
404 {
405 /* Make a NUL-terminated copy of the string. */
406 char *filename = alloca (token.val.str.len + 1);
407 memcpy (filename, token.val.str.text, token.val.str.len);
408 filename[token.val.str.len] = '\0';
409 if (cpp_included (pfile, filename))
58fea6af 410 cpp_warning (pfile,
93c80368
NB
411 "#pragma GCC implementation for \"%s\" appears after file is included",
412 filename);
413 }
414 else if (token.type != CPP_EOF)
415 {
416 cpp_error (pfile, "malformed #pragma GCC implementation");
417 return;
58fea6af
ZW
418 }
419
93c80368
NB
420 /* Output? This is nasty, but we don't have [GCC] implementation in
421 the buffer. */
d8090680 422 if (pfile->cb.def_pragma)
93c80368
NB
423 {
424 maybe_print_line (cpp_get_line (pfile)->output_line);
425 fputs ("#pragma GCC implementation ", print.outf);
426 cpp_output_line (pfile, print.outf);
427 print.lineno++;
428 }
58fea6af
ZW
429}
430
431/* Dump out the hash table. */
432static int
926c5678 433dump_macro (pfile, node, v)
58fea6af 434 cpp_reader *pfile;
93c80368 435 cpp_hashnode *node;
926c5678 436 void *v ATTRIBUTE_UNUSED;
58fea6af 437{
93c80368 438 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
58fea6af 439 {
93c80368
NB
440 fprintf (print.outf, "#define %s", node->name);
441 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
442 putc ('\n', print.outf);
443 print.lineno++;
58fea6af
ZW
444 }
445
446 return 1;
447}
This page took 0.677102 seconds and 5 git commands to generate.