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