00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021 #include "system.h"
00022 #include "coretypes.h"
00023 #include "tm.h"
00024 #include "cpplib.h"
00025 #include "../libcpp/internal.h"
00026 #include "tree.h"
00027 #include "c-common.h"
00028 #include "c-pragma.h"
00029
00030
00031
00032 static struct
00033 {
00034 FILE *outf;
00035 const cpp_token *prev;
00036 const cpp_token *source;
00037 int src_line;
00038 unsigned char printed;
00039 bool first_time;
00040 } print;
00041
00042
00043 static void scan_translation_unit (cpp_reader *);
00044 static void scan_translation_unit_trad (cpp_reader *);
00045 static void account_for_newlines (const unsigned char *, size_t);
00046 static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
00047
00048 static void print_line (source_location, const char *);
00049 static void maybe_print_line (source_location);
00050
00051
00052
00053 static void cb_line_change (cpp_reader *, const cpp_token *, int);
00054 static void cb_define (cpp_reader *, source_location, cpp_hashnode *);
00055 static void cb_undef (cpp_reader *, source_location, cpp_hashnode *);
00056 static void cb_include (cpp_reader *, source_location, const unsigned char *,
00057 const char *, int, const cpp_token **);
00058 static void cb_ident (cpp_reader *, source_location, const cpp_string *);
00059 static void cb_def_pragma (cpp_reader *, source_location);
00060 static void cb_read_pch (cpp_reader *pfile, const char *name,
00061 int fd, const char *orig_name);
00062
00063
00064 void
00065 preprocess_file (cpp_reader *pfile)
00066 {
00067
00068
00069 if (flag_no_output)
00070 {
00071
00072 while (pfile->buffer->prev)
00073 cpp_scan_nooutput (pfile);
00074 cpp_scan_nooutput (pfile);
00075 }
00076 else if (cpp_get_options (pfile)->traditional)
00077 scan_translation_unit_trad (pfile);
00078 else
00079 scan_translation_unit (pfile);
00080
00081
00082 if (flag_dump_macros == 'M')
00083 cpp_forall_identifiers (pfile, dump_macro, NULL);
00084
00085
00086 if (print.printed)
00087 putc ('\n', print.outf);
00088 }
00089
00090
00091 void
00092 init_pp_output (FILE *out_stream)
00093 {
00094 cpp_callbacks *cb = cpp_get_callbacks (parse_in);
00095
00096 if (!flag_no_output)
00097 {
00098 cb->line_change = cb_line_change;
00099
00100
00101 if (cpp_get_options (parse_in)->lang != CLK_ASM)
00102 {
00103 cb->ident = cb_ident;
00104 cb->def_pragma = cb_def_pragma;
00105 }
00106 }
00107
00108 if (flag_dump_includes)
00109 cb->include = cb_include;
00110
00111 if (flag_pch_preprocess)
00112 {
00113 cb->valid_pch = c_common_valid_pch;
00114 cb->read_pch = cb_read_pch;
00115 }
00116
00117 if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
00118 {
00119 cb->define = cb_define;
00120 cb->undef = cb_undef;
00121 }
00122
00123
00124
00125
00126 print.src_line = -1;
00127 print.printed = 0;
00128 print.prev = 0;
00129 print.outf = out_stream;
00130 print.first_time = 1;
00131 }
00132
00133
00134
00135 static void
00136 scan_translation_unit (cpp_reader *pfile)
00137 {
00138 bool avoid_paste = false;
00139
00140 print.source = NULL;
00141 for (;;)
00142 {
00143 const cpp_token *token = cpp_get_token (pfile);
00144
00145 if (token->type == CPP_PADDING)
00146 {
00147 avoid_paste = true;
00148 if (print.source == NULL
00149 || (!(print.source->flags & PREV_WHITE)
00150 && token->val.source == NULL))
00151 print.source = token->val.source;
00152 continue;
00153 }
00154
00155 if (token->type == CPP_EOF)
00156 break;
00157
00158
00159 if (avoid_paste)
00160 {
00161 if (print.source == NULL)
00162 print.source = token;
00163 if (print.source->flags & PREV_WHITE
00164 || (print.prev
00165 && cpp_avoid_paste (pfile, print.prev, token))
00166 || (print.prev == NULL && token->type == CPP_HASH))
00167 putc (' ', print.outf);
00168 }
00169 else if (token->flags & PREV_WHITE)
00170 putc (' ', print.outf);
00171
00172 avoid_paste = false;
00173 print.source = NULL;
00174 print.prev = token;
00175 cpp_output_token (token, print.outf);
00176
00177 if (token->type == CPP_COMMENT)
00178 account_for_newlines (token->val.str.text, token->val.str.len);
00179 }
00180 }
00181
00182
00183 static void
00184 account_for_newlines (const unsigned char *str, size_t len)
00185 {
00186 while (len--)
00187 if (*str++ == '\n')
00188 print.src_line++;
00189 }
00190
00191
00192 static void
00193 scan_translation_unit_trad (cpp_reader *pfile)
00194 {
00195 while (_cpp_read_logical_line_trad (pfile))
00196 {
00197 size_t len = pfile->out.cur - pfile->out.base;
00198 maybe_print_line (pfile->out.first_line);
00199 fwrite (pfile->out.base, 1, len, print.outf);
00200 print.printed = 1;
00201 if (!CPP_OPTION (pfile, discard_comments))
00202 account_for_newlines (pfile->out.base, len);
00203 }
00204 }
00205
00206
00207
00208
00209 static void
00210 maybe_print_line (source_location src_loc)
00211 {
00212 const struct line_map *map = linemap_lookup (&line_table, src_loc);
00213 int src_line = SOURCE_LINE (map, src_loc);
00214
00215 if (print.printed)
00216 {
00217 putc ('\n', print.outf);
00218 print.src_line++;
00219 print.printed = 0;
00220 }
00221
00222 if (src_line >= print.src_line && src_line < print.src_line + 8)
00223 {
00224 while (src_line > print.src_line)
00225 {
00226 putc ('\n', print.outf);
00227 print.src_line++;
00228 }
00229 }
00230 else
00231 print_line (src_loc, "");
00232 }
00233
00234
00235
00236 static void
00237 print_line (source_location src_loc, const char *special_flags)
00238 {
00239
00240 if (print.printed)
00241 putc ('\n', print.outf);
00242 print.printed = 0;
00243
00244 if (!flag_no_line_commands)
00245 {
00246 const struct line_map *map = linemap_lookup (&line_table, src_loc);
00247
00248 size_t to_file_len = strlen (map->to_file);
00249 unsigned char *to_file_quoted =
00250 (unsigned char *) alloca (to_file_len * 4 + 1);
00251 unsigned char *p;
00252
00253 print.src_line = SOURCE_LINE (map, src_loc);
00254
00255
00256
00257 p = cpp_quote_string (to_file_quoted,
00258 (unsigned char *) map->to_file, to_file_len);
00259 *p = '\0';
00260 fprintf (print.outf, "# %u \"%s\"%s",
00261 print.src_line == 0 ? 1 : print.src_line,
00262 to_file_quoted, special_flags);
00263
00264 if (map->sysp == 2)
00265 fputs (" 3 4", print.outf);
00266 else if (map->sysp == 1)
00267 fputs (" 3", print.outf);
00268
00269 putc ('\n', print.outf);
00270 }
00271 }
00272
00273
00274
00275 static void
00276 cb_line_change (cpp_reader *pfile, const cpp_token *token,
00277 int parsing_args)
00278 {
00279 source_location src_loc = token->src_loc;
00280
00281 if (token->type == CPP_EOF || parsing_args)
00282 return;
00283
00284 maybe_print_line (src_loc);
00285 print.prev = 0;
00286 print.source = 0;
00287
00288
00289
00290
00291
00292
00293 if (!CPP_OPTION (pfile, traditional))
00294 {
00295 const struct line_map *map = linemap_lookup (&line_table, src_loc);
00296 int spaces = SOURCE_COLUMN (map, src_loc) - 2;
00297 print.printed = 1;
00298
00299 while (-- spaces >= 0)
00300 putc (' ', print.outf);
00301 }
00302 }
00303
00304 static void
00305 cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
00306 const cpp_string *str)
00307 {
00308 maybe_print_line (line);
00309 fprintf (print.outf, "#ident %s\n", str->text);
00310 print.src_line++;
00311 }
00312
00313 static void
00314 cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node)
00315 {
00316 maybe_print_line (line);
00317 fputs ("#define ", print.outf);
00318
00319
00320 if (flag_dump_macros == 'D')
00321 fputs ((const char *) cpp_macro_definition (pfile, node),
00322 print.outf);
00323 else
00324 fputs ((const char *) NODE_NAME (node), print.outf);
00325
00326 putc ('\n', print.outf);
00327 if (linemap_lookup (&line_table, line)->to_line != 0)
00328 print.src_line++;
00329 }
00330
00331 static void
00332 cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
00333 cpp_hashnode *node)
00334 {
00335 maybe_print_line (line);
00336 fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
00337 print.src_line++;
00338 }
00339
00340 static void
00341 cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
00342 const unsigned char *dir, const char *header, int angle_brackets,
00343 const cpp_token **comments)
00344 {
00345 maybe_print_line (line);
00346 if (angle_brackets)
00347 fprintf (print.outf, "#%s <%s>", dir, header);
00348 else
00349 fprintf (print.outf, "#%s \"%s\"", dir, header);
00350
00351 if (comments != NULL)
00352 {
00353 while (*comments != NULL)
00354 {
00355 if ((*comments)->flags & PREV_WHITE)
00356 putc (' ', print.outf);
00357 cpp_output_token (*comments, print.outf);
00358 ++comments;
00359 }
00360 }
00361
00362 putc ('\n', print.outf);
00363 print.src_line++;
00364 }
00365
00366
00367
00368
00369 void
00370 pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
00371 {
00372 size_t to_file_len = strlen (dir);
00373 unsigned char *to_file_quoted =
00374 (unsigned char *) alloca (to_file_len * 4 + 1);
00375 unsigned char *p;
00376
00377
00378 p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len);
00379 *p = '\0';
00380 fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
00381 }
00382
00383
00384
00385
00386 void
00387 pp_file_change (const struct line_map *map)
00388 {
00389 const char *flags = "";
00390
00391 if (flag_no_line_commands)
00392 return;
00393
00394 if (map != NULL)
00395 {
00396 if (print.first_time)
00397 {
00398
00399 if (!cpp_get_options (parse_in)->preprocessed)
00400 print_line (map->start_location, flags);
00401 print.first_time = 0;
00402 }
00403 else
00404 {
00405
00406 if (map->reason == LC_ENTER)
00407 {
00408 const struct line_map *from = INCLUDED_FROM (&line_table, map);
00409 maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
00410 }
00411 if (map->reason == LC_ENTER)
00412 flags = " 1";
00413 else if (map->reason == LC_LEAVE)
00414 flags = " 2";
00415 print_line (map->start_location, flags);
00416 }
00417 }
00418 }
00419
00420
00421 static void
00422 cb_def_pragma (cpp_reader *pfile, source_location line)
00423 {
00424 maybe_print_line (line);
00425 fputs ("#pragma ", print.outf);
00426 cpp_output_line (pfile, print.outf);
00427 print.src_line++;
00428 }
00429
00430
00431 static int
00432 dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
00433 {
00434 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
00435 {
00436 fputs ("#define ", print.outf);
00437 fputs ((const char *) cpp_macro_definition (pfile, node),
00438 print.outf);
00439 putc ('\n', print.outf);
00440 print.src_line++;
00441 }
00442
00443 return 1;
00444 }
00445
00446
00447
00448
00449
00450 static void
00451 cb_read_pch (cpp_reader *pfile, const char *name,
00452 int fd, const char *orig_name ATTRIBUTE_UNUSED)
00453 {
00454 c_common_read_pch (pfile, name, fd, orig_name);
00455
00456 fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
00457 print.src_line++;
00458 }