OSDN Git Service

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