OSDN Git Service

* line-map.c: New.
[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_buffer 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_buffer_nooutput or cpp_get_token next.  */
155       if (options->no_output)
156         cpp_scan_buffer_nooutput (pfile, 1);
157       else
158         scan_buffer (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_buffer (pfile)
204      cpp_reader *pfile;
205 {
206   unsigned int index, line;
207   cpp_token tokens[2], *token;
208
209   do
210     {
211       for (index = 0;; index = 1 - index)
212         {
213           token = &tokens[index];
214           cpp_get_token (pfile, token);
215
216           if (token->type == CPP_EOF)
217             break;
218
219           line = cpp_get_line (pfile)->output_line;
220           if (print.lineno != line)
221             {
222               unsigned int col = cpp_get_line (pfile)->col;
223
224               /* Supply enough whitespace to put this token in its original
225                  column.  Don't bother trying to reconstruct tabs; we can't
226                  get it right in general, and nothing ought to care.  (Yes,
227                  some things do care; the fault lies with them.)  */
228               maybe_print_line (line);
229               if (col > 1)
230                 {
231                   if (token->flags & PREV_WHITE)
232                     col--;
233                   while (--col)
234                     putc (' ', print.outf);
235                 }
236             }
237           else if ((token->flags & (PREV_WHITE | AVOID_LPASTE))
238                        == AVOID_LPASTE
239                    && cpp_avoid_paste (pfile, &tokens[1 - index], token))
240             token->flags |= PREV_WHITE;
241           /* Special case '# <directive name>': insert a space between
242              the # and the token.  This will prevent it from being
243              treated as a directive when this code is re-preprocessed.
244              XXX Should do this only at the beginning of a line, but how?  */
245           else if (token->type == CPP_NAME && token->val.node->directive_index
246                    && tokens[1 - index].type == CPP_HASH)
247             token->flags |= PREV_WHITE;
248
249           cpp_output_token (token, print.outf);
250           print.printed = 1;
251           if (token->type == CPP_STRING || token->type == CPP_WSTRING
252               || token->type == CPP_COMMENT)
253             check_multiline_token (&token->val.str);
254         }
255     }
256   while (cpp_pop_buffer (pfile) != 0);
257 }
258
259 /* Adjust print.lineno for newlines embedded in tokens.  */
260 static void
261 check_multiline_token (str)
262      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.lineno++;
269 }
270
271 /* Initialize a cpp_printer structure.  As a side effect, open the
272    output file.  */
273 static int
274 printer_init (pfile)
275      cpp_reader *pfile;
276 {
277   print.last_fname = 0;
278   print.lineno = 0;
279   print.printed = 0;
280
281   if (options->out_fname[0] == '\0')
282     print.outf = stdout;
283   else
284     {
285       print.outf = fopen (options->out_fname, "w");
286       if (! print.outf)
287         {
288           cpp_notice_from_errno (pfile, options->out_fname);
289           return 1;
290         }
291     }
292
293   return 0;
294 }
295
296 /* Newline-terminate any output line currently in progress.  If
297    appropriate, write the current line number to the output, or pad
298    with newlines so the output line matches the current line.  */
299 static void
300 maybe_print_line (line)
301      unsigned int line;
302 {
303   /* End the previous line of text (probably only needed until we get
304      multi-line tokens fixed).  */
305   if (print.printed)
306     {
307       putc ('\n', print.outf);
308       print.lineno++;
309       print.printed = 0;
310     }
311
312   if (options->no_line_commands)
313     {
314       print.lineno = line;
315       return;
316     }
317
318   /* print.lineno is zero if this is the first token of the file.  We
319      handle this specially, so that a first line of "# 1 "foo.c" in
320      file foo.i outputs just the foo.c line, and not a foo.i line.  */
321   if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
322     {
323       while (line > print.lineno)
324         {
325           putc ('\n', print.outf);
326           print.lineno++;
327         }
328     }
329   else
330     {
331       print.lineno = line;
332       print_line ("");
333     }
334 }
335
336 static void
337 print_line (special_flags)
338   const char *special_flags;
339 {
340   /* End any previous line of text.  */
341   if (print.printed)
342     putc ('\n', print.outf);
343   print.printed = 0;
344
345   fprintf (print.outf, "# %u \"%s\"%s%s\n",
346            print.lineno, print.last_fname, special_flags, print.syshdr_flags);
347 }
348
349 /* Callbacks.  */
350
351 static void
352 cb_ident (pfile, str)
353      cpp_reader *pfile ATTRIBUTE_UNUSED;
354      const cpp_string * str;
355 {
356   maybe_print_line (cpp_get_line (pfile)->output_line);
357   fprintf (print.outf, "#ident \"%s\"\n", str->text);
358   print.lineno++;
359 }
360
361 static void
362 cb_define (pfile, node)
363      cpp_reader *pfile;
364      cpp_hashnode *node;
365 {
366   maybe_print_line (cpp_get_line (pfile)->output_line);
367   fputs ("#define ", print.outf);
368
369   /* -dD command line option.  */
370   if (options->dump_macros == dump_definitions)
371     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
372   else
373     fputs ((const char *) NODE_NAME (node), print.outf);
374
375   putc ('\n', print.outf);
376   print.lineno++;
377 }
378
379 static void
380 cb_undef (pfile, node)
381      cpp_reader *pfile;
382      cpp_hashnode *node;
383 {
384   maybe_print_line (cpp_get_line (pfile)->output_line);
385   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
386   print.lineno++;
387 }
388
389 static void
390 cb_include (pfile, dir, header)
391      cpp_reader *pfile ATTRIBUTE_UNUSED;
392      const unsigned char *dir;
393      const cpp_token *header;
394 {
395   maybe_print_line (cpp_get_line (pfile)->output_line);
396   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
397   print.lineno++;
398 }
399
400 static void
401 cb_file_change (pfile, fc)
402      cpp_reader *pfile ATTRIBUTE_UNUSED;
403      const cpp_file_change *fc;
404 {
405   /* Bring current file to correct line (except first file).  */
406   if (fc->reason == LC_ENTER && !MAIN_FILE_P (fc->map))
407     maybe_print_line (SOURCE_LINE (fc->map - 1, fc->line - 1));
408
409   print.map = fc->map;
410   print.last_fname = fc->map->to_file;
411   if (fc->externc)
412     print.syshdr_flags = " 3 4";
413   else if (fc->sysp)
414     print.syshdr_flags = " 3";
415   else
416     print.syshdr_flags = "";
417
418   if (print.lineno)
419     {
420       const char *flags = "";
421
422       print.lineno = SOURCE_LINE (fc->map, fc->line);
423       if (fc->reason == LC_ENTER)
424         flags = " 1";
425       else if (fc->reason == LC_LEAVE)
426         flags = " 2";
427
428       if (! options->no_line_commands)
429         print_line (flags);
430     }
431 }
432
433 /* Copy a #pragma directive to the preprocessed output.  LINE is the
434    line of the current source file, not the logical line.  */
435 static void
436 cb_def_pragma (pfile)
437      cpp_reader *pfile;
438 {
439   maybe_print_line (cpp_get_line (pfile)->output_line);
440   fputs ("#pragma ", print.outf);
441   cpp_output_line (pfile, print.outf);
442   print.lineno++;
443 }
444
445 /* Dump out the hash table.  */
446 static int
447 dump_macro (pfile, node, v)
448      cpp_reader *pfile;
449      cpp_hashnode *node;
450      void *v ATTRIBUTE_UNUSED;
451 {
452   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
453     {
454       fputs ("#define ", print.outf);
455       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
456       putc ('\n', print.outf);
457       print.lineno++;
458     }
459
460   return 1;
461 }