diff options
Diffstat (limited to '')
-rw-r--r-- | libpatch_format_copied_patch.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/libpatch_format_copied_patch.c b/libpatch_format_copied_patch.c new file mode 100644 index 0000000..9f0378d --- /dev/null +++ b/libpatch_format_copied_patch.c @@ -0,0 +1,109 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static void +print_line(struct libpatch_diff2_printer *printer, const struct libpatch_file *file, size_t lineno) +{ + printer->put_line(printer, file->lines[lineno]); + printer->put_newline(printer); + if (lineno + 1 == file->nlines && !file->lf_terminated) { + printer->put_no_newline(printer, "\\ No newline at end of file"); + printer->put_newline(printer); + } +} + + +static void +print_change(struct libpatch_diff2_printer *printer, int fileno, int both, const struct libpatch_file *file, size_t lineno) +{ + printer->put_change_prefix(printer, both ? "! " : fileno == 1 ? "- " : "+ ", fileno, 0, lineno); + print_line(printer, file, lineno); +} + + +static void +print_context(struct libpatch_diff2_printer *printer, int fileno, const struct libpatch_file *file, size_t lineno) +{ + printer->put_context_prefix(printer, " ", fileno == 1, fileno == 2, lineno); + print_line(printer, file, lineno); +} + + +static void +print_hunk_head(struct libpatch_diff2_printer *printer, const char *prefix, const char *suffix, + size_t lineno, size_t len, int file) +{ + printer->put_hunk_head_prefix(printer, prefix, file); + printer->put_whitespace(printer, " "); + printer->put_hunk_start(printer, "", lineno + (size_t)(len > 0), file); + if (len > 1) + printer->put_hunk_end(printer, ",", lineno + len, file); + printer->put_whitespace(printer, " "); + printer->put_hunk_head_suffix(printer, suffix, file); + printer->put_newline(printer); +} + + +int +libpatch_format_copied_patch(struct libpatch_diff2_printer *printer, struct libpatch_diff2 *diff, size_t difflen, + const struct libpatch_file *file1, const struct libpatch_file *file2) +{ +#define HUNK(FNO, FI, FN)\ + do {\ + for (; i < n; i++) {\ + if (changed_saved) {\ + changed_saved -= 1;\ + } else if (diff[i].repetition & 0x03) {\ + for (changed_saved = 0; changed_saved < n - i;)\ + changed |= diff[i + changed_saved++].repetition;\ + changed_saved -= 1;\ + } else {\ + changed = 0;\ + }\ + for (j = 0; j < diff[i].repetition; j++) {\ + if (diff[i].change == LIBPATCH_DIFF2_FILE##FNO##_ONLY ||\ + diff[i].change == LIBPATCH_DIFF2_TWO_FILE_CHANGE)\ + print_change(printer, FNO, changed == 0x03, file##FNO, FI++);\ + else if (diff[i].change == LIBPATCH_DIFF2_CONTEXT)\ + print_context(printer, FNO, file##FNO, FI++);\ + }\ + }\ + } while (0) + + size_t i, i0, j, n, ai, bi, an, bn, changed_saved = 0; + int changed = 0, have; + + printer->put_label_prefix(printer, "***", 1); + printer->put_whitespace(printer, " "); + if (file1->label) + printer->put_label(printer, file1->label, 1); + printer->put_newline(printer); + + printer->put_label_prefix(printer, "---", 2); + printer->put_whitespace(printer, " "); + if (file2->label) + printer->put_label(printer, file2->label, 2); + printer->put_newline(printer); + + ai = 0; + bi = 0; + for (i = 0; (n = libpatch_next_hunk(diff, difflen, &i, &ai, &bi, &an, &bn, 0));) { + have = 0; + for (n += j = i; j < n; j++) + have |= diff[j].change; + + printer->put_syntactical_garbage(printer, "***************"); + printer->put_newline(printer); + if (have & 1) { + i0 = i; + print_hunk_head(printer, "***", "****", ai, an, 1); + HUNK(1, ai, an); + i = i0; + } + print_hunk_head(printer, "---", "----", bi, bn, 2); + HUNK(2, bi, bn); + } + + return 0; +} |