OSDN Git Service

* cppinit.c (cpp_handle_option): help_only is now part of the
[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 (CPP_OPTION (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   maybe_print_line (cpp_get_line (pfile)->output_line);
348   fprintf (print.outf, "#define %s", node->name);
349
350   /* -dD command line option.  */
351   if (CPP_OPTION (pfile, dump_macros) == dump_definitions)
352     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
353
354   putc ('\n', print.outf);
355   print.lineno++;
356 }
357
358 static void
359 cb_undef (pfile, node)
360      cpp_reader *pfile;
361      cpp_hashnode *node;
362 {
363   maybe_print_line (cpp_get_line (pfile)->output_line);
364   fprintf (print.outf, "#undef %s\n", node->name);
365   print.lineno++;
366 }
367
368 static void
369 cb_include (pfile, dir, header)
370      cpp_reader *pfile ATTRIBUTE_UNUSED;
371      const unsigned char *dir;
372      const cpp_token *header;
373 {
374   maybe_print_line (cpp_get_line (pfile)->output_line);
375   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
376   print.lineno++;
377 }
378
379 static void
380 cb_file_change (pfile, fc)
381      cpp_reader *pfile ATTRIBUTE_UNUSED;
382      const cpp_file_change *fc;
383 {
384   /* Bring current file to correct line (except first file).  */
385   if (fc->reason == FC_ENTER && fc->from.filename)
386     maybe_print_line (fc->from.lineno);
387
388   print.last_fname = fc->to.filename;
389   if (fc->externc)
390     print.syshdr_flags = " 3 4";
391   else if (fc->sysp)
392     print.syshdr_flags = " 3";
393   else
394     print.syshdr_flags = "";
395
396   if (print.lineno)
397     {
398       const char *flags = "";
399
400       print.lineno = fc->to.lineno;
401       if (fc->reason == FC_ENTER)
402         flags = " 1";
403       else if (fc->reason == FC_LEAVE)
404         flags = " 2";
405       print_line (flags);
406     }
407 }
408
409 static void
410 cb_def_pragma (pfile)
411      cpp_reader *pfile;
412 {
413   maybe_print_line (cpp_get_line (pfile)->output_line);
414   fputs ("#pragma ", print.outf);
415   cpp_output_line (pfile, print.outf);
416   print.lineno++;
417 }
418
419 static void
420 do_pragma_implementation (pfile)
421      cpp_reader *pfile;
422 {
423   /* Be quiet about `#pragma implementation' for a file only if it hasn't
424      been included yet.  */
425   cpp_token token;
426
427   cpp_start_lookahead (pfile);
428   cpp_get_token (pfile, &token);
429   cpp_stop_lookahead (pfile, 0);
430
431   /* If it's not a string, pass it through and let the front end complain.  */
432   if (token.type == CPP_STRING)
433     {
434      /* Make a NUL-terminated copy of the string.  */
435       char *filename = alloca (token.val.str.len + 1);
436       memcpy (filename, token.val.str.text, token.val.str.len);
437       filename[token.val.str.len] = '\0';
438       if (cpp_included (pfile, filename))
439         cpp_warning (pfile,
440              "#pragma GCC implementation for \"%s\" appears after file is included",
441                      filename);
442     }
443   else if (token.type != CPP_EOF)
444     {
445       cpp_error (pfile, "malformed #pragma GCC implementation");
446       return;
447     }
448
449   /* Output?  This is nasty, but we don't have [GCC] implementation in
450      the buffer.  */
451   if (pfile->cb.def_pragma)
452     {
453       maybe_print_line (cpp_get_line (pfile)->output_line);
454       fputs ("#pragma GCC implementation ", print.outf);
455       cpp_output_line (pfile, print.outf);
456       print.lineno++;
457     }
458 }
459
460 /* Dump out the hash table.  */
461 static int
462 dump_macro (pfile, node, v)
463      cpp_reader *pfile;
464      cpp_hashnode *node;
465      void *v ATTRIBUTE_UNUSED;
466 {
467   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
468     {
469       fprintf (print.outf, "#define %s", node->name);
470       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
471       putc ('\n', print.outf);
472       print.lineno++;
473     }
474
475   return 1;
476 }