From: Junio C Hamano Date: Fri, 14 Mar 2014 21:25:31 +0000 (-0700) Subject: Merge branch 'nd/no-more-fnmatch' X-Git-Tag: v2.0.0-rc0~124 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/650c90a18506ce05e2be349d83fe1cef3dc7f8cb?ds=inline;hp=-c Merge branch 'nd/no-more-fnmatch' We started using wildmatch() in place of fnmatch(3); complete the process and stop using fnmatch(3). * nd/no-more-fnmatch: actually remove compat fnmatch source code stop using fnmatch (either native or compat) Revert "test-wildmatch: add "perf" command to compare wildmatch and fnmatch" use wildmatch() directly without fnmatch() wrapper --- 650c90a18506ce05e2be349d83fe1cef3dc7f8cb diff --combined Makefile index d4ce53a71b,ca38f99404..a20fbafd62 --- a/Makefile +++ b/Makefile @@@ -101,14 -101,6 +101,6 @@@ all: # # Define NO_MKSTEMPS if you don't have mkstemps in the C library. # - # Define NO_FNMATCH if you don't have fnmatch in the C library. - # - # Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the - # FNM_CASEFOLD GNU extension. - # - # Define NO_WILDMATCH if you do not want to use Git's wildmatch - # implementation as fnmatch - # # Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd # in the C library. # @@@ -555,7 -547,6 +547,7 @@@ TEST_PROGRAMS_NEED_X += test-dat TEST_PROGRAMS_NEED_X += test-delta TEST_PROGRAMS_NEED_X += test-dump-cache-tree TEST_PROGRAMS_NEED_X += test-genrandom +TEST_PROGRAMS_NEED_X += test-hashmap TEST_PROGRAMS_NEED_X += test-index-version TEST_PROGRAMS_NEED_X += test-line-buffer TEST_PROGRAMS_NEED_X += test-match-trees @@@ -664,8 -655,6 +656,8 @@@ LIB_H += diff. LIB_H += diffcore.h LIB_H += dir.h LIB_H += exec_cmd.h +LIB_H += ewah/ewok.h +LIB_H += ewah/ewok_rlw.h LIB_H += fetch-pack.h LIB_H += fmt-merge-msg.h LIB_H += fsck.h @@@ -674,7 -663,7 +666,7 @@@ LIB_H += git-compat-util. LIB_H += gpg-interface.h LIB_H += graph.h LIB_H += grep.h -LIB_H += hash.h +LIB_H += hashmap.h LIB_H += help.h LIB_H += http.h LIB_H += kwset.h @@@ -693,10 -682,8 +685,10 @@@ LIB_H += notes-merge. LIB_H += notes-utils.h LIB_H += notes.h LIB_H += object.h +LIB_H += pack-objects.h LIB_H += pack-revindex.h LIB_H += pack.h +LIB_H += pack-bitmap.h LIB_H += parse-options.h LIB_H += patch-ids.h LIB_H += pathspec.h @@@ -800,10 -787,6 +792,10 @@@ LIB_OBJS += dir. LIB_OBJS += editor.o LIB_OBJS += entry.o LIB_OBJS += environment.o +LIB_OBJS += ewah/bitmap.o +LIB_OBJS += ewah/ewah_bitmap.o +LIB_OBJS += ewah/ewah_io.o +LIB_OBJS += ewah/ewah_rlw.o LIB_OBJS += exec_cmd.o LIB_OBJS += fetch-pack.o LIB_OBJS += fsck.o @@@ -811,7 -794,7 +803,7 @@@ LIB_OBJS += gettext. LIB_OBJS += gpg-interface.o LIB_OBJS += graph.o LIB_OBJS += grep.o -LIB_OBJS += hash.o +LIB_OBJS += hashmap.o LIB_OBJS += help.o LIB_OBJS += hex.o LIB_OBJS += ident.o @@@ -835,10 -818,7 +827,10 @@@ LIB_OBJS += notes-cache. LIB_OBJS += notes-merge.o LIB_OBJS += notes-utils.o LIB_OBJS += object.o +LIB_OBJS += pack-bitmap.o +LIB_OBJS += pack-bitmap-write.o LIB_OBJS += pack-check.o +LIB_OBJS += pack-objects.o LIB_OBJS += pack-revindex.o LIB_OBJS += pack-write.o LIB_OBJS += pager.o @@@ -1283,20 -1263,6 +1275,6 @@@ endi ifdef NO_STRTOULL COMPAT_CFLAGS += -DNO_STRTOULL endif - ifdef NO_FNMATCH - COMPAT_CFLAGS += -Icompat/fnmatch - COMPAT_CFLAGS += -DNO_FNMATCH - COMPAT_OBJS += compat/fnmatch/fnmatch.o - else - ifdef NO_FNMATCH_CASEFOLD - COMPAT_CFLAGS += -Icompat/fnmatch - COMPAT_CFLAGS += -DNO_FNMATCH_CASEFOLD - COMPAT_OBJS += compat/fnmatch/fnmatch.o - endif - endif - ifndef NO_WILDMATCH - COMPAT_CFLAGS += -DUSE_WILDMATCH - endif ifdef NO_SETENV COMPAT_CFLAGS += -DNO_SETENV COMPAT_OBJS += compat/setenv.o @@@ -2491,9 -2457,8 +2469,9 @@@ profile-clean $(RM) $(addsuffix *.gcno,$(addprefix $(PROFILE_DIR)/, $(object_dirs))) clean: profile-clean coverage-clean - $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o vcs-svn/*.o \ - builtin/*.o $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB) + $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o + $(RM) xdiff/*.o vcs-svn/*.o ewah/*.o builtin/*.o + $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB) $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) $(NO_INSTALL) $(RM) -r bin-wrappers $(dep_dirs) diff --combined builtin/apply.c index a7e72d57ab,66e2eed539..0189523798 --- a/builtin/apply.c +++ b/builtin/apply.c @@@ -1943,7 -1943,13 +1943,7 @@@ static int parse_chunk(char *buffer, un size - offset - hdrsize, patch); if (!patchsize) { - static const char *binhdr[] = { - "Binary files ", - "Files ", - NULL, - }; static const char git_binary[] = "GIT binary patch\n"; - int i; int hd = hdrsize + offset; unsigned long llen = linelen(buffer + hd, size - hd); @@@ -1959,12 -1965,6 +1959,12 @@@ patchsize = 0; } else if (!memcmp(" differ\n", buffer + hd + llen - 8, 8)) { + static const char *binhdr[] = { + "Binary files ", + "Files ", + NULL, + }; + int i; for (i = 0; binhdr[i]; i++) { int len = strlen(binhdr[i]); if (len < size - hd && @@@ -4152,7 -4152,7 +4152,7 @@@ static int use_patch(struct patch *p /* See if it matches any of exclude/include rule */ for (i = 0; i < limit_by_name.nr; i++) { struct string_list_item *it = &limit_by_name.items[i]; - if (!fnmatch(it->string, pathname, 0)) + if (!wildmatch(it->string, pathname, 0, NULL)) return (it->util != NULL); } diff --combined builtin/describe.c index dadd999c41,848acdf299..24d740c8b1 --- a/builtin/describe.c +++ b/builtin/describe.c @@@ -6,7 -6,7 +6,7 @@@ #include "exec_cmd.h" #include "parse-options.h" #include "diff.h" -#include "hash.h" +#include "hashmap.h" #include "argv-array.h" #define SEEN (1u << 0) @@@ -25,7 -25,7 +25,7 @@@ static int longformat static int first_parent; static int abbrev = -1; /* unspecified */ static int max_candidates = 10; -static struct hash_table names; +static struct hashmap names; static int have_util; static const char *pattern; static int always; @@@ -37,7 -37,7 +37,7 @@@ static const char *diff_index_args[] = }; struct commit_name { - struct commit_name *next; + struct hashmap_entry entry; unsigned char peeled[20]; struct tag *tag; unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */ @@@ -50,12 -50,6 +50,12 @@@ static const char *prio_names[] = "head", "lightweight", "annotated", }; +static int commit_name_cmp(const struct commit_name *cn1, + const struct commit_name *cn2, const void *peeled) +{ + return hashcmp(cn1->peeled, peeled ? peeled : cn2->peeled); +} + static inline unsigned int hash_sha1(const unsigned char *sha1) { unsigned int hash; @@@ -65,9 -59,21 +65,9 @@@ static inline struct commit_name *find_commit_name(const unsigned char *peeled) { - struct commit_name *n = lookup_hash(hash_sha1(peeled), &names); - while (n && !!hashcmp(peeled, n->peeled)) - n = n->next; - return n; -} - -static int set_util(void *chain, void *data) -{ - struct commit_name *n; - for (n = chain; n; n = n->next) { - struct commit *c = lookup_commit_reference_gently(n->peeled, 1); - if (c) - c->util = n; - } - return 0; + struct commit_name key; + hashmap_entry_init(&key, hash_sha1(peeled)); + return hashmap_get(&names, &key, peeled); } static int replace_name(struct commit_name *e, @@@ -112,10 -118,16 +112,10 @@@ static void add_to_known_names(const ch struct tag *tag = NULL; if (replace_name(e, prio, sha1, &tag)) { if (!e) { - void **pos; e = xmalloc(sizeof(struct commit_name)); hashcpy(e->peeled, peeled); - pos = insert_hash(hash_sha1(peeled), e, &names); - if (pos) { - e->next = *pos; - *pos = e; - } else { - e->next = NULL; - } + hashmap_entry_init(e, hash_sha1(peeled)); + hashmap_add(&names, e); e->path = NULL; } e->tag = tag; @@@ -138,7 -150,7 +138,7 @@@ static int get_name(const char *path, c return 0; /* Accept only tags that match the pattern, if given */ - if (pattern && (!is_tag || fnmatch(pattern, path + 10, 0))) + if (pattern && (!is_tag || wildmatch(pattern, path + 10, 0, NULL))) return 0; /* Is it annotated? */ @@@ -280,14 -292,7 +280,14 @@@ static void describe(const char *arg, i fprintf(stderr, _("searching to describe %s\n"), arg); if (!have_util) { - for_each_hash(&names, set_util, NULL); + struct hashmap_iter iter; + struct commit *c; + struct commit_name *n = hashmap_iter_first(&names, &iter); + for (; n; n = hashmap_iter_next(&iter)) { + c = lookup_commit_reference_gently(n->peeled, 1); + if (c) + c->util = n; + } have_util = 1; } @@@ -458,9 -463,9 +458,9 @@@ int cmd_describe(int argc, const char * return cmd_name_rev(args.argc, args.argv, prefix); } - init_hash(&names); + hashmap_init(&names, (hashmap_cmp_fn) commit_name_cmp, 0); for_each_rawref(get_name, NULL); - if (!names.nr && !always) + if (!names.size && !always) die(_("No names found, cannot describe anything.")); if (argc == 0) { diff --combined diffcore-order.c index 1bfcc39f90,53ea4d14c2..97dd3d0095 --- a/diffcore-order.c +++ b/diffcore-order.c @@@ -57,6 -57,12 +57,6 @@@ static void prepare_order(const char *o } } -struct pair_order { - struct diff_filepair *pair; - int orig_order; - int order; -}; - static int match_order(const char *path) { int i; @@@ -67,7 -73,7 +67,7 @@@ strbuf_addstr(&p, path); while (p.buf[0]) { char *cp; - if (!fnmatch(order[i], p.buf, 0)) + if (!wildmatch(order[i], p.buf, 0, NULL)) return i; cp = strrchr(p.buf, '/'); if (!cp) @@@ -78,54 -84,35 +78,54 @@@ return order_cnt; } -static int compare_pair_order(const void *a_, const void *b_) +static int compare_objs_order(const void *a_, const void *b_) { - struct pair_order const *a, *b; - a = (struct pair_order const *)a_; - b = (struct pair_order const *)b_; + struct obj_order const *a, *b; + a = (struct obj_order const *)a_; + b = (struct obj_order const *)b_; if (a->order != b->order) return a->order - b->order; return a->orig_order - b->orig_order; } +void order_objects(const char *orderfile, obj_path_fn_t obj_path, + struct obj_order *objs, int nr) +{ + int i; + + if (!nr) + return; + + prepare_order(orderfile); + for (i = 0; i < nr; i++) { + objs[i].orig_order = i; + objs[i].order = match_order(obj_path(objs[i].obj)); + } + qsort(objs, nr, sizeof(*objs), compare_objs_order); +} + +static const char *pair_pathtwo(void *obj) +{ + struct diff_filepair *pair = (struct diff_filepair *)obj; + + return pair->two->path; +} + void diffcore_order(const char *orderfile) { struct diff_queue_struct *q = &diff_queued_diff; - struct pair_order *o; + struct obj_order *o; int i; if (!q->nr) return; o = xmalloc(sizeof(*o) * q->nr); - prepare_order(orderfile); - for (i = 0; i < q->nr; i++) { - o[i].pair = q->queue[i]; - o[i].orig_order = i; - o[i].order = match_order(o[i].pair->two->path); - } - qsort(o, q->nr, sizeof(*o), compare_pair_order); for (i = 0; i < q->nr; i++) - q->queue[i] = o[i].pair; + o[i].obj = q->queue[i]; + order_objects(orderfile, pair_pathtwo, o, q->nr); + for (i = 0; i < q->nr; i++) + q->queue[i] = o[i].obj; free(o); return; } diff --combined dir.c index 6c6a5d13c2,59ccb5218a..70eefdd350 --- a/dir.c +++ b/dir.c @@@ -49,7 -49,9 +49,9 @@@ int strncmp_icase(const char *a, const int fnmatch_icase(const char *pattern, const char *string, int flags) { - return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0)); + return wildmatch(pattern, string, + flags | (ignore_case ? WM_CASEFOLD : 0), + NULL); } inline int git_fnmatch(const struct pathspec_item *item, @@@ -58,7 -60,7 +60,7 @@@ { if (prefix > 0) { if (ps_strncmp(item, pattern, string, prefix)) - return FNM_NOMATCH; + return WM_NOMATCH; pattern += prefix; string += prefix; } @@@ -76,8 -78,9 +78,9 @@@ NULL); else /* wildmatch has not learned no FNM_PATHNAME mode yet */ - return fnmatch(pattern, string, - item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0); + return wildmatch(pattern, string, + item->magic & PATHSPEC_ICASE ? WM_CASEFOLD : 0, + NULL); } static int fnmatch_icase_mem(const char *pattern, int patternlen, @@@ -195,9 -198,6 +198,9 @@@ int within_depth(const char *name, int return 1; } +#define DO_MATCH_EXCLUDE 1 +#define DO_MATCH_DIRECTORY 2 + /* * Does 'match' match the given name? * A match is found if @@@ -211,7 -211,7 +214,7 @@@ * It returns 0 when there is no match. */ static int match_pathspec_item(const struct pathspec_item *item, int prefix, - const char *name, int namelen) + const char *name, int namelen, unsigned flags) { /* name/namelen has prefix cut off by caller */ const char *match = item->match + prefix; @@@ -221,7 -221,7 +224,7 @@@ * The normal call pattern is: * 1. prefix = common_prefix_len(ps); * 2. prune something, or fill_directory - * 3. match_pathspec_depth() + * 3. match_pathspec() * * 'prefix' at #1 may be shorter than the command's prefix and * it's ok for #2 to match extra files. Those extras will be @@@ -260,11 -260,7 +263,11 @@@ if (match[matchlen-1] == '/' || name[matchlen] == '/') return MATCHED_RECURSIVELY; - } + } else if ((flags & DO_MATCH_DIRECTORY) && + match[matchlen - 1] == '/' && + namelen == matchlen - 1 && + !ps_strncmp(item, match, name, namelen)) + return MATCHED_EXACTLY; if (item->nowildcard_len < item->len && !git_fnmatch(item, match, name, @@@ -289,12 -285,12 +292,12 @@@ * pathspec did not match any names, which could indicate that the * user mistyped the nth pathspec. */ -static int match_pathspec_depth_1(const struct pathspec *ps, - const char *name, int namelen, - int prefix, char *seen, - int exclude) +static int do_match_pathspec(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen, + unsigned flags) { - int i, retval = 0; + int i, retval = 0, exclude = flags & DO_MATCH_EXCLUDE; GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | @@@ -334,8 -330,7 +337,8 @@@ */ if (seen && ps->items[i].magic & PATHSPEC_EXCLUDE) seen[i] = MATCHED_FNMATCH; - how = match_pathspec_item(ps->items+i, prefix, name, namelen); + how = match_pathspec_item(ps->items+i, prefix, name, + namelen, flags); if (ps->recursive && (ps->magic & PATHSPEC_MAXDEPTH) && ps->max_depth != -1 && @@@ -358,19 -353,15 +361,19 @@@ return retval; } -int match_pathspec_depth(const struct pathspec *ps, - const char *name, int namelen, - int prefix, char *seen) +int match_pathspec(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen, int is_dir) { int positive, negative; - positive = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 0); + unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0; + positive = do_match_pathspec(ps, name, namelen, + prefix, seen, flags); if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive) return positive; - negative = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 1); + negative = do_match_pathspec(ps, name, namelen, + prefix, seen, + flags | DO_MATCH_EXCLUDE); return negative ? 0 : positive; } @@@ -503,25 -494,6 +506,25 @@@ void clear_exclude_list(struct exclude_ el->filebuf = NULL; } +static void trim_trailing_spaces(char *buf) +{ + int i, last_space = -1, nr_spaces, len = strlen(buf); + for (i = 0; i < len; i++) + if (buf[i] == '\\') + i++; + else if (buf[i] == ' ') { + if (last_space == -1) { + last_space = i; + nr_spaces = 1; + } else + nr_spaces++; + } else + last_space = -1; + + if (last_space != -1 && last_space + nr_spaces == len) + buf[last_space] = '\0'; +} + int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, @@@ -573,7 -545,6 +576,7 @@@ if (buf[i] == '\n') { if (entry != buf + i && entry[0] != '#') { buf[i - (i && buf[i-1] == '\r')] = 0; + trim_trailing_spaces(entry); add_exclude(entry, base, baselen, el, lineno); } lineno++; diff --combined git-compat-util.h index 082eb0d1b7,eaee4381f2..585ef8a79b --- a/git-compat-util.h +++ b/git-compat-util.h @@@ -116,9 -116,6 +116,6 @@@ #include #include #include - #ifndef USE_WILDMATCH - #include - #endif #include #include #include @@@ -304,16 -301,7 +301,7 @@@ extern char *gitbasename(char *) #include "compat/bswap.h" - #ifdef USE_WILDMATCH #include "wildmatch.h" - #define FNM_PATHNAME WM_PATHNAME - #define FNM_CASEFOLD WM_CASEFOLD - #define FNM_NOMATCH WM_NOMATCH - static inline int fnmatch(const char *pattern, const char *string, int flags) - { - return wildmatch(pattern, string, flags, NULL); - } - #endif /* General helper functions */ extern void vreportf(const char *prefix, const char *err, va_list params); @@@ -351,7 -339,9 +339,7 @@@ extern void set_error_routine(void (*ro extern void set_die_is_recursing_routine(int (*routine)(void)); extern int starts_with(const char *str, const char *prefix); -extern int prefixcmp(const char *str, const char *prefix); extern int ends_with(const char *str, const char *suffix); -extern int suffixcmp(const char *str, const char *suffix); static inline const char *skip_prefix(const char *str, const char *prefix) { @@@ -478,15 -468,9 +466,15 @@@ extern FILE *git_fopen(const char*, con #endif #ifdef SNPRINTF_RETURNS_BOGUS +#ifdef snprintf +#undef snprintf +#endif #define snprintf git_snprintf extern int git_snprintf(char *str, size_t maxsize, const char *format, ...); +#ifdef vsnprintf +#undef vsnprintf +#endif #define vsnprintf git_vsnprintf extern int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap); diff --combined revision.c index bd027bc015,6addff1b5f..78b5c3ac0b --- a/revision.c +++ b/revision.c @@@ -16,7 -16,6 +16,7 @@@ #include "line-log.h" #include "mailmap.h" #include "commit-slab.h" +#include "dir.h" volatile show_early_output_fn_t show_early_output; @@@ -497,14 -496,24 +497,14 @@@ static int rev_compare_tree(struct rev_ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit) { int retval; - void *tree; - unsigned long size; - struct tree_desc empty, real; struct tree *t1 = commit->tree; if (!t1) return 0; - tree = read_object_with_reference(t1->object.sha1, tree_type, &size, NULL); - if (!tree) - return 0; - init_tree_desc(&real, tree, size); - init_tree_desc(&empty, "", 0); - tree_difference = REV_TREE_SAME; DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); - retval = diff_tree(&empty, &real, "", &revs->pruning); - free(tree); + retval = diff_tree_sha1(NULL, t1->object.sha1, "", &revs->pruning); return retval >= 0 && (tree_difference == REV_TREE_SAME); } @@@ -774,10 -783,6 +774,10 @@@ static int add_parents_to_list(struct r return 0; commit->object.flags |= ADDED; + if (revs->include_check && + !revs->include_check(commit, revs->include_check_data)) + return 0; + /* * If the commit is uninteresting, don't try to * prune parents - we want the maximal uninteresting @@@ -1186,7 -1191,7 +1186,7 @@@ int ref_excluded(struct string_list *re if (!ref_excludes) return 0; for_each_string_list_item(item, ref_excludes) { - if (!fnmatch(item->string, path, 0)) + if (!wildmatch(item->string, path, 0, NULL)) return 1; } return 0; @@@ -1395,7 -1400,7 +1395,7 @@@ static void prepare_show_merge(struct r const struct cache_entry *ce = active_cache[i]; if (!ce_stage(ce)) continue; - if (ce_path_match(ce, &revs->prune_data)) { + if (ce_path_match(ce, &revs->prune_data, NULL)) { prune_num++; prune = xrealloc(prune, sizeof(*prune) * prune_num); prune[prune_num-2] = ce->name;