This function is the same as get_pathspec() except that it produces struct pathspec directly. no_prefix code path is necessary because init_pathspec() can be called without get_pathspec_old() in "diff --no-index" case. Without this exception, prefix_path() will be eventually called and die because there is not worktree. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- cache.h | 5 ++++ dir.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++---------------- setup.c | 4 +- 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/cache.h b/cache.h index 17df06f..719d4a3 100644 --- a/cache.h +++ b/cache.h @@ -443,6 +443,9 @@ extern void set_git_work_tree(const char *tree); #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" +struct pathspec_item; +extern const char *prefix_pathspec(struct pathspec_item *item, const char *prefix, + int prefixlen, const char *elt); extern const char **get_pathspec(const char *prefix, const char **pathspec); extern const char *pathspec_prefix(const char *prefix, const char **pathspec); extern void setup_work_tree(void); @@ -554,6 +557,8 @@ struct pathspec { }; extern int init_pathspec(struct pathspec *, const char **); +extern int parse_pathspec(struct pathspec *pathspec, const char *prefix, + int argc, const char **argv); extern void free_pathspec(struct pathspec *); extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); diff --git a/dir.c b/dir.c index 6c82615..d38af0f 100644 --- a/dir.c +++ b/dir.c @@ -18,6 +18,8 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, in int check_only, const struct path_simplify *simplify); static int get_dtype(struct dirent *de, const char *path, int len); +static const char *no_prefix = "We do not want outside repository check."; + /* helper string functions with support for the ignore_case flag */ int strcmp_icase(const char *a, const char *b) { @@ -1252,34 +1254,62 @@ static int pathspec_item_cmp(const void *a_, const void *b_) return strcmp(a->match, b->match); } -int init_pathspec(struct pathspec *pathspec, const char **paths) +extern const char *prefix_pathspec(struct pathspec_item *item, const char *prefix, + int prefixlen, const char *elt); +int parse_pathspec(struct pathspec *pathspec, const char *prefix, + int argc, const char **argv) { - const char **p = paths; - int i; + struct pathspec_item *pitem; + const char **dst; + int prefixlen; memset(pathspec, 0, sizeof(*pathspec)); - if (!p) - return 0; - while (*p) - p++; - pathspec->raw = paths; - pathspec->nr = p - paths; - pathspec->magic = PATHSPEC_NOGLOB; - if (!pathspec->nr) + + if (argc == -1) { + argc = 0; + for (dst = argv; *dst; dst++) + argc++; + } + + if ((!prefix || prefix == no_prefix) && !argc) return 0; - pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr); - memset(pathspec->items, 0, sizeof(struct pathspec_item)*pathspec->nr); - for (i = 0; i < pathspec->nr; i++) { - struct pathspec_item *item = pathspec->items+i; - const char *path = paths[i]; + if (!argc) { + static const char *spec[2]; + spec[0] = prefix; + spec[1] = NULL; + init_pathspec(pathspec, spec); + pathspec->items[0].plain_len = pathspec->items[0].len; + return 0; + } - item->match = path; - item->len = strlen(path); - if (no_wildcard(path)) - item->magic |= PATHSPEC_NOGLOB; + prefixlen = prefix && prefix != no_prefix ? strlen(prefix) : 0; + pathspec->nr = argc; /* be optimistic, lower it later if necessary */ + pathspec->items = xmalloc(sizeof(struct pathspec_item) * argc); + pathspec->raw = argv; + pathspec->magic = PATHSPEC_NOGLOB; + pitem = pathspec->items; + dst = argv; + + while (*argv) { + if (prefix == no_prefix) { + memset(pitem, 0, sizeof(*pitem)); + pitem->match = *argv; + pitem->len = strlen(pitem->match); + } + else + prefix_pathspec(pitem, prefix, prefixlen, *argv); + *dst = *argv++; + if (pitem->match && pitem->len) { + if (no_wildcard(pitem->match + pitem->plain_len)) + pitem->magic |= PATHSPEC_NOGLOB; + else + pathspec->magic &= ~PATHSPEC_NOGLOB; + pitem++; + dst++; + } else - pathspec->magic &= ~PATHSPEC_NOGLOB; + pathspec->nr--; } qsort(pathspec->items, pathspec->nr, @@ -1288,8 +1318,18 @@ int init_pathspec(struct pathspec *pathspec, const char **paths) return 0; } +int init_pathspec(struct pathspec *pathspec, const char **paths) +{ + const char **p = paths; + while (p && *p) + p++; + return parse_pathspec(pathspec, no_prefix, p - paths, paths); +} + void free_pathspec(struct pathspec *pathspec) { + /* memory leak: pathspec_item->match likely be xstrdup'd by + prefix_pathspec */ free(pathspec->items); pathspec->items = NULL; } diff --git a/setup.c b/setup.c index 8f1c2c0..b074210 100644 --- a/setup.c +++ b/setup.c @@ -126,8 +126,8 @@ static struct pathspec_magic { * the prefix part must always match literally, and a single stupid * string cannot express such a case. */ -static const char *prefix_pathspec(struct pathspec_item *item, const char *prefix, - int prefixlen, const char *elt) +const char *prefix_pathspec(struct pathspec_item *item, const char *prefix, + int prefixlen, const char *elt) { unsigned magic = 0; const char *copyfrom = elt; -- 1.7.3.1.256.g2539c.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html