OSDN Git Service

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