1#include"cache.h" 2#include"dir.h" 3#include"pathspec.h" 4 5/* 6 * Finds which of the given pathspecs match items in the index. 7 * 8 * For each pathspec, sets the corresponding entry in the seen[] array 9 * (which should be specs items long, i.e. the same size as pathspec) 10 * to the nature of the "closest" (i.e. most specific) match found for 11 * that pathspec in the index, if it was a closer type of match than 12 * the existing entry. As an optimization, matching is skipped 13 * altogether if seen[] already only contains non-zero entries. 14 * 15 * If seen[] has not already been written to, it may make sense 16 * to use find_pathspecs_matching_against_index() instead. 17 */ 18voidadd_pathspec_matches_against_index(const char**pathspec, 19char*seen,int specs) 20{ 21int num_unmatched =0, i; 22 23/* 24 * Since we are walking the index as if we were walking the directory, 25 * we have to mark the matched pathspec as seen; otherwise we will 26 * mistakenly think that the user gave a pathspec that did not match 27 * anything. 28 */ 29for(i =0; i < specs; i++) 30if(!seen[i]) 31 num_unmatched++; 32if(!num_unmatched) 33return; 34for(i =0; i < active_nr; i++) { 35struct cache_entry *ce = active_cache[i]; 36match_pathspec(pathspec, ce->name,ce_namelen(ce),0, seen); 37} 38} 39 40/* 41 * Finds which of the given pathspecs match items in the index. 42 * 43 * This is a one-shot wrapper around add_pathspec_matches_against_index() 44 * which allocates, populates, and returns a seen[] array indicating the 45 * nature of the "closest" (i.e. most specific) matches which each of the 46 * given pathspecs achieves against all items in the index. 47 */ 48char*find_pathspecs_matching_against_index(const char**pathspec) 49{ 50char*seen; 51int i; 52 53for(i =0; pathspec[i]; i++) 54;/* just counting */ 55 seen =xcalloc(i,1); 56add_pathspec_matches_against_index(pathspec, seen, i); 57return seen; 58} 59 60/* 61 * Check the index to see whether path refers to a submodule, or 62 * something inside a submodule. If the former, returns the path with 63 * any trailing slash stripped. If the latter, dies with an error 64 * message. 65 */ 66const char*check_path_for_gitlink(const char*path) 67{ 68int i, path_len =strlen(path); 69for(i =0; i < active_nr; i++) { 70struct cache_entry *ce = active_cache[i]; 71if(S_ISGITLINK(ce->ce_mode)) { 72int ce_len =ce_namelen(ce); 73if(path_len <= ce_len || path[ce_len] !='/'|| 74memcmp(ce->name, path, ce_len)) 75/* path does not refer to this 76 * submodule or anything inside it */ 77continue; 78if(path_len == ce_len +1) { 79/* path refers to submodule; 80 * strip trailing slash */ 81returnxstrndup(ce->name, ce_len); 82}else{ 83die(_("Path '%s' is in submodule '%.*s'"), 84 path, ce_len, ce->name); 85} 86} 87} 88return path; 89} 90 91/* 92 * Dies if the given path refers to a file inside a symlinked 93 * directory in the index. 94 */ 95voiddie_if_path_beyond_symlink(const char*path,const char*prefix) 96{ 97if(has_symlink_leading_path(path,strlen(path))) { 98int len = prefix ?strlen(prefix) :0; 99die(_("'%s' is beyond a symbolic link"), path + len); 100} 101} 102 103/* 104 * Magic pathspec 105 * 106 * Possible future magic semantics include stuff like: 107 * 108 * { PATHSPEC_NOGLOB, '!', "noglob" }, 109 * { PATHSPEC_ICASE, '\0', "icase" }, 110 * { PATHSPEC_RECURSIVE, '*', "recursive" }, 111 * { PATHSPEC_REGEXP, '\0', "regexp" }, 112 * 113 */ 114 115static struct pathspec_magic { 116unsigned bit; 117char mnemonic;/* this cannot be ':'! */ 118const char*name; 119} pathspec_magic[] = { 120{ PATHSPEC_FROMTOP,'/',"top"}, 121}; 122 123/* 124 * Take an element of a pathspec and check for magic signatures. 125 * Append the result to the prefix. Return the magic bitmap. 126 * 127 * For now, we only parse the syntax and throw out anything other than 128 * "top" magic. 129 * 130 * NEEDSWORK: This needs to be rewritten when we start migrating 131 * get_pathspec() users to use the "struct pathspec" interface. For 132 * example, a pathspec element may be marked as case-insensitive, but 133 * the prefix part must always match literally, and a single stupid 134 * string cannot express such a case. 135 */ 136static unsignedprefix_pathspec(struct pathspec_item *item, 137unsigned*p_short_magic, 138const char**raw,unsigned flags, 139const char*prefix,int prefixlen, 140const char*elt) 141{ 142unsigned magic =0, short_magic =0; 143const char*copyfrom = elt; 144char*match; 145int i; 146 147if(elt[0] !=':') { 148;/* nothing to do */ 149}else if(elt[1] =='(') { 150/* longhand */ 151const char*nextat; 152for(copyfrom = elt +2; 153*copyfrom && *copyfrom !=')'; 154 copyfrom = nextat) { 155size_t len =strcspn(copyfrom,",)"); 156if(copyfrom[len] ==',') 157 nextat = copyfrom + len +1; 158else 159/* handle ')' and '\0' */ 160 nextat = copyfrom + len; 161if(!len) 162continue; 163for(i =0; i <ARRAY_SIZE(pathspec_magic); i++) 164if(strlen(pathspec_magic[i].name) == len && 165!strncmp(pathspec_magic[i].name, copyfrom, len)) { 166 magic |= pathspec_magic[i].bit; 167break; 168} 169if(ARRAY_SIZE(pathspec_magic) <= i) 170die(_("Invalid pathspec magic '%.*s' in '%s'"), 171(int) len, copyfrom, elt); 172} 173if(*copyfrom !=')') 174die(_("Missing ')' at the end of pathspec magic in '%s'"), elt); 175 copyfrom++; 176}else{ 177/* shorthand */ 178for(copyfrom = elt +1; 179*copyfrom && *copyfrom !=':'; 180 copyfrom++) { 181char ch = *copyfrom; 182 183if(!is_pathspec_magic(ch)) 184break; 185for(i =0; i <ARRAY_SIZE(pathspec_magic); i++) 186if(pathspec_magic[i].mnemonic == ch) { 187 short_magic |= pathspec_magic[i].bit; 188break; 189} 190if(ARRAY_SIZE(pathspec_magic) <= i) 191die(_("Unimplemented pathspec magic '%c' in '%s'"), 192 ch, elt); 193} 194if(*copyfrom ==':') 195 copyfrom++; 196} 197 198 magic |= short_magic; 199*p_short_magic = short_magic; 200 201if(magic & PATHSPEC_FROMTOP) 202 match =xstrdup(copyfrom); 203else 204 match =prefix_path(prefix, prefixlen, copyfrom); 205*raw = item->match = match; 206 item->len =strlen(item->match); 207if(limit_pathspec_to_literal()) 208 item->nowildcard_len = item->len; 209else 210 item->nowildcard_len =simple_length(item->match); 211 item->flags =0; 212if(item->nowildcard_len < item->len && 213 item->match[item->nowildcard_len] =='*'&& 214no_wildcard(item->match + item->nowildcard_len +1)) 215 item->flags |= PATHSPEC_ONESTAR; 216return magic; 217} 218 219static intpathspec_item_cmp(const void*a_,const void*b_) 220{ 221struct pathspec_item *a, *b; 222 223 a = (struct pathspec_item *)a_; 224 b = (struct pathspec_item *)b_; 225returnstrcmp(a->match, b->match); 226} 227 228static void NORETURN unsupported_magic(const char*pattern, 229unsigned magic, 230unsigned short_magic) 231{ 232struct strbuf sb = STRBUF_INIT; 233int i, n; 234for(n = i =0; i <ARRAY_SIZE(pathspec_magic); i++) { 235const struct pathspec_magic *m = pathspec_magic + i; 236if(!(magic & m->bit)) 237continue; 238if(sb.len) 239strbuf_addstr(&sb," "); 240if(short_magic & m->bit) 241strbuf_addf(&sb,"'%c'", m->mnemonic); 242else 243strbuf_addf(&sb,"'%s'", m->name); 244 n++; 245} 246/* 247 * We may want to substitute "this command" with a command 248 * name. E.g. when add--interactive dies when running 249 * "checkout -p" 250 */ 251die(_("%s: pathspec magic not supported by this command:%s"), 252 pattern, sb.buf); 253} 254 255/* 256 * Given command line arguments and a prefix, convert the input to 257 * pathspec. die() if any magic in magic_mask is used. 258 */ 259voidparse_pathspec(struct pathspec *pathspec, 260unsigned magic_mask,unsigned flags, 261const char*prefix,const char**argv) 262{ 263struct pathspec_item *item; 264const char*entry = argv ? *argv : NULL; 265int i, n, prefixlen; 266 267memset(pathspec,0,sizeof(*pathspec)); 268 269/* No arguments, no prefix -> no pathspec */ 270if(!entry && !prefix) 271return; 272 273/* No arguments with prefix -> prefix pathspec */ 274if(!entry) { 275static const char*raw[2]; 276 277 pathspec->items = item =xmalloc(sizeof(*item)); 278memset(item,0,sizeof(*item)); 279 item->match = prefix; 280 item->nowildcard_len = item->len =strlen(prefix); 281 raw[0] = prefix; 282 raw[1] = NULL; 283 pathspec->nr =1; 284 pathspec->raw = raw; 285return; 286} 287 288 n =0; 289while(argv[n]) 290 n++; 291 292 pathspec->nr = n; 293 pathspec->items = item =xmalloc(sizeof(*item) * n); 294 pathspec->raw = argv; 295 prefixlen = prefix ?strlen(prefix) :0; 296 297for(i =0; i < n; i++) { 298unsigned short_magic; 299 entry = argv[i]; 300 301 item[i].magic =prefix_pathspec(item + i, &short_magic, 302 argv + i, flags, 303 prefix, prefixlen, entry); 304if(item[i].magic & magic_mask) 305unsupported_magic(entry, 306 item[i].magic & magic_mask, 307 short_magic); 308if(item[i].nowildcard_len < item[i].len) 309 pathspec->has_wildcard =1; 310 pathspec->magic |= item[i].magic; 311} 312 313qsort(pathspec->items, pathspec->nr, 314sizeof(struct pathspec_item), pathspec_item_cmp); 315} 316 317/* 318 * N.B. get_pathspec() is deprecated in favor of the "struct pathspec" 319 * based interface - see pathspec.c:parse_pathspec(). 320 * 321 * Arguments: 322 * - prefix - a path relative to the root of the working tree 323 * - pathspec - a list of paths underneath the prefix path 324 * 325 * Iterates over pathspec, prepending each path with prefix, 326 * and return the resulting list. 327 * 328 * If pathspec is empty, return a singleton list containing prefix. 329 * 330 * If pathspec and prefix are both empty, return an empty list. 331 * 332 * This is typically used by built-in commands such as add.c, in order 333 * to normalize argv arguments provided to the built-in into a list of 334 * paths to process, all relative to the root of the working tree. 335 */ 336const char**get_pathspec(const char*prefix,const char**pathspec) 337{ 338struct pathspec ps; 339parse_pathspec(&ps, 340 PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, 3410, prefix, pathspec); 342return ps.raw; 343} 344 345voidcopy_pathspec(struct pathspec *dst,const struct pathspec *src) 346{ 347*dst = *src; 348 dst->items =xmalloc(sizeof(struct pathspec_item) * dst->nr); 349memcpy(dst->items, src->items, 350sizeof(struct pathspec_item) * dst->nr); 351}