OSDN Git Service

2002-11-15 Eric Botcazou <ebotcazou@libertysurf.fr>
[pf3gnuchains/gcc-fork.git] / gcc / cppmain.c
1 /* Preprocess only, using cpplib.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002
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 "cpphash.h"
28
29 static void setup_callbacks PARAMS ((cpp_reader *));
30
31 /* General output routines.  */
32 static void scan_translation_unit PARAMS ((cpp_reader *));
33 static void scan_translation_unit_trad PARAMS ((cpp_reader *));
34 static void account_for_newlines PARAMS ((cpp_reader *, const uchar *,
35                                           size_t));
36 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
37
38 static void print_line PARAMS ((cpp_reader *, const struct line_map *,
39                                 unsigned int, const char *));
40 static void maybe_print_line PARAMS ((cpp_reader *, const struct line_map *,
41                                       unsigned int));
42
43 /* Callback routines for the parser.   Most of these are active only
44    in specific modes.  */
45 static void cb_line_change PARAMS ((cpp_reader *, const cpp_token *, int));
46 static void cb_define   PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
47 static void cb_undef    PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
48 static void cb_include  PARAMS ((cpp_reader *, unsigned int,
49                                  const unsigned char *, const cpp_token *));
50 static void cb_ident      PARAMS ((cpp_reader *, unsigned int,
51                                    const cpp_string *));
52 static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
53 static void cb_def_pragma PARAMS ((cpp_reader *, unsigned int));
54
55 /* Preprocess and output.  */
56 void
57 cpp_preprocess_file (pfile, in_fname, out_stream)
58      cpp_reader *pfile;
59      const char *in_fname;
60      FILE *out_stream;
61 {
62   /* Initialize the printer structure.  Setting print.line to -1 here
63      is a trick to guarantee that the first token of the file will
64      cause a linemarker to be output by maybe_print_line.  */
65   pfile->print.line = (unsigned int) -1;
66   pfile->print.printed = 0;
67   pfile->print.prev = 0;
68   pfile->print.map = 0;
69   pfile->print.outf = out_stream;
70
71   setup_callbacks (pfile);
72
73   if (cpp_read_main_file (pfile, in_fname, NULL))
74     {
75       cpp_options *options = &pfile->opts;
76       cpp_finish_options (pfile);
77
78       /* A successful cpp_read_main_file guarantees that we can call
79          cpp_scan_nooutput or cpp_get_token next.  */
80       if (options->no_output)
81         {
82           /* Scan -included buffers, then the main file.  */
83           while (pfile->buffer->prev)
84             cpp_scan_nooutput (pfile);
85           cpp_scan_nooutput (pfile);
86         }
87       else if (options->traditional)
88         scan_translation_unit_trad (pfile);
89       else
90         scan_translation_unit (pfile);
91
92       /* -dM command line option.  Should this be in cpp_finish?  */
93       if (options->dump_macros == dump_only)
94         cpp_forall_identifiers (pfile, dump_macro, NULL);
95     }
96
97   /* Flush any pending output.  */
98   if (pfile->print.printed)
99     putc ('\n', pfile->print.outf);
100 }
101
102 /* Set up the callbacks as appropriate.  */
103 static void
104 setup_callbacks (pfile)
105      cpp_reader *pfile;
106 {
107   cpp_options *options = &pfile->opts;
108   cpp_callbacks *cb = cpp_get_callbacks (pfile);
109
110   if (! options->no_output)
111     {
112       cb->line_change = cb_line_change;
113       /* Don't emit #pragma or #ident directives if we are processing
114          assembly language; the assembler may choke on them.  */
115       if (options->lang != CLK_ASM)
116         {
117           cb->ident      = cb_ident;
118           cb->def_pragma = cb_def_pragma;
119         }
120       if (! options->no_line_commands)
121         cb->file_change = cb_file_change;
122     }
123
124   if (options->dump_includes)
125     cb->include  = cb_include;
126
127   if (options->dump_macros == dump_names
128       || options->dump_macros == dump_definitions)
129     {
130       cb->define = cb_define;
131       cb->undef  = cb_undef;
132     }
133 }
134
135 /* Writes out the preprocessed file, handling spacing and paste
136    avoidance issues.  */
137 static void
138 scan_translation_unit (pfile)
139      cpp_reader *pfile;
140 {
141   bool avoid_paste = false;
142
143   pfile->print.source = NULL;
144   for (;;)
145     {
146       const cpp_token *token = cpp_get_token (pfile);
147
148       if (token->type == CPP_PADDING)
149         {
150           avoid_paste = true;
151           if (pfile->print.source == NULL
152               || (!(pfile->print.source->flags & PREV_WHITE)
153                   && token->val.source == NULL))
154             pfile->print.source = token->val.source;
155           continue;
156         }
157
158       if (token->type == CPP_EOF)
159         break;
160
161       /* Subtle logic to output a space if and only if necessary.  */
162       if (avoid_paste)
163         {
164           if (pfile->print.source == NULL)
165             pfile->print.source = token;
166           if (pfile->print.source->flags & PREV_WHITE
167               || (pfile->print.prev
168                   && cpp_avoid_paste (pfile, pfile->print.prev, token))
169               || (pfile->print.prev == NULL && token->type == CPP_HASH))
170             putc (' ', pfile->print.outf);
171         }
172       else if (token->flags & PREV_WHITE)
173         putc (' ', pfile->print.outf);
174
175       avoid_paste = false;
176       pfile->print.source = NULL;
177       pfile->print.prev = token;
178       cpp_output_token (token, pfile->print.outf);
179
180       if (token->type == CPP_COMMENT)
181         account_for_newlines (pfile, token->val.str.text, token->val.str.len);
182     }
183 }
184
185 /* Adjust pfile->print.line for newlines embedded in output.  */
186 static void
187 account_for_newlines (pfile, str, len)
188      cpp_reader *pfile;
189      const uchar *str;
190      size_t len;
191 {
192   while (len--)
193     if (*str++ == '\n')
194       pfile->print.line++;
195 }
196
197 /* Writes out a traditionally preprocessed file.  */
198 static void
199 scan_translation_unit_trad (pfile)
200      cpp_reader *pfile;
201 {
202   while (_cpp_read_logical_line_trad (pfile))
203     {
204       size_t len = pfile->out.cur - pfile->out.base;
205       maybe_print_line (pfile, pfile->print.map, pfile->out.first_line);
206       fwrite (pfile->out.base, 1, len, pfile->print.outf);
207       pfile->print.printed = 1;
208       if (!CPP_OPTION (pfile, discard_comments))
209         account_for_newlines (pfile, pfile->out.base, len);
210     }
211 }
212
213 /* If the token read on logical line LINE needs to be output on a
214    different line to the current one, output the required newlines or
215    a line marker, and return 1.  Otherwise return 0.  */
216 static void
217 maybe_print_line (pfile, map, line)
218      cpp_reader *pfile;
219      const struct line_map *map;
220      unsigned int line;
221 {
222   /* End the previous line of text.  */
223   if (pfile->print.printed)
224     {
225       putc ('\n', pfile->print.outf);
226       pfile->print.line++;
227       pfile->print.printed = 0;
228     }
229
230   if (line >= pfile->print.line && line < pfile->print.line + 8)
231     {
232       while (line > pfile->print.line)
233         {
234           putc ('\n', pfile->print.outf);
235           pfile->print.line++;
236         }
237     }
238   else
239     print_line (pfile, map, line, "");
240 }
241
242 /* Output a line marker for logical line LINE.  Special flags are "1"
243    or "2" indicating entering or leaving a file.  */
244 static void
245 print_line (pfile, map, line, special_flags)
246      cpp_reader *pfile;
247      const struct line_map *map;
248      unsigned int line;
249      const char *special_flags;
250 {
251   /* End any previous line of text.  */
252   if (pfile->print.printed)
253     putc ('\n', pfile->print.outf);
254   pfile->print.printed = 0;
255
256   pfile->print.line = line;
257   if (! CPP_OPTION (pfile, no_line_commands))
258     {
259       size_t to_file_len = strlen (map->to_file);
260       unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
261       unsigned char *p;
262
263       /* cpp_quote_string does not nul-terminate, so we have to do it
264          ourselves.  */
265       p = cpp_quote_string (to_file_quoted,
266                             (unsigned char *)map->to_file, to_file_len);
267       *p = '\0';
268       fprintf (pfile->print.outf, "# %u \"%s\"%s",
269                SOURCE_LINE (map, pfile->print.line),
270                to_file_quoted, special_flags);
271
272       if (map->sysp == 2)
273         fputs (" 3 4", pfile->print.outf);
274       else if (map->sysp == 1)
275         fputs (" 3", pfile->print.outf);
276
277       putc ('\n', pfile->print.outf);
278     }
279 }
280
281 /* Called when a line of output is started.  TOKEN is the first token
282    of the line, and at end of file will be CPP_EOF.  */
283 static void
284 cb_line_change (pfile, token, parsing_args)
285      cpp_reader *pfile;
286      const cpp_token *token;
287      int parsing_args;
288 {
289   if (token->type == CPP_EOF || parsing_args)
290     return;
291
292   maybe_print_line (pfile, pfile->print.map, token->line);
293   pfile->print.prev = 0;
294   pfile->print.source = 0;
295
296   /* Supply enough spaces to put this token in its original column,
297      one space per column greater than 2, since scan_translation_unit
298      will provide a space if PREV_WHITE.  Don't bother trying to
299      reconstruct tabs; we can't get it right in general, and nothing
300      ought to care.  Some things do care; the fault lies with them.  */
301   if (!CPP_OPTION (pfile, traditional))
302     {
303       pfile->print.printed = 1;
304       if (token->col > 2)
305         {
306           unsigned int spaces = token->col - 2;
307
308           while (spaces--)
309             putc (' ', pfile->print.outf);
310         }
311     }
312 }
313
314 static void
315 cb_ident (pfile, line, str)
316      cpp_reader *pfile;
317      unsigned int line;
318      const cpp_string * str;
319 {
320   maybe_print_line (pfile, pfile->print.map, line);
321   fprintf (pfile->print.outf, "#ident \"%s\"\n", str->text);
322   pfile->print.line++;
323 }
324
325 static void
326 cb_define (pfile, line, node)
327      cpp_reader *pfile;
328      unsigned int line;
329      cpp_hashnode *node;
330 {
331   maybe_print_line (pfile, pfile->print.map, line);
332   fputs ("#define ", pfile->print.outf);
333
334   /* -dD command line option.  */
335   if (CPP_OPTION (pfile, dump_macros) == dump_definitions)
336     fputs ((const char *) cpp_macro_definition (pfile, node),
337            pfile->print.outf);
338   else
339     fputs ((const char *) NODE_NAME (node), pfile->print.outf);
340
341   putc ('\n', pfile->print.outf);
342   pfile->print.line++;
343 }
344
345 static void
346 cb_undef (pfile, line, node)
347      cpp_reader *pfile;
348      unsigned int line;
349      cpp_hashnode *node;
350 {
351   maybe_print_line (pfile, pfile->print.map, line);
352   fprintf (pfile->print.outf, "#undef %s\n", NODE_NAME (node));
353   pfile->print.line++;
354 }
355
356 static void
357 cb_include (pfile, line, dir, header)
358      cpp_reader *pfile;
359      unsigned int line;
360      const unsigned char *dir;
361      const cpp_token *header;
362 {
363   maybe_print_line (pfile, pfile->print.map, line);
364   fprintf (pfile->print.outf, "#%s %s\n", dir,
365            cpp_token_as_text (pfile, header));
366   pfile->print.line++;
367 }
368
369 /* The file name, line number or system header flags have changed, as
370    described in MAP.  From this point on, the old pfile->print.map might be
371    pointing to freed memory, and so must not be dereferenced.  */
372
373 static void
374 cb_file_change (pfile, map)
375      cpp_reader *pfile;
376      const struct line_map *map;
377 {
378   const char *flags = "";
379
380   /* First time?  */
381   if (pfile->print.map == NULL)
382     {
383       /* Avoid printing foo.i when the main file is foo.c.  */
384       if (!CPP_OPTION (pfile, preprocessed))
385         print_line (pfile, map, map->from_line, flags);
386     }
387   else
388     {
389       /* Bring current file to correct line when entering a new file.  */
390       if (map->reason == LC_ENTER)
391         maybe_print_line (pfile, map - 1, map->from_line - 1);
392
393       if (map->reason == LC_ENTER)
394         flags = " 1";
395       else if (map->reason == LC_LEAVE)
396         flags = " 2";
397       print_line (pfile, map, map->from_line, flags);
398     }
399
400   pfile->print.map = map;
401 }
402
403 /* Copy a #pragma directive to the preprocessed output.  */
404 static void
405 cb_def_pragma (pfile, line)
406      cpp_reader *pfile;
407      unsigned int line;
408 {
409   maybe_print_line (pfile, pfile->print.map, line);
410   fputs ("#pragma ", pfile->print.outf);
411   cpp_output_line (pfile, pfile->print.outf);
412   pfile->print.line++;
413 }
414
415 /* Dump out the hash table.  */
416 static int
417 dump_macro (pfile, node, v)
418      cpp_reader *pfile;
419      cpp_hashnode *node;
420      void *v ATTRIBUTE_UNUSED;
421 {
422   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
423     {
424       fputs ("#define ", pfile->print.outf);
425       fputs ((const char *) cpp_macro_definition (pfile, node),
426              pfile->print.outf);
427       putc ('\n', pfile->print.outf);
428       pfile->print.line++;
429     }
430
431   return 1;
432 }