From 64952cee7002bc6f5c110d9979b3e6a2c33b62b8 Mon Sep 17 00:00:00 2001 From: James Farrell Date: Wed, 12 Oct 2022 15:27:10 +0000 Subject: [PATCH] Support diff -f AKA --show-function-line --- tests/diff.test | 48 +++++++++++++++++++++++++++++++++++++++++++++ toys/pending/diff.c | 42 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/tests/diff.test b/tests/diff.test index bbef9d32..ddca4766 100644 --- a/tests/diff.test +++ b/tests/diff.test @@ -55,6 +55,54 @@ testcmd "fifos" "-u -L fifo1 -L fifo2 fifo1 fifo2" '--- fifo1 +3 ' "" "" +echo -e 'int bar() { +} + +int foo() { +} + +int baz() { + 1 + {2 + 3 + 4 + foo +} +'> a +echo -e 'int barbar() { +} + +int foo() { +} + +int baz() { + 1a + {2 + 3 + 4 + bar +} +'> b +testcmd 'show function' "--show-function-line=' {$' -U1 -L lll -L rrr a b" \ +'--- lll ++++ rrr +@@ -1,2 +1,2 @@ +-int bar() { ++int barbar() { + } +@@ -7,3 +7,3 @@ int foo() { + int baz() { +- 1 ++ 1a + {2 +@@ -11,3 +11,3 @@ int baz() { + 4 +- foo ++ bar + } +' \ +'' '' + seq 1 100000 > one seq 1 4 100000 > two testcmd 'big hunk' '-u --label nope --label nope one two' \ diff --git a/toys/pending/diff.c b/toys/pending/diff.c index 0ea8fc39..f12b4a3c 100644 --- a/toys/pending/diff.c +++ b/toys/pending/diff.c @@ -8,18 +8,19 @@ * * Deviations from posix: always does -u -USE_DIFF(NEWTOY(diff, "<2>2(unchanged-line-format):;(old-line-format):;(new-line-format):;(color)(strip-trailing-cr)B(ignore-blank-lines)d(minimal)b(ignore-space-change)ut(expand-tabs)w(ignore-all-space)i(ignore-case)T(initial-tab)s(report-identical-files)q(brief)a(text)S(starting-file):L(label)*N(new-file)r(recursive)U(unified)#<0=3", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2))) +USE_DIFF(NEWTOY(diff, "<2>2(unchanged-line-format):;(old-line-format):;(new-line-format):;(color)(strip-trailing-cr)B(ignore-blank-lines)d(minimal)b(ignore-space-change)ut(expand-tabs)w(ignore-all-space)i(ignore-case)T(initial-tab)s(report-identical-files)q(brief)a(text)S(starting-file):F(show-function-line):;L(label)*N(new-file)r(recursive)U(unified)#<0=3", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2))) config DIFF bool "diff" default n help - usage: diff [-abBdiNqrTstw] [-L LABEL] [-S FILE] [-U LINES] FILE1 FILE2 + usage: diff [-abBdiNqrTstw] [-L LABEL] [-S FILE] [-U LINES] [-F REGEX ] FILE1 FILE2 -a Treat all files as text -b Ignore changes in the amount of whitespace -B Ignore changes whose lines are all blank -d Try hard to find a smaller set of changes + -F Show the most recent line matching the regex -i Ignore case differences -L Use LABEL instead of the filename in the unified header -N Treat absent files as empty @@ -48,7 +49,7 @@ config DIFF GLOBALS( long U; struct arg_list *L; - char *S, *new_line_format, *old_line_format, *unchanged_line_format; + char *F, *S, *new_line_format, *old_line_format, *unchanged_line_format; int dir_num, size, is_binary, differ, change, len[2], *offset[2]; struct stat st[2]; @@ -383,6 +384,33 @@ static int *diff(char **files) return create_j_vector(); } +static void print_line_matching_regex(int a, regex_t *reg, int *off_set, FILE *fp) { + int i = 0, j = 0, line_buf_size = 100, cc = 0; + char* line = xzalloc(line_buf_size * sizeof(char)); + for (i = a; a > 0; --i) { + int line_len = 0; + if (fseek(fp, off_set[i - 1], SEEK_SET)) perror_exit("fseek failed"); + for (j = 0; j < (off_set[i] - off_set[i - 1]); j++) { + cc = fgetc(fp); + if (cc == EOF || cc == '\n') { + break; + } + ++line_len; + if (line_len >= line_buf_size) { + line_buf_size = line_buf_size * 11 / 10; + line = xrealloc(line, line_buf_size*sizeof(char)); + } + line[j] = cc; + } + line[line_len] = '\0'; + if (!regexec0(reg, line, line_len, 0, NULL, 0)) { + printf(" %s", line); + break; + } + } + free(line); +} + static void print_diff(int a, int b, char c, int *off_set, FILE *fp) { int i, j, cc, cl; @@ -557,12 +585,17 @@ static void do_diff(char **files) struct diff *d; struct arg_list *llist = TT.L; int *J; + regex_t reg; TT.offset[0] = TT.offset[1] = NULL; J = diff(files); if (!J) return; //No need to compare, have to status only + if (TT.F) { + xregcomp(®, TT.F, 0); + } + d = xzalloc(size *sizeof(struct diff)); do { ignore_white = 0; @@ -656,6 +689,9 @@ calc_ct: else putchar(' '); printf("@@"); if (FLAG(color)) printf("\e[0m"); + if (TT.F) { + print_line_matching_regex(ptr1->suff-1, ®, TT.offset[0], TT.file[0].fp); + } putchar('\n'); } -- 2.39.2