OSDN Git Service

* cppinit.c (OPT_g): Remove.
[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 static void general_init PARAMS ((const char *));
42 static void setup_callbacks PARAMS ((void));
43
44 /* General output routines.  */
45 static void scan_buffer PARAMS ((cpp_reader *));
46 static void check_multiline_token PARAMS ((cpp_string *));
47 static int printer_init PARAMS ((cpp_reader *));
48 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
49
50 static void print_line PARAMS ((const char *));
51 static void maybe_print_line PARAMS ((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 *, cpp_hashnode *));
56 static void cb_undef    PARAMS ((cpp_reader *, cpp_hashnode *));
57 static void cb_include  PARAMS ((cpp_reader *, const unsigned char *,
58                                  const cpp_token *));
59 static void cb_ident      PARAMS ((cpp_reader *, const cpp_string *));
60 static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
61 static void cb_def_pragma PARAMS ((cpp_reader *));
62 static void do_pragma_implementation PARAMS ((cpp_reader *));
63
64 const char *progname;           /* Needs to be global.  */
65 static cpp_reader *pfile;
66 static struct printer print;
67
68 int
69 main (argc, argv)
70      int argc;
71      char **argv;
72 {
73   int argi = 1;  /* Next argument to handle.  */
74
75   general_init (argv[0]);
76   /* Default language is GNU C89.  */
77   pfile = cpp_create_reader (CLK_GNUC89);
78   
79   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
80   if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
81     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
82   cpp_post_options (pfile);
83   if (CPP_FATAL_ERRORS (pfile))
84     return (FATAL_EXIT_CODE);
85
86   /* If cpp_handle_options saw --help or --version on the command
87      line, it will have set pfile->help_only to indicate this.  Exit
88      successfully.  [The library does not exit itself, because
89      e.g. cc1 needs to print its own --help message at this point.]  */
90   if (pfile->help_only)
91     return (SUCCESS_EXIT_CODE);
92
93   /* Open the output now.  We must do so even if no_output is on,
94      because there may be other output than from the actual
95      preprocessing (e.g. from -dM).  */
96   if (printer_init (pfile))
97     return (FATAL_EXIT_CODE);
98
99   setup_callbacks ();
100
101   if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
102     return (FATAL_EXIT_CODE);
103
104   if (CPP_BUFFER (pfile))
105     {
106       if (CPP_OPTION (pfile, no_output))
107         cpp_scan_buffer_nooutput (pfile, 1);
108       else
109         scan_buffer (pfile);
110     }
111
112   /* -dM command line option.  */
113   if (CPP_OPTION (pfile, dump_macros) == dump_only)
114     cpp_forall_identifiers (pfile, dump_macro, NULL);
115
116   cpp_finish (pfile);
117   cpp_cleanup (pfile);
118
119   /* Flush any pending output.  */
120   if (print.printed)
121     putc ('\n', print.outf);
122   if (ferror (print.outf) || fclose (print.outf))
123     cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
124
125   if (pfile->errors)
126     return (FATAL_EXIT_CODE);
127   return (SUCCESS_EXIT_CODE);
128 }
129
130 /* Store the program name, and set the locale.  */
131 static void
132 general_init (const char *argv0)
133 {
134   progname = argv0 + strlen (argv0);
135
136   while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
137     --progname;
138
139   xmalloc_set_program_name (progname);
140
141 /* LC_CTYPE determines the character set used by the terminal so it has be set
142    to output messages correctly.  */
143
144 #ifdef HAVE_LC_MESSAGES
145   setlocale (LC_CTYPE, "");
146   setlocale (LC_MESSAGES, "");
147 #else
148   setlocale (LC_ALL, "");
149 #endif
150
151   (void) bindtextdomain (PACKAGE, localedir);
152   (void) textdomain (PACKAGE);
153 }
154
155 /* Set up the callbacks and register the pragmas we handle.  */
156 static void
157 setup_callbacks ()
158 {
159   /* Set callbacks.  */
160   if (! CPP_OPTION (pfile, no_output))
161     {
162       pfile->cb.ident      = cb_ident;
163       pfile->cb.def_pragma = cb_def_pragma;
164       if (! CPP_OPTION (pfile, no_line_commands))
165         pfile->cb.file_change = cb_file_change;
166     }
167
168   if (CPP_OPTION (pfile, dump_includes))
169     pfile->cb.include  = cb_include;
170
171   if (CPP_OPTION (pfile, dump_macros) == dump_names
172       || CPP_OPTION (pfile, dump_macros) == dump_definitions)
173     {
174       pfile->cb.define = cb_define;
175       pfile->cb.undef  = cb_undef;
176       pfile->cb.poison = cb_def_pragma;
177     }
178
179   /* Register one #pragma which needs special handling.  */
180   cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
181   cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
182 }
183
184 /* Writes out the preprocessed file.  Alternates between two tokens,
185    so that we can avoid accidental token pasting.  */
186 static void
187 scan_buffer (pfile)
188      cpp_reader *pfile;
189 {
190   unsigned int index, line;
191   cpp_token tokens[2], *token;
192
193   do
194     {
195       for (index = 0;; index = 1 - index)
196         {
197           token = &tokens[index];
198           cpp_get_token (pfile, token);
199
200           if (token->type == CPP_EOF)
201             break;
202
203           line = cpp_get_line (pfile)->output_line;
204           if (print.lineno != line)
205             {
206               unsigned int col = cpp_get_line (pfile)->col;
207
208               /* Supply enough whitespace to put this token in its original
209                  column.  Don't bother trying to reconstruct tabs; we can't
210                  get it right in general, and nothing ought to care.  (Yes,
211                  some things do care; the fault lies with them.)  */
212               maybe_print_line (line);
213               if (col > 1)
214                 {
215                   if (token->flags & PREV_WHITE)
216                     col--;
217                   while (--col)
218                     putc (' ', print.outf);
219                 }
220             }
221           else if (print.printed
222                    && ! (token->flags & PREV_WHITE)
223                    && CPP_OPTION (pfile, lang) != CLK_ASM
224                    && cpp_avoid_paste (pfile, &tokens[1 - index], token))
225             token->flags |= PREV_WHITE;
226
227           cpp_output_token (token, print.outf);
228           print.printed = 1;
229           if (token->type == CPP_STRING || token->type == CPP_WSTRING
230               || token->type == CPP_COMMENT)
231             check_multiline_token (&token->val.str);
232         }
233     }
234   while (cpp_pop_buffer (pfile) != 0);
235 }
236
237 /* Adjust print.lineno for newlines embedded in tokens.  */
238 static void
239 check_multiline_token (str)
240      cpp_string *str;
241 {
242   unsigned int i;
243
244   for (i = 0; i < str->len; i++)
245     if (str->text[i] == '\n')
246       print.lineno++;
247 }
248
249 /* Initialize a cpp_printer structure.  As a side effect, open the
250    output file.  */
251 static int
252 printer_init (pfile)
253      cpp_reader *pfile;
254 {
255   print.last_fname = 0;
256   print.lineno = 0;
257   print.printed = 0;
258   print.no_line_dirs = CPP_OPTION (pfile, no_line_commands);
259
260   if (CPP_OPTION (pfile, out_fname) == NULL)
261     CPP_OPTION (pfile, out_fname) = "";
262   
263   if (CPP_OPTION (pfile, out_fname)[0] == '\0')
264     print.outf = stdout;
265   else
266     {
267       print.outf = fopen (CPP_OPTION (pfile, out_fname), "w");
268       if (! print.outf)
269         {
270           cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
271           return 1;
272         }
273     }
274   return 0;
275 }
276
277 /* Newline-terminate any output line currently in progress.  If
278    appropriate, write the current line number to the output, or pad
279    with newlines so the output line matches the current line.  */
280 static void
281 maybe_print_line (line)
282      unsigned int line;
283 {
284   /* End the previous line of text (probably only needed until we get
285      multi-line tokens fixed).  */
286   if (print.printed)
287     {
288       putc ('\n', print.outf);
289       print.lineno++;
290       print.printed = 0;
291     }
292
293   if (print.no_line_dirs)
294     {
295       print.lineno = line;
296       return;
297     }
298
299   /* print.lineno is zero if this is the first token of the file.  We
300      handle this specially, so that a first line of "# 1 "foo.c" in
301      file foo.i outputs just the foo.c line, and not a foo.i line.  */
302   if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
303     {
304       while (line > print.lineno)
305         {
306           putc ('\n', print.outf);
307           print.lineno++;
308         }
309     }
310   else
311     {
312       print.lineno = line;
313       print_line ("");
314     }
315 }
316
317 static void
318 print_line (special_flags)
319   const char *special_flags;
320 {
321   /* End any previous line of text.  */
322   if (print.printed)
323     putc ('\n', print.outf);
324   print.printed = 0;
325
326   fprintf (print.outf, "# %u \"%s\"%s%s\n",
327            print.lineno, print.last_fname, special_flags, print.syshdr_flags);
328 }
329
330 /* Callbacks */
331
332 static void
333 cb_ident (pfile, str)
334      cpp_reader *pfile ATTRIBUTE_UNUSED;
335      const cpp_string * str;
336 {
337   maybe_print_line (cpp_get_line (pfile)->output_line);
338   fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
339   print.lineno++;
340 }
341
342 static void
343 cb_define (pfile, node)
344      cpp_reader *pfile;
345      cpp_hashnode *node;
346 {
347   if (pfile->done_initializing)
348     {
349       maybe_print_line (cpp_get_line (pfile)->output_line);
350       fprintf (print.outf, "#define %s", node->name);
351
352       /* -dD command line option.  */
353       if (CPP_OPTION (pfile, dump_macros) == dump_definitions)
354         fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
355
356       putc ('\n', print.outf);
357       print.lineno++;
358     }
359 }
360
361 static void
362 cb_undef (pfile, node)
363      cpp_reader *pfile;
364      cpp_hashnode *node;
365 {
366   if (pfile->done_initializing)
367     {
368       maybe_print_line (cpp_get_line (pfile)->output_line);
369       fprintf (print.outf, "#undef %s\n", node->name);
370       print.lineno++;
371     }
372 }
373
374 static void
375 cb_include (pfile, dir, header)
376      cpp_reader *pfile ATTRIBUTE_UNUSED;
377      const unsigned char *dir;
378      const cpp_token *header;
379 {
380   maybe_print_line (cpp_get_line (pfile)->output_line);
381   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
382   print.lineno++;
383 }
384
385 static void
386 cb_file_change (pfile, fc)
387      cpp_reader *pfile ATTRIBUTE_UNUSED;
388      const cpp_file_change *fc;
389 {
390   /* Bring current file to correct line (except first file).  */
391   if (fc->reason == FC_ENTER && fc->from.filename)
392     maybe_print_line (fc->from.lineno);
393
394   print.last_fname = fc->to.filename;
395   if (fc->externc)
396     print.syshdr_flags = " 3 4";
397   else if (fc->sysp)
398     print.syshdr_flags = " 3";
399   else
400     print.syshdr_flags = "";
401
402   if (print.lineno)
403     {
404       const char *flags = "";
405
406       print.lineno = fc->to.lineno;
407       if (fc->reason == FC_ENTER)
408         flags = " 1";
409       else if (fc->reason == FC_LEAVE)
410         flags = " 2";
411       print_line (flags);
412     }
413 }
414
415 static void
416 cb_def_pragma (pfile)
417      cpp_reader *pfile;
418 {
419   maybe_print_line (cpp_get_line (pfile)->output_line);
420   fputs ("#pragma ", print.outf);
421   cpp_output_line (pfile, print.outf);
422   print.lineno++;
423 }
424
425 static void
426 do_pragma_implementation (pfile)
427      cpp_reader *pfile;
428 {
429   /* Be quiet about `#pragma implementation' for a file only if it hasn't
430      been included yet.  */
431   cpp_token token;
432
433   cpp_start_lookahead (pfile);
434   cpp_get_token (pfile, &token);
435   cpp_stop_lookahead (pfile, 0);
436
437   /* If it's not a string, pass it through and let the front end complain.  */
438   if (token.type == CPP_STRING)
439     {
440      /* Make a NUL-terminated copy of the string.  */
441       char *filename = alloca (token.val.str.len + 1);
442       memcpy (filename, token.val.str.text, token.val.str.len);
443       filename[token.val.str.len] = '\0';
444       if (cpp_included (pfile, filename))
445         cpp_warning (pfile,
446              "#pragma GCC implementation for \"%s\" appears after file is included",
447                      filename);
448     }
449   else if (token.type != CPP_EOF)
450     {
451       cpp_error (pfile, "malformed #pragma GCC implementation");
452       return;
453     }
454
455   /* Output?  This is nasty, but we don't have [GCC] implementation in
456      the buffer.  */
457   if (pfile->cb.def_pragma)
458     {
459       maybe_print_line (cpp_get_line (pfile)->output_line);
460       fputs ("#pragma GCC implementation ", print.outf);
461       cpp_output_line (pfile, print.outf);
462       print.lineno++;
463     }
464 }
465
466 /* Dump out the hash table.  */
467 static int
468 dump_macro (pfile, node, v)
469      cpp_reader *pfile;
470      cpp_hashnode *node;
471      void *v ATTRIBUTE_UNUSED;
472 {
473   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
474     {
475       fprintf (print.outf, "#define %s", node->name);
476       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
477       putc ('\n', print.outf);
478       print.lineno++;
479     }
480
481   return 1;
482 }