Skip to content

Commit

Permalink
Handle git extended headers.
Browse files Browse the repository at this point in the history
The fullheader1 test case should now pass.
  • Loading branch information
twaugh committed Apr 14, 2015
1 parent 88aef8a commit 14261ad
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 34 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
@@ -1,5 +1,8 @@
2014-04-14 Tim Waugh <twaugh@redhat.com>

* src/filterdiff.c: Handle git extended headers.
* Makefile.am: The fullheader1 test case should now pass.

* tests/lsdiff6/run-test: Fixed typo.
* tests/fullheader1/run-test: Fixed typo.

Expand Down
3 changes: 1 addition & 2 deletions Makefile.am
Expand Up @@ -224,8 +224,7 @@ XFAIL_TESTS = \
tests/delhunk5/run-test \
tests/delhunk6/run-test \
tests/trimlast1/run-test \
tests/trimlast2/run-test \
tests/fullheader1/run-test
tests/trimlast2/run-test

distclean-local:
-rm -rf $(top_builddir)/test-arena
Expand Down
143 changes: 111 additions & 32 deletions src/filterdiff.c
Expand Up @@ -279,7 +279,8 @@ hunk_matches (unsigned long orig_offset, unsigned long orig_count,
}

static int
do_unified (FILE *f, char *header[2], int match, char **line,
do_unified (FILE *f, char **header, unsigned int num_headers,
int match, char **line,
size_t *linelen, unsigned long *linenum,
unsigned long start_linenum, char status,
const char *bestname, const char *patchname,
Expand Down Expand Up @@ -390,10 +391,13 @@ do_unified (FILE *f, char *header[2], int match, char **line,
if (!header_displayed &&
mode != mode_grep) {
// Display the header.
unsigned int i;
for (i = 0; i < num_headers - 2; i++)
output_header_line (header[i]);
if (number_lines != After)
output_header_line (header[0]);
output_header_line (header[num_headers - 2]);
if (number_lines != Before)
output_header_line (header[1]);
output_header_line (header[num_headers - 1]);
header_displayed = 1;
}
switch (number_lines) {
Expand Down Expand Up @@ -476,16 +480,16 @@ do_unified (FILE *f, char *header[2], int match, char **line,
}
} else {
if (match_tmpf) {
if (!header_displayed &&
number_lines != After)
output_header_line (header[0]);

if (!header_displayed &&
number_lines != Before)
output_header_line (header[1]);

if (!header_displayed)
if (!header_displayed) {
unsigned int i;
for (i = 0; i < num_headers - 2; i++)
output_header_line (header[i]);
if (number_lines != After)
output_header_line (header[num_headers - 2]);
if (number_lines != Before)
output_header_line (header[num_headers - 1]);
header_displayed = 1;
}

rewind (match_tmpf);
while (!feof (match_tmpf)) {
Expand Down Expand Up @@ -533,7 +537,8 @@ do_unified (FILE *f, char *header[2], int match, char **line,
}

static int
do_context (FILE *f, char *header[2], int match, char **line,
do_context (FILE *f, char **header, unsigned int num_headers,
int match, char **line,
size_t *linelen, unsigned long *linenum,
unsigned long start_linenum, char status,
const char *bestname, const char *patchname,
Expand Down Expand Up @@ -687,10 +692,13 @@ do_context (FILE *f, char *header[2], int match, char **line,

// Display the line counts.
if (!header_displayed && mode == mode_filter) {
unsigned int i;
for (i = 0; i < num_headers - 2; i++)
output_header_line (header[i]);
if (number_lines != After)
output_header_line (header[0]);
output_header_line (header[num_headers - 2]);
if (number_lines != Before)
output_header_line (header[1]);
output_header_line (header[num_headers - 1]);
header_displayed = 1;
}

Expand Down Expand Up @@ -787,10 +795,13 @@ do_context (FILE *f, char *header[2], int match, char **line,
}
} else {
if (!header_displayed) {
unsigned int i;
for (i = 0; i < num_headers - 2; i++)
output_header_line (header[i]);
if (number_lines != After)
output_header_line (header[0]);
output_header_line (header[num_headers - 2]);
if (number_lines != Before)
output_header_line (header[1]);
output_header_line (header[num_headers - 1]);
header_displayed = 1;
}

Expand Down Expand Up @@ -899,11 +910,13 @@ do_context (FILE *f, char *header[2], int match, char **line,
return ret;
}

#define MAX_HEADERS 5
static int filterdiff (FILE *f, const char *patchname)
{
static unsigned long linenum = 1;
char *names[2];
char *header[2] = { NULL, NULL };
char *header[MAX_HEADERS] = { NULL, NULL };
unsigned int num_headers = 0;
char *line = NULL;
size_t linelen = 0;
char *p;
Expand All @@ -918,18 +931,22 @@ static int filterdiff (FILE *f, const char *patchname)
char status = '!';
unsigned long start_linenum;
int orig_file_exists, new_file_exists;
int is_context = 0;
int is_context = -1;
int result;
int (*do_diff) (FILE *, char *[2], int, char **, size_t *,
int (*do_diff) (FILE *, char **, unsigned int,
int, char **, size_t *,
unsigned long *, unsigned long,
char, const char *, const char *,
int *, int *);

orig_file_exists = 0; // shut gcc up

// Search for start of patch ("--- " for unified diff,
// "*** " for context).
// Search for start of patch ("diff ", or "--- " for
// unified diff, "*** " for context).
for (;;) {
if (!strncmp (line, "diff ", 5))
break;

if (!strncmp (line, "--- ", 4)) {
is_context = 0;
break;
Expand All @@ -953,6 +970,70 @@ static int filterdiff (FILE *f, const char *patchname)

start_linenum = linenum;
header[0] = xstrdup (line);
num_headers = 1;

if (is_context == -1) {
int valid_extended = 1;
for (;;) {
if (getline (&line, &linelen, f) == -1)
goto eof;
linenum++;

if (!strncmp (line, "diff ", 5)) {
header[num_headers++] = xstrdup (line);
break;
}

if (!strncmp (line, "--- ", 4))
is_context = 0;
else if (!strncmp (line, "*** ", 4))
is_context = 1;
else if (strncmp (line, "old mode ", 9) &&
strncmp (line, "new mode ", 9) &&
strncmp (line, "deleted file mode ", 18) &&
strncmp (line, "new file mode ", 15) &&
strncmp (line, "copy from ", 10) &&
strncmp (line, "copy to ", 8) &&
strncmp (line, "rename from ", 12) &&
strncmp (line, "rename to ", 10) &&
strncmp (line, "similarity index ", 17) &&
strncmp (line, "dissimilarity index ", 20) &&
strncmp (line, "index ", 6))
valid_extended = 0;

if (!valid_extended)
break;

/* Drop excess header lines */
if (num_headers < MAX_HEADERS - 2)
header[num_headers++] = xstrdup (line);

if (is_context != -1)
break;
}

if (!valid_extended)
goto flush_continue;
}

if (is_context == -1) {
/* We don't yet do anything with diffs with
* zero hunks. */
unsigned int i = 0;
flush_continue:
if (mode == mode_filter && (pat_exclude || verbose)
&& !clean_comments) {
for (i = 0; i < num_headers; i++)
fputs (header[i], stdout);
}
for (i = 0; i < num_headers; i++) {
free (header[i]);
header[i] = NULL;
}
num_headers = 0;
continue;
}

names[0] = filename_from_header (line + 4);
if (mode != mode_filter && show_status)
orig_file_exists = file_exists (names[0], line + 4 +
Expand All @@ -972,17 +1053,12 @@ static int filterdiff (FILE *f, const char *patchname)
if (strncmp (line, is_context ? "--- " : "+++ ", 4)) {
/* Show non-diff lines if excluding, or if
* in verbose mode, and if --clean isn't specified. */
if (mode == mode_filter && (pat_exclude || verbose)
&& !clean_comments)
fputs (header[0], stdout);
free (names[0]);
free (header[0]);
header[0] = NULL;
continue;
goto flush_continue;
}

filecount++;
header[1] = xstrdup (line);
header[num_headers++] = xstrdup (line);
names[1] = filename_from_header (line + 4);

if (mode != mode_filter && show_status)
Expand All @@ -1007,7 +1083,8 @@ static int filterdiff (FILE *f, const char *patchname)
else
do_diff = do_unified;

result = do_diff (f, header, match, &line,
result = do_diff (f, header, num_headers,
match, &line,
&linelen, &linenum,
start_linenum, status, p, patchname,
&orig_file_exists, &new_file_exists);
Expand All @@ -1033,15 +1110,17 @@ static int filterdiff (FILE *f, const char *patchname)
}

next_diff:
for (i = 0; i < 2; i++) {
for (i = 0; i < 2; i++)
free (names[i]);
for (i = 0; i < num_headers; i++) {
free (header[i]);
header[i] = NULL;
}
num_headers = 0;
}

eof:
for (i = 0; i < 2; i++)
for (i = 0; i < num_headers; i++)
if (header[i])
free (header[i]);

Expand Down

0 comments on commit 14261ad

Please sign in to comment.