OSDN Git Service

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