Skip to content

Commit 14261ad

Browse files
committed
Handle git extended headers.
The fullheader1 test case should now pass.
1 parent 88aef8a commit 14261ad

File tree

3 files changed

+115
-34
lines changed

3 files changed

+115
-34
lines changed

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
2014-04-14 Tim Waugh <[email protected]>
22

3+
* src/filterdiff.c: Handle git extended headers.
4+
* Makefile.am: The fullheader1 test case should now pass.
5+
36
* tests/lsdiff6/run-test: Fixed typo.
47
* tests/fullheader1/run-test: Fixed typo.
58

Makefile.am

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,7 @@ XFAIL_TESTS = \
224224
tests/delhunk5/run-test \
225225
tests/delhunk6/run-test \
226226
tests/trimlast1/run-test \
227-
tests/trimlast2/run-test \
228-
tests/fullheader1/run-test
227+
tests/trimlast2/run-test
229228

230229
distclean-local:
231230
-rm -rf $(top_builddir)/test-arena

src/filterdiff.c

Lines changed: 111 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ hunk_matches (unsigned long orig_offset, unsigned long orig_count,
279279
}
280280

281281
static int
282-
do_unified (FILE *f, char *header[2], int match, char **line,
282+
do_unified (FILE *f, char **header, unsigned int num_headers,
283+
int match, char **line,
283284
size_t *linelen, unsigned long *linenum,
284285
unsigned long start_linenum, char status,
285286
const char *bestname, const char *patchname,
@@ -390,10 +391,13 @@ do_unified (FILE *f, char *header[2], int match, char **line,
390391
if (!header_displayed &&
391392
mode != mode_grep) {
392393
// Display the header.
394+
unsigned int i;
395+
for (i = 0; i < num_headers - 2; i++)
396+
output_header_line (header[i]);
393397
if (number_lines != After)
394-
output_header_line (header[0]);
398+
output_header_line (header[num_headers - 2]);
395399
if (number_lines != Before)
396-
output_header_line (header[1]);
400+
output_header_line (header[num_headers - 1]);
397401
header_displayed = 1;
398402
}
399403
switch (number_lines) {
@@ -476,16 +480,16 @@ do_unified (FILE *f, char *header[2], int match, char **line,
476480
}
477481
} else {
478482
if (match_tmpf) {
479-
if (!header_displayed &&
480-
number_lines != After)
481-
output_header_line (header[0]);
482-
483-
if (!header_displayed &&
484-
number_lines != Before)
485-
output_header_line (header[1]);
486-
487-
if (!header_displayed)
483+
if (!header_displayed) {
484+
unsigned int i;
485+
for (i = 0; i < num_headers - 2; i++)
486+
output_header_line (header[i]);
487+
if (number_lines != After)
488+
output_header_line (header[num_headers - 2]);
489+
if (number_lines != Before)
490+
output_header_line (header[num_headers - 1]);
488491
header_displayed = 1;
492+
}
489493

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

535539
static int
536-
do_context (FILE *f, char *header[2], int match, char **line,
540+
do_context (FILE *f, char **header, unsigned int num_headers,
541+
int match, char **line,
537542
size_t *linelen, unsigned long *linenum,
538543
unsigned long start_linenum, char status,
539544
const char *bestname, const char *patchname,
@@ -687,10 +692,13 @@ do_context (FILE *f, char *header[2], int match, char **line,
687692

688693
// Display the line counts.
689694
if (!header_displayed && mode == mode_filter) {
695+
unsigned int i;
696+
for (i = 0; i < num_headers - 2; i++)
697+
output_header_line (header[i]);
690698
if (number_lines != After)
691-
output_header_line (header[0]);
699+
output_header_line (header[num_headers - 2]);
692700
if (number_lines != Before)
693-
output_header_line (header[1]);
701+
output_header_line (header[num_headers - 1]);
694702
header_displayed = 1;
695703
}
696704

@@ -787,10 +795,13 @@ do_context (FILE *f, char *header[2], int match, char **line,
787795
}
788796
} else {
789797
if (!header_displayed) {
798+
unsigned int i;
799+
for (i = 0; i < num_headers - 2; i++)
800+
output_header_line (header[i]);
790801
if (number_lines != After)
791-
output_header_line (header[0]);
802+
output_header_line (header[num_headers - 2]);
792803
if (number_lines != Before)
793-
output_header_line (header[1]);
804+
output_header_line (header[num_headers - 1]);
794805
header_displayed = 1;
795806
}
796807

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

913+
#define MAX_HEADERS 5
902914
static int filterdiff (FILE *f, const char *patchname)
903915
{
904916
static unsigned long linenum = 1;
905917
char *names[2];
906-
char *header[2] = { NULL, NULL };
918+
char *header[MAX_HEADERS] = { NULL, NULL };
919+
unsigned int num_headers = 0;
907920
char *line = NULL;
908921
size_t linelen = 0;
909922
char *p;
@@ -918,18 +931,22 @@ static int filterdiff (FILE *f, const char *patchname)
918931
char status = '!';
919932
unsigned long start_linenum;
920933
int orig_file_exists, new_file_exists;
921-
int is_context = 0;
934+
int is_context = -1;
922935
int result;
923-
int (*do_diff) (FILE *, char *[2], int, char **, size_t *,
936+
int (*do_diff) (FILE *, char **, unsigned int,
937+
int, char **, size_t *,
924938
unsigned long *, unsigned long,
925939
char, const char *, const char *,
926940
int *, int *);
927941

928942
orig_file_exists = 0; // shut gcc up
929943

930-
// Search for start of patch ("--- " for unified diff,
931-
// "*** " for context).
944+
// Search for start of patch ("diff ", or "--- " for
945+
// unified diff, "*** " for context).
932946
for (;;) {
947+
if (!strncmp (line, "diff ", 5))
948+
break;
949+
933950
if (!strncmp (line, "--- ", 4)) {
934951
is_context = 0;
935952
break;
@@ -953,6 +970,70 @@ static int filterdiff (FILE *f, const char *patchname)
953970

954971
start_linenum = linenum;
955972
header[0] = xstrdup (line);
973+
num_headers = 1;
974+
975+
if (is_context == -1) {
976+
int valid_extended = 1;
977+
for (;;) {
978+
if (getline (&line, &linelen, f) == -1)
979+
goto eof;
980+
linenum++;
981+
982+
if (!strncmp (line, "diff ", 5)) {
983+
header[num_headers++] = xstrdup (line);
984+
break;
985+
}
986+
987+
if (!strncmp (line, "--- ", 4))
988+
is_context = 0;
989+
else if (!strncmp (line, "*** ", 4))
990+
is_context = 1;
991+
else if (strncmp (line, "old mode ", 9) &&
992+
strncmp (line, "new mode ", 9) &&
993+
strncmp (line, "deleted file mode ", 18) &&
994+
strncmp (line, "new file mode ", 15) &&
995+
strncmp (line, "copy from ", 10) &&
996+
strncmp (line, "copy to ", 8) &&
997+
strncmp (line, "rename from ", 12) &&
998+
strncmp (line, "rename to ", 10) &&
999+
strncmp (line, "similarity index ", 17) &&
1000+
strncmp (line, "dissimilarity index ", 20) &&
1001+
strncmp (line, "index ", 6))
1002+
valid_extended = 0;
1003+
1004+
if (!valid_extended)
1005+
break;
1006+
1007+
/* Drop excess header lines */
1008+
if (num_headers < MAX_HEADERS - 2)
1009+
header[num_headers++] = xstrdup (line);
1010+
1011+
if (is_context != -1)
1012+
break;
1013+
}
1014+
1015+
if (!valid_extended)
1016+
goto flush_continue;
1017+
}
1018+
1019+
if (is_context == -1) {
1020+
/* We don't yet do anything with diffs with
1021+
* zero hunks. */
1022+
unsigned int i = 0;
1023+
flush_continue:
1024+
if (mode == mode_filter && (pat_exclude || verbose)
1025+
&& !clean_comments) {
1026+
for (i = 0; i < num_headers; i++)
1027+
fputs (header[i], stdout);
1028+
}
1029+
for (i = 0; i < num_headers; i++) {
1030+
free (header[i]);
1031+
header[i] = NULL;
1032+
}
1033+
num_headers = 0;
1034+
continue;
1035+
}
1036+
9561037
names[0] = filename_from_header (line + 4);
9571038
if (mode != mode_filter && show_status)
9581039
orig_file_exists = file_exists (names[0], line + 4 +
@@ -972,17 +1053,12 @@ static int filterdiff (FILE *f, const char *patchname)
9721053
if (strncmp (line, is_context ? "--- " : "+++ ", 4)) {
9731054
/* Show non-diff lines if excluding, or if
9741055
* in verbose mode, and if --clean isn't specified. */
975-
if (mode == mode_filter && (pat_exclude || verbose)
976-
&& !clean_comments)
977-
fputs (header[0], stdout);
9781056
free (names[0]);
979-
free (header[0]);
980-
header[0] = NULL;
981-
continue;
1057+
goto flush_continue;
9821058
}
9831059

9841060
filecount++;
985-
header[1] = xstrdup (line);
1061+
header[num_headers++] = xstrdup (line);
9861062
names[1] = filename_from_header (line + 4);
9871063

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

1010-
result = do_diff (f, header, match, &line,
1086+
result = do_diff (f, header, num_headers,
1087+
match, &line,
10111088
&linelen, &linenum,
10121089
start_linenum, status, p, patchname,
10131090
&orig_file_exists, &new_file_exists);
@@ -1033,15 +1110,17 @@ static int filterdiff (FILE *f, const char *patchname)
10331110
}
10341111

10351112
next_diff:
1036-
for (i = 0; i < 2; i++) {
1113+
for (i = 0; i < 2; i++)
10371114
free (names[i]);
1115+
for (i = 0; i < num_headers; i++) {
10381116
free (header[i]);
10391117
header[i] = NULL;
10401118
}
1119+
num_headers = 0;
10411120
}
10421121

10431122
eof:
1044-
for (i = 0; i < 2; i++)
1123+
for (i = 0; i < num_headers; i++)
10451124
if (header[i])
10461125
free (header[i]);
10471126

0 commit comments

Comments
 (0)