OSDN Git Service

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