Blame SOURCES/patchutils-handle_git_extended_headers.patch

7fe9a8
commit 14261ad5461e6c4b3ffc2f87131601ff79e2a0fc
7fe9a8
Author: Tim Waugh <twaugh@redhat.com>
7fe9a8
Date:   Tue Apr 14 17:33:49 2015 +0100
7fe9a8
7fe9a8
    Handle git extended headers.
7fe9a8
    
7fe9a8
    The fullheader1 test case should now pass.
7fe9a8
7fe9a8
diff --git a/src/filterdiff.c b/src/filterdiff.c
7fe9a8
index d6f121e..2870746 100644
7fe9a8
--- a/src/filterdiff.c
7fe9a8
+++ b/src/filterdiff.c
7fe9a8
@@ -279,7 +279,8 @@ hunk_matches (unsigned long orig_offset, unsigned long orig_count,
7fe9a8
 }
7fe9a8
 
7fe9a8
 static int
7fe9a8
-do_unified (FILE *f, char *header[2], int match, char **line,
7fe9a8
+do_unified (FILE *f, char **header, unsigned int num_headers,
7fe9a8
+            int match, char **line,
7fe9a8
 	    size_t *linelen, unsigned long *linenum,
7fe9a8
 	    unsigned long start_linenum, char status,
7fe9a8
 	    const char *bestname, const char *patchname,
7fe9a8
@@ -390,10 +391,13 @@ do_unified (FILE *f, char *header[2], int match, char **line,
7fe9a8
 				if (!header_displayed &&
7fe9a8
 				    mode != mode_grep) {
7fe9a8
 					// Display the header.
7fe9a8
+                                        unsigned int i;
7fe9a8
+                                        for (i = 0; i < num_headers - 2; i++)
7fe9a8
+                                                output_header_line (header[i]);
7fe9a8
 					if (number_lines != After)
7fe9a8
-						output_header_line (header[0]);
7fe9a8
+						output_header_line (header[num_headers - 2]);
7fe9a8
 					if (number_lines != Before)
7fe9a8
-						output_header_line (header[1]);
7fe9a8
+						output_header_line (header[num_headers - 1]);
7fe9a8
 					header_displayed = 1;
7fe9a8
 				}
7fe9a8
 				switch (number_lines) {
7fe9a8
@@ -476,16 +480,16 @@ do_unified (FILE *f, char *header[2], int match, char **line,
7fe9a8
 				}
7fe9a8
 			} else {
7fe9a8
 				if (match_tmpf) {
7fe9a8
-					if (!header_displayed &&
7fe9a8
-					    number_lines != After)
7fe9a8
-						output_header_line (header[0]);
7fe9a8
-
7fe9a8
-					if (!header_displayed &&
7fe9a8
-					    number_lines != Before)
7fe9a8
-						output_header_line (header[1]);
7fe9a8
-
7fe9a8
-					if (!header_displayed)
7fe9a8
+                                        if (!header_displayed) {
7fe9a8
+                                                unsigned int i;
7fe9a8
+                                                for (i = 0; i < num_headers - 2; i++)
7fe9a8
+                                                        output_header_line (header[i]);
7fe9a8
+                                                if (number_lines != After)
7fe9a8
+                                                        output_header_line (header[num_headers - 2]);
7fe9a8
+                                                if (number_lines != Before)
7fe9a8
+                                                        output_header_line (header[num_headers - 1]);
7fe9a8
 						header_displayed = 1;
7fe9a8
+                                        }
7fe9a8
 
7fe9a8
 					rewind (match_tmpf);
7fe9a8
 					while (!feof (match_tmpf)) {
7fe9a8
@@ -533,7 +537,8 @@ do_unified (FILE *f, char *header[2], int match, char **line,
7fe9a8
 }
7fe9a8
 
7fe9a8
 static int
7fe9a8
-do_context (FILE *f, char *header[2], int match, char **line,
7fe9a8
+do_context (FILE *f, char **header, unsigned int num_headers,
7fe9a8
+            int match, char **line,
7fe9a8
 	    size_t *linelen, unsigned long *linenum,
7fe9a8
 	    unsigned long start_linenum, char status,
7fe9a8
 	    const char *bestname, const char *patchname,
7fe9a8
@@ -687,10 +692,13 @@ do_context (FILE *f, char *header[2], int match, char **line,
7fe9a8
 
7fe9a8
 			// Display the line counts.
7fe9a8
 			if (!header_displayed && mode == mode_filter) {
7fe9a8
+                                unsigned int i;
7fe9a8
+                                for (i = 0; i < num_headers - 2; i++)
7fe9a8
+                                        output_header_line (header[i]);
7fe9a8
 				if (number_lines != After)
7fe9a8
-					output_header_line (header[0]);
7fe9a8
+					output_header_line (header[num_headers - 2]);
7fe9a8
 				if (number_lines != Before)
7fe9a8
-					output_header_line (header[1]);
7fe9a8
+					output_header_line (header[num_headers - 1]);
7fe9a8
 				header_displayed = 1;
7fe9a8
 			}
7fe9a8
 
7fe9a8
@@ -787,10 +795,13 @@ do_context (FILE *f, char *header[2], int match, char **line,
7fe9a8
 					}
7fe9a8
 				} else {
7fe9a8
 					if (!header_displayed) {
7fe9a8
+                                                unsigned int i;
7fe9a8
+                                                for (i = 0; i < num_headers - 2; i++)
7fe9a8
+                                                        output_header_line (header[i]);
7fe9a8
 						if (number_lines != After)
7fe9a8
-							output_header_line (header[0]);
7fe9a8
+							output_header_line (header[num_headers - 2]);
7fe9a8
 						if (number_lines != Before)
7fe9a8
-							output_header_line (header[1]);
7fe9a8
+							output_header_line (header[num_headers - 1]);
7fe9a8
 						header_displayed = 1;
7fe9a8
 					}
7fe9a8
 
7fe9a8
@@ -899,11 +910,13 @@ out:
7fe9a8
 	return ret;
7fe9a8
 }
7fe9a8
 
7fe9a8
+#define MAX_HEADERS 5
7fe9a8
 static int filterdiff (FILE *f, const char *patchname)
7fe9a8
 {
7fe9a8
 	static unsigned long linenum = 1;
7fe9a8
 	char *names[2];
7fe9a8
-	char *header[2] = { NULL, NULL };
7fe9a8
+	char *header[MAX_HEADERS] = { NULL, NULL };
7fe9a8
+        unsigned int num_headers = 0;
7fe9a8
 	char *line = NULL;
7fe9a8
 	size_t linelen = 0;
7fe9a8
 	char *p;
7fe9a8
@@ -918,18 +931,22 @@ static int filterdiff (FILE *f, const char *patchname)
7fe9a8
 		char status = '!';
7fe9a8
 		unsigned long start_linenum;
7fe9a8
 		int orig_file_exists, new_file_exists;
7fe9a8
-		int is_context = 0;
7fe9a8
+		int is_context = -1;
7fe9a8
 		int result;
7fe9a8
-		int (*do_diff) (FILE *, char *[2], int, char **, size_t *,
7fe9a8
+		int (*do_diff) (FILE *, char **, unsigned int,
7fe9a8
+                                int, char **, size_t *,
7fe9a8
 				unsigned long *, unsigned long,
7fe9a8
 				char, const char *, const char *,
7fe9a8
 				int *, int *);
7fe9a8
 
7fe9a8
 		orig_file_exists = 0; // shut gcc up
7fe9a8
 
7fe9a8
-		// Search for start of patch ("--- " for unified diff,
7fe9a8
-		// "*** " for context).
7fe9a8
+		// Search for start of patch ("diff ", or "--- " for
7fe9a8
+		// unified diff, "*** " for context).
7fe9a8
 		for (;;) {
7fe9a8
+                        if (!strncmp (line, "diff ", 5))
7fe9a8
+                                break;
7fe9a8
+
7fe9a8
 			if (!strncmp (line, "--- ", 4)) {
7fe9a8
 				is_context = 0;
7fe9a8
 				break;
7fe9a8
@@ -953,6 +970,70 @@ static int filterdiff (FILE *f, const char *patchname)
7fe9a8
 
7fe9a8
 		start_linenum = linenum;
7fe9a8
 		header[0] = xstrdup (line);
7fe9a8
+                num_headers = 1;
7fe9a8
+
7fe9a8
+                if (is_context == -1) {
7fe9a8
+                        int valid_extended = 1;
7fe9a8
+                        for (;;) {
7fe9a8
+                                if (getline (&line, &linelen, f) == -1)
7fe9a8
+                                        goto eof;
7fe9a8
+                                linenum++;
7fe9a8
+
7fe9a8
+                                if (!strncmp (line, "diff ", 5)) {
7fe9a8
+                                        header[num_headers++] = xstrdup (line);
7fe9a8
+                                        break;
7fe9a8
+                                }
7fe9a8
+
7fe9a8
+                                if (!strncmp (line, "--- ", 4))
7fe9a8
+                                        is_context = 0;
7fe9a8
+                                else if (!strncmp (line, "*** ", 4))
7fe9a8
+                                        is_context = 1;
7fe9a8
+                                else if (strncmp (line, "old mode ", 9) &&
7fe9a8
+                                    strncmp (line, "new mode ", 9) &&
7fe9a8
+                                    strncmp (line, "deleted file mode ", 18) &&
7fe9a8
+                                    strncmp (line, "new file mode ", 15) &&
7fe9a8
+                                    strncmp (line, "copy from ", 10) &&
7fe9a8
+                                    strncmp (line, "copy to ", 8) &&
7fe9a8
+                                    strncmp (line, "rename from ", 12) &&
7fe9a8
+                                    strncmp (line, "rename to ", 10) &&
7fe9a8
+                                    strncmp (line, "similarity index ", 17) &&
7fe9a8
+                                    strncmp (line, "dissimilarity index ", 20) &&
7fe9a8
+                                    strncmp (line, "index ", 6))
7fe9a8
+                                        valid_extended = 0;
7fe9a8
+
7fe9a8
+                                if (!valid_extended)
7fe9a8
+                                        break;
7fe9a8
+
7fe9a8
+                                /* Drop excess header lines */
7fe9a8
+                                if (num_headers < MAX_HEADERS - 2)
7fe9a8
+                                        header[num_headers++] = xstrdup (line);
7fe9a8
+
7fe9a8
+                                if (is_context != -1)
7fe9a8
+                                        break;
7fe9a8
+                        }
7fe9a8
+
7fe9a8
+                        if (!valid_extended)
7fe9a8
+                                goto flush_continue;
7fe9a8
+                }
7fe9a8
+
7fe9a8
+                if (is_context == -1) {
7fe9a8
+                        /* We don't yet do anything with diffs with
7fe9a8
+                         * zero hunks. */
7fe9a8
+                        unsigned int i = 0;
7fe9a8
+                flush_continue:
7fe9a8
+                        if (mode == mode_filter && (pat_exclude || verbose)
7fe9a8
+                            && !clean_comments) {
7fe9a8
+                                for (i = 0; i < num_headers; i++)
7fe9a8
+                                        fputs (header[i], stdout);
7fe9a8
+                        }
7fe9a8
+                        for (i = 0; i < num_headers; i++) {
7fe9a8
+                                free (header[i]);
7fe9a8
+                                header[i] = NULL;
7fe9a8
+                        }
7fe9a8
+                        num_headers = 0;
7fe9a8
+                        continue;
7fe9a8
+                }
7fe9a8
+
7fe9a8
 		names[0] = filename_from_header (line + 4);
7fe9a8
 		if (mode != mode_filter && show_status)
7fe9a8
 			orig_file_exists = file_exists (names[0], line + 4 +
7fe9a8
@@ -972,17 +1053,12 @@ static int filterdiff (FILE *f, const char *patchname)
7fe9a8
 		if (strncmp (line, is_context ? "--- " : "+++ ", 4)) {
7fe9a8
 			/* Show non-diff lines if excluding, or if
7fe9a8
 			 * in verbose mode, and if --clean isn't specified. */
7fe9a8
-			if (mode == mode_filter && (pat_exclude || verbose)
7fe9a8
-				&& !clean_comments)
7fe9a8
-				fputs (header[0], stdout);
7fe9a8
 			free (names[0]);
7fe9a8
-			free (header[0]);
7fe9a8
-			header[0] = NULL;
7fe9a8
-			continue;
7fe9a8
+                        goto flush_continue;
7fe9a8
 		}
7fe9a8
 
7fe9a8
 		filecount++;
7fe9a8
-		header[1] = xstrdup (line);
7fe9a8
+		header[num_headers++] = xstrdup (line);
7fe9a8
 		names[1] = filename_from_header (line + 4);
7fe9a8
 
7fe9a8
 		if (mode != mode_filter && show_status)
7fe9a8
@@ -1007,7 +1083,8 @@ static int filterdiff (FILE *f, const char *patchname)
7fe9a8
 		else
7fe9a8
 			do_diff = do_unified;
7fe9a8
 
7fe9a8
-		result = do_diff (f, header, match, &line,
7fe9a8
+		result = do_diff (f, header, num_headers,
7fe9a8
+                                  match, &line,
7fe9a8
 				  &linelen, &linenum,
7fe9a8
 				  start_linenum, status, p, patchname,
7fe9a8
 				  &orig_file_exists, &new_file_exists);
7fe9a8
@@ -1033,15 +1110,17 @@ static int filterdiff (FILE *f, const char *patchname)
7fe9a8
 		}
7fe9a8
 
7fe9a8
 	next_diff:
7fe9a8
-		for (i = 0; i < 2; i++) {
7fe9a8
+		for (i = 0; i < 2; i++)
7fe9a8
 			free (names[i]);
7fe9a8
+                for (i = 0; i < num_headers; i++) {
7fe9a8
 			free (header[i]);
7fe9a8
 			header[i] = NULL;
7fe9a8
 		}
7fe9a8
+                num_headers = 0;
7fe9a8
 	}
7fe9a8
 
7fe9a8
  eof:
7fe9a8
-	for (i = 0; i < 2; i++)
7fe9a8
+	for (i = 0; i < num_headers; i++)
7fe9a8
 		if (header[i])
7fe9a8
 			free (header[i]);
7fe9a8