/* Writes out the preprocessed file, handling spacing and paste avoidance issues. */ static void scan_translation_unit (cpp_reader *pfile) { bool avoid_paste = false; bool do_line_adjustments = cpp_get_options (parse_in)->lang != CLK_ASM && !flag_no_line_commands; bool in_pragma = false; print.source = NULL; for (;;) { source_location loc; const cpp_token *token = cpp_get_token_with_location (pfile, &loc); if (token->type == CPP_PADDING) { avoid_paste = true; if (print.source == NULL || (!(print.source->flags & PREV_WHITE) && token->val.source == NULL)) print.source = token->val.source; continue; } if (token->type == CPP_EOF) break; /* Subtle logic to output a space if and only if necessary. */ if (avoid_paste) { const struct line_map *map = linemap_lookup (line_table, loc); int src_line = SOURCE_LINE (map, loc); if (print.source == NULL) print.source = token; if (src_line != print.src_line && do_line_adjustments && !in_pragma) { do_line_change (pfile, token, loc, false); putc (' ', print.outf); } else if (print.source->flags & PREV_WHITE || (print.prev && cpp_avoid_paste (pfile, print.prev, token)) || (print.prev == NULL && token->type == CPP_HASH)) putc (' ', print.outf); } else if (token->flags & PREV_WHITE) { const struct line_map *map = linemap_lookup (line_table, loc); int src_line = SOURCE_LINE (map, loc); if (src_line != print.src_line && do_line_adjustments && !in_pragma) do_line_change (pfile, token, loc, false); putc (' ', print.outf); } avoid_paste = false; print.source = NULL; print.prev = token; if (token->type == CPP_PRAGMA) { const char *space; const char *name; maybe_print_line (token->src_loc); fputs ("#pragma ", print.outf); c_pp_lookup_pragma (token->val.pragma, &space, &name); if (space) fprintf (print.outf, "%s %s", space, name); else fprintf (print.outf, "%s", name); print.printed = 1; in_pragma = true; } else if (token->type == CPP_PRAGMA_EOL) { maybe_print_line (token->src_loc); in_pragma = false; } else cpp_output_token (token, print.outf); if (token->type == CPP_COMMENT) account_for_newlines (token->val.str.text, token->val.str.len); } }
/* Writes out the preprocessed file, handling spacing and paste avoidance issues. */ static void scan_translation_unit (cpp_reader *pfile) { bool avoid_paste = false; bool do_line_adjustments = cpp_get_options (parse_in)->lang != CLK_ASM && !flag_no_line_commands; bool in_pragma = false; print.source = NULL; for (;;) { source_location loc; const cpp_token *token = cpp_get_token_with_location (pfile, &loc); if (token->type == CPP_PADDING) { avoid_paste = true; if (print.source == NULL || (!(print.source->flags & PREV_WHITE) && token->val.source == NULL)) print.source = token->val.source; continue; } if (token->type == CPP_EOF) break; /* Subtle logic to output a space if and only if necessary. */ if (avoid_paste) { int src_line = LOCATION_LINE (loc); if (print.source == NULL) print.source = token; if (src_line != print.src_line && do_line_adjustments && !in_pragma) { do_line_change (pfile, token, loc, false); putc (' ', print.outf); } else if (print.source->flags & PREV_WHITE || (print.prev && cpp_avoid_paste (pfile, print.prev, token)) || (print.prev == NULL && token->type == CPP_HASH)) putc (' ', print.outf); } else if (token->flags & PREV_WHITE) { int src_line = LOCATION_LINE (loc); if (src_line != print.src_line && do_line_adjustments && !in_pragma) do_line_change (pfile, token, loc, false); putc (' ', print.outf); } avoid_paste = false; print.source = NULL; print.prev = token; if (token->type == CPP_PRAGMA) { const char *space; const char *name; maybe_print_line (token->src_loc); fputs ("#pragma ", print.outf); c_pp_lookup_pragma (token->val.pragma, &space, &name); if (space) fprintf (print.outf, "%s %s", space, name); else fprintf (print.outf, "%s", name); print.printed = 1; in_pragma = true; } else if (token->type == CPP_PRAGMA_EOL) { maybe_print_line (token->src_loc); in_pragma = false; } else { if (cpp_get_options (parse_in)->debug) linemap_dump_location (line_table, token->src_loc, print.outf); cpp_output_token (token, print.outf); } /* CPP_COMMENT tokens and raw-string literal tokens can have embedded new-line characters. Rather than enumerating all the possible token types just check if token uses val.str union member. */ if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR) account_for_newlines (token->val.str.text, token->val.str.len); } }