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);
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 = alloca (to_file_len * 4 + 1);
00250 unsigned char *p;
00251
00252 print.src_line = SOURCE_LINE (map, src_loc);
00253
00254
00255
00256 p = cpp_quote_string (to_file_quoted,
00257 (unsigned char *) map->to_file, to_file_len);
00258 *p = '\0';
00259 fprintf (print.outf, "# %u \"%s\"%s", print.src_line,
00260 to_file_quoted, special_flags);
00261
00262 if (map->sysp == 2)
00263 fputs (" 3 4", print.outf);
00264 else if (map->sysp == 1)
00265 fputs (" 3", print.outf);
00266
00267 putc ('\n', print.outf);
00268 }
00269 }
00270
00271
00272
00273 static void
00274 cb_line_change (cpp_reader *pfile, const cpp_token *token,
00275 int parsing_args)
00276 {
00277 source_location src_loc = token->src_loc;
00278
00279 if (token->type == CPP_EOF || parsing_args)
00280 return;
00281
00282 maybe_print_line (src_loc);
00283 print.prev = 0;
00284 print.source = 0;
00285
00286
00287
00288
00289
00290
00291 if (!CPP_OPTION (pfile, traditional))
00292 {
00293 const struct line_map *map = linemap_lookup (&line_table, src_loc);
00294 int spaces = SOURCE_COLUMN (map, src_loc) - 2;
00295 print.printed = 1;
00296
00297 while (-- spaces >= 0)
00298 putc (' ', print.outf);
00299 }
00300 }
00301
00302 static void
00303 cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
00304 const cpp_string *str)
00305 {
00306 maybe_print_line (line);
00307 fprintf (print.outf, "#ident %s\n", str->text);
00308 print.src_line++;
00309 }
00310
00311 static void
00312 cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node)
00313 {
00314 maybe_print_line (line);
00315 fputs ("#define ", print.outf);
00316
00317
00318 if (flag_dump_macros == 'D')
00319 fputs ((const char *) cpp_macro_definition (pfile, node),
00320 print.outf);
00321 else
00322 fputs ((const char *) NODE_NAME (node), print.outf);
00323
00324 putc ('\n', print.outf);
00325 print.src_line++;
00326 }
00327
00328 static void
00329 cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
00330 cpp_hashnode *node)
00331 {
00332 maybe_print_line (line);
00333 fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
00334 print.src_line++;
00335 }
00336
00337 static void
00338 cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
00339 const unsigned char *dir, const char *header, int angle_brackets)
00340 {
00341 maybe_print_line (line);
00342 if (angle_brackets)
00343 fprintf (print.outf, "#%s <%s>\n", dir, header);
00344 else
00345 fprintf (print.outf, "#%s \"%s\"\n", dir, header);
00346 print.src_line++;
00347 }
00348
00349
00350
00351
00352 void
00353 pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
00354 {
00355 size_t to_file_len = strlen (dir);
00356 unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
00357 unsigned char *p;
00358
00359
00360 p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len);
00361 *p = '\0';
00362 fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
00363 }
00364
00365
00366
00367
00368 void
00369 pp_file_change (const struct line_map *map)
00370 {
00371 const char *flags = "";
00372
00373 if (flag_no_line_commands)
00374 return;
00375
00376 if (map != NULL)
00377 {
00378 if (print.first_time)
00379 {
00380
00381 if (!cpp_get_options (parse_in)->preprocessed)
00382 print_line (map->start_location, flags);
00383 print.first_time = 0;
00384 }
00385 else
00386 {
00387
00388 if (map->reason == LC_ENTER)
00389 {
00390 const struct line_map *from = INCLUDED_FROM (&line_table, map);
00391 maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
00392 }
00393 if (map->reason == LC_ENTER)
00394 flags = " 1";
00395 else if (map->reason == LC_LEAVE)
00396 flags = " 2";
00397 print_line (map->start_location, flags);
00398 }
00399 }
00400 }
00401
00402
00403 static void
00404 cb_def_pragma (cpp_reader *pfile, source_location line)
00405 {
00406 maybe_print_line (line);
00407 fputs ("#pragma ", print.outf);
00408 cpp_output_line (pfile, print.outf);
00409 print.src_line++;
00410 }
00411
00412
00413 static int
00414 dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
00415 {
00416 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
00417 {
00418 fputs ("#define ", print.outf);
00419 fputs ((const char *) cpp_macro_definition (pfile, node),
00420 print.outf);
00421 putc ('\n', print.outf);
00422 print.src_line++;
00423 }
00424
00425 return 1;
00426 }
00427
00428
00429
00430
00431
00432 static void
00433 cb_read_pch (cpp_reader *pfile, const char *name,
00434 int fd, const char *orig_name ATTRIBUTE_UNUSED)
00435 {
00436 c_common_read_pch (pfile, name, fd, orig_name);
00437
00438 fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
00439 print.src_line++;
00440 }