New testcase
[official-gcc.git] / gcc / cppmain.c
blobca966fc220e66e6598e4ae6c2a7b4dcc70d84ff2
1 /* CPP main program, using CPP Library.
2 Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3 Written by Per Bothner, 1994-95.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
8 later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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! */
23 #include "config.h"
24 #include "system.h"
25 #include "cpplib.h"
26 #include "intl.h"
28 /* Encapsulates state used to convert the stream of tokens coming from
29 cpp_get_token back into a text file. */
30 struct printer
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. */
40 int main PARAMS ((int, char **));
42 /* General output routines. */
43 static void scan_buffer PARAMS ((cpp_reader *));
44 static int printer_init PARAMS ((cpp_reader *));
45 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
47 static void print_line PARAMS ((const char *));
48 static void maybe_print_line PARAMS ((unsigned int));
49 static void move_printer PARAMS ((cpp_reader *, unsigned int, const char *));
51 /* Callback routines for the parser. Most of these are active only
52 in specific modes. */
53 static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *));
54 static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
55 static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
56 const cpp_token *));
57 static void cb_ident PARAMS ((cpp_reader *, const cpp_string *));
58 static void cb_enter_file PARAMS ((cpp_reader *));
59 static void cb_leave_file PARAMS ((cpp_reader *));
60 static void cb_rename_file PARAMS ((cpp_reader *));
61 static void cb_def_pragma PARAMS ((cpp_reader *));
62 static void do_pragma_implementation PARAMS ((cpp_reader *));
64 const char *progname;
65 static cpp_reader parse_in;
66 static struct printer print;
68 int
69 main (argc, argv)
70 int argc;
71 char **argv;
73 char *p;
74 cpp_reader *pfile = &parse_in;
75 int argi = 1; /* Next argument to handle. */
77 p = argv[0] + strlen (argv[0]);
78 while (p != argv[0] && ! IS_DIR_SEPARATOR (p[-1])) --p;
79 progname = p;
81 xmalloc_set_program_name (progname);
83 #ifdef HAVE_LC_MESSAGES
84 setlocale (LC_MESSAGES, "");
85 #endif
86 (void) bindtextdomain (PACKAGE, localedir);
87 (void) textdomain (PACKAGE);
89 cpp_init ();
90 cpp_reader_init (pfile);
92 argi += cpp_handle_options (pfile, argc - argi , argv + argi);
93 if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
94 cpp_fatal (pfile, "Invalid option %s", argv[argi]);
95 if (CPP_FATAL_ERRORS (pfile))
96 return (FATAL_EXIT_CODE);
98 /* Open the output now. We must do so even if no_output is on,
99 because there may be other output than from the actual
100 preprocessing (e.g. from -dM). */
101 if (printer_init (pfile))
102 return (FATAL_EXIT_CODE);
104 /* Set callbacks. */
105 if (! CPP_OPTION (pfile, no_output))
107 pfile->cb.ident = cb_ident;
108 pfile->cb.def_pragma = cb_def_pragma;
109 if (! CPP_OPTION (pfile, no_line_commands))
111 pfile->cb.enter_file = cb_enter_file;
112 pfile->cb.leave_file = cb_leave_file;
113 pfile->cb.rename_file = cb_rename_file;
117 if (CPP_OPTION (pfile, dump_includes))
118 pfile->cb.include = cb_include;
120 if (CPP_OPTION (pfile, debug_output)
121 || CPP_OPTION (pfile, dump_macros) == dump_names
122 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
124 pfile->cb.define = cb_define;
125 pfile->cb.undef = cb_undef;
126 pfile->cb.poison = cb_def_pragma;
129 /* Register one #pragma which needs special handling. */
130 cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
131 cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
133 if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
134 return (FATAL_EXIT_CODE);
136 if (CPP_BUFFER (pfile))
138 if (CPP_OPTION (pfile, no_output))
139 cpp_scan_buffer_nooutput (pfile);
140 else
141 scan_buffer (pfile);
144 /* -dM command line option. */
145 if (CPP_OPTION (pfile, dump_macros) == dump_only)
146 cpp_forall_identifiers (pfile, dump_macro, NULL);
148 cpp_finish (pfile);
149 cpp_cleanup (pfile);
151 /* Flush any pending output. */
152 if (print.printed)
153 putc ('\n', print.outf);
154 if (ferror (print.outf) || fclose (print.outf))
155 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
157 if (parse_in.errors)
158 return (FATAL_EXIT_CODE);
159 return (SUCCESS_EXIT_CODE);
162 /* Writes out the preprocessed file. Alternates between two tokens,
163 so that we can avoid accidental token pasting. */
164 static void
165 scan_buffer (pfile)
166 cpp_reader *pfile;
168 unsigned int index, line;
169 cpp_token tokens[2], *token;
173 for (index = 0;; index = 1 - index)
175 token = &tokens[index];
176 cpp_get_token (pfile, token);
178 if (token->type == CPP_EOF)
179 break;
181 line = cpp_get_line (pfile)->output_line;
182 if (print.lineno != line)
184 unsigned int col = cpp_get_line (pfile)->col;
186 /* Supply enough whitespace to put this token in its original
187 column. Don't bother trying to reconstruct tabs; we can't
188 get it right in general, and nothing ought to care. (Yes,
189 some things do care; the fault lies with them.) */
190 maybe_print_line (line);
191 if (col > 1)
193 if (token->flags & PREV_WHITE)
194 col--;
195 while (--col)
196 putc (' ', print.outf);
199 else if (print.printed
200 && ! (token->flags & PREV_WHITE)
201 && ! CPP_OPTION (pfile, lang_asm)
202 && cpp_avoid_paste (pfile, &tokens[1 - index], token))
203 token->flags |= PREV_WHITE;
205 cpp_output_token (token, print.outf);
206 print.printed = 1;
209 while (cpp_pop_buffer (pfile) != 0);
212 /* Initialize a cpp_printer structure. As a side effect, open the
213 output file. */
214 static int
215 printer_init (pfile)
216 cpp_reader *pfile;
218 print.last_fname = 0;
219 print.lineno = 0;
220 print.printed = 0;
221 print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
223 if (CPP_OPTION (pfile, out_fname) == NULL)
224 CPP_OPTION (pfile, out_fname) = "";
226 if (CPP_OPTION (pfile, out_fname)[0] == '\0')
227 print.outf = stdout;
228 else
230 print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
231 if (! print.outf)
233 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
234 return 1;
237 return 0;
240 /* Newline-terminate any output line currently in progress. If
241 appropriate, write the current line number to the output, or pad
242 with newlines so the output line matches the current line. */
243 static void
244 maybe_print_line (line)
245 unsigned int line;
247 /* End the previous line of text (probably only needed until we get
248 multi-line tokens fixed). */
249 if (print.printed)
251 putc ('\n', print.outf);
252 print.lineno++;
253 print.printed = 0;
256 if (print.no_line_dirs)
257 return;
259 if (line >= print.lineno && line < print.lineno + 8)
261 while (line > print.lineno)
263 putc ('\n', print.outf);
264 print.lineno++;
267 else
269 print.lineno = line;
270 print_line ("");
274 static void
275 print_line (special_flags)
276 const char *special_flags;
278 /* End any previous line of text. */
279 if (print.printed)
280 putc ('\n', print.outf);
281 print.printed = 0;
283 fprintf (print.outf, "# %u \"%s\"%s%s\n",
284 print.lineno, print.last_fname, special_flags, print.syshdr_flags);
287 static void
288 move_printer (pfile, line, special_flags)
289 cpp_reader *pfile;
290 unsigned int line;
291 const char *special_flags;
293 print.lineno = line;
294 print.last_fname = pfile->buffer->nominal_fname;
295 print.syshdr_flags = cpp_syshdr_flags (pfile, pfile->buffer);
296 print_line (special_flags);
299 /* Callbacks */
301 static void
302 cb_ident (pfile, str)
303 cpp_reader *pfile ATTRIBUTE_UNUSED;
304 const cpp_string * str;
306 maybe_print_line (cpp_get_line (pfile)->output_line);
307 fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
308 print.lineno++;
311 static void
312 cb_define (pfile, node)
313 cpp_reader *pfile;
314 cpp_hashnode *node;
316 if (pfile->done_initializing)
318 maybe_print_line (cpp_get_line (pfile)->output_line);
319 fprintf (print.outf, "#define %s", node->name);
321 /* -dD or -g3 command line options. */
322 if (CPP_OPTION (pfile, debug_output)
323 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
324 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
326 putc ('\n', print.outf);
327 print.lineno++;
331 static void
332 cb_undef (pfile, node)
333 cpp_reader *pfile;
334 cpp_hashnode *node;
336 if (pfile->done_initializing)
338 maybe_print_line (cpp_get_line (pfile)->output_line);
339 fprintf (print.outf, "#undef %s\n", node->name);
340 print.lineno++;
344 static void
345 cb_include (pfile, dir, header)
346 cpp_reader *pfile ATTRIBUTE_UNUSED;
347 const unsigned char *dir;
348 const cpp_token *header;
350 maybe_print_line (cpp_get_line (pfile)->output_line);
351 fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
352 print.lineno++;
355 static void
356 cb_enter_file (pfile)
357 cpp_reader *pfile;
359 /* Bring current file to correct line (except main file). FIXME: we
360 may be using the same buffer via a # NUMBER "file" 1 directive. */
361 if (pfile->done_initializing && pfile->buffer->prev)
362 maybe_print_line (pfile->buffer->prev->lineno);
364 move_printer (pfile, 1, pfile->done_initializing ? " 1": "");
367 static void
368 cb_leave_file (pfile)
369 cpp_reader *pfile;
371 move_printer (pfile, pfile->buffer->lineno + 1, " 2");
374 static void
375 cb_rename_file (pfile)
376 cpp_reader *pfile;
378 move_printer (pfile, pfile->buffer->lineno + 1, "");
381 static void
382 cb_def_pragma (pfile)
383 cpp_reader *pfile;
385 maybe_print_line (cpp_get_line (pfile)->output_line);
386 fputs ("#pragma ", print.outf);
387 cpp_output_line (pfile, print.outf);
388 print.lineno++;
391 static void
392 do_pragma_implementation (pfile)
393 cpp_reader *pfile;
395 /* Be quiet about `#pragma implementation' for a file only if it hasn't
396 been included yet. */
397 cpp_token token;
399 cpp_start_lookahead (pfile);
400 cpp_get_token (pfile, &token);
401 cpp_stop_lookahead (pfile, 0);
403 /* If it's not a string, pass it through and let the front end complain. */
404 if (token.type == CPP_STRING)
406 /* Make a NUL-terminated copy of the string. */
407 char *filename = alloca (token.val.str.len + 1);
408 memcpy (filename, token.val.str.text, token.val.str.len);
409 filename[token.val.str.len] = '\0';
410 if (cpp_included (pfile, filename))
411 cpp_warning (pfile,
412 "#pragma GCC implementation for \"%s\" appears after file is included",
413 filename);
415 else if (token.type != CPP_EOF)
417 cpp_error (pfile, "malformed #pragma GCC implementation");
418 return;
421 /* Output? This is nasty, but we don't have [GCC] implementation in
422 the buffer. */
423 if (pfile->cb.def_pragma)
425 maybe_print_line (cpp_get_line (pfile)->output_line);
426 fputs ("#pragma GCC implementation ", print.outf);
427 cpp_output_line (pfile, print.outf);
428 print.lineno++;
432 /* Dump out the hash table. */
433 static int
434 dump_macro (pfile, node, v)
435 cpp_reader *pfile;
436 cpp_hashnode *node;
437 void *v ATTRIBUTE_UNUSED;
439 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
441 fprintf (print.outf, "#define %s", node->name);
442 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
443 putc ('\n', print.outf);
444 print.lineno++;
447 return 1;