OSDN Git Service

* c-parse.in (finish_parse): Add comment about cpp_destroy.
[pf3gnuchains/gcc-fork.git] / gcc / cppmain.c
1 /* CPP main program, using CPP Library.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4    Written by Per Bothner, 1994-95.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20  In other words, you are welcome to use, share and improve this program.
21  You are forbidden to forbid anyone else to use, share and improve
22  what you give them.   Help stamp out software-hoarding!  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "cpplib.h"
27 #include "intl.h"
28
29 /* Encapsulates state used to convert the stream of tokens coming from
30    cpp_get_token back into a text file.  */
31 struct printer
32 {
33   FILE *outf;                   /* stream to write to.  */
34   const char *last_fname;       /* previous file name.  */
35   const char *syshdr_flags;     /* system header flags, if any.  */
36   unsigned int lineno;          /* line currently being written.  */
37   unsigned char printed;        /* nonzero if something output at lineno.  */
38 };
39
40 int main                PARAMS ((int, char **));
41 static void general_init PARAMS ((const char *));
42 static void do_preprocessing PARAMS ((int, char **));
43 static void setup_callbacks PARAMS ((void));
44
45 /* General output routines.  */
46 static void scan_buffer PARAMS ((cpp_reader *));
47 static void check_multiline_token PARAMS ((cpp_string *));
48 static int printer_init PARAMS ((cpp_reader *));
49 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
50
51 static void print_line PARAMS ((const char *));
52 static void maybe_print_line PARAMS ((unsigned int));
53
54 /* Callback routines for the parser.   Most of these are active only
55    in specific modes.  */
56 static void cb_define   PARAMS ((cpp_reader *, cpp_hashnode *));
57 static void cb_undef    PARAMS ((cpp_reader *, cpp_hashnode *));
58 static void cb_include  PARAMS ((cpp_reader *, const unsigned char *,
59                                  const cpp_token *));
60 static void cb_ident      PARAMS ((cpp_reader *, const cpp_string *));
61 static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
62 static void cb_def_pragma PARAMS ((cpp_reader *));
63
64 const char *progname;           /* Needs to be global.  */
65 static cpp_reader *pfile;       /* An opaque handle.  */
66 static cpp_options *options;    /* Options of pfile.  */
67 static struct printer print;
68
69 int
70 main (argc, argv)
71      int argc;
72      char **argv;
73 {
74   general_init (argv[0]);
75
76   /* Contruct a reader with default language GNU C89.  */
77   pfile = cpp_create_reader (CLK_GNUC89);
78   options = cpp_get_options (pfile);
79   
80   do_preprocessing (argc, argv);
81
82   /* Call to cpp_destroy () omitted for performance reasons.  */
83   if (cpp_errors (pfile))
84     return FATAL_EXIT_CODE;
85
86   return SUCCESS_EXIT_CODE;
87 }
88
89 /* Store the program name, and set the locale.  */
90 static void
91 general_init (const char *argv0)
92 {
93   progname = argv0 + strlen (argv0);
94
95   while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
96     --progname;
97
98   xmalloc_set_program_name (progname);
99
100 /* LC_CTYPE determines the character set used by the terminal so it
101    has to be set to output messages correctly.  */
102
103 #ifdef HAVE_LC_MESSAGES
104   setlocale (LC_CTYPE, "");
105   setlocale (LC_MESSAGES, "");
106 #else
107   setlocale (LC_ALL, "");
108 #endif
109
110   (void) bindtextdomain (PACKAGE, localedir);
111   (void) textdomain (PACKAGE);
112 }
113
114 /* Handle switches, preprocess and output.  */
115 static void
116 do_preprocessing (argc, argv)
117      int argc;
118      char **argv;
119 {
120   int argi = 1;  /* Next argument to handle.  */
121
122   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
123   if (CPP_FATAL_ERRORS (pfile))
124     return;
125
126   if (argi < argc)
127     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
128   else
129     cpp_post_options (pfile);
130
131   if (CPP_FATAL_ERRORS (pfile))
132     return;
133
134   /* If cpp_handle_options saw --help or --version on the command
135      line, it will have set pfile->help_only to indicate this.  Exit
136      successfully.  [The library does not exit itself, because
137      e.g. cc1 needs to print its own --help message at this point.]  */
138   if (options->help_only)
139     return;
140
141   /* Open the output now.  We must do so even if no_output is on,
142      because there may be other output than from the actual
143      preprocessing (e.g. from -dM).  */
144   if (printer_init (pfile))
145     return;
146
147   setup_callbacks ();
148
149   if (cpp_start_read (pfile, options->in_fname))
150     {
151       /* A successful cpp_start_read guarantees that we can call
152          cpp_scan_buffer_nooutput or cpp_get_token next.  */
153       if (options->no_output)
154         cpp_scan_buffer_nooutput (pfile, 1);
155       else
156         scan_buffer (pfile);
157
158       /* -dM command line option.  Should this be in cpp_finish?  */
159       if (options->dump_macros == dump_only)
160         cpp_forall_identifiers (pfile, dump_macro, NULL);
161
162       cpp_finish (pfile);
163     }
164
165   /* Flush any pending output.  */
166   if (print.printed)
167     putc ('\n', print.outf);
168
169   if (ferror (print.outf) || fclose (print.outf))
170     cpp_notice_from_errno (pfile, options->out_fname);
171 }
172
173 /* Set up the callbacks as appropriate.  */
174 static void
175 setup_callbacks ()
176 {
177   cpp_callbacks *cb = cpp_get_callbacks (pfile);
178
179   if (! options->no_output)
180     {
181       cb->ident      = cb_ident;
182       cb->def_pragma = cb_def_pragma;
183       if (! options->no_line_commands)
184         cb->file_change = cb_file_change;
185     }
186
187   if (options->dump_includes)
188     cb->include  = cb_include;
189
190   if (options->dump_macros == dump_names
191       || options->dump_macros == dump_definitions)
192     {
193       cb->define = cb_define;
194       cb->undef  = cb_undef;
195       cb->poison = cb_def_pragma;
196     }
197 }
198
199 /* Writes out the preprocessed file.  Alternates between two tokens,
200    so that we can avoid accidental token pasting.  */
201 static void
202 scan_buffer (pfile)
203      cpp_reader *pfile;
204 {
205   unsigned int index, line;
206   cpp_token tokens[2], *token;
207
208   do
209     {
210       for (index = 0;; index = 1 - index)
211         {
212           token = &tokens[index];
213           cpp_get_token (pfile, token);
214
215           if (token->type == CPP_EOF)
216             break;
217
218           line = cpp_get_line (pfile)->output_line;
219           if (print.lineno != line)
220             {
221               unsigned int col = cpp_get_line (pfile)->col;
222
223               /* Supply enough whitespace to put this token in its original
224                  column.  Don't bother trying to reconstruct tabs; we can't
225                  get it right in general, and nothing ought to care.  (Yes,
226                  some things do care; the fault lies with them.)  */
227               maybe_print_line (line);
228               if (col > 1)
229                 {
230                   if (token->flags & PREV_WHITE)
231                     col--;
232                   while (--col)
233                     putc (' ', print.outf);
234                 }
235             }
236           else if (print.printed
237                    && ! (token->flags & PREV_WHITE)
238                    && options->lang != CLK_ASM
239                    && cpp_avoid_paste (pfile, &tokens[1 - index], token))
240             token->flags |= PREV_WHITE;
241
242           cpp_output_token (token, print.outf);
243           print.printed = 1;
244           if (token->type == CPP_STRING || token->type == CPP_WSTRING
245               || token->type == CPP_COMMENT)
246             check_multiline_token (&token->val.str);
247         }
248     }
249   while (cpp_pop_buffer (pfile) != 0);
250 }
251
252 /* Adjust print.lineno for newlines embedded in tokens.  */
253 static void
254 check_multiline_token (str)
255      cpp_string *str;
256 {
257   unsigned int i;
258
259   for (i = 0; i < str->len; i++)
260     if (str->text[i] == '\n')
261       print.lineno++;
262 }
263
264 /* Initialize a cpp_printer structure.  As a side effect, open the
265    output file.  */
266 static int
267 printer_init (pfile)
268      cpp_reader *pfile;
269 {
270   print.last_fname = 0;
271   print.lineno = 0;
272   print.printed = 0;
273
274   if (options->out_fname == NULL)
275     options->out_fname = "";
276   
277   if (options->out_fname[0] == '\0')
278     print.outf = stdout;
279   else
280     {
281       print.outf = fopen (options->out_fname, "w");
282       if (! print.outf)
283         {
284           cpp_notice_from_errno (pfile, options->out_fname);
285           return 1;
286         }
287     }
288
289   return 0;
290 }
291
292 /* Newline-terminate any output line currently in progress.  If
293    appropriate, write the current line number to the output, or pad
294    with newlines so the output line matches the current line.  */
295 static void
296 maybe_print_line (line)
297      unsigned int line;
298 {
299   /* End the previous line of text (probably only needed until we get
300      multi-line tokens fixed).  */
301   if (print.printed)
302     {
303       putc ('\n', print.outf);
304       print.lineno++;
305       print.printed = 0;
306     }
307
308   if (options->no_line_commands)
309     {
310       print.lineno = line;
311       return;
312     }
313
314   /* print.lineno is zero if this is the first token of the file.  We
315      handle this specially, so that a first line of "# 1 "foo.c" in
316      file foo.i outputs just the foo.c line, and not a foo.i line.  */
317   if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
318     {
319       while (line > print.lineno)
320         {
321           putc ('\n', print.outf);
322           print.lineno++;
323         }
324     }
325   else
326     {
327       print.lineno = line;
328       print_line ("");
329     }
330 }
331
332 static void
333 print_line (special_flags)
334   const char *special_flags;
335 {
336   /* End any previous line of text.  */
337   if (print.printed)
338     putc ('\n', print.outf);
339   print.printed = 0;
340
341   fprintf (print.outf, "# %u \"%s\"%s%s\n",
342            print.lineno, print.last_fname, special_flags, print.syshdr_flags);
343 }
344
345 /* Callbacks.  */
346
347 static void
348 cb_ident (pfile, str)
349      cpp_reader *pfile ATTRIBUTE_UNUSED;
350      const cpp_string * str;
351 {
352   maybe_print_line (cpp_get_line (pfile)->output_line);
353   fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
354   print.lineno++;
355 }
356
357 static void
358 cb_define (pfile, node)
359      cpp_reader *pfile;
360      cpp_hashnode *node;
361 {
362   maybe_print_line (cpp_get_line (pfile)->output_line);
363   fprintf (print.outf, "#define %s", node->name);
364
365   /* -dD command line option.  */
366   if (options->dump_macros == dump_definitions)
367     fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
368
369   putc ('\n', print.outf);
370   print.lineno++;
371 }
372
373 static void
374 cb_undef (pfile, node)
375      cpp_reader *pfile;
376      cpp_hashnode *node;
377 {
378   maybe_print_line (cpp_get_line (pfile)->output_line);
379   fprintf (print.outf, "#undef %s\n", node->name);
380   print.lineno++;
381 }
382
383 static void
384 cb_include (pfile, dir, header)
385      cpp_reader *pfile ATTRIBUTE_UNUSED;
386      const unsigned char *dir;
387      const cpp_token *header;
388 {
389   maybe_print_line (cpp_get_line (pfile)->output_line);
390   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
391   print.lineno++;
392 }
393
394 static void
395 cb_file_change (pfile, fc)
396      cpp_reader *pfile ATTRIBUTE_UNUSED;
397      const cpp_file_change *fc;
398 {
399   /* Bring current file to correct line (except first file).  */
400   if (fc->reason == FC_ENTER && fc->from.filename)
401     maybe_print_line (fc->from.lineno);
402
403   print.last_fname = fc->to.filename;
404   if (fc->externc)
405     print.syshdr_flags = " 3 4";
406   else if (fc->sysp)
407     print.syshdr_flags = " 3";
408   else
409     print.syshdr_flags = "";
410
411   if (print.lineno)
412     {
413       const char *flags = "";
414
415       print.lineno = fc->to.lineno;
416       if (fc->reason == FC_ENTER)
417         flags = " 1";
418       else if (fc->reason == FC_LEAVE)
419         flags = " 2";
420
421       if (! options->no_line_commands)
422         print_line (flags);
423     }
424 }
425
426 static void
427 cb_def_pragma (pfile)
428      cpp_reader *pfile;
429 {
430   maybe_print_line (cpp_get_line (pfile)->output_line);
431   fputs ("#pragma ", print.outf);
432   cpp_output_line (pfile, print.outf);
433   print.lineno++;
434 }
435
436 /* Dump out the hash table.  */
437 static int
438 dump_macro (pfile, node, v)
439      cpp_reader *pfile;
440      cpp_hashnode *node;
441      void *v ATTRIBUTE_UNUSED;
442 {
443   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
444     {
445       fprintf (print.outf, "#define %s", node->name);
446       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
447       putc ('\n', print.outf);
448       print.lineno++;
449     }
450
451   return 1;
452 }