OSDN Git Service

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