Daily bump.
[official-gcc.git] / gcc / cppmain.c
blobcc958e0040382494538c02b9e43c6e149ec3a4f9
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 **));
41 static void general_init PARAMS ((const char *));
42 static void setup_callbacks PARAMS ((void));
44 /* General output routines. */
45 static void scan_buffer PARAMS ((cpp_reader *));
46 static int printer_init PARAMS ((cpp_reader *));
47 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
49 static void print_line PARAMS ((const char *));
50 static void maybe_print_line PARAMS ((unsigned int));
52 /* Callback routines for the parser. Most of these are active only
53 in specific modes. */
54 static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *));
55 static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
56 static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
57 const cpp_token *));
58 static void cb_ident PARAMS ((cpp_reader *, const cpp_string *));
59 static void cb_change_file PARAMS ((cpp_reader *, const cpp_file_change *));
60 static void cb_def_pragma PARAMS ((cpp_reader *));
61 static void do_pragma_implementation PARAMS ((cpp_reader *));
63 const char *progname; /* Needs to be global. */
64 static cpp_reader *pfile;
65 static struct printer print;
67 int
68 main (argc, argv)
69 int argc;
70 char **argv;
72 int argi = 1; /* Next argument to handle. */
74 general_init (argv[0]);
75 /* Default language is GNU C89. */
76 pfile = cpp_create_reader (CLK_GNUC89);
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))
82 return (FATAL_EXIT_CODE);
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). */
87 if (printer_init (pfile))
88 return (FATAL_EXIT_CODE);
90 setup_callbacks ();
92 if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
93 return (FATAL_EXIT_CODE);
95 if (CPP_BUFFER (pfile))
97 if (CPP_OPTION (pfile, no_output))
98 cpp_scan_buffer_nooutput (pfile, 1);
99 else
100 scan_buffer (pfile);
103 /* -dM command line option. */
104 if (CPP_OPTION (pfile, dump_macros) == dump_only)
105 cpp_forall_identifiers (pfile, dump_macro, NULL);
107 cpp_finish (pfile);
108 cpp_cleanup (pfile);
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));
116 if (pfile->errors)
117 return (FATAL_EXIT_CODE);
118 return (SUCCESS_EXIT_CODE);
121 /* Store the program name, and set the locale. */
122 static void
123 general_init (const char *argv0)
125 progname = argv0 + strlen (argv0);
127 while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
128 --progname;
130 xmalloc_set_program_name (progname);
132 #ifdef HAVE_LC_MESSAGES
133 setlocale (LC_MESSAGES, "");
134 #endif
135 (void) bindtextdomain (PACKAGE, localedir);
136 (void) textdomain (PACKAGE);
139 /* Set up the callbacks and register the pragmas we handle. */
140 static void
141 setup_callbacks ()
143 /* Set callbacks. */
144 if (! CPP_OPTION (pfile, no_output))
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;
152 if (CPP_OPTION (pfile, dump_includes))
153 pfile->cb.include = cb_include;
155 if (CPP_OPTION (pfile, debug_output)
156 || CPP_OPTION (pfile, dump_macros) == dump_names
157 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
159 pfile->cb.define = cb_define;
160 pfile->cb.undef = cb_undef;
161 pfile->cb.poison = cb_def_pragma;
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);
169 /* Writes out the preprocessed file. Alternates between two tokens,
170 so that we can avoid accidental token pasting. */
171 static void
172 scan_buffer (pfile)
173 cpp_reader *pfile;
175 unsigned int index, line;
176 cpp_token tokens[2], *token;
180 for (index = 0;; index = 1 - index)
182 token = &tokens[index];
183 cpp_get_token (pfile, token);
185 if (token->type == CPP_EOF)
186 break;
188 line = cpp_get_line (pfile)->output_line;
189 if (print.lineno != line)
191 unsigned int col = cpp_get_line (pfile)->col;
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)
200 if (token->flags & PREV_WHITE)
201 col--;
202 while (--col)
203 putc (' ', print.outf);
206 else if (print.printed
207 && ! (token->flags & PREV_WHITE)
208 && CPP_OPTION (pfile, lang) != CLK_ASM
209 && cpp_avoid_paste (pfile, &tokens[1 - index], token))
210 token->flags |= PREV_WHITE;
212 cpp_output_token (token, print.outf);
213 print.printed = 1;
216 while (cpp_pop_buffer (pfile) != 0);
219 /* Initialize a cpp_printer structure. As a side effect, open the
220 output file. */
221 static int
222 printer_init (pfile)
223 cpp_reader *pfile;
225 print.last_fname = 0;
226 print.lineno = 0;
227 print.printed = 0;
228 print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
230 if (CPP_OPTION (pfile, out_fname) == NULL)
231 CPP_OPTION (pfile, out_fname) = "";
233 if (CPP_OPTION (pfile, out_fname)[0] == '\0')
234 print.outf = stdout;
235 else
237 print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
238 if (! print.outf)
240 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
241 return 1;
244 return 0;
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. */
250 static void
251 maybe_print_line (line)
252 unsigned int line;
254 /* End the previous line of text (probably only needed until we get
255 multi-line tokens fixed). */
256 if (print.printed)
258 putc ('\n', print.outf);
259 print.lineno++;
260 print.printed = 0;
263 if (print.no_line_dirs)
264 return;
266 if (line >= print.lineno && line < print.lineno + 8)
268 while (line > print.lineno)
270 putc ('\n', print.outf);
271 print.lineno++;
274 else
276 print.lineno = line;
277 print_line ("");
281 static void
282 print_line (special_flags)
283 const char *special_flags;
285 /* End any previous line of text. */
286 if (print.printed)
287 putc ('\n', print.outf);
288 print.printed = 0;
290 fprintf (print.outf, "# %u \"%s\"%s%s\n",
291 print.lineno, print.last_fname, special_flags, print.syshdr_flags);
294 /* Callbacks */
296 static void
297 cb_ident (pfile, str)
298 cpp_reader *pfile ATTRIBUTE_UNUSED;
299 const cpp_string * str;
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++;
306 static void
307 cb_define (pfile, node)
308 cpp_reader *pfile;
309 cpp_hashnode *node;
311 if (pfile->done_initializing)
313 maybe_print_line (cpp_get_line (pfile)->output_line);
314 fprintf (print.outf, "#define %s", node->name);
316 /* -dD or -g3 command line options. */
317 if (CPP_OPTION (pfile, debug_output)
318 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
319 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
321 putc ('\n', print.outf);
322 print.lineno++;
326 static void
327 cb_undef (pfile, node)
328 cpp_reader *pfile;
329 cpp_hashnode *node;
331 if (pfile->done_initializing)
333 maybe_print_line (cpp_get_line (pfile)->output_line);
334 fprintf (print.outf, "#undef %s\n", node->name);
335 print.lineno++;
339 static void
340 cb_include (pfile, dir, header)
341 cpp_reader *pfile ATTRIBUTE_UNUSED;
342 const unsigned char *dir;
343 const cpp_token *header;
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++;
350 static void
351 cb_change_file (pfile, fc)
352 cpp_reader *pfile ATTRIBUTE_UNUSED;
353 const cpp_file_change *fc;
355 const char *flags;
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);
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 = "";
370 switch (fc->reason)
372 case FC_ENTER : flags = fc->from.filename ? " 1": ""; break;
373 case FC_LEAVE : flags = " 2"; break;
374 case FC_RENAME: flags = ""; break;
377 print_line (flags);
380 static void
381 cb_def_pragma (pfile)
382 cpp_reader *pfile;
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++;
390 static void
391 do_pragma_implementation (pfile)
392 cpp_reader *pfile;
394 /* Be quiet about `#pragma implementation' for a file only if it hasn't
395 been included yet. */
396 cpp_token token;
398 cpp_start_lookahead (pfile);
399 cpp_get_token (pfile, &token);
400 cpp_stop_lookahead (pfile, 0);
402 /* If it's not a string, pass it through and let the front end complain. */
403 if (token.type == CPP_STRING)
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))
410 cpp_warning (pfile,
411 "#pragma GCC implementation for \"%s\" appears after file is included",
412 filename);
414 else if (token.type != CPP_EOF)
416 cpp_error (pfile, "malformed #pragma GCC implementation");
417 return;
420 /* Output? This is nasty, but we don't have [GCC] implementation in
421 the buffer. */
422 if (pfile->cb.def_pragma)
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++;
431 /* Dump out the hash table. */
432 static int
433 dump_macro (pfile, node, v)
434 cpp_reader *pfile;
435 cpp_hashnode *node;
436 void *v ATTRIBUTE_UNUSED;
438 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
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++;
446 return 1;