OSDN Git Service

no xfail
[pf3gnuchains/gcc-fork.git] / gcc / cppmain.c
1 /* CPP main program, using CPP Library.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002
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   const cpp_token *source;      /* Source token for spacing.  */
37   unsigned int line;            /* Line currently being written.  */
38   unsigned char printed;        /* Nonzero if something output at line.  */
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 ((const cpp_string *));
49 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
50
51 static void print_line PARAMS ((const struct line_map *, unsigned int,
52                                 const char *));
53 static void maybe_print_line PARAMS ((const struct line_map *, unsigned int));
54
55 /* Callback routines for the parser.   Most of these are active only
56    in specific modes.  */
57 static void cb_line_change PARAMS ((cpp_reader *, const cpp_token *, int));
58 static void cb_define   PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
59 static void cb_undef    PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
60 static void cb_include  PARAMS ((cpp_reader *, unsigned int,
61                                  const unsigned char *, const cpp_token *));
62 static void cb_ident      PARAMS ((cpp_reader *, unsigned int,
63                                    const cpp_string *));
64 static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
65 static void cb_def_pragma PARAMS ((cpp_reader *, unsigned int));
66
67 const char *progname;           /* Needs to be global.  */
68 static cpp_reader *pfile;       /* An opaque handle.  */
69 static cpp_options *options;    /* Options of pfile.  */
70 static struct printer print;
71
72 int
73 main (argc, argv)
74      int argc;
75      char **argv;
76 {
77   general_init (argv[0]);
78
79   /* Construct a reader with default language GNU C89.  */
80   pfile = cpp_create_reader (CLK_GNUC89);
81   options = cpp_get_options (pfile);
82   
83   do_preprocessing (argc, argv);
84
85   if (cpp_destroy (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   hex_init ();
104   gcc_init_libintl ();
105 }
106
107 /* Handle switches, preprocess and output.  */
108 static void
109 do_preprocessing (argc, argv)
110      int argc;
111      char **argv;
112 {
113   int argi = 1;  /* Next argument to handle.  */
114
115   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
116   if (CPP_FATAL_ERRORS (pfile))
117     return;
118
119   if (argi < argc)
120     {
121       cpp_fatal (pfile, "invalid option %s", argv[argi]);
122       return;
123     }
124
125   cpp_post_options (pfile);
126   if (CPP_FATAL_ERRORS (pfile))
127     return;
128
129   /* If cpp_handle_options saw --help or --version on the command
130      line, it will have set pfile->help_only to indicate this.  Exit
131      successfully.  [The library does not exit itself, because
132      e.g. cc1 needs to print its own --help message at this point.]  */
133   if (options->help_only)
134     return;
135
136   /* Initialize the printer structure.  Setting print.line to -1 here
137      is a trick to guarantee that the first token of the file will
138      cause a linemarker to be output by maybe_print_line.  */
139   print.line = (unsigned int) -1;
140   print.printed = 0;
141   print.prev = 0;
142   print.map = 0;
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   if (options->out_fname[0] == '\0')
148     print.outf = stdout;
149   else
150     {
151       print.outf = fopen (options->out_fname, "w");
152       if (print.outf == NULL)
153         {
154           cpp_notice_from_errno (pfile, options->out_fname);
155           return;
156         }
157     }
158
159   setup_callbacks ();
160
161   if (cpp_read_main_file (pfile, options->in_fname, NULL))
162     {
163       cpp_finish_options (pfile);
164
165       /* A successful cpp_read_main_file guarantees that we can call
166          cpp_scan_nooutput or cpp_get_token next.  */
167       if (options->no_output)
168         cpp_scan_nooutput (pfile);
169       else
170         scan_translation_unit (pfile);
171
172       /* -dM command line option.  Should this be in cpp_finish?  */
173       if (options->dump_macros == dump_only)
174         cpp_forall_identifiers (pfile, dump_macro, NULL);
175
176       cpp_finish (pfile);
177     }
178
179   /* Flush any pending output.  */
180   if (print.printed)
181     putc ('\n', print.outf);
182
183   if (ferror (print.outf) || fclose (print.outf))
184     cpp_notice_from_errno (pfile, options->out_fname);
185 }
186
187 /* Set up the callbacks as appropriate.  */
188 static void
189 setup_callbacks ()
190 {
191   cpp_callbacks *cb = cpp_get_callbacks (pfile);
192
193   if (! options->no_output)
194     {
195       cb->line_change = cb_line_change;
196       cb->ident      = cb_ident;
197       cb->def_pragma = cb_def_pragma;
198       if (! options->no_line_commands)
199         cb->file_change = cb_file_change;
200     }
201
202   if (options->dump_includes)
203     cb->include  = cb_include;
204
205   if (options->dump_macros == dump_names
206       || options->dump_macros == dump_definitions)
207     {
208       cb->define = cb_define;
209       cb->undef  = cb_undef;
210     }
211 }
212
213 /* Writes out the preprocessed file, handling spacing and paste
214    avoidance issues.  */
215 static void
216 scan_translation_unit (pfile)
217      cpp_reader *pfile;
218 {
219   bool avoid_paste = false;
220
221   print.source = NULL;
222   for (;;)
223     {
224       const cpp_token *token = cpp_get_token (pfile);
225
226       if (token->type == CPP_PADDING)
227         {
228           avoid_paste = true;
229           if (print.source == NULL
230               || (!(print.source->flags & PREV_WHITE)
231                   && token->val.source == NULL))
232             print.source = token->val.source;
233           continue;
234         }
235
236       if (token->type == CPP_EOF)
237         break;
238
239       /* Subtle logic to output a space if and only if necessary.  */
240       if (avoid_paste)
241         {
242           if (print.source == NULL)
243             print.source = token;
244           if (print.source->flags & PREV_WHITE
245               || (print.prev && cpp_avoid_paste (pfile, print.prev, token))
246               || (print.prev == NULL && token->type == CPP_HASH))
247             putc (' ', print.outf);
248         }
249       else if (token->flags & PREV_WHITE)
250         putc (' ', print.outf);
251
252       avoid_paste = false;
253       print.source = NULL;
254       print.prev = token;
255       cpp_output_token (token, print.outf);
256
257       if (token->type == CPP_STRING || token->type == CPP_WSTRING
258           || token->type == CPP_COMMENT)
259         check_multiline_token (&token->val.str);
260     }
261 }
262
263 /* Adjust print.line for newlines embedded in tokens.  */
264 static void
265 check_multiline_token (str)
266      const cpp_string *str;
267 {
268   unsigned int i;
269
270   for (i = 0; i < str->len; i++)
271     if (str->text[i] == '\n')
272       print.line++;
273 }
274
275 /* If the token read on logical line LINE needs to be output on a
276    different line to the current one, output the required newlines or
277    a line marker, and return 1.  Otherwise return 0.  */
278 static void
279 maybe_print_line (map, line)
280      const struct line_map *map;
281      unsigned int line;
282 {
283   /* End the previous line of text.  */
284   if (print.printed)
285     {
286       putc ('\n', print.outf);
287       print.line++;
288       print.printed = 0;
289     }
290
291   if (line >= print.line && line < print.line + 8)
292     {
293       while (line > print.line)
294         {
295           putc ('\n', print.outf);
296           print.line++;
297         }
298     }
299   else
300     print_line (map, line, "");
301 }
302
303 /* Output a line marker for logical line LINE.  Special flags are "1"
304    or "2" indicating entering or leaving a file.  */
305 static void
306 print_line (map, line, special_flags)
307      const struct line_map *map;
308      unsigned int line;
309      const char *special_flags;
310 {
311   /* End any previous line of text.  */
312   if (print.printed)
313     putc ('\n', print.outf);
314   print.printed = 0;
315
316   print.line = line;
317   if (! options->no_line_commands)
318     {
319       fprintf (print.outf, "# %u \"%s\"%s",
320                SOURCE_LINE (map, print.line), map->to_file, special_flags);
321
322       if (map->sysp == 2)
323         fputs (" 3 4", print.outf);
324       else if (map->sysp == 1)
325         fputs (" 3", print.outf);
326
327       putc ('\n', print.outf);
328     }
329 }
330
331 /* Called when a line of output is started.  TOKEN is the first token
332    of the line, and at end of file will be CPP_EOF.  */
333 static void
334 cb_line_change (pfile, token, parsing_args)
335      cpp_reader *pfile ATTRIBUTE_UNUSED;
336      const cpp_token *token;
337      int parsing_args;
338 {
339   if (token->type == CPP_EOF || parsing_args)
340     return;
341
342   maybe_print_line (print.map, token->line);
343   print.printed = 1;
344   print.prev = 0;
345   print.source = 0;
346
347   /* Supply enough spaces to put this token in its original column,
348      one space per column greater than 2, since scan_translation_unit
349      will provide a space if PREV_WHITE.  Don't bother trying to
350      reconstruct tabs; we can't get it right in general, and nothing
351      ought to care.  Some things do care; the fault lies with them.  */
352   if (token->col > 2)
353     {
354       unsigned int spaces = token->col - 2;
355
356       while (spaces--)
357         putc (' ', print.outf);
358     }
359 }
360
361 static void
362 cb_ident (pfile, line, str)
363      cpp_reader *pfile ATTRIBUTE_UNUSED;
364      unsigned int line;
365      const cpp_string * str;
366 {
367   maybe_print_line (print.map, line);
368   fprintf (print.outf, "#ident \"%s\"\n", str->text);
369   print.line++;
370 }
371
372 static void
373 cb_define (pfile, line, node)
374      cpp_reader *pfile;
375      unsigned int line;
376      cpp_hashnode *node;
377 {
378   maybe_print_line (print.map, line);
379   fputs ("#define ", print.outf);
380
381   /* -dD command line option.  */
382   if (options->dump_macros == dump_definitions)
383     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
384   else
385     fputs ((const char *) NODE_NAME (node), print.outf);
386
387   putc ('\n', print.outf);
388   print.line++;
389 }
390
391 static void
392 cb_undef (pfile, line, node)
393      cpp_reader *pfile ATTRIBUTE_UNUSED;
394      unsigned int line;
395      cpp_hashnode *node;
396 {
397   maybe_print_line (print.map, line);
398   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
399   print.line++;
400 }
401
402 static void
403 cb_include (pfile, line, dir, header)
404      cpp_reader *pfile;
405      unsigned int line;
406      const unsigned char *dir;
407      const cpp_token *header;
408 {
409   maybe_print_line (print.map, line);
410   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
411   print.line++;
412 }
413
414 /* The file name, line number or system header flags have changed, as
415    described in MAP.  From this point on, the old print.map might be
416    pointing to freed memory, and so must not be dereferenced.  */
417
418 static void
419 cb_file_change (pfile, map)
420      cpp_reader *pfile ATTRIBUTE_UNUSED;
421      const struct line_map *map;
422 {
423   const char *flags = "";
424
425   /* First time?  */
426   if (print.map == NULL)
427     {
428       /* Avoid printing foo.i when the main file is foo.c.  */
429       if (!options->preprocessed)
430         print_line (map, map->from_line, flags);
431     }
432   else
433     {
434       /* Bring current file to correct line when entering a new file.  */
435       if (map->reason == LC_ENTER)
436         maybe_print_line (map - 1, map->from_line - 1);
437
438       if (map->reason == LC_ENTER)
439         flags = " 1";
440       else if (map->reason == LC_LEAVE)
441         flags = " 2";
442       print_line (map, map->from_line, flags);
443     }
444
445   print.map = map;
446 }
447
448 /* Copy a #pragma directive to the preprocessed output.  */
449 static void
450 cb_def_pragma (pfile, line)
451      cpp_reader *pfile;
452      unsigned int line;
453 {
454   maybe_print_line (print.map, line);
455   fputs ("#pragma ", print.outf);
456   cpp_output_line (pfile, print.outf);
457   print.line++;
458 }
459
460 /* Dump out the hash table.  */
461 static int
462 dump_macro (pfile, node, v)
463      cpp_reader *pfile;
464      cpp_hashnode *node;
465      void *v ATTRIBUTE_UNUSED;
466 {
467   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
468     {
469       fputs ("#define ", print.outf);
470       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
471       putc ('\n', print.outf);
472       print.line++;
473     }
474
475   return 1;
476 }