X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=diff.c;h=361d7c09ddfad2cb7e1589367ec74bad8f9ca67d;hb=c742b813971a415fea6e623de4d9e45286a0a976;hp=a72029058e195c596ab958e26cc0176cb0dc6b1c;hpb=36e4d74a210ba618e1520f11ce7fc2f8baec5bb8;p=git.git diff --git a/diff.c b/diff.c index a7202905..361d7c09 100644 --- a/diff.c +++ b/diff.c @@ -5,6 +5,7 @@ #include #include #include "cache.h" +#include "quote.h" #include "diff.h" #include "diffcore.h" @@ -40,42 +41,6 @@ static const char *external_diff(void) return external_diff_cmd; } -/* Help to copy the thing properly quoted for the shell safety. - * any single quote is replaced with '\'', and the caller is - * expected to enclose the result within a single quote pair. - * - * E.g. - * original sq_expand result - * name ==> name ==> 'name' - * a b ==> a b ==> 'a b' - * a'b ==> a'\''b ==> 'a'\''b' - */ -static char *sq_expand(const char *src) -{ - static char *buf = NULL; - int cnt, c; - const char *cp; - char *bp; - - /* count bytes needed to store the quoted string. */ - for (cnt = 1, cp = src; *cp; cnt++, cp++) - if (*cp == '\'') - cnt += 3; - - buf = xmalloc(cnt); - bp = buf; - while ((c = *src++)) { - if (c != '\'') - *bp++ = c; - else { - bp = strcpy(bp, "'\\''"); - bp += 4; - } - } - *bp = 0; - return buf; -} - static struct diff_tempfile { const char *name; /* filename external diff should read from */ char hex[41]; @@ -167,16 +132,16 @@ static void builtin_diff(const char *name_a, int complete_rewrite) { int i, next_at, cmd_size; - const char *diff_cmd = "diff -L'%s%s' -L'%s%s'"; - const char *diff_arg = "'%s' '%s'||:"; /* "||:" is to return 0 */ + const char *diff_cmd = "diff -L%s%s -L%s%s"; + const char *diff_arg = "%s %s||:"; /* "||:" is to return 0 */ const char *input_name_sq[2]; const char *path0[2]; const char *path1[2]; const char *name_sq[2]; char *cmd; - name_sq[0] = sq_expand(name_a); - name_sq[1] = sq_expand(name_b); + name_sq[0] = sq_quote(name_a); + name_sq[1] = sq_quote(name_b); /* diff_cmd and diff_arg have 6 %s in total which makes * the sum of these strings 12 bytes larger than required. @@ -186,7 +151,7 @@ static void builtin_diff(const char *name_a, cmd_size = (strlen(diff_cmd) + strlen(diff_opts) + strlen(diff_arg) - 9); for (i = 0; i < 2; i++) { - input_name_sq[i] = sq_expand(temp[i].name); + input_name_sq[i] = sq_quote(temp[i].name); if (!strcmp(temp[i].name, "/dev/null")) { path0[i] = "/dev/null"; path1[i] = ""; @@ -412,8 +377,10 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) if (fd < 0) goto err_empty; s->data = mmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0); - s->should_munmap = 1; close(fd); + if (s->data == MAP_FAILED) + goto err_empty; + s->should_munmap = 1; } else { char type[20]; @@ -652,7 +619,7 @@ static void run_diff(struct diff_filepair *p) other = (strcmp(name, p->two->path) ? p->two->path : NULL); one = p->one; two = p->two; switch (p->status) { - case 'C': + case DIFF_STATUS_COPIED: sprintf(msg_, "similarity index %d%%\n" "copy from %s\n" @@ -661,7 +628,7 @@ static void run_diff(struct diff_filepair *p) name, other); xfrm_msg = msg_; break; - case 'R': + case DIFF_STATUS_RENAMED: sprintf(msg_, "similarity index %d%%\n" "rename from %s\n" @@ -670,7 +637,7 @@ static void run_diff(struct diff_filepair *p) name, other); xfrm_msg = msg_; break; - case 'M': + case DIFF_STATUS_MODIFIED: if (p->score) { sprintf(msg_, "dissimilarity index %d%%", @@ -831,10 +798,12 @@ static void diff_flush_raw(struct diff_filepair *p, status[1] = 0; } switch (p->status) { - case 'C': case 'R': + case DIFF_STATUS_COPIED: + case DIFF_STATUS_RENAMED: two_paths = 1; break; - case 'N': case 'D': + case DIFF_STATUS_ADDED: + case DIFF_STATUS_DELETED: two_paths = 0; break; default: @@ -853,6 +822,12 @@ static void diff_flush_raw(struct diff_filepair *p, putchar(line_termination); } +static void diff_flush_name(struct diff_filepair *p, + int line_termination) +{ + printf("%s%c", p->two->path, line_termination); +} + int diff_unmodified_pair(struct diff_filepair *p) { /* This function is written stricter than necessary to support @@ -957,13 +932,13 @@ static void diff_resolve_rename_copy(void) p = q->queue[i]; p->status = 0; /* undecided */ if (DIFF_PAIR_UNMERGED(p)) - p->status = 'U'; + p->status = DIFF_STATUS_UNMERGED; else if (!DIFF_FILE_VALID(p->one)) - p->status = 'N'; + p->status = DIFF_STATUS_ADDED; else if (!DIFF_FILE_VALID(p->two)) - p->status = 'D'; + p->status = DIFF_STATUS_DELETED; else if (DIFF_PAIR_TYPE_CHANGED(p)) - p->status = 'T'; + p->status = DIFF_STATUS_TYPE_CHANGED; /* from this point on, we are dealing with a pair * whose both sides are valid and of the same type, i.e. @@ -971,7 +946,7 @@ static void diff_resolve_rename_copy(void) */ else if (DIFF_PAIR_RENAME(p)) { if (p->source_stays) { - p->status = 'C'; + p->status = DIFF_STATUS_COPIED; continue; } /* See if there is some other filepair that @@ -985,41 +960,40 @@ static void diff_resolve_rename_copy(void) if (!DIFF_PAIR_RENAME(pp)) continue; /* not a rename/copy */ /* pp is a rename/copy from the same source */ - p->status = 'C'; + p->status = DIFF_STATUS_COPIED; break; } if (!p->status) - p->status = 'R'; + p->status = DIFF_STATUS_RENAMED; } else if (memcmp(p->one->sha1, p->two->sha1, 20) || p->one->mode != p->two->mode) - p->status = 'M'; + p->status = DIFF_STATUS_MODIFIED; else { /* This is a "no-change" entry and should not * happen anymore, but prepare for broken callers. */ error("feeding unmodified %s to diffcore", p->one->path); - p->status = 'X'; + p->status = DIFF_STATUS_UNKNOWN; } } diff_debug_queue("resolve-rename-copy done", q); } -void diff_flush(int diff_output_style) +void diff_flush(int diff_output_style, int line_termination) { struct diff_queue_struct *q = &diff_queued_diff; int i; - int line_termination = '\n'; int inter_name_termination = '\t'; - if (diff_output_style == DIFF_FORMAT_MACHINE) - line_termination = inter_name_termination = 0; + if (!line_termination) + inter_name_termination = 0; for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; if ((diff_output_style == DIFF_FORMAT_NO_OUTPUT) || - (p->status == 'X')) + (p->status == DIFF_STATUS_UNKNOWN)) continue; if (p->status == 0) die("internal error in diff-resolve-rename-copy"); @@ -1027,11 +1001,13 @@ void diff_flush(int diff_output_style) case DIFF_FORMAT_PATCH: diff_flush_patch(p); break; - case DIFF_FORMAT_HUMAN: - case DIFF_FORMAT_MACHINE: + case DIFF_FORMAT_RAW: diff_flush_raw(p, line_termination, inter_name_termination); break; + case DIFF_FORMAT_NAME: + diff_flush_name(p, line_termination); + break; } } for (i = 0; i < q->nr; i++) @@ -1052,15 +1028,17 @@ static void diffcore_apply_filter(const char *filter) if (!filter) return; - if (strchr(filter, 'A')) { - /* All-or-none */ + if (strchr(filter, DIFF_STATUS_FILTER_AON)) { int found; for (i = found = 0; !found && i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - if (((p->status == 'M') && - ((p->score && strchr(filter, 'B')) || - (!p->score && strchr(filter, 'M')))) || - ((p->status != 'M') && strchr(filter, p->status))) + if (((p->status == DIFF_STATUS_MODIFIED) && + ((p->score && + strchr(filter, DIFF_STATUS_FILTER_BROKEN)) || + (!p->score && + strchr(filter, DIFF_STATUS_MODIFIED)))) || + ((p->status != DIFF_STATUS_MODIFIED) && + strchr(filter, p->status))) found++; } if (found) @@ -1078,10 +1056,14 @@ static void diffcore_apply_filter(const char *filter) /* Only the matching ones */ for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - if (((p->status == 'M') && - ((p->score && strchr(filter, 'B')) || - (!p->score && strchr(filter, 'M')))) || - ((p->status != 'M') && strchr(filter, p->status))) + + if (((p->status == DIFF_STATUS_MODIFIED) && + ((p->score && + strchr(filter, DIFF_STATUS_FILTER_BROKEN)) || + (!p->score && + strchr(filter, DIFF_STATUS_MODIFIED)))) || + ((p->status != DIFF_STATUS_MODIFIED) && + strchr(filter, p->status))) diff_q(&outq, p); else diff_free_filepair(p);