OSDN Git Service

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