OSDN Git Service

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