OSDN Git Service

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