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
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! */
28 /* Encapsulates state used to convert the stream of tokens coming from
29 cpp_get_token back into a text file. */
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
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 *,
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;
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);
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);
103 /* -dM command line option. */
104 if (CPP_OPTION (pfile, dump_macros) == dump_only)
105 cpp_forall_identifiers (pfile, dump_macro, NULL);
110 /* Flush any pending output. */
112 putc ('\n', print.outf);
113 if (ferror (print.outf) || fclose (print.outf))
114 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
117 return (FATAL_EXIT_CODE);
118 return (SUCCESS_EXIT_CODE);
121 /* Store the program name, and set the locale. */
123 general_init (const char *argv0)
125 progname = argv0 + strlen (argv0);
127 while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
130 xmalloc_set_program_name (progname);
132 /* LC_CTYPE determines the character set used by the terminal so it has be set
133 to output messages correctly. */
135 #ifdef HAVE_LC_MESSAGES
136 setlocale (LC_CTYPE, "");
137 setlocale (LC_MESSAGES, "");
139 setlocale (LC_ALL, "");
142 (void) bindtextdomain (PACKAGE, localedir);
143 (void) textdomain (PACKAGE);
146 /* Set up the callbacks and register the pragmas we handle. */
151 if (! CPP_OPTION (pfile, no_output))
153 pfile->cb.ident = cb_ident;
154 pfile->cb.def_pragma = cb_def_pragma;
155 if (! CPP_OPTION (pfile, no_line_commands))
156 pfile->cb.change_file = cb_change_file;
159 if (CPP_OPTION (pfile, dump_includes))
160 pfile->cb.include = cb_include;
162 if (CPP_OPTION (pfile, debug_output)
163 || CPP_OPTION (pfile, dump_macros) == dump_names
164 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
166 pfile->cb.define = cb_define;
167 pfile->cb.undef = cb_undef;
168 pfile->cb.poison = cb_def_pragma;
171 /* Register one #pragma which needs special handling. */
172 cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
173 cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
176 /* Writes out the preprocessed file. Alternates between two tokens,
177 so that we can avoid accidental token pasting. */
182 unsigned int index, line;
183 cpp_token tokens[2], *token;
187 for (index = 0;; index = 1 - index)
189 token = &tokens[index];
190 cpp_get_token (pfile, token);
192 if (token->type == CPP_EOF)
195 line = cpp_get_line (pfile)->output_line;
196 if (print.lineno != line)
198 unsigned int col = cpp_get_line (pfile)->col;
200 /* Supply enough whitespace to put this token in its original
201 column. Don't bother trying to reconstruct tabs; we can't
202 get it right in general, and nothing ought to care. (Yes,
203 some things do care; the fault lies with them.) */
204 maybe_print_line (line);
207 if (token->flags & PREV_WHITE)
210 putc (' ', print.outf);
213 else if (print.printed
214 && ! (token->flags & PREV_WHITE)
215 && CPP_OPTION (pfile, lang) != CLK_ASM
216 && cpp_avoid_paste (pfile, &tokens[1 - index], token))
217 token->flags |= PREV_WHITE;
219 cpp_output_token (token, print.outf);
223 while (cpp_pop_buffer (pfile) != 0);
226 /* Initialize a cpp_printer structure. As a side effect, open the
232 print.last_fname = 0;
235 print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
237 if (CPP_OPTION (pfile, out_fname) == NULL)
238 CPP_OPTION (pfile, out_fname) = "";
240 if (CPP_OPTION (pfile, out_fname)[0] == '\0')
244 print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
247 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
254 /* Newline-terminate any output line currently in progress. If
255 appropriate, write the current line number to the output, or pad
256 with newlines so the output line matches the current line. */
258 maybe_print_line (line)
261 /* End the previous line of text (probably only needed until we get
262 multi-line tokens fixed). */
265 putc ('\n', print.outf);
270 if (print.no_line_dirs)
273 /* print.lineno is zero if this is the first token of the file. We
274 handle this specially, so that a first line of "# 1 "foo.c" in
275 file foo.i outputs just the foo.c line, and not a foo.i line. */
276 if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
278 while (line > print.lineno)
280 putc ('\n', print.outf);
292 print_line (special_flags)
293 const char *special_flags;
295 /* End any previous line of text. */
297 putc ('\n', print.outf);
300 fprintf (print.outf, "# %u \"%s\"%s%s\n",
301 print.lineno, print.last_fname, special_flags, print.syshdr_flags);
307 cb_ident (pfile, str)
308 cpp_reader *pfile ATTRIBUTE_UNUSED;
309 const cpp_string * str;
311 maybe_print_line (cpp_get_line (pfile)->output_line);
312 fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
317 cb_define (pfile, node)
321 if (pfile->done_initializing)
323 maybe_print_line (cpp_get_line (pfile)->output_line);
324 fprintf (print.outf, "#define %s", node->name);
326 /* -dD or -g3 command line options. */
327 if (CPP_OPTION (pfile, debug_output)
328 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
329 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
331 putc ('\n', print.outf);
337 cb_undef (pfile, node)
341 if (pfile->done_initializing)
343 maybe_print_line (cpp_get_line (pfile)->output_line);
344 fprintf (print.outf, "#undef %s\n", node->name);
350 cb_include (pfile, dir, header)
351 cpp_reader *pfile ATTRIBUTE_UNUSED;
352 const unsigned char *dir;
353 const cpp_token *header;
355 maybe_print_line (cpp_get_line (pfile)->output_line);
356 fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
361 cb_change_file (pfile, fc)
362 cpp_reader *pfile ATTRIBUTE_UNUSED;
363 const cpp_file_change *fc;
367 /* Bring current file to correct line (except first file). */
368 if (fc->reason == FC_ENTER && fc->from.filename)
369 maybe_print_line (fc->from.lineno);
371 print.last_fname = fc->to.filename;
373 print.syshdr_flags = " 3 4";
375 print.syshdr_flags = " 3";
377 print.syshdr_flags = "";
381 print.lineno = fc->to.lineno;
384 case FC_ENTER : flags = " 1"; break;
385 case FC_LEAVE : flags = " 2"; break;
386 case FC_RENAME: flags = ""; break;
394 cb_def_pragma (pfile)
397 maybe_print_line (cpp_get_line (pfile)->output_line);
398 fputs ("#pragma ", print.outf);
399 cpp_output_line (pfile, print.outf);
404 do_pragma_implementation (pfile)
407 /* Be quiet about `#pragma implementation' for a file only if it hasn't
408 been included yet. */
411 cpp_start_lookahead (pfile);
412 cpp_get_token (pfile, &token);
413 cpp_stop_lookahead (pfile, 0);
415 /* If it's not a string, pass it through and let the front end complain. */
416 if (token.type == CPP_STRING)
418 /* Make a NUL-terminated copy of the string. */
419 char *filename = alloca (token.val.str.len + 1);
420 memcpy (filename, token.val.str.text, token.val.str.len);
421 filename[token.val.str.len] = '\0';
422 if (cpp_included (pfile, filename))
424 "#pragma GCC implementation for \"%s\" appears after file is included",
427 else if (token.type != CPP_EOF)
429 cpp_error (pfile, "malformed #pragma GCC implementation");
433 /* Output? This is nasty, but we don't have [GCC] implementation in
435 if (pfile->cb.def_pragma)
437 maybe_print_line (cpp_get_line (pfile)->output_line);
438 fputs ("#pragma GCC implementation ", print.outf);
439 cpp_output_line (pfile, print.outf);
444 /* Dump out the hash table. */
446 dump_macro (pfile, node, v)
449 void *v ATTRIBUTE_UNUSED;
451 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
453 fprintf (print.outf, "#define %s", node->name);
454 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
455 putc ('\n', print.outf);