1/* 2 * This handles recursive filename detection with exclude 3 * files, index knowledge etc.. 4 * 5 * See Documentation/technical/api-directory-listing.txt 6 * 7 * Copyright (C) Linus Torvalds, 2005-2006 8 * Junio Hamano, 2005-2006 9 */ 10#include"cache.h" 11#include"dir.h" 12#include"refs.h" 13#include"wildmatch.h" 14 15struct path_simplify { 16int len; 17const char*path; 18}; 19 20/* 21 * Tells read_directory_recursive how a file or directory should be treated. 22 * Values are ordered by significance, e.g. if a directory contains both 23 * excluded and untracked files, it is listed as untracked because 24 * path_untracked > path_excluded. 25 */ 26enum path_treatment { 27 path_none =0, 28 path_recurse, 29 path_excluded, 30 path_untracked 31}; 32 33static enum path_treatment read_directory_recursive(struct dir_struct *dir, 34const char*path,int len, 35int check_only,const struct path_simplify *simplify); 36static intget_dtype(struct dirent *de,const char*path,int len); 37 38/* helper string functions with support for the ignore_case flag */ 39intstrcmp_icase(const char*a,const char*b) 40{ 41return ignore_case ?strcasecmp(a, b) :strcmp(a, b); 42} 43 44intstrncmp_icase(const char*a,const char*b,size_t count) 45{ 46return ignore_case ?strncasecmp(a, b, count) :strncmp(a, b, count); 47} 48 49intfnmatch_icase(const char*pattern,const char*string,int flags) 50{ 51returnfnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD :0)); 52} 53 54inlineintgit_fnmatch(const char*pattern,const char*string, 55int flags,int prefix) 56{ 57int fnm_flags =0; 58if(flags & GFNM_PATHNAME) 59 fnm_flags |= FNM_PATHNAME; 60if(prefix >0) { 61if(strncmp(pattern, string, prefix)) 62return FNM_NOMATCH; 63 pattern += prefix; 64 string += prefix; 65} 66if(flags & GFNM_ONESTAR) { 67int pattern_len =strlen(++pattern); 68int string_len =strlen(string); 69return string_len < pattern_len || 70strcmp(pattern, 71 string + string_len - pattern_len); 72} 73returnfnmatch(pattern, string, fnm_flags); 74} 75 76static intfnmatch_icase_mem(const char*pattern,int patternlen, 77const char*string,int stringlen, 78int flags) 79{ 80int match_status; 81struct strbuf pat_buf = STRBUF_INIT; 82struct strbuf str_buf = STRBUF_INIT; 83const char*use_pat = pattern; 84const char*use_str = string; 85 86if(pattern[patternlen]) { 87strbuf_add(&pat_buf, pattern, patternlen); 88 use_pat = pat_buf.buf; 89} 90if(string[stringlen]) { 91strbuf_add(&str_buf, string, stringlen); 92 use_str = str_buf.buf; 93} 94 95if(ignore_case) 96 flags |= WM_CASEFOLD; 97 match_status =wildmatch(use_pat, use_str, flags, NULL); 98 99strbuf_release(&pat_buf); 100strbuf_release(&str_buf); 101 102return match_status; 103} 104 105static size_tcommon_prefix_len(const char**pathspec) 106{ 107const char*n, *first; 108size_t max =0; 109int literal =limit_pathspec_to_literal(); 110 111if(!pathspec) 112return max; 113 114 first = *pathspec; 115while((n = *pathspec++)) { 116size_t i, len =0; 117for(i =0; first == n || i < max; i++) { 118char c = n[i]; 119if(!c || c != first[i] || (!literal &&is_glob_special(c))) 120break; 121if(c =='/') 122 len = i +1; 123} 124if(first == n || len < max) { 125 max = len; 126if(!max) 127break; 128} 129} 130return max; 131} 132 133/* 134 * Returns a copy of the longest leading path common among all 135 * pathspecs. 136 */ 137char*common_prefix(const char**pathspec) 138{ 139unsigned long len =common_prefix_len(pathspec); 140 141return len ?xmemdupz(*pathspec, len) : NULL; 142} 143 144intfill_directory(struct dir_struct *dir,const char**pathspec) 145{ 146size_t len; 147 148/* 149 * Calculate common prefix for the pathspec, and 150 * use that to optimize the directory walk 151 */ 152 len =common_prefix_len(pathspec); 153 154/* Read the directory and prune it */ 155read_directory(dir, pathspec ? *pathspec :"", len, pathspec); 156return len; 157} 158 159intwithin_depth(const char*name,int namelen, 160int depth,int max_depth) 161{ 162const char*cp = name, *cpe = name + namelen; 163 164while(cp < cpe) { 165if(*cp++ !='/') 166continue; 167 depth++; 168if(depth > max_depth) 169return0; 170} 171return1; 172} 173 174/* 175 * Does 'match' match the given name? 176 * A match is found if 177 * 178 * (1) the 'match' string is leading directory of 'name', or 179 * (2) the 'match' string is a wildcard and matches 'name', or 180 * (3) the 'match' string is exactly the same as 'name'. 181 * 182 * and the return value tells which case it was. 183 * 184 * It returns 0 when there is no match. 185 */ 186static intmatch_one(const char*match,const char*name,int namelen) 187{ 188int matchlen; 189int literal =limit_pathspec_to_literal(); 190 191/* If the match was just the prefix, we matched */ 192if(!*match) 193return MATCHED_RECURSIVELY; 194 195if(ignore_case) { 196for(;;) { 197unsigned char c1 =tolower(*match); 198unsigned char c2 =tolower(*name); 199if(c1 =='\0'|| (!literal &&is_glob_special(c1))) 200break; 201if(c1 != c2) 202return0; 203 match++; 204 name++; 205 namelen--; 206} 207}else{ 208for(;;) { 209unsigned char c1 = *match; 210unsigned char c2 = *name; 211if(c1 =='\0'|| (!literal &&is_glob_special(c1))) 212break; 213if(c1 != c2) 214return0; 215 match++; 216 name++; 217 namelen--; 218} 219} 220 221/* 222 * If we don't match the matchstring exactly, 223 * we need to match by fnmatch 224 */ 225 matchlen =strlen(match); 226if(strncmp_icase(match, name, matchlen)) { 227if(literal) 228return0; 229return!fnmatch_icase(match, name,0) ? MATCHED_FNMATCH :0; 230} 231 232if(namelen == matchlen) 233return MATCHED_EXACTLY; 234if(match[matchlen-1] =='/'|| name[matchlen] =='/') 235return MATCHED_RECURSIVELY; 236return0; 237} 238 239/* 240 * Given a name and a list of pathspecs, returns the nature of the 241 * closest (i.e. most specific) match of the name to any of the 242 * pathspecs. 243 * 244 * The caller typically calls this multiple times with the same 245 * pathspec and seen[] array but with different name/namelen 246 * (e.g. entries from the index) and is interested in seeing if and 247 * how each pathspec matches all the names it calls this function 248 * with. A mark is left in the seen[] array for each pathspec element 249 * indicating the closest type of match that element achieved, so if 250 * seen[n] remains zero after multiple invocations, that means the nth 251 * pathspec did not match any names, which could indicate that the 252 * user mistyped the nth pathspec. 253 */ 254intmatch_pathspec(const char**pathspec,const char*name,int namelen, 255int prefix,char*seen) 256{ 257int i, retval =0; 258 259if(!pathspec) 260return1; 261 262 name += prefix; 263 namelen -= prefix; 264 265for(i =0; pathspec[i] != NULL; i++) { 266int how; 267const char*match = pathspec[i] + prefix; 268if(seen && seen[i] == MATCHED_EXACTLY) 269continue; 270 how =match_one(match, name, namelen); 271if(how) { 272if(retval < how) 273 retval = how; 274if(seen && seen[i] < how) 275 seen[i] = how; 276} 277} 278return retval; 279} 280 281/* 282 * Does 'match' match the given name? 283 * A match is found if 284 * 285 * (1) the 'match' string is leading directory of 'name', or 286 * (2) the 'match' string is a wildcard and matches 'name', or 287 * (3) the 'match' string is exactly the same as 'name'. 288 * 289 * and the return value tells which case it was. 290 * 291 * It returns 0 when there is no match. 292 */ 293static intmatch_pathspec_item(const struct pathspec_item *item,int prefix, 294const char*name,int namelen) 295{ 296/* name/namelen has prefix cut off by caller */ 297const char*match = item->match + prefix; 298int matchlen = item->len - prefix; 299 300/* If the match was just the prefix, we matched */ 301if(!*match) 302return MATCHED_RECURSIVELY; 303 304if(matchlen <= namelen && !strncmp(match, name, matchlen)) { 305if(matchlen == namelen) 306return MATCHED_EXACTLY; 307 308if(match[matchlen-1] =='/'|| name[matchlen] =='/') 309return MATCHED_RECURSIVELY; 310} 311 312if(item->nowildcard_len < item->len && 313!git_fnmatch(match, name, 314 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR :0, 315 item->nowildcard_len - prefix)) 316return MATCHED_FNMATCH; 317 318return0; 319} 320 321/* 322 * Given a name and a list of pathspecs, returns the nature of the 323 * closest (i.e. most specific) match of the name to any of the 324 * pathspecs. 325 * 326 * The caller typically calls this multiple times with the same 327 * pathspec and seen[] array but with different name/namelen 328 * (e.g. entries from the index) and is interested in seeing if and 329 * how each pathspec matches all the names it calls this function 330 * with. A mark is left in the seen[] array for each pathspec element 331 * indicating the closest type of match that element achieved, so if 332 * seen[n] remains zero after multiple invocations, that means the nth 333 * pathspec did not match any names, which could indicate that the 334 * user mistyped the nth pathspec. 335 */ 336intmatch_pathspec_depth(const struct pathspec *ps, 337const char*name,int namelen, 338int prefix,char*seen) 339{ 340int i, retval =0; 341 342if(!ps->nr) { 343if(!ps->recursive || ps->max_depth == -1) 344return MATCHED_RECURSIVELY; 345 346if(within_depth(name, namelen,0, ps->max_depth)) 347return MATCHED_EXACTLY; 348else 349return0; 350} 351 352 name += prefix; 353 namelen -= prefix; 354 355for(i = ps->nr -1; i >=0; i--) { 356int how; 357if(seen && seen[i] == MATCHED_EXACTLY) 358continue; 359 how =match_pathspec_item(ps->items+i, prefix, name, namelen); 360if(ps->recursive && ps->max_depth != -1&& 361 how && how != MATCHED_FNMATCH) { 362int len = ps->items[i].len; 363if(name[len] =='/') 364 len++; 365if(within_depth(name+len, namelen-len,0, ps->max_depth)) 366 how = MATCHED_EXACTLY; 367else 368 how =0; 369} 370if(how) { 371if(retval < how) 372 retval = how; 373if(seen && seen[i] < how) 374 seen[i] = how; 375} 376} 377return retval; 378} 379 380/* 381 * Return the length of the "simple" part of a path match limiter. 382 */ 383static intsimple_length(const char*match) 384{ 385int len = -1; 386 387for(;;) { 388unsigned char c = *match++; 389 len++; 390if(c =='\0'||is_glob_special(c)) 391return len; 392} 393} 394 395static intno_wildcard(const char*string) 396{ 397return string[simple_length(string)] =='\0'; 398} 399 400voidparse_exclude_pattern(const char**pattern, 401int*patternlen, 402int*flags, 403int*nowildcardlen) 404{ 405const char*p = *pattern; 406size_t i, len; 407 408*flags =0; 409if(*p =='!') { 410*flags |= EXC_FLAG_NEGATIVE; 411 p++; 412} 413 len =strlen(p); 414if(len && p[len -1] =='/') { 415 len--; 416*flags |= EXC_FLAG_MUSTBEDIR; 417} 418for(i =0; i < len; i++) { 419if(p[i] =='/') 420break; 421} 422if(i == len) 423*flags |= EXC_FLAG_NODIR; 424*nowildcardlen =simple_length(p); 425/* 426 * we should have excluded the trailing slash from 'p' too, 427 * but that's one more allocation. Instead just make sure 428 * nowildcardlen does not exceed real patternlen 429 */ 430if(*nowildcardlen > len) 431*nowildcardlen = len; 432if(*p =='*'&&no_wildcard(p +1)) 433*flags |= EXC_FLAG_ENDSWITH; 434*pattern = p; 435*patternlen = len; 436} 437 438voidadd_exclude(const char*string,const char*base, 439int baselen,struct exclude_list *el,int srcpos) 440{ 441struct exclude *x; 442int patternlen; 443int flags; 444int nowildcardlen; 445 446parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); 447if(flags & EXC_FLAG_MUSTBEDIR) { 448char*s; 449 x =xmalloc(sizeof(*x) + patternlen +1); 450 s = (char*)(x+1); 451memcpy(s, string, patternlen); 452 s[patternlen] ='\0'; 453 x->pattern = s; 454}else{ 455 x =xmalloc(sizeof(*x)); 456 x->pattern = string; 457} 458 x->patternlen = patternlen; 459 x->nowildcardlen = nowildcardlen; 460 x->base = base; 461 x->baselen = baselen; 462 x->flags = flags; 463 x->srcpos = srcpos; 464ALLOC_GROW(el->excludes, el->nr +1, el->alloc); 465 el->excludes[el->nr++] = x; 466 x->el = el; 467} 468 469static void*read_skip_worktree_file_from_index(const char*path,size_t*size) 470{ 471int pos, len; 472unsigned long sz; 473enum object_type type; 474void*data; 475 476 len =strlen(path); 477 pos =cache_name_pos(path, len); 478if(pos <0) 479return NULL; 480if(!ce_skip_worktree(active_cache[pos])) 481return NULL; 482 data =read_sha1_file(active_cache[pos]->sha1, &type, &sz); 483if(!data || type != OBJ_BLOB) { 484free(data); 485return NULL; 486} 487*size =xsize_t(sz); 488return data; 489} 490 491/* 492 * Frees memory within el which was allocated for exclude patterns and 493 * the file buffer. Does not free el itself. 494 */ 495voidclear_exclude_list(struct exclude_list *el) 496{ 497int i; 498 499for(i =0; i < el->nr; i++) 500free(el->excludes[i]); 501free(el->excludes); 502free(el->filebuf); 503 504 el->nr =0; 505 el->excludes = NULL; 506 el->filebuf = NULL; 507} 508 509intadd_excludes_from_file_to_list(const char*fname, 510const char*base, 511int baselen, 512struct exclude_list *el, 513int check_index) 514{ 515struct stat st; 516int fd, i, lineno =1; 517size_t size =0; 518char*buf, *entry; 519 520 fd =open(fname, O_RDONLY); 521if(fd <0||fstat(fd, &st) <0) { 522if(errno != ENOENT) 523warn_on_inaccessible(fname); 524if(0<= fd) 525close(fd); 526if(!check_index || 527(buf =read_skip_worktree_file_from_index(fname, &size)) == NULL) 528return-1; 529if(size ==0) { 530free(buf); 531return0; 532} 533if(buf[size-1] !='\n') { 534 buf =xrealloc(buf, size+1); 535 buf[size++] ='\n'; 536} 537} 538else{ 539 size =xsize_t(st.st_size); 540if(size ==0) { 541close(fd); 542return0; 543} 544 buf =xmalloc(size+1); 545if(read_in_full(fd, buf, size) != size) { 546free(buf); 547close(fd); 548return-1; 549} 550 buf[size++] ='\n'; 551close(fd); 552} 553 554 el->filebuf = buf; 555 entry = buf; 556for(i =0; i < size; i++) { 557if(buf[i] =='\n') { 558if(entry != buf + i && entry[0] !='#') { 559 buf[i - (i && buf[i-1] =='\r')] =0; 560add_exclude(entry, base, baselen, el, lineno); 561} 562 lineno++; 563 entry = buf + i +1; 564} 565} 566return0; 567} 568 569struct exclude_list *add_exclude_list(struct dir_struct *dir, 570int group_type,const char*src) 571{ 572struct exclude_list *el; 573struct exclude_list_group *group; 574 575 group = &dir->exclude_list_group[group_type]; 576ALLOC_GROW(group->el, group->nr +1, group->alloc); 577 el = &group->el[group->nr++]; 578memset(el,0,sizeof(*el)); 579 el->src = src; 580return el; 581} 582 583/* 584 * Used to set up core.excludesfile and .git/info/exclude lists. 585 */ 586voidadd_excludes_from_file(struct dir_struct *dir,const char*fname) 587{ 588struct exclude_list *el; 589 el =add_exclude_list(dir, EXC_FILE, fname); 590if(add_excludes_from_file_to_list(fname,"",0, el,0) <0) 591die("cannot use%sas an exclude file", fname); 592} 593 594intmatch_basename(const char*basename,int basenamelen, 595const char*pattern,int prefix,int patternlen, 596int flags) 597{ 598if(prefix == patternlen) { 599if(patternlen == basenamelen && 600!strncmp_icase(pattern, basename, basenamelen)) 601return1; 602}else if(flags & EXC_FLAG_ENDSWITH) { 603/* "*literal" matching against "fooliteral" */ 604if(patternlen -1<= basenamelen && 605!strncmp_icase(pattern +1, 606 basename + basenamelen - (patternlen -1), 607 patternlen -1)) 608return1; 609}else{ 610if(fnmatch_icase_mem(pattern, patternlen, 611 basename, basenamelen, 6120) ==0) 613return1; 614} 615return0; 616} 617 618intmatch_pathname(const char*pathname,int pathlen, 619const char*base,int baselen, 620const char*pattern,int prefix,int patternlen, 621int flags) 622{ 623const char*name; 624int namelen; 625 626/* 627 * match with FNM_PATHNAME; the pattern has base implicitly 628 * in front of it. 629 */ 630if(*pattern =='/') { 631 pattern++; 632 patternlen--; 633 prefix--; 634} 635 636/* 637 * baselen does not count the trailing slash. base[] may or 638 * may not end with a trailing slash though. 639 */ 640if(pathlen < baselen +1|| 641(baselen && pathname[baselen] !='/') || 642strncmp_icase(pathname, base, baselen)) 643return0; 644 645 namelen = baselen ? pathlen - baselen -1: pathlen; 646 name = pathname + pathlen - namelen; 647 648if(prefix) { 649/* 650 * if the non-wildcard part is longer than the 651 * remaining pathname, surely it cannot match. 652 */ 653if(prefix > namelen) 654return0; 655 656if(strncmp_icase(pattern, name, prefix)) 657return0; 658 pattern += prefix; 659 patternlen -= prefix; 660 name += prefix; 661 namelen -= prefix; 662 663/* 664 * If the whole pattern did not have a wildcard, 665 * then our prefix match is all we need; we 666 * do not need to call fnmatch at all. 667 */ 668if(!patternlen && !namelen) 669return1; 670} 671 672returnfnmatch_icase_mem(pattern, patternlen, 673 name, namelen, 674 WM_PATHNAME) ==0; 675} 676 677/* 678 * Scan the given exclude list in reverse to see whether pathname 679 * should be ignored. The first match (i.e. the last on the list), if 680 * any, determines the fate. Returns the exclude_list element which 681 * matched, or NULL for undecided. 682 */ 683static struct exclude *last_exclude_matching_from_list(const char*pathname, 684int pathlen, 685const char*basename, 686int*dtype, 687struct exclude_list *el) 688{ 689int i; 690 691if(!el->nr) 692return NULL;/* undefined */ 693 694for(i = el->nr -1;0<= i; i--) { 695struct exclude *x = el->excludes[i]; 696const char*exclude = x->pattern; 697int prefix = x->nowildcardlen; 698 699if(x->flags & EXC_FLAG_MUSTBEDIR) { 700if(*dtype == DT_UNKNOWN) 701*dtype =get_dtype(NULL, pathname, pathlen); 702if(*dtype != DT_DIR) 703continue; 704} 705 706if(x->flags & EXC_FLAG_NODIR) { 707if(match_basename(basename, 708 pathlen - (basename - pathname), 709 exclude, prefix, x->patternlen, 710 x->flags)) 711return x; 712continue; 713} 714 715assert(x->baselen ==0|| x->base[x->baselen -1] =='/'); 716if(match_pathname(pathname, pathlen, 717 x->base, x->baselen ? x->baselen -1:0, 718 exclude, prefix, x->patternlen, x->flags)) 719return x; 720} 721return NULL;/* undecided */ 722} 723 724/* 725 * Scan the list and let the last match determine the fate. 726 * Return 1 for exclude, 0 for include and -1 for undecided. 727 */ 728intis_excluded_from_list(const char*pathname, 729int pathlen,const char*basename,int*dtype, 730struct exclude_list *el) 731{ 732struct exclude *exclude; 733 exclude =last_exclude_matching_from_list(pathname, pathlen, basename, dtype, el); 734if(exclude) 735return exclude->flags & EXC_FLAG_NEGATIVE ?0:1; 736return-1;/* undecided */ 737} 738 739static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir, 740const char*pathname,int pathlen,const char*basename, 741int*dtype_p) 742{ 743int i, j; 744struct exclude_list_group *group; 745struct exclude *exclude; 746for(i = EXC_CMDL; i <= EXC_FILE; i++) { 747 group = &dir->exclude_list_group[i]; 748for(j = group->nr -1; j >=0; j--) { 749 exclude =last_exclude_matching_from_list( 750 pathname, pathlen, basename, dtype_p, 751&group->el[j]); 752if(exclude) 753return exclude; 754} 755} 756return NULL; 757} 758 759/* 760 * Loads the per-directory exclude list for the substring of base 761 * which has a char length of baselen. 762 */ 763static voidprep_exclude(struct dir_struct *dir,const char*base,int baselen) 764{ 765struct exclude_list_group *group; 766struct exclude_list *el; 767struct exclude_stack *stk = NULL; 768int current; 769 770 group = &dir->exclude_list_group[EXC_DIRS]; 771 772/* Pop the exclude lists from the EXCL_DIRS exclude_list_group 773 * which originate from directories not in the prefix of the 774 * path being checked. */ 775while((stk = dir->exclude_stack) != NULL) { 776if(stk->baselen <= baselen && 777!strncmp(dir->basebuf, base, stk->baselen)) 778break; 779 el = &group->el[dir->exclude_stack->exclude_ix]; 780 dir->exclude_stack = stk->prev; 781 dir->exclude = NULL; 782free((char*)el->src);/* see strdup() below */ 783clear_exclude_list(el); 784free(stk); 785 group->nr--; 786} 787 788/* Skip traversing into sub directories if the parent is excluded */ 789if(dir->exclude) 790return; 791 792/* Read from the parent directories and push them down. */ 793 current = stk ? stk->baselen : -1; 794while(current < baselen) { 795struct exclude_stack *stk =xcalloc(1,sizeof(*stk)); 796const char*cp; 797 798if(current <0) { 799 cp = base; 800 current =0; 801} 802else{ 803 cp =strchr(base + current +1,'/'); 804if(!cp) 805die("oops in prep_exclude"); 806 cp++; 807} 808 stk->prev = dir->exclude_stack; 809 stk->baselen = cp - base; 810 stk->exclude_ix = group->nr; 811 el =add_exclude_list(dir, EXC_DIRS, NULL); 812memcpy(dir->basebuf + current, base + current, 813 stk->baselen - current); 814 815/* Abort if the directory is excluded */ 816if(stk->baselen) { 817int dt = DT_DIR; 818 dir->basebuf[stk->baselen -1] =0; 819 dir->exclude =last_exclude_matching_from_lists(dir, 820 dir->basebuf, stk->baselen -1, 821 dir->basebuf + current, &dt); 822 dir->basebuf[stk->baselen -1] ='/'; 823if(dir->exclude && 824 dir->exclude->flags & EXC_FLAG_NEGATIVE) 825 dir->exclude = NULL; 826if(dir->exclude) { 827 dir->basebuf[stk->baselen] =0; 828 dir->exclude_stack = stk; 829return; 830} 831} 832 833/* Try to read per-directory file unless path is too long */ 834if(dir->exclude_per_dir && 835 stk->baselen +strlen(dir->exclude_per_dir) < PATH_MAX) { 836strcpy(dir->basebuf + stk->baselen, 837 dir->exclude_per_dir); 838/* 839 * dir->basebuf gets reused by the traversal, but we 840 * need fname to remain unchanged to ensure the src 841 * member of each struct exclude correctly 842 * back-references its source file. Other invocations 843 * of add_exclude_list provide stable strings, so we 844 * strdup() and free() here in the caller. 845 */ 846 el->src =strdup(dir->basebuf); 847add_excludes_from_file_to_list(dir->basebuf, 848 dir->basebuf, stk->baselen, el,1); 849} 850 dir->exclude_stack = stk; 851 current = stk->baselen; 852} 853 dir->basebuf[baselen] ='\0'; 854} 855 856/* 857 * Loads the exclude lists for the directory containing pathname, then 858 * scans all exclude lists to determine whether pathname is excluded. 859 * Returns the exclude_list element which matched, or NULL for 860 * undecided. 861 */ 862struct exclude *last_exclude_matching(struct dir_struct *dir, 863const char*pathname, 864int*dtype_p) 865{ 866int pathlen =strlen(pathname); 867const char*basename =strrchr(pathname,'/'); 868 basename = (basename) ? basename+1: pathname; 869 870prep_exclude(dir, pathname, basename-pathname); 871 872if(dir->exclude) 873return dir->exclude; 874 875returnlast_exclude_matching_from_lists(dir, pathname, pathlen, 876 basename, dtype_p); 877} 878 879/* 880 * Loads the exclude lists for the directory containing pathname, then 881 * scans all exclude lists to determine whether pathname is excluded. 882 * Returns 1 if true, otherwise 0. 883 */ 884intis_excluded(struct dir_struct *dir,const char*pathname,int*dtype_p) 885{ 886struct exclude *exclude = 887last_exclude_matching(dir, pathname, dtype_p); 888if(exclude) 889return exclude->flags & EXC_FLAG_NEGATIVE ?0:1; 890return0; 891} 892 893static struct dir_entry *dir_entry_new(const char*pathname,int len) 894{ 895struct dir_entry *ent; 896 897 ent =xmalloc(sizeof(*ent) + len +1); 898 ent->len = len; 899memcpy(ent->name, pathname, len); 900 ent->name[len] =0; 901return ent; 902} 903 904static struct dir_entry *dir_add_name(struct dir_struct *dir,const char*pathname,int len) 905{ 906if(cache_name_exists(pathname, len, ignore_case)) 907return NULL; 908 909ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc); 910return dir->entries[dir->nr++] =dir_entry_new(pathname, len); 911} 912 913struct dir_entry *dir_add_ignored(struct dir_struct *dir,const char*pathname,int len) 914{ 915if(!cache_name_is_other(pathname, len)) 916return NULL; 917 918ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc); 919return dir->ignored[dir->ignored_nr++] =dir_entry_new(pathname, len); 920} 921 922enum exist_status { 923 index_nonexistent =0, 924 index_directory, 925 index_gitdir 926}; 927 928/* 929 * Do not use the alphabetically sorted index to look up 930 * the directory name; instead, use the case insensitive 931 * name hash. 932 */ 933static enum exist_status directory_exists_in_index_icase(const char*dirname,int len) 934{ 935const struct cache_entry *ce =cache_name_exists(dirname, len +1, ignore_case); 936unsigned char endchar; 937 938if(!ce) 939return index_nonexistent; 940 endchar = ce->name[len]; 941 942/* 943 * The cache_entry structure returned will contain this dirname 944 * and possibly additional path components. 945 */ 946if(endchar =='/') 947return index_directory; 948 949/* 950 * If there are no additional path components, then this cache_entry 951 * represents a submodule. Submodules, despite being directories, 952 * are stored in the cache without a closing slash. 953 */ 954if(!endchar &&S_ISGITLINK(ce->ce_mode)) 955return index_gitdir; 956 957/* This should never be hit, but it exists just in case. */ 958return index_nonexistent; 959} 960 961/* 962 * The index sorts alphabetically by entry name, which 963 * means that a gitlink sorts as '\0' at the end, while 964 * a directory (which is defined not as an entry, but as 965 * the files it contains) will sort with the '/' at the 966 * end. 967 */ 968static enum exist_status directory_exists_in_index(const char*dirname,int len) 969{ 970int pos; 971 972if(ignore_case) 973returndirectory_exists_in_index_icase(dirname, len); 974 975 pos =cache_name_pos(dirname, len); 976if(pos <0) 977 pos = -pos-1; 978while(pos < active_nr) { 979const struct cache_entry *ce = active_cache[pos++]; 980unsigned char endchar; 981 982if(strncmp(ce->name, dirname, len)) 983break; 984 endchar = ce->name[len]; 985if(endchar >'/') 986break; 987if(endchar =='/') 988return index_directory; 989if(!endchar &&S_ISGITLINK(ce->ce_mode)) 990return index_gitdir; 991} 992return index_nonexistent; 993} 994 995/* 996 * When we find a directory when traversing the filesystem, we 997 * have three distinct cases: 998 * 999 * - ignore it1000 * - see it as a directory1001 * - recurse into it1002 *1003 * and which one we choose depends on a combination of existing1004 * git index contents and the flags passed into the directory1005 * traversal routine.1006 *1007 * Case 1: If we *already* have entries in the index under that1008 * directory name, we always recurse into the directory to see1009 * all the files.1010 *1011 * Case 2: If we *already* have that directory name as a gitlink,1012 * we always continue to see it as a gitlink, regardless of whether1013 * there is an actual git directory there or not (it might not1014 * be checked out as a subproject!)1015 *1016 * Case 3: if we didn't have it in the index previously, we1017 * have a few sub-cases:1018 *1019 * (a) if "show_other_directories" is true, we show it as1020 * just a directory, unless "hide_empty_directories" is1021 * also true, in which case we need to check if it contains any1022 * untracked and / or ignored files.1023 * (b) if it looks like a git directory, and we don't have1024 * 'no_gitlinks' set we treat it as a gitlink, and show it1025 * as a directory.1026 * (c) otherwise, we recurse into it.1027 */1028static enum path_treatment treat_directory(struct dir_struct *dir,1029const char*dirname,int len,int exclude,1030const struct path_simplify *simplify)1031{1032/* The "len-1" is to strip the final '/' */1033switch(directory_exists_in_index(dirname, len-1)) {1034case index_directory:1035return path_recurse;10361037case index_gitdir:1038return path_none;10391040case index_nonexistent:1041if(dir->flags & DIR_SHOW_OTHER_DIRECTORIES)1042break;1043if(!(dir->flags & DIR_NO_GITLINKS)) {1044unsigned char sha1[20];1045if(resolve_gitlink_ref(dirname,"HEAD", sha1) ==0)1046return path_untracked;1047}1048return path_recurse;1049}10501051/* This is the "show_other_directories" case */10521053if(!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))1054return exclude ? path_excluded : path_untracked;10551056returnread_directory_recursive(dir, dirname, len,1, simplify);1057}10581059/*1060 * This is an inexact early pruning of any recursive directory1061 * reading - if the path cannot possibly be in the pathspec,1062 * return true, and we'll skip it early.1063 */1064static intsimplify_away(const char*path,int pathlen,const struct path_simplify *simplify)1065{1066if(simplify) {1067for(;;) {1068const char*match = simplify->path;1069int len = simplify->len;10701071if(!match)1072break;1073if(len > pathlen)1074 len = pathlen;1075if(!memcmp(path, match, len))1076return0;1077 simplify++;1078}1079return1;1080}1081return0;1082}10831084/*1085 * This function tells us whether an excluded path matches a1086 * list of "interesting" pathspecs. That is, whether a path matched1087 * by any of the pathspecs could possibly be ignored by excluding1088 * the specified path. This can happen if:1089 *1090 * 1. the path is mentioned explicitly in the pathspec1091 *1092 * 2. the path is a directory prefix of some element in the1093 * pathspec1094 */1095static intexclude_matches_pathspec(const char*path,int len,1096const struct path_simplify *simplify)1097{1098if(simplify) {1099for(; simplify->path; simplify++) {1100if(len == simplify->len1101&& !memcmp(path, simplify->path, len))1102return1;1103if(len < simplify->len1104&& simplify->path[len] =='/'1105&& !memcmp(path, simplify->path, len))1106return1;1107}1108}1109return0;1110}11111112static intget_index_dtype(const char*path,int len)1113{1114int pos;1115const struct cache_entry *ce;11161117 ce =cache_name_exists(path, len,0);1118if(ce) {1119if(!ce_uptodate(ce))1120return DT_UNKNOWN;1121if(S_ISGITLINK(ce->ce_mode))1122return DT_DIR;1123/*1124 * Nobody actually cares about the1125 * difference between DT_LNK and DT_REG1126 */1127return DT_REG;1128}11291130/* Try to look it up as a directory */1131 pos =cache_name_pos(path, len);1132if(pos >=0)1133return DT_UNKNOWN;1134 pos = -pos-1;1135while(pos < active_nr) {1136 ce = active_cache[pos++];1137if(strncmp(ce->name, path, len))1138break;1139if(ce->name[len] >'/')1140break;1141if(ce->name[len] <'/')1142continue;1143if(!ce_uptodate(ce))1144break;/* continue? */1145return DT_DIR;1146}1147return DT_UNKNOWN;1148}11491150static intget_dtype(struct dirent *de,const char*path,int len)1151{1152int dtype = de ?DTYPE(de) : DT_UNKNOWN;1153struct stat st;11541155if(dtype != DT_UNKNOWN)1156return dtype;1157 dtype =get_index_dtype(path, len);1158if(dtype != DT_UNKNOWN)1159return dtype;1160if(lstat(path, &st))1161return dtype;1162if(S_ISREG(st.st_mode))1163return DT_REG;1164if(S_ISDIR(st.st_mode))1165return DT_DIR;1166if(S_ISLNK(st.st_mode))1167return DT_LNK;1168return dtype;1169}11701171static enum path_treatment treat_one_path(struct dir_struct *dir,1172struct strbuf *path,1173const struct path_simplify *simplify,1174int dtype,struct dirent *de)1175{1176int exclude;1177int has_path_in_index = !!cache_name_exists(path->buf, path->len, ignore_case);11781179if(dtype == DT_UNKNOWN)1180 dtype =get_dtype(de, path->buf, path->len);11811182/* Always exclude indexed files */1183if(dtype != DT_DIR && has_path_in_index)1184return path_none;11851186/*1187 * When we are looking at a directory P in the working tree,1188 * there are three cases:1189 *1190 * (1) P exists in the index. Everything inside the directory P in1191 * the working tree needs to go when P is checked out from the1192 * index.1193 *1194 * (2) P does not exist in the index, but there is P/Q in the index.1195 * We know P will stay a directory when we check out the contents1196 * of the index, but we do not know yet if there is a directory1197 * P/Q in the working tree to be killed, so we need to recurse.1198 *1199 * (3) P does not exist in the index, and there is no P/Q in the index1200 * to require P to be a directory, either. Only in this case, we1201 * know that everything inside P will not be killed without1202 * recursing.1203 */1204if((dir->flags & DIR_COLLECT_KILLED_ONLY) &&1205(dtype == DT_DIR) &&1206!has_path_in_index) {1207/*1208 * NEEDSWORK: directory_exists_in_index_icase()1209 * assumes that one byte past the given path is1210 * readable and has '/', which needs to be fixed, but1211 * until then, work it around in the caller.1212 */1213strbuf_addch(path,'/');1214if(directory_exists_in_index(path->buf, path->len -1) ==1215 index_nonexistent) {1216strbuf_setlen(path, path->len -1);1217return path_none;1218}1219strbuf_setlen(path, path->len -1);1220}12211222 exclude =is_excluded(dir, path->buf, &dtype);12231224/*1225 * Excluded? If we don't explicitly want to show1226 * ignored files, ignore it1227 */1228if(exclude && !(dir->flags & (DIR_SHOW_IGNORED|DIR_SHOW_IGNORED_TOO)))1229return path_excluded;12301231switch(dtype) {1232default:1233return path_none;1234case DT_DIR:1235strbuf_addch(path,'/');1236returntreat_directory(dir, path->buf, path->len, exclude,1237 simplify);1238case DT_REG:1239case DT_LNK:1240return exclude ? path_excluded : path_untracked;1241}1242}12431244static enum path_treatment treat_path(struct dir_struct *dir,1245struct dirent *de,1246struct strbuf *path,1247int baselen,1248const struct path_simplify *simplify)1249{1250int dtype;12511252if(is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name,".git"))1253return path_none;1254strbuf_setlen(path, baselen);1255strbuf_addstr(path, de->d_name);1256if(simplify_away(path->buf, path->len, simplify))1257return path_none;12581259 dtype =DTYPE(de);1260returntreat_one_path(dir, path, simplify, dtype, de);1261}12621263/*1264 * Read a directory tree. We currently ignore anything but1265 * directories, regular files and symlinks. That's because git1266 * doesn't handle them at all yet. Maybe that will change some1267 * day.1268 *1269 * Also, we ignore the name ".git" (even if it is not a directory).1270 * That likely will not change.1271 *1272 * Returns the most significant path_treatment value encountered in the scan.1273 */1274static enum path_treatment read_directory_recursive(struct dir_struct *dir,1275const char*base,int baselen,1276int check_only,1277const struct path_simplify *simplify)1278{1279DIR*fdir;1280enum path_treatment state, subdir_state, dir_state = path_none;1281struct dirent *de;1282struct strbuf path = STRBUF_INIT;12831284strbuf_add(&path, base, baselen);12851286 fdir =opendir(path.len ? path.buf :".");1287if(!fdir)1288goto out;12891290while((de =readdir(fdir)) != NULL) {1291/* check how the file or directory should be treated */1292 state =treat_path(dir, de, &path, baselen, simplify);1293if(state > dir_state)1294 dir_state = state;12951296/* recurse into subdir if instructed by treat_path */1297if(state == path_recurse) {1298 subdir_state =read_directory_recursive(dir, path.buf,1299 path.len, check_only, simplify);1300if(subdir_state > dir_state)1301 dir_state = subdir_state;1302}13031304if(check_only) {1305/* abort early if maximum state has been reached */1306if(dir_state == path_untracked)1307break;1308/* skip the dir_add_* part */1309continue;1310}13111312/* add the path to the appropriate result list */1313switch(state) {1314case path_excluded:1315if(dir->flags & DIR_SHOW_IGNORED)1316dir_add_name(dir, path.buf, path.len);1317else if((dir->flags & DIR_SHOW_IGNORED_TOO) ||1318((dir->flags & DIR_COLLECT_IGNORED) &&1319exclude_matches_pathspec(path.buf, path.len,1320 simplify)))1321dir_add_ignored(dir, path.buf, path.len);1322break;13231324case path_untracked:1325if(!(dir->flags & DIR_SHOW_IGNORED))1326dir_add_name(dir, path.buf, path.len);1327break;13281329default:1330break;1331}1332}1333closedir(fdir);1334 out:1335strbuf_release(&path);13361337return dir_state;1338}13391340static intcmp_name(const void*p1,const void*p2)1341{1342const struct dir_entry *e1 = *(const struct dir_entry **)p1;1343const struct dir_entry *e2 = *(const struct dir_entry **)p2;13441345returncache_name_compare(e1->name, e1->len,1346 e2->name, e2->len);1347}13481349static struct path_simplify *create_simplify(const char**pathspec)1350{1351int nr, alloc =0;1352struct path_simplify *simplify = NULL;13531354if(!pathspec)1355return NULL;13561357for(nr =0; ; nr++) {1358const char*match;1359if(nr >= alloc) {1360 alloc =alloc_nr(alloc);1361 simplify =xrealloc(simplify, alloc *sizeof(*simplify));1362}1363 match = *pathspec++;1364if(!match)1365break;1366 simplify[nr].path = match;1367 simplify[nr].len =simple_length(match);1368}1369 simplify[nr].path = NULL;1370 simplify[nr].len =0;1371return simplify;1372}13731374static voidfree_simplify(struct path_simplify *simplify)1375{1376free(simplify);1377}13781379static inttreat_leading_path(struct dir_struct *dir,1380const char*path,int len,1381const struct path_simplify *simplify)1382{1383struct strbuf sb = STRBUF_INIT;1384int baselen, rc =0;1385const char*cp;1386int old_flags = dir->flags;13871388while(len && path[len -1] =='/')1389 len--;1390if(!len)1391return1;1392 baselen =0;1393 dir->flags &= ~DIR_SHOW_OTHER_DIRECTORIES;1394while(1) {1395 cp = path + baselen + !!baselen;1396 cp =memchr(cp,'/', path + len - cp);1397if(!cp)1398 baselen = len;1399else1400 baselen = cp - path;1401strbuf_setlen(&sb,0);1402strbuf_add(&sb, path, baselen);1403if(!is_directory(sb.buf))1404break;1405if(simplify_away(sb.buf, sb.len, simplify))1406break;1407if(treat_one_path(dir, &sb, simplify,1408 DT_DIR, NULL) == path_none)1409break;/* do not recurse into it */1410if(len <= baselen) {1411 rc =1;1412break;/* finished checking */1413}1414}1415strbuf_release(&sb);1416 dir->flags = old_flags;1417return rc;1418}14191420intread_directory(struct dir_struct *dir,const char*path,int len,const char**pathspec)1421{1422struct path_simplify *simplify;14231424if(has_symlink_leading_path(path, len))1425return dir->nr;14261427 simplify =create_simplify(pathspec);1428if(!len ||treat_leading_path(dir, path, len, simplify))1429read_directory_recursive(dir, path, len,0, simplify);1430free_simplify(simplify);1431qsort(dir->entries, dir->nr,sizeof(struct dir_entry *), cmp_name);1432qsort(dir->ignored, dir->ignored_nr,sizeof(struct dir_entry *), cmp_name);1433return dir->nr;1434}14351436intfile_exists(const char*f)1437{1438struct stat sb;1439returnlstat(f, &sb) ==0;1440}14411442/*1443 * Given two normalized paths (a trailing slash is ok), if subdir is1444 * outside dir, return -1. Otherwise return the offset in subdir that1445 * can be used as relative path to dir.1446 */1447intdir_inside_of(const char*subdir,const char*dir)1448{1449int offset =0;14501451assert(dir && subdir && *dir && *subdir);14521453while(*dir && *subdir && *dir == *subdir) {1454 dir++;1455 subdir++;1456 offset++;1457}14581459/* hel[p]/me vs hel[l]/yeah */1460if(*dir && *subdir)1461return-1;14621463if(!*subdir)1464return!*dir ? offset : -1;/* same dir */14651466/* foo/[b]ar vs foo/[] */1467if(is_dir_sep(dir[-1]))1468returnis_dir_sep(subdir[-1]) ? offset : -1;14691470/* foo[/]bar vs foo[] */1471returnis_dir_sep(*subdir) ? offset +1: -1;1472}14731474intis_inside_dir(const char*dir)1475{1476char cwd[PATH_MAX];1477if(!dir)1478return0;1479if(!getcwd(cwd,sizeof(cwd)))1480die_errno("can't find the current directory");1481returndir_inside_of(cwd, dir) >=0;1482}14831484intis_empty_dir(const char*path)1485{1486DIR*dir =opendir(path);1487struct dirent *e;1488int ret =1;14891490if(!dir)1491return0;14921493while((e =readdir(dir)) != NULL)1494if(!is_dot_or_dotdot(e->d_name)) {1495 ret =0;1496break;1497}14981499closedir(dir);1500return ret;1501}15021503static intremove_dir_recurse(struct strbuf *path,int flag,int*kept_up)1504{1505DIR*dir;1506struct dirent *e;1507int ret =0, original_len = path->len, len, kept_down =0;1508int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);1509int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);1510unsigned char submodule_head[20];15111512if((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&1513!resolve_gitlink_ref(path->buf,"HEAD", submodule_head)) {1514/* Do not descend and nuke a nested git work tree. */1515if(kept_up)1516*kept_up =1;1517return0;1518}15191520 flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;1521 dir =opendir(path->buf);1522if(!dir) {1523/* an empty dir could be removed even if it is unreadble */1524if(!keep_toplevel)1525returnrmdir(path->buf);1526else1527return-1;1528}1529if(path->buf[original_len -1] !='/')1530strbuf_addch(path,'/');15311532 len = path->len;1533while((e =readdir(dir)) != NULL) {1534struct stat st;1535if(is_dot_or_dotdot(e->d_name))1536continue;15371538strbuf_setlen(path, len);1539strbuf_addstr(path, e->d_name);1540if(lstat(path->buf, &st))1541;/* fall thru */1542else if(S_ISDIR(st.st_mode)) {1543if(!remove_dir_recurse(path, flag, &kept_down))1544continue;/* happy */1545}else if(!only_empty && !unlink(path->buf))1546continue;/* happy, too */15471548/* path too long, stat fails, or non-directory still exists */1549 ret = -1;1550break;1551}1552closedir(dir);15531554strbuf_setlen(path, original_len);1555if(!ret && !keep_toplevel && !kept_down)1556 ret =rmdir(path->buf);1557else if(kept_up)1558/*1559 * report the uplevel that it is not an error that we1560 * did not rmdir() our directory.1561 */1562*kept_up = !ret;1563return ret;1564}15651566intremove_dir_recursively(struct strbuf *path,int flag)1567{1568returnremove_dir_recurse(path, flag, NULL);1569}15701571voidsetup_standard_excludes(struct dir_struct *dir)1572{1573const char*path;1574char*xdg_path;15751576 dir->exclude_per_dir =".gitignore";1577 path =git_path("info/exclude");1578if(!excludes_file) {1579home_config_paths(NULL, &xdg_path,"ignore");1580 excludes_file = xdg_path;1581}1582if(!access_or_warn(path, R_OK,0))1583add_excludes_from_file(dir, path);1584if(excludes_file && !access_or_warn(excludes_file, R_OK,0))1585add_excludes_from_file(dir, excludes_file);1586}15871588intremove_path(const char*name)1589{1590char*slash;15911592if(unlink(name) && errno != ENOENT && errno != ENOTDIR)1593return-1;15941595 slash =strrchr(name,'/');1596if(slash) {1597char*dirs =xstrdup(name);1598 slash = dirs + (slash - name);1599do{1600*slash ='\0';1601}while(rmdir(dirs) ==0&& (slash =strrchr(dirs,'/')));1602free(dirs);1603}1604return0;1605}16061607static intpathspec_item_cmp(const void*a_,const void*b_)1608{1609struct pathspec_item *a, *b;16101611 a = (struct pathspec_item *)a_;1612 b = (struct pathspec_item *)b_;1613returnstrcmp(a->match, b->match);1614}16151616intinit_pathspec(struct pathspec *pathspec,const char**paths)1617{1618const char**p = paths;1619int i;16201621memset(pathspec,0,sizeof(*pathspec));1622if(!p)1623return0;1624while(*p)1625 p++;1626 pathspec->raw = paths;1627 pathspec->nr = p - paths;1628if(!pathspec->nr)1629return0;16301631 pathspec->items =xmalloc(sizeof(struct pathspec_item)*pathspec->nr);1632for(i =0; i < pathspec->nr; i++) {1633struct pathspec_item *item = pathspec->items+i;1634const char*path = paths[i];16351636 item->match = path;1637 item->len =strlen(path);1638 item->flags =0;1639if(limit_pathspec_to_literal()) {1640 item->nowildcard_len = item->len;1641}else{1642 item->nowildcard_len =simple_length(path);1643if(item->nowildcard_len < item->len) {1644 pathspec->has_wildcard =1;1645if(path[item->nowildcard_len] =='*'&&1646no_wildcard(path + item->nowildcard_len +1))1647 item->flags |= PATHSPEC_ONESTAR;1648}1649}1650}16511652qsort(pathspec->items, pathspec->nr,1653sizeof(struct pathspec_item), pathspec_item_cmp);16541655return0;1656}16571658voidfree_pathspec(struct pathspec *pathspec)1659{1660free(pathspec->items);1661 pathspec->items = NULL;1662}16631664intlimit_pathspec_to_literal(void)1665{1666static int flag = -1;1667if(flag <0)1668 flag =git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT,0);1669return flag;1670}16711672/*1673 * Frees memory within dir which was allocated for exclude lists and1674 * the exclude_stack. Does not free dir itself.1675 */1676voidclear_directory(struct dir_struct *dir)1677{1678int i, j;1679struct exclude_list_group *group;1680struct exclude_list *el;1681struct exclude_stack *stk;16821683for(i = EXC_CMDL; i <= EXC_FILE; i++) {1684 group = &dir->exclude_list_group[i];1685for(j =0; j < group->nr; j++) {1686 el = &group->el[j];1687if(i == EXC_DIRS)1688free((char*)el->src);1689clear_exclude_list(el);1690}1691free(group->el);1692}16931694 stk = dir->exclude_stack;1695while(stk) {1696struct exclude_stack *prev = stk->prev;1697free(stk);1698 stk = prev;1699}1700}