2003-03-13 Aldy Hernandez <aldyh@redhat.com>
[official-gcc.git] / gcc / c-ppoutput.c
blob14ae31bb0b6a0f14731500b2e85f4639af2a1b11
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.
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.
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.
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. */
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. */
30 /* Encapsulates state used to convert a stream of tokens into a text
31 file. */
32 static struct
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;
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 *));
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));
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));
64 /* Preprocess and output. */
65 void
66 preprocess_file (pfile)
67 cpp_reader *pfile;
69 cpp_finish_options (pfile);
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)
75 /* Scan -included buffers, then the main file. */
76 while (pfile->buffer->prev)
77 cpp_scan_nooutput (pfile);
78 cpp_scan_nooutput (pfile);
80 else if (cpp_get_options (pfile)->traditional)
81 scan_translation_unit_trad (pfile);
82 else
83 scan_translation_unit (pfile);
85 /* -dM command line option. Should this be elsewhere? */
86 if (flag_dump_macros == 'M')
87 cpp_forall_identifiers (pfile, dump_macro, NULL);
89 /* Flush any pending output. */
90 if (print.printed)
91 putc ('\n', print.outf);
94 /* Set up the callbacks as appropriate. */
95 void
96 init_pp_output (out_stream)
97 FILE *out_stream;
99 cpp_callbacks *cb = cpp_get_callbacks (parse_in);
101 cb->register_builtins = cb_register_builtins;
103 if (!flag_no_output)
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)
110 cb->ident = cb_ident;
111 cb->def_pragma = cb_def_pragma;
113 if (!flag_no_line_commands)
114 cb->file_change = cb_file_change;
117 if (flag_dump_includes)
118 cb->include = cb_include;
120 if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
122 cb->define = cb_define;
123 cb->undef = cb_undef;
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;
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;
142 bool avoid_paste = false;
144 print.source = NULL;
145 for (;;)
147 const cpp_token *token = cpp_get_token (pfile);
149 if (token->type == CPP_PADDING)
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;
159 if (token->type == CPP_EOF)
160 break;
162 /* Subtle logic to output a space if and only if necessary. */
163 if (avoid_paste)
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);
173 else if (token->flags & PREV_WHITE)
174 putc (' ', print.outf);
176 avoid_paste = false;
177 print.source = NULL;
178 print.prev = token;
179 cpp_output_token (token, print.outf);
181 if (token->type == CPP_COMMENT)
182 account_for_newlines (token->val.str.text, token->val.str.len);
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;
192 while (len--)
193 if (*str++ == '\n')
194 print.line++;
197 /* Writes out a traditionally preprocessed file. */
198 static void
199 scan_translation_unit_trad (pfile)
200 cpp_reader *pfile;
202 while (_cpp_read_logical_line_trad (pfile))
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);
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;
221 /* End the previous line of text. */
222 if (print.printed)
224 putc ('\n', print.outf);
225 print.line++;
226 print.printed = 0;
229 if (line >= print.line && line < print.line + 8)
231 while (line > print.line)
233 putc ('\n', print.outf);
234 print.line++;
237 else
238 print_line (map, line, "");
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;
249 /* End any previous line of text. */
250 if (print.printed)
251 putc ('\n', print.outf);
252 print.printed = 0;
254 print.line = line;
255 if (!flag_no_line_commands)
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;
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);
270 if (map->sysp == 2)
271 fputs (" 3 4", print.outf);
272 else if (map->sysp == 1)
273 fputs (" 3", print.outf);
275 putc ('\n', print.outf);
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;
287 if (token->type == CPP_EOF || parsing_args)
288 return;
290 maybe_print_line (print.map, token->line);
291 print.prev = 0;
292 print.source = 0;
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))
301 print.printed = 1;
302 if (token->col > 2)
304 unsigned int spaces = token->col - 2;
306 while (spaces--)
307 putc (' ', print.outf);
312 static void
313 cb_ident (pfile, line, str)
314 cpp_reader *pfile ATTRIBUTE_UNUSED;
315 unsigned int line;
316 const cpp_string * str;
318 maybe_print_line (print.map, line);
319 fprintf (print.outf, "#ident \"%s\"\n", str->text);
320 print.line++;
323 static void
324 cb_define (pfile, line, node)
325 cpp_reader *pfile;
326 unsigned int line;
327 cpp_hashnode *node;
329 maybe_print_line (print.map, line);
330 fputs ("#define ", print.outf);
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);
339 putc ('\n', print.outf);
340 print.line++;
343 static void
344 cb_undef (pfile, line, node)
345 cpp_reader *pfile ATTRIBUTE_UNUSED;
346 unsigned int line;
347 cpp_hashnode *node;
349 maybe_print_line (print.map, line);
350 fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
351 print.line++;
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;
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++;
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. */
371 static void
372 cb_file_change (pfile, map)
373 cpp_reader *pfile;
374 const struct line_map *map;
376 const char *flags = "";
378 /* First time? */
379 if (print.map == NULL)
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);
385 else
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);
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);
398 print.map = map;
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;
407 maybe_print_line (print.map, line);
408 fputs ("#pragma ", print.outf);
409 cpp_output_line (pfile, print.outf);
410 print.line++;
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;
420 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
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++;
429 return 1;