OSDN Git Service

PR preprocessor/3081
[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 char *filename;         /* Name of current file.  */
35   const char *syshdr_flags;     /* System header flags, if any.  */
36   unsigned int line;            /* Line currently being written.  */
37   unsigned char printed;        /* Nonzero if something output at line.  */
38   struct line_map *map;         /* Logical to physical line mappings.  */
39 };
40
41 int main                PARAMS ((int, char **));
42 static void general_init PARAMS ((const char *));
43 static void do_preprocessing PARAMS ((int, char **));
44 static void setup_callbacks PARAMS ((void));
45
46 /* General output routines.  */
47 static void scan_translation_unit PARAMS ((cpp_reader *));
48 static void check_multiline_token PARAMS ((cpp_string *));
49 static void printer_init PARAMS ((void));
50 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
51
52 static void print_line PARAMS ((unsigned int, const char *));
53 static void maybe_print_line PARAMS ((unsigned int));
54
55 /* Callback routines for the parser.   Most of these are active only
56    in specific modes.  */
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 cpp_file_change *));
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   /* Call to cpp_destroy () omitted for performance reasons.  */
85   if (cpp_errors (pfile))
86     return FATAL_EXIT_CODE;
87
88   return SUCCESS_EXIT_CODE;
89 }
90
91 /* Store the program name, and set the locale.  */
92 static void
93 general_init (argv0)
94      const char *argv0;
95 {
96   progname = argv0 + strlen (argv0);
97
98   while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
99     --progname;
100
101   xmalloc_set_program_name (progname);
102
103 /* LC_CTYPE determines the character set used by the terminal so it
104    has to be set to output messages correctly.  */
105
106 #ifdef HAVE_LC_MESSAGES
107   setlocale (LC_CTYPE, "");
108   setlocale (LC_MESSAGES, "");
109 #else
110   setlocale (LC_ALL, "");
111 #endif
112
113   (void) bindtextdomain (PACKAGE, localedir);
114   (void) textdomain (PACKAGE);
115 }
116
117 /* Handle switches, preprocess and output.  */
118 static void
119 do_preprocessing (argc, argv)
120      int argc;
121      char **argv;
122 {
123   int argi = 1;  /* Next argument to handle.  */
124
125   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
126   if (CPP_FATAL_ERRORS (pfile))
127     return;
128
129   if (argi < argc)
130     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
131   else
132     cpp_post_options (pfile);
133
134   if (CPP_FATAL_ERRORS (pfile))
135     return;
136
137   /* If cpp_handle_options saw --help or --version on the command
138      line, it will have set pfile->help_only to indicate this.  Exit
139      successfully.  [The library does not exit itself, because
140      e.g. cc1 needs to print its own --help message at this point.]  */
141   if (options->help_only)
142     return;
143
144   /* Open the output now.  We must do so even if no_output is on,
145      because there may be other output than from the actual
146      preprocessing (e.g. from -dM).  */
147   printer_init ();
148   if (print.outf == NULL)
149     {
150       cpp_notice_from_errno (pfile, options->out_fname);
151       return;
152     }
153
154   setup_callbacks ();
155
156   if (cpp_start_read (pfile, options->in_fname))
157     {
158       /* A successful cpp_start_read guarantees that we can call
159          cpp_scan_nooutput or cpp_get_token next.  */
160       if (options->no_output)
161         cpp_scan_nooutput (pfile);
162       else
163         scan_translation_unit (pfile);
164
165       /* -dM command line option.  Should this be in cpp_finish?  */
166       if (options->dump_macros == dump_only)
167         cpp_forall_identifiers (pfile, dump_macro, NULL);
168
169       cpp_finish (pfile);
170     }
171
172   /* Flush any pending output.  */
173   if (print.printed)
174     putc ('\n', print.outf);
175
176   if (ferror (print.outf) || fclose (print.outf))
177     cpp_notice_from_errno (pfile, options->out_fname);
178 }
179
180 /* Set up the callbacks as appropriate.  */
181 static void
182 setup_callbacks ()
183 {
184   cpp_callbacks *cb = cpp_get_callbacks (pfile);
185
186   if (! options->no_output)
187     {
188       cb->ident      = cb_ident;
189       cb->def_pragma = cb_def_pragma;
190       if (! options->no_line_commands)
191         cb->file_change = cb_file_change;
192     }
193
194   if (options->dump_includes)
195     cb->include  = cb_include;
196
197   if (options->dump_macros == dump_names
198       || options->dump_macros == dump_definitions)
199     {
200       cb->define = cb_define;
201       cb->undef  = cb_undef;
202     }
203 }
204
205 /* Writes out the preprocessed file.  Alternates between two tokens,
206    so that we can avoid accidental token pasting.  */
207 static void
208 scan_translation_unit (pfile)
209      cpp_reader *pfile;
210 {
211   unsigned int index, line;
212   cpp_token tokens[2], *token;
213
214   for (index = 0;; index = 1 - index)
215     {
216       token = &tokens[index];
217       cpp_get_token (pfile, token);
218
219       if (token->type == CPP_EOF)
220         break;
221
222       line = cpp_get_line (pfile)->output_line;
223       if (print.line != line)
224         {
225           unsigned int col = cpp_get_line (pfile)->col;
226
227           /* Supply enough whitespace to put this token in its original
228              column.  Don't bother trying to reconstruct tabs; we can't
229              get it right in general, and nothing ought to care.  (Yes,
230              some things do care; the fault lies with them.)  */
231           maybe_print_line (line);
232           if (col > 1)
233             {
234               if (token->flags & PREV_WHITE)
235                 col--;
236               while (--col)
237                 putc (' ', print.outf);
238             }
239         }
240       else if ((token->flags & (PREV_WHITE | AVOID_LPASTE))
241                == AVOID_LPASTE
242                && cpp_avoid_paste (pfile, &tokens[1 - index], token))
243         token->flags |= PREV_WHITE;
244       /* Special case '# <directive name>': insert a space between
245          the # and the token.  This will prevent it from being
246          treated as a directive when this code is re-preprocessed.
247          XXX Should do this only at the beginning of a line, but how?  */
248       else if (token->type == CPP_NAME && token->val.node->directive_index
249                && tokens[1 - index].type == CPP_HASH)
250         token->flags |= PREV_WHITE;
251
252       cpp_output_token (token, print.outf);
253       print.printed = 1;
254       if (token->type == CPP_STRING || token->type == CPP_WSTRING
255           || token->type == CPP_COMMENT)
256         check_multiline_token (&token->val.str);
257     }
258 }
259
260 /* Adjust print.line for newlines embedded in tokens.  */
261 static void
262 check_multiline_token (str)
263      cpp_string *str;
264 {
265   unsigned int i;
266
267   for (i = 0; i < str->len; i++)
268     if (str->text[i] == '\n')
269       print.line++;
270 }
271
272 /* Initialize a cpp_printer structure.  As a side effect, open the
273    output file.  If print.outf is NULL an error occurred.  */
274 static void
275 printer_init ()
276 {
277   /* Setting print.line to -1 here guarantees that the first token of
278      the file will cause a linemarker to be output by maybe_print_line.  */
279   print.line = (unsigned int) -1;
280   print.printed = 0;
281   print.map = 0;
282
283   if (options->out_fname[0] == '\0')
284     print.outf = stdout;
285   else
286     print.outf = fopen (options->out_fname, "w");
287 }
288
289 /* If the token read on logical line LINE needs to be output on a
290    different line to the current one, output the required newlines or
291    a line marker, and return 1.  Otherwise return 0.  */
292
293 static void
294 maybe_print_line (line)
295      unsigned int line;
296 {
297   /* End the previous line of text.  */
298   if (print.printed)
299     {
300       putc ('\n', print.outf);
301       print.line++;
302       print.printed = 0;
303     }
304
305   if (line >= print.line && line < print.line + 8)
306     {
307       while (line > print.line)
308         {
309           putc ('\n', print.outf);
310           print.line++;
311         }
312     }
313   else
314     print_line (line, "");
315 }
316
317 static void
318 print_line (line, special_flags)
319      unsigned int line;
320      const char *special_flags;
321 {
322   /* End any previous line of text.  */
323   if (print.printed)
324     putc ('\n', print.outf);
325   print.printed = 0;
326
327   print.line = line;
328   if (! options->no_line_commands)
329     fprintf (print.outf, "# %u \"%s\"%s%s\n",
330              SOURCE_LINE (print.map, print.line),
331              print.filename, special_flags, print.syshdr_flags);
332 }
333
334 /* Callbacks.  */
335
336 static void
337 cb_ident (pfile, line, str)
338      cpp_reader *pfile ATTRIBUTE_UNUSED;
339      unsigned int line;
340      const cpp_string * str;
341 {
342   maybe_print_line (line);
343   fprintf (print.outf, "#ident \"%s\"\n", str->text);
344   print.line++;
345 }
346
347 static void
348 cb_define (pfile, line, node)
349      cpp_reader *pfile;
350      unsigned int line;
351      cpp_hashnode *node;
352 {
353   maybe_print_line (line);
354   fputs ("#define ", print.outf);
355
356   /* -dD command line option.  */
357   if (options->dump_macros == dump_definitions)
358     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
359   else
360     fputs ((const char *) NODE_NAME (node), print.outf);
361
362   putc ('\n', print.outf);
363   print.line++;
364 }
365
366 static void
367 cb_undef (pfile, line, node)
368      cpp_reader *pfile ATTRIBUTE_UNUSED;
369      unsigned int line;
370      cpp_hashnode *node;
371 {
372   maybe_print_line (line);
373   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
374   print.line++;
375 }
376
377 static void
378 cb_include (pfile, line, dir, header)
379      cpp_reader *pfile;
380      unsigned int line;
381      const unsigned char *dir;
382      const cpp_token *header;
383 {
384   maybe_print_line (line);
385   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
386   print.line++;
387 }
388
389 static void
390 cb_file_change (pfile, fc)
391      cpp_reader *pfile ATTRIBUTE_UNUSED;
392      const cpp_file_change *fc;
393 {
394   bool first_time = print.map == NULL;
395
396   /* Bring current file to correct line.  We handle the first file
397      change callback specially, so that a first line of "# 1 "foo.c"
398      in file foo.i outputs just the foo.c line, and not a foo.i line.  */
399   if (fc->reason == LC_ENTER && !first_time)
400     maybe_print_line (fc->line - 1);
401
402   print.map = fc->map;
403   print.filename = fc->map->to_file;
404   if (fc->externc)
405     print.syshdr_flags = " 3 4";
406   else if (fc->sysp)
407     print.syshdr_flags = " 3";
408   else
409     print.syshdr_flags = "";
410
411   if (!first_time)
412     {
413       const char *flags = "";
414
415       if (fc->reason == LC_ENTER)
416         flags = " 1";
417       else if (fc->reason == LC_LEAVE)
418         flags = " 2";
419
420       print_line (fc->line, flags);
421     }
422 }
423
424 /* Copy a #pragma directive to the preprocessed output.  LINE is the
425    line of the current source file, not the logical line.  */
426 static void
427 cb_def_pragma (pfile, line)
428      cpp_reader *pfile;
429      unsigned int line;
430 {
431   maybe_print_line (line);
432   fputs ("#pragma ", print.outf);
433   cpp_output_line (pfile, print.outf);
434   print.line++;
435 }
436
437 /* Dump out the hash table.  */
438 static int
439 dump_macro (pfile, node, v)
440      cpp_reader *pfile;
441      cpp_hashnode *node;
442      void *v ATTRIBUTE_UNUSED;
443 {
444   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
445     {
446       fputs ("#define ", print.outf);
447       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
448       putc ('\n', print.outf);
449       print.line++;
450     }
451
452   return 1;
453 }