/* Helper function for cb_line_change and scan_translation_unit. */ static void do_line_change (cpp_reader *pfile, const cpp_token *token, source_location src_loc, int parsing_args) { if (define_queue || undef_queue) dump_queued_macros (pfile); if (token->type == CPP_EOF || parsing_args) return; maybe_print_line (src_loc); print.prev = 0; print.source = 0; /* Supply enough spaces to put this token in its original column, one space per column greater than 2, since scan_translation_unit will provide a space if PREV_WHITE. Don't bother trying to reconstruct tabs; we can't get it right in general, and nothing ought to care. Some things do care; the fault lies with them. */ if (!CPP_OPTION (pfile, traditional)) { const struct line_map *map = linemap_lookup (line_table, src_loc); int spaces = SOURCE_COLUMN (map, src_loc) - 2; print.printed = 1; while (-- spaces >= 0) putc (' ', print.outf); } }
/* Called when a line of output is started. TOKEN is the first token of the line, and at end of file will be CPP_EOF. */ static void cb_line_change (cpp_reader *pfile, const cpp_token *token, int parsing_args) { if (token->type == CPP_EOF || parsing_args) return; maybe_print_line (print.map, token->line); print.prev = 0; print.source = 0; /* Supply enough spaces to put this token in its original column, one space per column greater than 2, since scan_translation_unit will provide a space if PREV_WHITE. Don't bother trying to reconstruct tabs; we can't get it right in general, and nothing ought to care. Some things do care; the fault lies with them. */ if (!CPP_OPTION (pfile, traditional)) { print.printed = 1; if (token->col > 2) { unsigned int spaces = token->col - 2; while (spaces--) putc (' ', print.outf); } } }
/* Writes out a traditionally preprocessed file. */ static void scan_translation_unit_trad (cpp_reader *pfile) { while (_cpp_read_logical_line_trad (pfile)) { size_t len = pfile->out.cur - pfile->out.base; maybe_print_line (pfile->out.first_line); fwrite (pfile->out.base, 1, len, print.outf); print.printed = 1; if (!CPP_OPTION (pfile, discard_comments)) account_for_newlines (pfile->out.base, 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) { 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); } }