commit - d50c8991ddc68e92266707a26186b792429d767f
commit + 235b06458a4e60a61dced04eccef13dfe62c270e
blob - 859db450301302dc99c3de2be338542c3ced2112
blob + 9eefe7a7a92b333c9eb4231c478f26c9255591d7
--- lib/patch.c
+++ lib/patch.c
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
+struct got_patch_line {
+ char mode;
+ char *line;
+ size_t len;
+};
+
struct got_patch_hunk {
STAILQ_ENTRY(got_patch_hunk) entries;
const struct got_error *err;
int new_lines;
size_t len;
size_t cap;
- char **lines;
+ struct got_patch_line *lines;
};
STAILQ_HEAD(got_patch_hunk_head, got_patch_hunk);
STAILQ_REMOVE_HEAD(&p->head, entries);
for (i = 0; i < h->len; ++i)
- free(h->lines[i]);
+ free(h->lines[i].line);
free(h->lines);
free(h);
}
}
static const struct got_error *
-pushline(struct got_patch_hunk *h, const char *line)
+pushline(struct got_patch_hunk *h, const char *line, size_t len)
{
void *t;
size_t newcap;
h->cap = newcap;
}
- if ((t = strdup(line)) == NULL)
- return got_error_from_errno("strdup");
+ if ((t = malloc(len - 1)) == NULL)
+ return got_error_from_errno("malloc");
+ memcpy(t, line + 1, len - 1); /* skip the line type */
- h->lines[h->len++] = t;
+ h->lines[h->len].mode = *line;
+ h->lines[h->len].line = t;
+ h->lines[h->len].len = len - 2; /* line type and trailing NUL */
+ h->len++;
return NULL;
}
}
if (*t != '\\')
- err = pushline(h, t);
+ err = pushline(h, t, datalen);
else if (lastmode == '-')
h->old_nonl = 1;
else if (lastmode == '+')
h->new_nonl = tmp;
for (i = 0; i < h->len; ++i) {
- if (*h->lines[i] == '+')
- *h->lines[i] = '-';
- else if (*h->lines[i] == '-')
- *h->lines[i] = '+';
+ if (h->lines[i].mode == '+')
+ h->lines[i].mode = '-';
+ else if (h->lines[i].mode == '-')
+ h->lines[i].mode = '+';
}
}
}
return NULL;
}
-static int linecmp(const char *, const char *, int *);
+static int lines_eq(struct got_patch_line *, const char *, size_t, int *);
static const struct got_error *
locate_hunk(FILE *orig, struct got_patch_hunk *h, off_t *pos, int *lineno)
{
const struct got_error *err = NULL;
+ struct got_patch_line *l = &h->lines[0];
char *line = NULL;
- char mode = *h->lines[0];
+ char mode = l->mode;
size_t linesize = 0;
ssize_t linelen;
off_t match = -1;
err = got_error(GOT_ERR_HUNK_FAILED);
break;
}
- if (line[linelen - 1] == '\n')
- line[linelen - 1] = '\0';
(*lineno)++;
- if ((mode == ' ' && !linecmp(h->lines[0] + 1, line, &mangled)) ||
- (mode == '-' && !linecmp(h->lines[0] + 1, line, &mangled)) ||
+ if ((mode == ' ' && lines_eq(l, line, linelen, &mangled)) ||
+ (mode == '-' && lines_eq(l, line, linelen, &mangled)) ||
(mode == '+' && *lineno == h->old_from)) {
match = ftello(orig);
if (match == -1) {
}
static int
-linecmp(const char *a, const char *b, int *mangled)
+lines_eq(struct got_patch_line *l, const char *b, size_t len, int *mangled)
{
- int c;
+ char *a = l->line;
+ size_t i, j;
+ if (len > 00 && b[len - 1] == '\n')
+ len--;
+
*mangled = 0;
- c = strcmp(a, b);
- if (c == 0)
- return c;
+ if (l->len == len && !memcmp(a, b, len))
+ return 1;
*mangled = 1;
+
+ i = j = 0;
for (;;) {
- while (*a == '\t' || *a == ' ' || *a == '\f')
- a++;
- while (*b == '\t' || *b == ' ' || *b == '\f')
- b++;
- if (*a == '\0' || *a != *b)
+ while (i < l->len &&
+ (a[i] == '\t' || a[i] == ' ' || a[i] == '\f'))
+ i++;
+ while (j < len &&
+ (b[j] == '\t' || b[j] == ' ' || b[j] == '\f'))
+ j++;
+ if (i == l->len || j == len || a[i] != b[j])
break;
- a++, b++;
+ i++, j++;
}
- return *a - *b;
+ return (i == l->len && j == len);
}
static const struct got_error *
int mangled;
for (i = 0; i < h->len; ++i) {
- switch (*h->lines[i]) {
+ switch (h->lines[i].mode) {
case '+':
continue;
case ' ':
GOT_ERR_HUNK_FAILED);
goto done;
}
- if (line[linelen - 1] == '\n')
- line[linelen - 1] = '\0';
- if (linecmp(h->lines[i] + 1, line, &mangled)) {
+ if (!lines_eq(&h->lines[i], line, linelen, &mangled)) {
err = got_error(GOT_ERR_HUNK_FAILED);
goto done;
}
size_t linesize = 0, i, new = 0;
char *line = NULL;
char mode;
+ size_t l;
ssize_t linelen;
if (orig != NULL && fseeko(orig, from, SEEK_SET) == -1)
return got_error_from_errno("fseeko");
for (i = 0; i < h->len; ++i) {
- switch (mode = *h->lines[i]) {
+ switch (mode = h->lines[i].mode) {
case '-':
case ' ':
(*lineno)++;
if (line[linelen - 1] == '\n')
line[linelen - 1] = '\0';
t = line;
- } else
- t = h->lines[i] + 1;
+ l = linelen - 1;
+ } else {
+ t = h->lines[i].line;
+ l = h->lines[i].len;
+ }
if (mode == '-')
continue;
- if (fprintf(tmp, "%s\n", t) < 0) {
+ if (fwrite(t, 1, l, tmp) != l ||
+ fputc('\n', tmp) == EOF) {
err = got_error_from_errno("fprintf");
goto done;
}
break;
case '+':
new++;
- if (fprintf(tmp, "%s", h->lines[i] + 1) < 0) {
+ t = h->lines[i].line;
+ l = h->lines[i].len;
+ if (fwrite(t, 1, l, tmp) != l) {
err = got_error_from_errno("fprintf");
goto done;
}
blob - 356a98a6a2717f7b336945d2f9e218faf421ebda
blob + 2bd03989ae5d34928f3c1eada815a2c0085adfca
--- libexec/got-read-patch/got-read-patch.c
+++ libexec/got-read-patch/got-read-patch.c
}
static const struct got_error *
-send_line(const char *line)
+send_line(const char *line, size_t len)
{
static const struct got_error *err = NULL;
- char *p = NULL;
+ struct iovec iov[2];
+ int iovcnt = 0;
+ memset(&iov, 0, sizeof(iov));
+
if (*line != '+' && *line != '-' && *line != ' ' && *line != '\\') {
- if (asprintf(&p, " %s", line) == -1)
- return got_error_from_errno("asprintf");
- line = p;
+ iov[iovcnt].iov_base = (void *)" ";
+ iov[iovcnt].iov_len = 1;
+ iovcnt++;
}
- if (imsg_compose(&ibuf, GOT_IMSG_PATCH_LINE, 0, 0, -1,
- line, strlen(line) + 1) == -1)
+ iov[iovcnt].iov_base = (void *)line;
+ iov[iovcnt].iov_len = len;
+ iovcnt++;
+
+ if (imsg_composev(&ibuf, GOT_IMSG_PATCH_LINE, 0, 0, -1,
+ iov, iovcnt) == -1)
err = got_error_from_errno(
"imsg_compose GOT_IMSG_PATCH_LINE");
- free(p);
return err;
}
}
if (ch == '\\') {
- err = send_line("\\");
+ err = send_line("\\", 2);
if (err)
return err;
}
goto done;
}
- err = send_line(line);
+ err = send_line(line, linelen);
if (err)
goto done;