OSDN Git Service

* cpplib.h (struct cpp_reader): Remove lang_asm.
[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   /* Default language is GNU C89.  */
91   cpp_reader_init (pfile, CLK_GNUC89);
92   
93   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
94   if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
95     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
96   if (CPP_FATAL_ERRORS (pfile))
97     return (FATAL_EXIT_CODE);
98
99   /* Open the output now.  We must do so even if no_output is on,
100      because there may be other output than from the actual
101      preprocessing (e.g. from -dM).  */
102   if (printer_init (pfile))
103     return (FATAL_EXIT_CODE);
104
105   /* Set callbacks.  */
106   if (! CPP_OPTION (pfile, no_output))
107     {
108       pfile->cb.ident      = cb_ident;
109       pfile->cb.def_pragma = cb_def_pragma;
110       if (! CPP_OPTION (pfile, no_line_commands))
111         {
112           pfile->cb.enter_file = cb_enter_file;
113           pfile->cb.leave_file = cb_leave_file;
114           pfile->cb.rename_file = cb_rename_file;
115         }
116     }
117
118   if (CPP_OPTION (pfile, dump_includes))
119     pfile->cb.include  = cb_include;
120
121   if (CPP_OPTION (pfile, debug_output)
122       || CPP_OPTION (pfile, dump_macros) == dump_names
123       || CPP_OPTION (pfile, dump_macros) == dump_definitions)
124     {
125       pfile->cb.define = cb_define;
126       pfile->cb.undef  = cb_undef;
127       pfile->cb.poison = cb_def_pragma;
128     }
129
130   /* Register one #pragma which needs special handling.  */
131   cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
132   cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
133
134   if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
135     return (FATAL_EXIT_CODE);
136
137   if (CPP_BUFFER (pfile))
138     {
139       if (CPP_OPTION (pfile, no_output))
140         cpp_scan_buffer_nooutput (pfile);
141       else
142         scan_buffer (pfile);
143     }
144
145   /* -dM command line option.  */
146   if (CPP_OPTION (pfile, dump_macros) == dump_only)
147     cpp_forall_identifiers (pfile, dump_macro, NULL);
148
149   cpp_finish (pfile);
150   cpp_cleanup (pfile);
151
152   /* Flush any pending output.  */
153   if (print.printed)
154     putc ('\n', print.outf);
155   if (ferror (print.outf) || fclose (print.outf))
156     cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
157
158   if (parse_in.errors)
159     return (FATAL_EXIT_CODE);
160   return (SUCCESS_EXIT_CODE);
161 }
162
163 /* Writes out the preprocessed file.  Alternates between two tokens,
164    so that we can avoid accidental token pasting.  */
165 static void
166 scan_buffer (pfile)
167      cpp_reader *pfile;
168 {
169   unsigned int index, line;
170   cpp_token tokens[2], *token;
171
172   do
173     {
174       for (index = 0;; index = 1 - index)
175         {
176           token = &tokens[index];
177           cpp_get_token (pfile, token);
178
179           if (token->type == CPP_EOF)
180             break;
181
182           line = cpp_get_line (pfile)->output_line;
183           if (print.lineno != line)
184             {
185               unsigned int col = cpp_get_line (pfile)->col;
186
187               /* Supply enough whitespace to put this token in its original
188                  column.  Don't bother trying to reconstruct tabs; we can't
189                  get it right in general, and nothing ought to care.  (Yes,
190                  some things do care; the fault lies with them.)  */
191               maybe_print_line (line);
192               if (col > 1)
193                 {
194                   if (token->flags & PREV_WHITE)
195                     col--;
196                   while (--col)
197                     putc (' ', print.outf);
198                 }
199             }
200           else if (print.printed
201                    && ! (token->flags & PREV_WHITE)
202                    && CPP_OPTION (pfile, lang) != CLK_ASM
203                    && cpp_avoid_paste (pfile, &tokens[1 - index], token))
204             token->flags |= PREV_WHITE;
205
206           cpp_output_token (token, print.outf);
207           print.printed = 1;
208         }
209     }
210   while (cpp_pop_buffer (pfile) != 0);
211 }
212
213 /* Initialize a cpp_printer structure.  As a side effect, open the
214    output file.  */
215 static int
216 printer_init (pfile)
217      cpp_reader *pfile;
218 {
219   print.last_fname = 0;
220   print.lineno = 0;
221   print.printed = 0;
222   print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
223
224   if (CPP_OPTION (pfile, out_fname) == NULL)
225     CPP_OPTION (pfile, out_fname) = "";
226   
227   if (CPP_OPTION (pfile, out_fname)[0] == '\0')
228     print.outf = stdout;
229   else
230     {
231       print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
232       if (! print.outf)
233         {
234           cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
235           return 1;
236         }
237     }
238   return 0;
239 }
240
241 /* Newline-terminate any output line currently in progress.  If
242    appropriate, write the current line number to the output, or pad
243    with newlines so the output line matches the current line.  */
244 static void
245 maybe_print_line (line)
246      unsigned int line;
247 {
248   /* End the previous line of text (probably only needed until we get
249      multi-line tokens fixed).  */
250   if (print.printed)
251     {
252       putc ('\n', print.outf);
253       print.lineno++;
254       print.printed = 0;
255     }
256
257   if (print.no_line_dirs)
258     return;
259
260   if (line >= print.lineno && line < print.lineno + 8)
261     {
262       while (line > print.lineno)
263         {
264           putc ('\n', print.outf);
265           print.lineno++;
266         }
267     }
268   else
269     {
270       print.lineno = line;
271       print_line ("");
272     }
273 }
274
275 static void
276 print_line (special_flags)
277   const char *special_flags;
278 {
279   /* End any previous line of text.  */
280   if (print.printed)
281     putc ('\n', print.outf);
282   print.printed = 0;
283
284   fprintf (print.outf, "# %u \"%s\"%s%s\n",
285            print.lineno, print.last_fname, special_flags, print.syshdr_flags);
286 }
287
288 static void
289 move_printer (pfile, line, special_flags)
290      cpp_reader *pfile;
291      unsigned int line;
292      const char *special_flags;
293 {
294   print.lineno = line;
295   print.last_fname = pfile->buffer->nominal_fname;
296   print.syshdr_flags = cpp_syshdr_flags (pfile, pfile->buffer);
297   print_line (special_flags);
298 }
299
300 /* Callbacks */
301
302 static void
303 cb_ident (pfile, str)
304      cpp_reader *pfile ATTRIBUTE_UNUSED;
305      const cpp_string * str;
306 {
307   maybe_print_line (cpp_get_line (pfile)->output_line);
308   fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
309   print.lineno++;
310 }
311
312 static void
313 cb_define (pfile, node)
314      cpp_reader *pfile;
315      cpp_hashnode *node;
316 {
317   if (pfile->done_initializing)
318     {
319       maybe_print_line (cpp_get_line (pfile)->output_line);
320       fprintf (print.outf, "#define %s", node->name);
321
322       /* -dD or -g3 command line options.  */
323       if (CPP_OPTION (pfile, debug_output)
324           || CPP_OPTION (pfile, dump_macros) == dump_definitions)
325         fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
326
327       putc ('\n', print.outf);
328       print.lineno++;
329     }
330 }
331
332 static void
333 cb_undef (pfile, node)
334      cpp_reader *pfile;
335      cpp_hashnode *node;
336 {
337   if (pfile->done_initializing)
338     {
339       maybe_print_line (cpp_get_line (pfile)->output_line);
340       fprintf (print.outf, "#undef %s\n", node->name);
341       print.lineno++;
342     }
343 }
344
345 static void
346 cb_include (pfile, dir, header)
347      cpp_reader *pfile ATTRIBUTE_UNUSED;
348      const unsigned char *dir;
349      const cpp_token *header;
350 {
351   maybe_print_line (cpp_get_line (pfile)->output_line);
352   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
353   print.lineno++;
354 }
355
356 static void
357 cb_enter_file (pfile)
358      cpp_reader *pfile;
359 {
360   /* Bring current file to correct line (except main file).  FIXME: we
361      may be using the same buffer via a # NUMBER "file" 1 directive.  */
362   if (pfile->done_initializing && pfile->buffer->prev)
363     maybe_print_line (pfile->buffer->prev->lineno);
364
365   move_printer (pfile, 1, pfile->done_initializing ? " 1": "");
366 }
367
368 static void
369 cb_leave_file (pfile)
370      cpp_reader *pfile;
371 {
372   move_printer (pfile, pfile->buffer->lineno + 1, " 2");
373 }
374
375 static void
376 cb_rename_file (pfile)
377      cpp_reader *pfile;
378 {
379   move_printer (pfile, pfile->buffer->lineno + 1, "");
380 }
381
382 static void
383 cb_def_pragma (pfile)
384      cpp_reader *pfile;
385 {
386   maybe_print_line (cpp_get_line (pfile)->output_line);
387   fputs ("#pragma ", print.outf);
388   cpp_output_line (pfile, print.outf);
389   print.lineno++;
390 }
391
392 static void
393 do_pragma_implementation (pfile)
394      cpp_reader *pfile;
395 {
396   /* Be quiet about `#pragma implementation' for a file only if it hasn't
397      been included yet.  */
398   cpp_token token;
399
400   cpp_start_lookahead (pfile);
401   cpp_get_token (pfile, &token);
402   cpp_stop_lookahead (pfile, 0);
403
404   /* If it's not a string, pass it through and let the front end complain.  */
405   if (token.type == CPP_STRING)
406     {
407      /* Make a NUL-terminated copy of the string.  */
408       char *filename = alloca (token.val.str.len + 1);
409       memcpy (filename, token.val.str.text, token.val.str.len);
410       filename[token.val.str.len] = '\0';
411       if (cpp_included (pfile, filename))
412         cpp_warning (pfile,
413              "#pragma GCC implementation for \"%s\" appears after file is included",
414                      filename);
415     }
416   else if (token.type != CPP_EOF)
417     {
418       cpp_error (pfile, "malformed #pragma GCC implementation");
419       return;
420     }
421
422   /* Output?  This is nasty, but we don't have [GCC] implementation in
423      the buffer.  */
424   if (pfile->cb.def_pragma)
425     {
426       maybe_print_line (cpp_get_line (pfile)->output_line);
427       fputs ("#pragma GCC implementation ", print.outf);
428       cpp_output_line (pfile, print.outf);
429       print.lineno++;
430     }
431 }
432
433 /* Dump out the hash table.  */
434 static int
435 dump_macro (pfile, node, v)
436      cpp_reader *pfile;
437      cpp_hashnode *node;
438      void *v ATTRIBUTE_UNUSED;
439 {
440   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
441     {
442       fprintf (print.outf, "#define %s", node->name);
443       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
444       putc ('\n', print.outf);
445       print.lineno++;
446     }
447
448   return 1;
449 }