OSDN Git Service

config:
[pf3gnuchains/gcc-fork.git] / gcc / cppmain.c
1 /* CPP main program, using CPP Library.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3    Written by Per Bothner, 1994-95.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
8 later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19  In other words, you are welcome to use, share and improve this program.
20  You are forbidden to forbid anyone else to use, share and improve
21  what you give them.   Help stamp out software-hoarding!  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "cpplib.h"
26 #include "intl.h"
27
28 /* Encapsulates state used to convert the stream of tokens coming from
29    cpp_get_token back into a text file.  */
30 struct printer
31 {
32   FILE *outf;                   /* stream to write to.  */
33   const char *last_fname;       /* previous file name.  */
34   const char *syshdr_flags;     /* system header flags, if any.  */
35   unsigned int lineno;          /* line currently being written.  */
36   unsigned char printed;        /* nonzero if something output at lineno.  */
37   unsigned char no_line_dirs;   /* nonzero to output no line directives.  */
38 };
39
40 int main                PARAMS ((int, char **));
41
42 /* General output routines.  */
43 static void scan_buffer PARAMS ((cpp_reader *));
44 static int printer_init PARAMS ((cpp_reader *));
45 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
46
47 static void print_line PARAMS ((const char *));
48 static void maybe_print_line PARAMS ((unsigned int));
49 static void move_printer PARAMS ((cpp_reader *, unsigned int, const char *));
50
51 /* Callback routines for the parser.   Most of these are active only
52    in specific modes.  */
53 static void cb_define   PARAMS ((cpp_reader *, cpp_hashnode *));
54 static void cb_undef    PARAMS ((cpp_reader *, cpp_hashnode *));
55 static void cb_include  PARAMS ((cpp_reader *, const unsigned char *,
56                                  const cpp_token *));
57 static void cb_ident      PARAMS ((cpp_reader *, const cpp_string *));
58 static void cb_enter_file PARAMS ((cpp_reader *));
59 static void cb_leave_file PARAMS ((cpp_reader *));
60 static void cb_rename_file PARAMS ((cpp_reader *));
61 static void cb_def_pragma PARAMS ((cpp_reader *));
62 static void do_pragma_implementation PARAMS ((cpp_reader *));
63
64 const char *progname;
65 static cpp_reader parse_in;
66 static struct printer print;
67
68 int
69 main (argc, argv)
70      int argc;
71      char **argv;
72 {
73   char *p;
74   cpp_reader *pfile = &parse_in;
75   int argi = 1;  /* Next argument to handle.  */
76
77   p = argv[0] + strlen (argv[0]);
78   while (p != argv[0] && ! IS_DIR_SEPARATOR (p[-1])) --p;
79   progname = p;
80
81   xmalloc_set_program_name (progname);
82
83 #ifdef HAVE_LC_MESSAGES
84   setlocale (LC_MESSAGES, "");
85 #endif
86   (void) bindtextdomain (PACKAGE, localedir);
87   (void) textdomain (PACKAGE);
88
89   cpp_init ();
90   cpp_reader_init (pfile);
91   
92   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
93   if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
94     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
95   if (CPP_FATAL_ERRORS (pfile))
96     return (FATAL_EXIT_CODE);
97
98   /* Open the output now.  We must do so even if no_output is on,
99      because there may be other output than from the actual
100      preprocessing (e.g. from -dM).  */
101   if (printer_init (pfile))
102     return (FATAL_EXIT_CODE);
103
104   /* Set callbacks.  */
105   if (! CPP_OPTION (pfile, no_output))
106     {
107       pfile->cb.ident      = cb_ident;
108       pfile->cb.def_pragma = cb_def_pragma;
109       if (! CPP_OPTION (pfile, no_line_commands))
110         {
111           pfile->cb.enter_file = cb_enter_file;
112           pfile->cb.leave_file = cb_leave_file;
113           pfile->cb.rename_file = cb_rename_file;
114         }
115     }
116
117   if (CPP_OPTION (pfile, dump_includes))
118     pfile->cb.include  = cb_include;
119
120   if (CPP_OPTION (pfile, debug_output)
121       || CPP_OPTION (pfile, dump_macros) == dump_names
122       || CPP_OPTION (pfile, dump_macros) == dump_definitions)
123     {
124       pfile->cb.define = cb_define;
125       pfile->cb.undef  = cb_undef;
126       pfile->cb.poison = cb_def_pragma;
127     }
128
129   /* Register one #pragma which needs special handling.  */
130   cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
131   cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
132
133   if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
134     return (FATAL_EXIT_CODE);
135
136   if (CPP_BUFFER (pfile))
137     {
138       if (CPP_OPTION (pfile, no_output))
139         cpp_scan_buffer_nooutput (pfile);
140       else
141         scan_buffer (pfile);
142     }
143
144   /* -dM command line option.  */
145   if (CPP_OPTION (pfile, dump_macros) == dump_only)
146     cpp_forall_identifiers (pfile, dump_macro, NULL);
147
148   cpp_finish (pfile);
149   cpp_cleanup (pfile);
150
151   /* Flush any pending output.  */
152   if (print.printed)
153     putc ('\n', print.outf);
154   if (ferror (print.outf) || fclose (print.outf))
155     cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
156
157   if (parse_in.errors)
158     return (FATAL_EXIT_CODE);
159   return (SUCCESS_EXIT_CODE);
160 }
161
162 /* Writes out the preprocessed file.  Alternates between two tokens,
163    so that we can avoid accidental token pasting.  */
164 static void
165 scan_buffer (pfile)
166      cpp_reader *pfile;
167 {
168   unsigned int index, line;
169   cpp_token tokens[2], *token;
170
171   do
172     {
173       for (index = 0;; index = 1 - index)
174         {
175           token = &tokens[index];
176           cpp_get_token (pfile, token);
177
178           if (token->type == CPP_EOF)
179             break;
180
181           line = cpp_get_line (pfile)->output_line;
182           if (print.lineno != line)
183             {
184               unsigned int col = cpp_get_line (pfile)->col;
185
186               /* Supply enough whitespace to put this token in its original
187                  column.  Don't bother trying to reconstruct tabs; we can't
188                  get it right in general, and nothing ought to care.  (Yes,
189                  some things do care; the fault lies with them.)  */
190               maybe_print_line (line);
191               if (col > 1)
192                 {
193                   if (token->flags & PREV_WHITE)
194                     col--;
195                   while (--col)
196                     putc (' ', print.outf);
197                 }
198             }
199           else if (print.printed
200                    && ! (token->flags & PREV_WHITE)
201                    && ! CPP_OPTION (pfile, lang_asm)
202                    && cpp_avoid_paste (pfile, &tokens[1 - index], token))
203             token->flags |= PREV_WHITE;
204
205           cpp_output_token (token, print.outf);
206           print.printed = 1;
207         }
208     }
209   while (cpp_pop_buffer (pfile) != 0);
210 }
211
212 /* Initialize a cpp_printer structure.  As a side effect, open the
213    output file.  */
214 static int
215 printer_init (pfile)
216      cpp_reader *pfile;
217 {
218   print.last_fname = 0;
219   print.lineno = 0;
220   print.printed = 0;
221   print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
222
223   if (CPP_OPTION (pfile, out_fname) == NULL)
224     CPP_OPTION (pfile, out_fname) = "";
225   
226   if (CPP_OPTION (pfile, out_fname)[0] == '\0')
227     print.outf = stdout;
228   else
229     {
230       print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
231       if (! print.outf)
232         {
233           cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
234           return 1;
235         }
236     }
237   return 0;
238 }
239
240 /* Newline-terminate any output line currently in progress.  If
241    appropriate, write the current line number to the output, or pad
242    with newlines so the output line matches the current line.  */
243 static void
244 maybe_print_line (line)
245      unsigned int line;
246 {
247   /* End the previous line of text (probably only needed until we get
248      multi-line tokens fixed).  */
249   if (print.printed)
250     {
251       putc ('\n', print.outf);
252       print.lineno++;
253       print.printed = 0;
254     }
255
256   if (print.no_line_dirs)
257     return;
258
259   if (line >= print.lineno && line < print.lineno + 8)
260     {
261       while (line > print.lineno)
262         {
263           putc ('\n', print.outf);
264           print.lineno++;
265         }
266     }
267   else
268     {
269       print.lineno = line;
270       print_line ("");
271     }
272 }
273
274 static void
275 print_line (special_flags)
276   const char *special_flags;
277 {
278   /* End any previous line of text.  */
279   if (print.printed)
280     putc ('\n', print.outf);
281   print.printed = 0;
282
283   fprintf (print.outf, "# %u \"%s\"%s%s\n",
284            print.lineno, print.last_fname, special_flags, print.syshdr_flags);
285 }
286
287 static void
288 move_printer (pfile, line, special_flags)
289      cpp_reader *pfile;
290      unsigned int line;
291      const char *special_flags;
292 {
293   print.lineno = line;
294   print.last_fname = pfile->buffer->nominal_fname;
295   print.syshdr_flags = cpp_syshdr_flags (pfile, pfile->buffer);
296   print_line (special_flags);
297 }
298
299 /* Callbacks */
300
301 static void
302 cb_ident (pfile, str)
303      cpp_reader *pfile ATTRIBUTE_UNUSED;
304      const cpp_string * str;
305 {
306   maybe_print_line (cpp_get_line (pfile)->output_line);
307   fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
308   print.lineno++;
309 }
310
311 static void
312 cb_define (pfile, node)
313      cpp_reader *pfile;
314      cpp_hashnode *node;
315 {
316   if (pfile->done_initializing)
317     {
318       maybe_print_line (cpp_get_line (pfile)->output_line);
319       fprintf (print.outf, "#define %s", node->name);
320
321       /* -dD or -g3 command line options.  */
322       if (CPP_OPTION (pfile, debug_output)
323           || CPP_OPTION (pfile, dump_macros) == dump_definitions)
324         fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
325
326       putc ('\n', print.outf);
327       print.lineno++;
328     }
329 }
330
331 static void
332 cb_undef (pfile, node)
333      cpp_reader *pfile;
334      cpp_hashnode *node;
335 {
336   if (pfile->done_initializing)
337     {
338       maybe_print_line (cpp_get_line (pfile)->output_line);
339       fprintf (print.outf, "#undef %s\n", node->name);
340       print.lineno++;
341     }
342 }
343
344 static void
345 cb_include (pfile, dir, header)
346      cpp_reader *pfile ATTRIBUTE_UNUSED;
347      const unsigned char *dir;
348      const cpp_token *header;
349 {
350   maybe_print_line (cpp_get_line (pfile)->output_line);
351   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
352   print.lineno++;
353 }
354
355 static void
356 cb_enter_file (pfile)
357      cpp_reader *pfile;
358 {
359   /* Bring current file to correct line (except main file).  FIXME: we
360      may be using the same buffer via a # NUMBER "file" 1 directive.  */
361   if (pfile->done_initializing && pfile->buffer->prev)
362     maybe_print_line (pfile->buffer->prev->lineno);
363
364   move_printer (pfile, 1, pfile->done_initializing ? " 1": "");
365 }
366
367 static void
368 cb_leave_file (pfile)
369      cpp_reader *pfile;
370 {
371   move_printer (pfile, pfile->buffer->lineno + 1, " 2");
372 }
373
374 static void
375 cb_rename_file (pfile)
376      cpp_reader *pfile;
377 {
378   move_printer (pfile, pfile->buffer->lineno + 1, "");
379 }
380
381 static void
382 cb_def_pragma (pfile)
383      cpp_reader *pfile;
384 {
385   maybe_print_line (cpp_get_line (pfile)->output_line);
386   fputs ("#pragma ", print.outf);
387   cpp_output_line (pfile, print.outf);
388   print.lineno++;
389 }
390
391 static void
392 do_pragma_implementation (pfile)
393      cpp_reader *pfile;
394 {
395   /* Be quiet about `#pragma implementation' for a file only if it hasn't
396      been included yet.  */
397   cpp_token token;
398
399   cpp_start_lookahead (pfile);
400   cpp_get_token (pfile, &token);
401   cpp_stop_lookahead (pfile, 0);
402
403   /* If it's not a string, pass it through and let the front end complain.  */
404   if (token.type == CPP_STRING)
405     {
406      /* Make a NUL-terminated copy of the string.  */
407       char *filename = alloca (token.val.str.len + 1);
408       memcpy (filename, token.val.str.text, token.val.str.len);
409       filename[token.val.str.len] = '\0';
410       if (cpp_included (pfile, filename))
411         cpp_warning (pfile,
412              "#pragma GCC implementation for \"%s\" appears after file is included",
413                      filename);
414     }
415   else if (token.type != CPP_EOF)
416     {
417       cpp_error (pfile, "malformed #pragma GCC implementation");
418       return;
419     }
420
421   /* Output?  This is nasty, but we don't have [GCC] implementation in
422      the buffer.  */
423   if (pfile->cb.def_pragma)
424     {
425       maybe_print_line (cpp_get_line (pfile)->output_line);
426       fputs ("#pragma GCC implementation ", print.outf);
427       cpp_output_line (pfile, print.outf);
428       print.lineno++;
429     }
430 }
431
432 /* Dump out the hash table.  */
433 static int
434 dump_macro (pfile, node, v)
435      cpp_reader *pfile;
436      cpp_hashnode *node;
437      void *v ATTRIBUTE_UNUSED;
438 {
439   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
440     {
441       fprintf (print.outf, "#define %s", node->name);
442       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
443       putc ('\n', print.outf);
444       print.lineno++;
445     }
446
447   return 1;
448 }