X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=diff.c;h=1c6be897b2c95fc481c02834e4fe022b6bd405ae;hb=18e143487ddb5b32b2f6003972d2115bb4ac460f;hp=a2f4850d4fdf3758b75cc086e47e18736075c999;hpb=de813435621b914f2b3e148c6cc94ab0066300c3;p=git.git diff --git a/diff.c b/diff.c index a2f4850d4..1c6be897b 100644 --- a/diff.c +++ b/diff.c @@ -96,32 +96,37 @@ static int parse_lldiff_command(const char *var, const char *ep, const char *val * to define a customized regexp to find the beginning of a function to * be used for hunk header lines of "diff -p" style output. */ -static struct funcname_pattern { +struct funcname_pattern_entry { char *name; char *pattern; - struct funcname_pattern *next; + int cflags; +}; +static struct funcname_pattern_list { + struct funcname_pattern_list *next; + struct funcname_pattern_entry e; } *funcname_pattern_list; -static int parse_funcname_pattern(const char *var, const char *ep, const char *value) +static int parse_funcname_pattern(const char *var, const char *ep, const char *value, int cflags) { const char *name; int namelen; - struct funcname_pattern *pp; + struct funcname_pattern_list *pp; name = var + 5; /* "diff." */ namelen = ep - name; for (pp = funcname_pattern_list; pp; pp = pp->next) - if (!strncmp(pp->name, name, namelen) && !pp->name[namelen]) + if (!strncmp(pp->e.name, name, namelen) && !pp->e.name[namelen]) break; if (!pp) { pp = xcalloc(1, sizeof(*pp)); - pp->name = xmemdupz(name, namelen); + pp->e.name = xmemdupz(name, namelen); pp->next = funcname_pattern_list; funcname_pattern_list = pp; } - free(pp->pattern); - pp->pattern = xstrdup(value); + free(pp->e.pattern); + pp->e.pattern = xstrdup(value); + pp->e.cflags = cflags; return 0; } @@ -194,7 +199,13 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) if (!strcmp(ep, ".funcname")) { if (!value) return config_error_nonbool(var); - return parse_funcname_pattern(var, ep, value); + return parse_funcname_pattern(var, ep, value, + 0); + } else if (!strcmp(ep, ".xfuncname")) { + if (!value) + return config_error_nonbool(var); + return parse_funcname_pattern(var, ep, value, + REG_EXTENDED); } } } @@ -206,9 +217,8 @@ static char *quote_two(const char *one, const char *two) { int need_one = quote_c_style(one, NULL, NULL, 1); int need_two = quote_c_style(two, NULL, NULL, 1); - struct strbuf res; + struct strbuf res = STRBUF_INIT; - strbuf_init(&res, 0); if (need_one + need_two) { strbuf_addch(&res, '"'); quote_c_style(one, &res, NULL, 1); @@ -672,7 +682,7 @@ static char *pprint_rename(const char *a, const char *b) { const char *old = a; const char *new = b; - struct strbuf name; + struct strbuf name = STRBUF_INIT; int pfx_length, sfx_length; int len_a = strlen(a); int len_b = strlen(b); @@ -680,7 +690,6 @@ static char *pprint_rename(const char *a, const char *b) int qlen_a = quote_c_style(a, NULL, NULL, 0); int qlen_b = quote_c_style(b, NULL, NULL, 0); - strbuf_init(&name, 0); if (qlen_a || qlen_b) { quote_c_style(a, &name, NULL, 0); strbuf_addstr(&name, " => "); @@ -823,8 +832,7 @@ static void fill_print_name(struct diffstat_file *file) return; if (!file->is_renamed) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; if (quote_c_style(file->name, &buf, NULL, 0)) { pname = strbuf_detach(&buf, NULL); } else { @@ -1400,42 +1408,53 @@ int diff_filespec_is_binary(struct diff_filespec *one) return one->is_binary; } -static const char *funcname_pattern(const char *ident) +static const struct funcname_pattern_entry *funcname_pattern(const char *ident) { - struct funcname_pattern *pp; + struct funcname_pattern_list *pp; for (pp = funcname_pattern_list; pp; pp = pp->next) - if (!strcmp(ident, pp->name)) - return pp->pattern; + if (!strcmp(ident, pp->e.name)) + return &pp->e; return NULL; } -static struct builtin_funcname_pattern { - const char *name; - const char *pattern; -} builtin_funcname_pattern[] = { - { "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" }, - { "html", "^\\s*\\(<[Hh][1-6]\\s.*>.*\\)$" }, - { "java", "!^[ ]*\\(catch\\|do\\|for\\|if\\|instanceof\\|" - "new\\|return\\|switch\\|throw\\|while\\)\n" - "^[ ]*\\(\\([ ]*" - "[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}" - "[ ]*([^;]*\\)$" }, - { "pascal", "^\\(\\(procedure\\|function\\|constructor\\|" - "destructor\\|interface\\|implementation\\|" - "initialization\\|finalization\\)[ \t]*.*\\)$" - "\\|" - "^\\(.*=[ \t]*\\(class\\|record\\).*\\)$" - }, - { "php", "^[\t ]*\\(\\(function\\|class\\).*\\)" }, - { "python", "^\\s*\\(\\(class\\|def\\)\\s.*\\)$" }, - { "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" }, - { "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" }, +static const struct funcname_pattern_entry builtin_funcname_pattern[] = { + { "bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$", + REG_EXTENDED }, + { "html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$", REG_EXTENDED }, + { "java", + "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n" + "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$", + REG_EXTENDED }, + { "objc", + /* Negate C statements that can look like functions */ + "!^[ \t]*(do|for|if|else|return|switch|while)\n" + /* Objective-C methods */ + "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n" + /* C functions */ + "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n" + /* Objective-C class/protocol definitions */ + "^(@(implementation|interface|protocol)[ \t].*)$", + REG_EXTENDED }, + { "pascal", + "^((procedure|function|constructor|destructor|interface|" + "implementation|initialization|finalization)[ \t]*.*)$" + "\n" + "^(.*=[ \t]*(class|record).*)$", + REG_EXTENDED }, + { "php", "^[\t ]*((function|class).*)", REG_EXTENDED }, + { "python", "^[ \t]*((class|def)[ \t].*)$", REG_EXTENDED }, + { "ruby", "^[ \t]*((class|module|def)[ \t].*)$", + REG_EXTENDED }, + { "tex", + "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$", + REG_EXTENDED }, }; -static const char *diff_funcname_pattern(struct diff_filespec *one) +static const struct funcname_pattern_entry *diff_funcname_pattern(struct diff_filespec *one) { - const char *ident, *pattern; + const char *ident; + const struct funcname_pattern_entry *pe; int i; diff_filespec_check_attr(one); @@ -1450,9 +1469,9 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) return funcname_pattern("default"); /* Look up custom "funcname.$ident" regexp from config. */ - pattern = funcname_pattern(ident); - if (pattern) - return pattern; + pe = funcname_pattern(ident); + if (pe) + return pe; /* * And define built-in fallback patterns here. Note that @@ -1460,7 +1479,7 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) */ for (i = 0; i < ARRAY_SIZE(builtin_funcname_pattern); i++) if (!strcmp(ident, builtin_funcname_pattern[i].name)) - return builtin_funcname_pattern[i].pattern; + return &builtin_funcname_pattern[i]; return NULL; } @@ -1497,6 +1516,10 @@ static void builtin_diff(const char *name_a, b_prefix = o->b_prefix; } + /* Never use a non-valid filename anywhere if at all possible */ + name_a = DIFF_FILE_VALID(one) ? name_a : name_b; + name_b = DIFF_FILE_VALID(two) ? name_b : name_a; + a_one = quote_two(a_prefix, name_a + (*name_a == '/')); b_two = quote_two(b_prefix, name_b + (*name_b == '/')); lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null"; @@ -1556,11 +1579,11 @@ static void builtin_diff(const char *name_a, xdemitconf_t xecfg; xdemitcb_t ecb; struct emit_callback ecbdata; - const char *funcname_pattern; + const struct funcname_pattern_entry *pe; - funcname_pattern = diff_funcname_pattern(one); - if (!funcname_pattern) - funcname_pattern = diff_funcname_pattern(two); + pe = diff_funcname_pattern(one); + if (!pe) + pe = diff_funcname_pattern(two); memset(&xecfg, 0, sizeof(xecfg)); memset(&ecbdata, 0, sizeof(ecbdata)); @@ -1572,8 +1595,8 @@ static void builtin_diff(const char *name_a, xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; xecfg.flags = XDL_EMIT_FUNCNAMES; - if (funcname_pattern) - xdiff_set_find_func(&xecfg, funcname_pattern); + if (pe) + xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags); if (!diffopts) ; else if (!prefixcmp(diffopts, "--unified=")) @@ -1794,10 +1817,9 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int static int populate_from_stdin(struct diff_filespec *s) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; size_t size = 0; - strbuf_init(&buf, 0); if (strbuf_read(&buf, 0, 0) < 0) return error("error while reading from stdin %s", strerror(errno)); @@ -1849,7 +1871,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) if (!s->sha1_valid || reuse_worktree_file(s->path, s->sha1, 0)) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; struct stat st; int fd; @@ -1892,7 +1914,6 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) /* * Convert from working tree format to canonical git format */ - strbuf_init(&buf, 0); if (convert_to_git(s->path, s->data, s->size, &buf, safe_crlf)) { size_t size = 0; munmap(s->data, s->size); @@ -3075,7 +3096,7 @@ static void diff_summary(FILE *file, struct diff_filepair *p) } struct patch_id_t { - SHA_CTX *ctx; + git_SHA_CTX *ctx; int patchlen; }; @@ -3103,7 +3124,7 @@ static void patch_id_consume(void *priv, char *line, unsigned long len) new_len = remove_space(line, len); - SHA1_Update(data->ctx, line, new_len); + git_SHA1_Update(data->ctx, line, new_len); data->patchlen += new_len; } @@ -3112,11 +3133,11 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1) { struct diff_queue_struct *q = &diff_queued_diff; int i; - SHA_CTX ctx; + git_SHA_CTX ctx; struct patch_id_t data; char buffer[PATH_MAX * 4 + 20]; - SHA1_Init(&ctx); + git_SHA1_Init(&ctx); memset(&data, 0, sizeof(struct patch_id_t)); data.ctx = &ctx; @@ -3178,7 +3199,7 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1) len2, p->two->path, len1, p->one->path, len2, p->two->path); - SHA1_Update(&ctx, buffer, len1); + git_SHA1_Update(&ctx, buffer, len1); xpp.flags = XDF_NEED_MINIMAL; xecfg.ctxlen = 3; @@ -3187,7 +3208,7 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1) &xpp, &xecfg, &ecb); } - SHA1_Final(sha1, &ctx); + git_SHA1_Final(sha1, &ctx); return 0; }