OSDN Git Service

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