]> gcc.gnu.org Git - gcc.git/blame - gcc/cppmain.c
cppinit.c (OPT_g): Remove.
[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 *));
dfbf62ec 46static void check_multiline_token PARAMS ((cpp_string *));
93c80368 47static int printer_init PARAMS ((cpp_reader *));
926c5678 48static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
93c80368
NB
49
50static void print_line PARAMS ((const char *));
51static void maybe_print_line PARAMS ((unsigned int));
93c80368 52
58fea6af
ZW
53/* Callback routines for the parser. Most of these are active only
54 in specific modes. */
55static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *));
56static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
57static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
93c80368
NB
58 const cpp_token *));
59static void cb_ident PARAMS ((cpp_reader *, const cpp_string *));
eb1f4d9d 60static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
58fea6af 61static void cb_def_pragma PARAMS ((cpp_reader *));
58fea6af 62static void do_pragma_implementation PARAMS ((cpp_reader *));
93c80368 63
cf44ea52
NB
64const char *progname; /* Needs to be global. */
65static cpp_reader *pfile;
926c5678 66static struct printer print;
58fea6af 67
7f2935c7
PB
68int
69main (argc, argv)
70 int argc;
71 char **argv;
72{
0f41302f 73 int argi = 1; /* Next argument to handle. */
7f2935c7 74
cf44ea52 75 general_init (argv[0]);
dd07b884 76 /* Default language is GNU C89. */
cf44ea52 77 pfile = cpp_create_reader (CLK_GNUC89);
7f2935c7 78
ae79697b
ZW
79 argi += cpp_handle_options (pfile, argc - argi , argv + argi);
80 if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
81 cpp_fatal (pfile, "Invalid option %s", argv[argi]);
96302433 82 cpp_post_options (pfile);
ae79697b 83 if (CPP_FATAL_ERRORS (pfile))
bcc5cac9 84 return (FATAL_EXIT_CODE);
7f2935c7 85
f4cdc368
ZW
86 /* If cpp_handle_options saw --help or --version on the command
87 line, it will have set pfile->help_only to indicate this. Exit
88 successfully. [The library does not exit itself, because
89 e.g. cc1 needs to print its own --help message at this point.] */
90 if (pfile->help_only)
91 return (SUCCESS_EXIT_CODE);
92
f2d5f0cc
ZW
93 /* Open the output now. We must do so even if no_output is on,
94 because there may be other output than from the actual
95 preprocessing (e.g. from -dM). */
93c80368 96 if (printer_init (pfile))
bcc5cac9 97 return (FATAL_EXIT_CODE);
58fea6af 98
cf44ea52 99 setup_callbacks ();
7f2935c7 100
93c80368 101 if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
f2d5f0cc
ZW
102 return (FATAL_EXIT_CODE);
103
93c80368
NB
104 if (CPP_BUFFER (pfile))
105 {
106 if (CPP_OPTION (pfile, no_output))
8dc4676d 107 cpp_scan_buffer_nooutput (pfile, 1);
93c80368
NB
108 else
109 scan_buffer (pfile);
110 }
7f2935c7 111
93c80368 112 /* -dM command line option. */
58fea6af 113 if (CPP_OPTION (pfile, dump_macros) == dump_only)
926c5678 114 cpp_forall_identifiers (pfile, dump_macro, NULL);
93c80368
NB
115
116 cpp_finish (pfile);
ae79697b 117 cpp_cleanup (pfile);
a9ae4483 118
93c80368
NB
119 /* Flush any pending output. */
120 if (print.printed)
121 putc ('\n', print.outf);
122 if (ferror (print.outf) || fclose (print.outf))
123 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
124
cf44ea52 125 if (pfile->errors)
bcc5cac9
KG
126 return (FATAL_EXIT_CODE);
127 return (SUCCESS_EXIT_CODE);
7f2935c7 128}
58fea6af 129
cf44ea52
NB
130/* Store the program name, and set the locale. */
131static void
132general_init (const char *argv0)
133{
134 progname = argv0 + strlen (argv0);
135
136 while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
137 --progname;
138
139 xmalloc_set_program_name (progname);
140
04650349
PT
141/* LC_CTYPE determines the character set used by the terminal so it has be set
142 to output messages correctly. */
143
cf44ea52 144#ifdef HAVE_LC_MESSAGES
04650349 145 setlocale (LC_CTYPE, "");
cf44ea52 146 setlocale (LC_MESSAGES, "");
04650349
PT
147#else
148 setlocale (LC_ALL, "");
cf44ea52 149#endif
04650349 150
cf44ea52
NB
151 (void) bindtextdomain (PACKAGE, localedir);
152 (void) textdomain (PACKAGE);
153}
154
155/* Set up the callbacks and register the pragmas we handle. */
156static void
157setup_callbacks ()
158{
159 /* Set callbacks. */
160 if (! CPP_OPTION (pfile, no_output))
161 {
162 pfile->cb.ident = cb_ident;
163 pfile->cb.def_pragma = cb_def_pragma;
164 if (! CPP_OPTION (pfile, no_line_commands))
eb1f4d9d 165 pfile->cb.file_change = cb_file_change;
cf44ea52
NB
166 }
167
168 if (CPP_OPTION (pfile, dump_includes))
169 pfile->cb.include = cb_include;
170
5c5d1ea0 171 if (CPP_OPTION (pfile, dump_macros) == dump_names
cf44ea52
NB
172 || CPP_OPTION (pfile, dump_macros) == dump_definitions)
173 {
174 pfile->cb.define = cb_define;
175 pfile->cb.undef = cb_undef;
176 pfile->cb.poison = cb_def_pragma;
177 }
178
179 /* Register one #pragma which needs special handling. */
180 cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
181 cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
182}
183
93c80368
NB
184/* Writes out the preprocessed file. Alternates between two tokens,
185 so that we can avoid accidental token pasting. */
186static void
187scan_buffer (pfile)
188 cpp_reader *pfile;
189{
190 unsigned int index, line;
191 cpp_token tokens[2], *token;
58fea6af 192
93c80368
NB
193 do
194 {
195 for (index = 0;; index = 1 - index)
196 {
197 token = &tokens[index];
198 cpp_get_token (pfile, token);
199
200 if (token->type == CPP_EOF)
201 break;
202
203 line = cpp_get_line (pfile)->output_line;
204 if (print.lineno != line)
205 {
206 unsigned int col = cpp_get_line (pfile)->col;
207
208 /* Supply enough whitespace to put this token in its original
209 column. Don't bother trying to reconstruct tabs; we can't
210 get it right in general, and nothing ought to care. (Yes,
211 some things do care; the fault lies with them.) */
212 maybe_print_line (line);
213 if (col > 1)
214 {
215 if (token->flags & PREV_WHITE)
216 col--;
217 while (--col)
218 putc (' ', print.outf);
219 }
220 }
3a59c77c
RH
221 else if (print.printed
222 && ! (token->flags & PREV_WHITE)
bdb05a7b 223 && CPP_OPTION (pfile, lang) != CLK_ASM
93c80368
NB
224 && cpp_avoid_paste (pfile, &tokens[1 - index], token))
225 token->flags |= PREV_WHITE;
226
227 cpp_output_token (token, print.outf);
228 print.printed = 1;
dfbf62ec
NB
229 if (token->type == CPP_STRING || token->type == CPP_WSTRING
230 || token->type == CPP_COMMENT)
231 check_multiline_token (&token->val.str);
93c80368
NB
232 }
233 }
234 while (cpp_pop_buffer (pfile) != 0);
235}
236
dfbf62ec
NB
237/* Adjust print.lineno for newlines embedded in tokens. */
238static void
239check_multiline_token (str)
240 cpp_string *str;
241{
242 unsigned int i;
243
244 for (i = 0; i < str->len; i++)
245 if (str->text[i] == '\n')
246 print.lineno++;
247}
248
93c80368
NB
249/* Initialize a cpp_printer structure. As a side effect, open the
250 output file. */
251static int
252printer_init (pfile)
253 cpp_reader *pfile;
254{
255 print.last_fname = 0;
256 print.lineno = 0;
257 print.printed = 0;
258 print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
259
260 if (CPP_OPTION (pfile, out_fname) == NULL)
261 CPP_OPTION (pfile, out_fname) = "";
262
263 if (CPP_OPTION (pfile, out_fname)[0] == '\0')
264 print.outf = stdout;
265 else
266 {
267 print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
268 if (! print.outf)
269 {
270 cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
271 return 1;
272 }
273 }
274 return 0;
275}
276
277/* Newline-terminate any output line currently in progress. If
278 appropriate, write the current line number to the output, or pad
279 with newlines so the output line matches the current line. */
58fea6af 280static void
93c80368
NB
281maybe_print_line (line)
282 unsigned int line;
283{
284 /* End the previous line of text (probably only needed until we get
285 multi-line tokens fixed). */
286 if (print.printed)
287 {
288 putc ('\n', print.outf);
289 print.lineno++;
290 print.printed = 0;
291 }
292
293 if (print.no_line_dirs)
3cab4133
NB
294 {
295 print.lineno = line;
296 return;
297 }
93c80368 298
ad2a084d
NB
299 /* print.lineno is zero if this is the first token of the file. We
300 handle this specially, so that a first line of "# 1 "foo.c" in
301 file foo.i outputs just the foo.c line, and not a foo.i line. */
302 if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
93c80368
NB
303 {
304 while (line > print.lineno)
305 {
306 putc ('\n', print.outf);
307 print.lineno++;
308 }
309 }
310 else
311 {
312 print.lineno = line;
313 print_line ("");
314 }
315}
316
317static void
318print_line (special_flags)
319 const char *special_flags;
320{
321 /* End any previous line of text. */
322 if (print.printed)
323 putc ('\n', print.outf);
324 print.printed = 0;
325
326 fprintf (print.outf, "# %u \"%s\"%s%s\n",
327 print.lineno, print.last_fname, special_flags, print.syshdr_flags);
328}
329
93c80368
NB
330/* Callbacks */
331
332static void
333cb_ident (pfile, str)
334 cpp_reader *pfile ATTRIBUTE_UNUSED;
335 const cpp_string * str;
58fea6af 336{
93c80368
NB
337 maybe_print_line (cpp_get_line (pfile)->output_line);
338 fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
339 print.lineno++;
58fea6af
ZW
340}
341
342static void
93c80368 343cb_define (pfile, node)
58fea6af 344 cpp_reader *pfile;
93c80368 345 cpp_hashnode *node;
58fea6af 346{
5ef865d5
ZW
347 if (pfile->done_initializing)
348 {
93c80368
NB
349 maybe_print_line (cpp_get_line (pfile)->output_line);
350 fprintf (print.outf, "#define %s", node->name);
351
5c5d1ea0
NB
352 /* -dD command line option. */
353 if (CPP_OPTION (pfile, dump_macros) == dump_definitions)
93c80368
NB
354 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
355
356 putc ('\n', print.outf);
357 print.lineno++;
5ef865d5 358 }
58fea6af
ZW
359}
360
361static void
93c80368 362cb_undef (pfile, node)
58fea6af 363 cpp_reader *pfile;
93c80368 364 cpp_hashnode *node;
58fea6af 365{
5ef865d5 366 if (pfile->done_initializing)
3cb553b4 367 {
93c80368
NB
368 maybe_print_line (cpp_get_line (pfile)->output_line);
369 fprintf (print.outf, "#undef %s\n", node->name);
370 print.lineno++;
3cb553b4 371 }
58fea6af
ZW
372}
373
374static void
93c80368
NB
375cb_include (pfile, dir, header)
376 cpp_reader *pfile ATTRIBUTE_UNUSED;
58fea6af 377 const unsigned char *dir;
93c80368 378 const cpp_token *header;
58fea6af 379{
93c80368
NB
380 maybe_print_line (cpp_get_line (pfile)->output_line);
381 fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
382 print.lineno++;
58fea6af
ZW
383}
384
385static void
eb1f4d9d 386cb_file_change (pfile, fc)
27e2564a
NB
387 cpp_reader *pfile ATTRIBUTE_UNUSED;
388 const cpp_file_change *fc;
58fea6af 389{
27e2564a
NB
390 /* Bring current file to correct line (except first file). */
391 if (fc->reason == FC_ENTER && fc->from.filename)
392 maybe_print_line (fc->from.lineno);
393
27e2564a
NB
394 print.last_fname = fc->to.filename;
395 if (fc->externc)
396 print.syshdr_flags = " 3 4";
397 else if (fc->sysp)
398 print.syshdr_flags = " 3";
399 else
400 print.syshdr_flags = "";
58fea6af 401
ad2a084d 402 if (print.lineno)
27e2564a 403 {
dfbf62ec 404 const char *flags = "";
58fea6af 405
dfbf62ec
NB
406 print.lineno = fc->to.lineno;
407 if (fc->reason == FC_ENTER)
408 flags = " 1";
409 else if (fc->reason == FC_LEAVE)
410 flags = " 2";
ad2a084d
NB
411 print_line (flags);
412 }
9ec7291f
ZW
413}
414
58fea6af
ZW
415static void
416cb_def_pragma (pfile)
417 cpp_reader *pfile;
418{
93c80368
NB
419 maybe_print_line (cpp_get_line (pfile)->output_line);
420 fputs ("#pragma ", print.outf);
421 cpp_output_line (pfile, print.outf);
422 print.lineno++;
58fea6af
ZW
423}
424
425static void
426do_pragma_implementation (pfile)
427 cpp_reader *pfile;
428{
429 /* Be quiet about `#pragma implementation' for a file only if it hasn't
430 been included yet. */
93c80368 431 cpp_token token;
58fea6af 432
93c80368
NB
433 cpp_start_lookahead (pfile);
434 cpp_get_token (pfile, &token);
435 cpp_stop_lookahead (pfile, 0);
58fea6af 436
93c80368
NB
437 /* If it's not a string, pass it through and let the front end complain. */
438 if (token.type == CPP_STRING)
439 {
440 /* Make a NUL-terminated copy of the string. */
441 char *filename = alloca (token.val.str.len + 1);
442 memcpy (filename, token.val.str.text, token.val.str.len);
443 filename[token.val.str.len] = '\0';
444 if (cpp_included (pfile, filename))
58fea6af 445 cpp_warning (pfile,
93c80368
NB
446 "#pragma GCC implementation for \"%s\" appears after file is included",
447 filename);
448 }
449 else if (token.type != CPP_EOF)
450 {
451 cpp_error (pfile, "malformed #pragma GCC implementation");
452 return;
58fea6af
ZW
453 }
454
93c80368
NB
455 /* Output? This is nasty, but we don't have [GCC] implementation in
456 the buffer. */
d8090680 457 if (pfile->cb.def_pragma)
93c80368
NB
458 {
459 maybe_print_line (cpp_get_line (pfile)->output_line);
460 fputs ("#pragma GCC implementation ", print.outf);
461 cpp_output_line (pfile, print.outf);
462 print.lineno++;
463 }
58fea6af
ZW
464}
465
466/* Dump out the hash table. */
467static int
926c5678 468dump_macro (pfile, node, v)
58fea6af 469 cpp_reader *pfile;
93c80368 470 cpp_hashnode *node;
926c5678 471 void *v ATTRIBUTE_UNUSED;
58fea6af 472{
93c80368 473 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
58fea6af 474 {
93c80368
NB
475 fprintf (print.outf, "#define %s", node->name);
476 fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
477 putc ('\n', print.outf);
478 print.lineno++;
58fea6af
ZW
479 }
480
481 return 1;
482}
This page took 0.717674 seconds and 5 git commands to generate.