summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5e224a2)
raw | patch | inline | side by side (parent: 5e224a2)
author | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Mon, 23 May 2005 21:38:49 +0000 (14:38 -0700) | ||
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Mon, 23 May 2005 21:38:49 +0000 (14:38 -0700) |
In particular, give line numbers when detecting corrupt patches.
This makes the tool a lot more friendly (indeed, much more so
than regular "patch", I think).
This makes the tool a lot more friendly (indeed, much more so
than regular "patch", I think).
apply.c | patch | blob | history |
index 536b06829292485e36f1a8a8d83bed094702e49e..05f921a311e51166f824fb3e3e25c4e71ae712c7 100644 (file)
--- a/apply.c
+++ b/apply.c
static int merge_patch = 1;
static const char apply_usage[] = "git-apply <patch>";
+static int linenr = 1;
+
#define CHUNKSIZE (8192)
static void *read_patch_file(int fd, unsigned long *sizep)
{
unsigned long offset, len;
- for (offset = 0 ; size > 0 ; offset += len, size -= len, line += len) {
+ for (offset = 0 ; size > 0 ; offset += len, size -= len, line += len, linenr++) {
len = linelen(line, size);
if (!len)
break;
return offset ? :-1;
}
+static int parse_num(const char *line, int len, int offset, const char *expect, unsigned long *p)
+{
+ char *ptr;
+ int digits, ex;
+
+ if (offset < 0 || offset >= len)
+ return -1;
+ line += offset;
+ len -= offset;
+
+ if (!isdigit(*line))
+ return -1;
+ *p = strtoul(line, &ptr, 10);
+
+ digits = ptr - line;
+
+ offset += digits;
+ line += digits;
+ len -= digits;
+
+ ex = strlen(expect);
+ if (ex > len)
+ return -1;
+ if (memcmp(line, expect, ex))
+ return -1;
+
+ return offset + ex;
+}
+
+/*
+ * Parse a unified diff fragment header of the
+ * form "@@ -a,b +c,d @@"
+ */
+static int parse_fragment_header(char *line, int len, unsigned long *pos)
+{
+ int offset;
+
+ if (!len || line[len-1] != '\n')
+ return -1;
+
+ /* Figure out the number of lines in a fragment */
+ offset = parse_num(line, len, 4, ",", pos);
+ offset = parse_num(line, len, offset, " +", pos+1);
+ offset = parse_num(line, len, offset, ",", pos+2);
+ offset = parse_num(line, len, offset, " @@", pos+3);
+
+ return offset;
+}
+
static int find_header(char *line, unsigned long size, int *hdrsize)
{
unsigned long offset, len;
- for (offset = 0; size > 0; offset += len, size -= len, line += len) {
+ for (offset = 0; size > 0; offset += len, size -= len, line += len, linenr++) {
unsigned long nextlen;
len = linelen(line, size);
/* Testing this early allows us to take a few shortcuts.. */
if (len < 6)
continue;
+
+ /*
+ * Make sure we don't find any unconnected patch fragmants.
+ * That's a sign that we didn't find a header, and that a
+ * patch has become corrupted/broken up.
+ */
+ if (!memcmp("@@ -", line, 4)) {
+ unsigned long pos[4];
+ if (parse_fragment_header(line, len, pos) < 0)
+ continue;
+ error("patch fragment without header at line %d: %.*s", linenr, len-1, line);
+ }
+
if (size < len + 6)
break;
/* Ok, we'll consider it a patch */
*hdrsize = len + nextlen;
+ linenr += 2;
return offset;
}
return -1;
}
-static int parse_num(const char *line, int len, int offset, const char *expect, unsigned long *p)
-{
- char *ptr;
- int digits, ex;
-
- if (offset < 0 || offset >= len)
- return -1;
- line += offset;
- len -= offset;
-
- if (!isdigit(*line))
- return -1;
- *p = strtoul(line, &ptr, 10);
-
- digits = ptr - line;
-
- offset += digits;
- line += digits;
- len -= digits;
-
- ex = strlen(expect);
- if (ex > len)
- return -1;
- if (memcmp(line, expect, ex))
- return -1;
-
- return offset + ex;
-}
-
/*
* Parse a unified diff. Note that this really needs
* to parse each fragment separately, since the only
@@ -193,23 +229,19 @@ static int parse_num(const char *line, int len, int offset, const char *expect,
static int apply_fragment(char *line, unsigned long size)
{
int len = linelen(line, size), offset;
- unsigned long oldpos, oldlines, newpos, newlines;
+ unsigned long pos[4], oldlines, newlines;
- if (!len || line[len-1] != '\n')
- return -1;
-
- /* Figure out the number of lines in a fragment */
- offset = parse_num(line, len, 4, ",", &oldpos);
- offset = parse_num(line, len, offset, " +", &oldlines);
- offset = parse_num(line, len, offset, ",", &newpos);
- offset = parse_num(line, len, offset, " @@", &newlines);
+ offset = parse_fragment_header(line, len, pos);
if (offset < 0)
return -1;
+ oldlines = pos[1];
+ newlines = pos[3];
/* Parse the thing.. */
line += len;
size -= len;
- for (offset = len; size > 0; offset += len, size -= len, line += len) {
+ linenr++;
+ for (offset = len; size > 0; offset += len, size -= len, line += len, linenr++) {
if (!oldlines && !newlines)
break;
len = linelen(line, size);
while (size > 4 && !memcmp(line, "@@ -", 4)) {
int len = apply_fragment(line, size);
if (len <= 0)
- die("corrupt patch");
+ die("corrupt patch at line %d", linenr);
printf("applying fragment:\n%.*s\n\n", len, line);