OSDN Git Service

* Makefile.in (CPPLIB_H): New, so that dependencies on cpplib.h
[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 *last_fname;       /* previous file name.  */
35   const char *syshdr_flags;     /* system header flags, if any.  */
36   unsigned int lineno;          /* line currently being written.  */
37   unsigned char printed;        /* nonzero if something output at lineno.  */
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 int printer_init PARAMS ((cpp_reader *));
50 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
51
52 static void print_line PARAMS ((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 *, cpp_hashnode *));
58 static void cb_undef    PARAMS ((cpp_reader *, cpp_hashnode *));
59 static void cb_include  PARAMS ((cpp_reader *, const unsigned char *,
60                                  const cpp_token *));
61 static void cb_ident      PARAMS ((cpp_reader *, const cpp_string *));
62 static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
63 static void cb_def_pragma PARAMS ((cpp_reader *));
64
65 const char *progname;           /* Needs to be global.  */
66 static cpp_reader *pfile;       /* An opaque handle.  */
67 static cpp_options *options;    /* Options of pfile.  */
68 static struct printer print;
69
70 int
71 main (argc, argv)
72      int argc;
73      char **argv;
74 {
75   general_init (argv[0]);
76
77   /* Contruct a reader with default language GNU C89.  */
78   pfile = cpp_create_reader (NULL, CLK_GNUC89);
79   options = cpp_get_options (pfile);
80   
81   do_preprocessing (argc, argv);
82
83   /* Call to cpp_destroy () omitted for performance reasons.  */
84   if (cpp_errors (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   /* Open the output now.  We must do so even if no_output is on,
144      because there may be other output than from the actual
145      preprocessing (e.g. from -dM).  */
146   if (printer_init (pfile))
147     return;
148
149   setup_callbacks ();
150
151   if (cpp_start_read (pfile, options->in_fname))
152     {
153       /* A successful cpp_start_read guarantees that we can call
154          cpp_scan_nooutput or cpp_get_token next.  */
155       if (options->no_output)
156         cpp_scan_nooutput (pfile);
157       else
158         scan_translation_unit (pfile);
159
160       /* -dM command line option.  Should this be in cpp_finish?  */
161       if (options->dump_macros == dump_only)
162         cpp_forall_identifiers (pfile, dump_macro, NULL);
163
164       cpp_finish (pfile);
165     }
166
167   /* Flush any pending output.  */
168   if (print.printed)
169     putc ('\n', print.outf);
170
171   if (ferror (print.outf) || fclose (print.outf))
172     cpp_notice_from_errno (pfile, options->out_fname);
173 }
174
175 /* Set up the callbacks as appropriate.  */
176 static void
177 setup_callbacks ()
178 {
179   cpp_callbacks *cb = cpp_get_callbacks (pfile);
180
181   if (! options->no_output)
182     {
183       cb->ident      = cb_ident;
184       cb->def_pragma = cb_def_pragma;
185       if (! options->no_line_commands)
186         cb->file_change = cb_file_change;
187     }
188
189   if (options->dump_includes)
190     cb->include  = cb_include;
191
192   if (options->dump_macros == dump_names
193       || options->dump_macros == dump_definitions)
194     {
195       cb->define = cb_define;
196       cb->undef  = cb_undef;
197     }
198 }
199
200 /* Writes out the preprocessed file.  Alternates between two tokens,
201    so that we can avoid accidental token pasting.  */
202 static void
203 scan_translation_unit (pfile)
204      cpp_reader *pfile;
205 {
206   unsigned int index, line;
207   cpp_token tokens[2], *token;
208
209   for (index = 0;; index = 1 - index)
210     {
211       token = &tokens[index];
212       cpp_get_token (pfile, token);
213
214       if (token->type == CPP_EOF)
215         break;
216
217       line = cpp_get_line (pfile)->output_line;
218       if (print.lineno != line)
219         {
220           unsigned int col = cpp_get_line (pfile)->col;
221
222           /* Supply enough whitespace to put this token in its original
223              column.  Don't bother trying to reconstruct tabs; we can't
224              get it right in general, and nothing ought to care.  (Yes,
225              some things do care; the fault lies with them.)  */
226           maybe_print_line (line);
227           if (col > 1)
228             {
229               if (token->flags & PREV_WHITE)
230                 col--;
231               while (--col)
232                 putc (' ', print.outf);
233             }
234         }
235       else if ((token->flags & (PREV_WHITE | AVOID_LPASTE))
236                == AVOID_LPASTE
237                && cpp_avoid_paste (pfile, &tokens[1 - index], token))
238         token->flags |= PREV_WHITE;
239       /* Special case '# <directive name>': insert a space between
240          the # and the token.  This will prevent it from being
241          treated as a directive when this code is re-preprocessed.
242          XXX Should do this only at the beginning of a line, but how?  */
243       else if (token->type == CPP_NAME && token->val.node->directive_index
244                && tokens[1 - index].type == CPP_HASH)
245         token->flags |= PREV_WHITE;
246
247       cpp_output_token (token, print.outf);
248       print.printed = 1;
249       if (token->type == CPP_STRING || token->type == CPP_WSTRING
250           || token->type == CPP_COMMENT)
251         check_multiline_token (&token->val.str);
252     }
253 }
254
255 /* Adjust print.lineno for newlines embedded in tokens.  */
256 static void
257 check_multiline_token (str)
258      cpp_string *str;
259 {
260   unsigned int i;
261
262   for (i = 0; i < str->len; i++)
263     if (str->text[i] == '\n')
264       print.lineno++;
265 }
266
267 /* Initialize a cpp_printer structure.  As a side effect, open the
268    output file.  */
269 static int
270 printer_init (pfile)
271      cpp_reader *pfile;
272 {
273   print.last_fname = 0;
274   print.lineno = 0;
275   print.printed = 0;
276
277   if (options->out_fname[0] == '\0')
278     print.outf = stdout;
279   else
280     {
281       print.outf = fopen (options->out_fname, "w");
282       if (! print.outf)
283         {
284           cpp_notice_from_errno (pfile, options->out_fname);
285           return 1;
286         }
287     }
288
289   return 0;
290 }
291
292 /* Newline-terminate any output line currently in progress.  If
293    appropriate, write the current line number to the output, or pad
294    with newlines so the output line matches the current line.  */
295 static void
296 maybe_print_line (line)
297      unsigned int line;
298 {
299   /* End the previous line of text (probably only needed until we get
300      multi-line tokens fixed).  */
301   if (print.printed)
302     {
303       putc ('\n', print.outf);
304       print.lineno++;
305       print.printed = 0;
306     }
307
308   if (options->no_line_commands)
309     {
310       print.lineno = line;
311       return;
312     }
313
314   /* print.lineno is zero if this is the first token of the file.  We
315      handle this specially, so that a first line of "# 1 "foo.c" in
316      file foo.i outputs just the foo.c line, and not a foo.i line.  */
317   if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
318     {
319       while (line > print.lineno)
320         {
321           putc ('\n', print.outf);
322           print.lineno++;
323         }
324     }
325   else
326     {
327       print.lineno = line;
328       print_line ("");
329     }
330 }
331
332 static void
333 print_line (special_flags)
334   const char *special_flags;
335 {
336   /* End any previous line of text.  */
337   if (print.printed)
338     putc ('\n', print.outf);
339   print.printed = 0;
340
341   fprintf (print.outf, "# %u \"%s\"%s%s\n",
342            print.lineno, print.last_fname, special_flags, print.syshdr_flags);
343 }
344
345 /* Callbacks.  */
346
347 static void
348 cb_ident (pfile, str)
349      cpp_reader *pfile ATTRIBUTE_UNUSED;
350      const cpp_string * str;
351 {
352   maybe_print_line (cpp_get_line (pfile)->output_line);
353   fprintf (print.outf, "#ident \"%s\"\n", str->text);
354   print.lineno++;
355 }
356
357 static void
358 cb_define (pfile, node)
359      cpp_reader *pfile;
360      cpp_hashnode *node;
361 {
362   maybe_print_line (cpp_get_line (pfile)->output_line);
363   fputs ("#define ", print.outf);
364
365   /* -dD command line option.  */
366   if (options->dump_macros == dump_definitions)
367     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
368   else
369     fputs ((const char *) NODE_NAME (node), print.outf);
370
371   putc ('\n', print.outf);
372   print.lineno++;
373 }
374
375 static void
376 cb_undef (pfile, node)
377      cpp_reader *pfile;
378      cpp_hashnode *node;
379 {
380   maybe_print_line (cpp_get_line (pfile)->output_line);
381   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
382   print.lineno++;
383 }
384
385 static void
386 cb_include (pfile, dir, header)
387      cpp_reader *pfile ATTRIBUTE_UNUSED;
388      const unsigned char *dir;
389      const cpp_token *header;
390 {
391   maybe_print_line (cpp_get_line (pfile)->output_line);
392   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
393   print.lineno++;
394 }
395
396 static void
397 cb_file_change (pfile, fc)
398      cpp_reader *pfile ATTRIBUTE_UNUSED;
399      const cpp_file_change *fc;
400 {
401   /* Bring current file to correct line (except first file).  */
402   if (fc->reason == LC_ENTER && !MAIN_FILE_P (fc->map))
403     maybe_print_line (SOURCE_LINE (fc->map - 1, fc->line - 1));
404
405   print.map = fc->map;
406   print.last_fname = fc->map->to_file;
407   if (fc->externc)
408     print.syshdr_flags = " 3 4";
409   else if (fc->sysp)
410     print.syshdr_flags = " 3";
411   else
412     print.syshdr_flags = "";
413
414   if (print.lineno)
415     {
416       const char *flags = "";
417
418       print.lineno = SOURCE_LINE (fc->map, fc->line);
419       if (fc->reason == LC_ENTER)
420         flags = " 1";
421       else if (fc->reason == LC_LEAVE)
422         flags = " 2";
423
424       if (! options->no_line_commands)
425         print_line (flags);
426     }
427 }
428
429 /* Copy a #pragma directive to the preprocessed output.  LINE is the
430    line of the current source file, not the logical line.  */
431 static void
432 cb_def_pragma (pfile)
433      cpp_reader *pfile;
434 {
435   maybe_print_line (cpp_get_line (pfile)->output_line);
436   fputs ("#pragma ", print.outf);
437   cpp_output_line (pfile, print.outf);
438   print.lineno++;
439 }
440
441 /* Dump out the hash table.  */
442 static int
443 dump_macro (pfile, node, v)
444      cpp_reader *pfile;
445      cpp_hashnode *node;
446      void *v ATTRIBUTE_UNUSED;
447 {
448   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
449     {
450       fputs ("#define ", print.outf);
451       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
452       putc ('\n', print.outf);
453       print.lineno++;
454     }
455
456   return 1;
457 }