OSDN Git Service

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