OSDN Git Service

* c-lex.c (cb_def_pragma): Update.
[pf3gnuchains/gcc-fork.git] / gcc / cppmain.c
1 /* CPP main program, using CPP Library.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4    Written by Per Bothner, 1994-95.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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
24 #include "config.h"
25 #include "system.h"
26 #include "cpplib.h"
27 #include "intl.h"
28
29 /* Encapsulates state used to convert the stream of tokens coming from
30    cpp_get_token back into a text file.  */
31 struct printer
32 {
33   FILE *outf;                   /* Stream to write to.  */
34   const struct line_map *map;   /* Logical to physical line mappings.  */
35   const cpp_token *prev;        /* Previous token.  */
36   unsigned int line;            /* Line currently being written.  */
37   unsigned char printed;        /* Nonzero if something output at line.  */
38 };
39
40 int main                PARAMS ((int, char **));
41 static void general_init PARAMS ((const char *));
42 static void do_preprocessing PARAMS ((int, char **));
43 static void setup_callbacks PARAMS ((void));
44
45 /* General output routines.  */
46 static void scan_translation_unit PARAMS ((cpp_reader *));
47 static void check_multiline_token PARAMS ((const cpp_string *));
48 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
49
50 static void print_line PARAMS ((const struct line_map *, unsigned int,
51                                 const char *));
52 static void maybe_print_line PARAMS ((const struct line_map *, unsigned int));
53
54 /* Callback routines for the parser.   Most of these are active only
55    in specific modes.  */
56 static void cb_line_change PARAMS ((cpp_reader *, const cpp_token *, int));
57 static void cb_define   PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
58 static void cb_undef    PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
59 static void cb_include  PARAMS ((cpp_reader *, unsigned int,
60                                  const unsigned char *, const cpp_token *));
61 static void cb_ident      PARAMS ((cpp_reader *, unsigned int,
62                                    const cpp_string *));
63 static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
64 static void cb_def_pragma PARAMS ((cpp_reader *, unsigned int));
65
66 const char *progname;           /* Needs to be global.  */
67 static cpp_reader *pfile;       /* An opaque handle.  */
68 static cpp_options *options;    /* Options of pfile.  */
69 static struct printer print;
70
71 int
72 main (argc, argv)
73      int argc;
74      char **argv;
75 {
76   general_init (argv[0]);
77
78   /* Contruct a reader with default language GNU C89.  */
79   pfile = cpp_create_reader (NULL, CLK_GNUC89);
80   options = cpp_get_options (pfile);
81   
82   do_preprocessing (argc, argv);
83
84   if (cpp_destroy (pfile))
85     return FATAL_EXIT_CODE;
86
87   return SUCCESS_EXIT_CODE;
88 }
89
90 /* Store the program name, and set the locale.  */
91 static void
92 general_init (argv0)
93      const char *argv0;
94 {
95   progname = argv0 + strlen (argv0);
96
97   while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
98     --progname;
99
100   xmalloc_set_program_name (progname);
101
102 /* LC_CTYPE determines the character set used by the terminal so it
103    has to be set to output messages correctly.  */
104
105 #ifdef HAVE_LC_MESSAGES
106   setlocale (LC_CTYPE, "");
107   setlocale (LC_MESSAGES, "");
108 #else
109   setlocale (LC_ALL, "");
110 #endif
111
112   (void) bindtextdomain (PACKAGE, localedir);
113   (void) textdomain (PACKAGE);
114 }
115
116 /* Handle switches, preprocess and output.  */
117 static void
118 do_preprocessing (argc, argv)
119      int argc;
120      char **argv;
121 {
122   int argi = 1;  /* Next argument to handle.  */
123
124   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
125   if (CPP_FATAL_ERRORS (pfile))
126     return;
127
128   if (argi < argc)
129     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
130   else
131     cpp_post_options (pfile);
132
133   if (CPP_FATAL_ERRORS (pfile))
134     return;
135
136   /* If cpp_handle_options saw --help or --version on the command
137      line, it will have set pfile->help_only to indicate this.  Exit
138      successfully.  [The library does not exit itself, because
139      e.g. cc1 needs to print its own --help message at this point.]  */
140   if (options->help_only)
141     return;
142
143   /* Initialize the printer structure.  Setting print.line to -1 here
144      is a trick to guarantee that the first token of the file will
145      cause a linemarker to be output by maybe_print_line.  */
146   print.line = (unsigned int) -1;
147   print.printed = 0;
148   print.prev = 0;
149   print.map = 0;
150   
151   /* Open the output now.  We must do so even if no_output is on,
152      because there may be other output than from the actual
153      preprocessing (e.g. from -dM).  */
154   if (options->out_fname[0] == '\0')
155     print.outf = stdout;
156   else
157     {
158       print.outf = fopen (options->out_fname, "w");
159       if (print.outf == NULL)
160         {
161           cpp_notice_from_errno (pfile, options->out_fname);
162           return;
163         }
164     }
165
166   setup_callbacks ();
167
168   if (cpp_start_read (pfile, options->in_fname))
169     {
170       /* A successful cpp_start_read guarantees that we can call
171          cpp_scan_nooutput or cpp_get_token next.  */
172       if (options->no_output)
173         cpp_scan_nooutput (pfile);
174       else
175         scan_translation_unit (pfile);
176
177       /* -dM command line option.  Should this be in cpp_finish?  */
178       if (options->dump_macros == dump_only)
179         cpp_forall_identifiers (pfile, dump_macro, NULL);
180
181       cpp_finish (pfile);
182     }
183
184   /* Flush any pending output.  */
185   if (print.printed)
186     putc ('\n', print.outf);
187
188   if (ferror (print.outf) || fclose (print.outf))
189     cpp_notice_from_errno (pfile, options->out_fname);
190 }
191
192 /* Set up the callbacks as appropriate.  */
193 static void
194 setup_callbacks ()
195 {
196   cpp_callbacks *cb = cpp_get_callbacks (pfile);
197
198   if (! options->no_output)
199     {
200       cb->line_change = cb_line_change;
201       cb->ident      = cb_ident;
202       cb->def_pragma = cb_def_pragma;
203       if (! options->no_line_commands)
204         cb->file_change = cb_file_change;
205     }
206
207   if (options->dump_includes)
208     cb->include  = cb_include;
209
210   if (options->dump_macros == dump_names
211       || options->dump_macros == dump_definitions)
212     {
213       cb->define = cb_define;
214       cb->undef  = cb_undef;
215     }
216 }
217
218 /* Writes out the preprocessed file.  Alternates between two tokens,
219    so that we can avoid accidental token pasting.  */
220 static void
221 scan_translation_unit (pfile)
222      cpp_reader *pfile;
223 {
224   bool avoid_paste = false;
225   const cpp_token *source = NULL;
226
227   for (;;)
228     {
229       const cpp_token *token = cpp_get_token (pfile);
230
231       if (token->type == CPP_PADDING)
232         {
233           avoid_paste = true;
234           if (source == NULL
235               || (!(source->flags & PREV_WHITE) && token->val.source == NULL))
236             source = token->val.source;
237           continue;
238         }
239
240       if (token->type == CPP_EOF)
241         break;
242
243       /* Subtle logic to output a space if and only if necessary.  */
244       if (avoid_paste)
245         {
246           if (source == NULL)
247             source = token;
248           if (source->flags & PREV_WHITE
249               || (print.prev && cpp_avoid_paste (pfile, print.prev, token))
250               || (print.prev == NULL && token->type == CPP_HASH))
251             putc (' ', print.outf);
252         }
253       else if (token->flags & PREV_WHITE)
254         putc (' ', print.outf);
255
256       avoid_paste = false;
257       source = NULL;
258       print.prev = token;
259       cpp_output_token (token, print.outf);
260
261       if (token->type == CPP_STRING || token->type == CPP_WSTRING
262           || token->type == CPP_COMMENT)
263         check_multiline_token (&token->val.str);
264     }
265 }
266
267 /* Adjust print.line for newlines embedded in tokens.  */
268 static void
269 check_multiline_token (str)
270      const cpp_string *str;
271 {
272   unsigned int i;
273
274   for (i = 0; i < str->len; i++)
275     if (str->text[i] == '\n')
276       print.line++;
277 }
278
279 /* If the token read on logical line LINE needs to be output on a
280    different line to the current one, output the required newlines or
281    a line marker, and return 1.  Otherwise return 0.  */
282
283 static void
284 maybe_print_line (map, line)
285      const struct line_map *map;
286      unsigned int line;
287 {
288   /* End the previous line of text.  */
289   if (print.printed)
290     {
291       putc ('\n', print.outf);
292       print.line++;
293       print.printed = 0;
294     }
295
296   if (line >= print.line && line < print.line + 8)
297     {
298       while (line > print.line)
299         {
300           putc ('\n', print.outf);
301           print.line++;
302         }
303     }
304   else
305     print_line (map, line, "");
306 }
307
308 /* Output a line marker for logical line LINE.  Special flags are "1"
309    or "2" indicating entering or leaving a file.  */
310 static void
311 print_line (map, line, special_flags)
312      const struct line_map *map;
313      unsigned int line;
314      const char *special_flags;
315 {
316   /* End any previous line of text.  */
317   if (print.printed)
318     putc ('\n', print.outf);
319   print.printed = 0;
320
321   print.line = line;
322   if (! options->no_line_commands)
323     {
324       fprintf (print.outf, "# %u \"%s\"%s",
325                SOURCE_LINE (map, print.line), map->to_file, special_flags);
326
327       if (map->sysp == 2)
328         fputs (" 3 4", print.outf);
329       else if (map->sysp == 1)
330         fputs (" 3", print.outf);
331
332       putc ('\n', print.outf);
333     }
334 }
335
336 /* Called when a line of output is started.  TOKEN is the first token
337    of the line, and maybe be CPP_EOF.  */
338
339 static void
340 cb_line_change (pfile, token, parsing_args)
341      cpp_reader *pfile ATTRIBUTE_UNUSED;
342      const cpp_token *token;
343      int parsing_args;
344 {
345   if (token->type == CPP_EOF || parsing_args)
346     return;
347
348   maybe_print_line (print.map, token->line);
349   print.printed = 1;
350   print.prev = 0;
351
352   /* Supply enough spaces to put this token in its original column,
353      one space per column greater than 2, since scan_translation_unit
354      will provide a space if PREV_WHITE.  Don't bother trying to
355      reconstruct tabs; we can't get it right in general, and nothing
356      ought to care.  Some things do care; the fault lies with them.  */
357   if (token->col > 2)
358     {
359       unsigned int spaces = token->col - 2;
360
361       while (spaces--)
362         putc (' ', print.outf);
363     }
364 }
365
366 static void
367 cb_ident (pfile, line, str)
368      cpp_reader *pfile ATTRIBUTE_UNUSED;
369      unsigned int line;
370      const cpp_string * str;
371 {
372   maybe_print_line (print.map, line);
373   fprintf (print.outf, "#ident \"%s\"\n", str->text);
374   print.line++;
375 }
376
377 static void
378 cb_define (pfile, line, node)
379      cpp_reader *pfile;
380      unsigned int line;
381      cpp_hashnode *node;
382 {
383   maybe_print_line (print.map, line);
384   fputs ("#define ", print.outf);
385
386   /* -dD command line option.  */
387   if (options->dump_macros == dump_definitions)
388     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
389   else
390     fputs ((const char *) NODE_NAME (node), print.outf);
391
392   putc ('\n', print.outf);
393   print.line++;
394 }
395
396 static void
397 cb_undef (pfile, line, node)
398      cpp_reader *pfile ATTRIBUTE_UNUSED;
399      unsigned int line;
400      cpp_hashnode *node;
401 {
402   maybe_print_line (print.map, line);
403   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
404   print.line++;
405 }
406
407 static void
408 cb_include (pfile, line, dir, header)
409      cpp_reader *pfile;
410      unsigned int line;
411      const unsigned char *dir;
412      const cpp_token *header;
413 {
414   maybe_print_line (print.map, line);
415   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
416   print.line++;
417 }
418
419 /* The file name, line number or system header flags have changed, as
420    described in MAP.  From this point on, the old print.map might be
421    pointing to freed memory, and so must not be dereferenced.  */
422
423 static void
424 cb_file_change (pfile, map)
425      cpp_reader *pfile ATTRIBUTE_UNUSED;
426      const struct line_map *map;
427 {
428   const char *flags = "";
429
430   /* First time?  */
431   if (print.map == NULL)
432     {
433       /* Avoid printing foo.i when the main file is foo.c.  */
434       if (!options->preprocessed)
435         print_line (map, map->from_line, flags);
436     }
437   else
438     {
439       /* Bring current file to correct line when entering a new file.  */
440       if (map->reason == LC_ENTER)
441         maybe_print_line (map - 1, map->from_line - 1);
442
443       if (map->reason == LC_ENTER)
444         flags = " 1";
445       else if (map->reason == LC_LEAVE)
446         flags = " 2";
447       print_line (map, map->from_line, flags);
448     }
449
450   print.map = map;
451 }
452
453 /* Copy a #pragma directive to the preprocessed output.  */
454 static void
455 cb_def_pragma (pfile, line)
456      cpp_reader *pfile;
457      unsigned int line;
458 {
459   maybe_print_line (print.map, line);
460   fputs ("#pragma ", print.outf);
461   cpp_output_line (pfile, print.outf);
462   print.line++;
463 }
464
465 /* Dump out the hash table.  */
466 static int
467 dump_macro (pfile, node, v)
468      cpp_reader *pfile;
469      cpp_hashnode *node;
470      void *v ATTRIBUTE_UNUSED;
471 {
472   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
473     {
474       fputs ("#define ", print.outf);
475       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
476       putc ('\n', print.outf);
477       print.line++;
478     }
479
480   return 1;
481 }