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