1#ifndef DIR_H 2#define DIR_H 3 4/* See Documentation/technical/api-directory-listing.txt */ 5 6#include"strbuf.h" 7 8struct dir_entry { 9unsigned int len; 10char name[FLEX_ARRAY];/* more */ 11}; 12 13#define EXC_FLAG_NODIR 1 14#define EXC_FLAG_ENDSWITH 4 15#define EXC_FLAG_MUSTBEDIR 8 16#define EXC_FLAG_NEGATIVE 16 17 18/* 19 * Each excludes file will be parsed into a fresh exclude_list which 20 * is appended to the relevant exclude_list_group (either EXC_DIRS or 21 * EXC_FILE). An exclude_list within the EXC_CMDL exclude_list_group 22 * can also be used to represent the list of --exclude values passed 23 * via CLI args. 24 */ 25struct exclude_list { 26int nr; 27int alloc; 28 29/* remember pointer to exclude file contents so we can free() */ 30char*filebuf; 31 32/* origin of list, e.g. path to filename, or descriptive string */ 33const char*src; 34 35struct exclude { 36/* 37 * This allows callers of last_exclude_matching() etc. 38 * to determine the origin of the matching pattern. 39 */ 40struct exclude_list *el; 41 42const char*pattern; 43int patternlen; 44int nowildcardlen; 45const char*base; 46int baselen; 47int flags; 48 49/* 50 * Counting starts from 1 for line numbers in ignore files, 51 * and from -1 decrementing for patterns from CLI args. 52 */ 53int srcpos; 54} **excludes; 55}; 56 57/* 58 * The contents of the per-directory exclude files are lazily read on 59 * demand and then cached in memory, one per exclude_stack struct, in 60 * order to avoid opening and parsing each one every time that 61 * directory is traversed. 62 */ 63struct exclude_stack { 64struct exclude_stack *prev;/* the struct exclude_stack for the parent directory */ 65int baselen; 66int exclude_ix;/* index of exclude_list within EXC_DIRS exclude_list_group */ 67}; 68 69struct exclude_list_group { 70int nr, alloc; 71struct exclude_list *el; 72}; 73 74struct dir_struct { 75int nr, alloc; 76int ignored_nr, ignored_alloc; 77enum{ 78 DIR_SHOW_IGNORED =1<<0, 79 DIR_SHOW_OTHER_DIRECTORIES =1<<1, 80 DIR_HIDE_EMPTY_DIRECTORIES =1<<2, 81 DIR_NO_GITLINKS =1<<3, 82 DIR_COLLECT_IGNORED =1<<4 83} flags; 84struct dir_entry **entries; 85struct dir_entry **ignored; 86 87/* Exclude info */ 88const char*exclude_per_dir; 89 90/* 91 * We maintain three groups of exclude pattern lists: 92 * 93 * EXC_CMDL lists patterns explicitly given on the command line. 94 * EXC_DIRS lists patterns obtained from per-directory ignore files. 95 * EXC_FILE lists patterns from fallback ignore files, e.g. 96 * - .git/info/exclude 97 * - core.excludesfile 98 * 99 * Each group contains multiple exclude lists, a single list 100 * per source. 101 */ 102#define EXC_CMDL 0 103#define EXC_DIRS 1 104#define EXC_FILE 2 105struct exclude_list_group exclude_list_group[3]; 106 107/* 108 * Temporary variables which are used during loading of the 109 * per-directory exclude lists. 110 * 111 * exclude_stack points to the top of the exclude_stack, and 112 * basebuf contains the full path to the current 113 * (sub)directory in the traversal. Exclude points to the 114 * matching exclude struct if the directory is excluded. 115 */ 116struct exclude_stack *exclude_stack; 117struct exclude *exclude; 118char basebuf[PATH_MAX]; 119}; 120 121/* 122 * The ordering of these constants is significant, with 123 * higher-numbered match types signifying "closer" (i.e. more 124 * specific) matches which will override lower-numbered match types 125 * when populating the seen[] array. 126 */ 127#define MATCHED_RECURSIVELY 1 128#define MATCHED_FNMATCH 2 129#define MATCHED_EXACTLY 3 130externchar*common_prefix(const char**pathspec); 131externintmatch_pathspec(const char**pathspec,const char*name,int namelen,int prefix,char*seen); 132externintmatch_pathspec_depth(const struct pathspec *pathspec, 133const char*name,int namelen, 134int prefix,char*seen); 135externintwithin_depth(const char*name,int namelen,int depth,int max_depth); 136 137externintfill_directory(struct dir_struct *dir,const char**pathspec); 138externintread_directory(struct dir_struct *,const char*path,int len,const char**pathspec); 139 140externintis_excluded_from_list(const char*pathname,int pathlen,const char*basename, 141int*dtype,struct exclude_list *el); 142struct dir_entry *dir_add_ignored(struct dir_struct *dir,const char*pathname,int len); 143 144/* 145 * these implement the matching logic for dir.c:excluded_from_list and 146 * attr.c:path_matches() 147 */ 148externintmatch_basename(const char*,int, 149const char*,int,int,int); 150externintmatch_pathname(const char*,int, 151const char*,int, 152const char*,int,int,int); 153 154/* 155 * The is_excluded() API is meant for callers that check each level of leading 156 * directory hierarchies with is_excluded() to avoid recursing into excluded 157 * directories. Callers that do not do so should use this API instead. 158 */ 159struct path_exclude_check { 160struct dir_struct *dir; 161}; 162externvoidpath_exclude_check_init(struct path_exclude_check *,struct dir_struct *); 163externvoidpath_exclude_check_clear(struct path_exclude_check *); 164externstruct exclude *last_exclude_matching_path(struct path_exclude_check *,const char*, 165int namelen,int*dtype); 166externintis_path_excluded(struct path_exclude_check *,const char*,int namelen,int*dtype); 167 168 169externstruct exclude_list *add_exclude_list(struct dir_struct *dir, 170int group_type,const char*src); 171externintadd_excludes_from_file_to_list(const char*fname,const char*base,int baselen, 172struct exclude_list *el,int check_index); 173externvoidadd_excludes_from_file(struct dir_struct *,const char*fname); 174externvoidparse_exclude_pattern(const char**string,int*patternlen,int*flags,int*nowildcardlen); 175externvoidadd_exclude(const char*string,const char*base, 176int baselen,struct exclude_list *el,int srcpos); 177externvoidclear_exclude_list(struct exclude_list *el); 178externvoidclear_directory(struct dir_struct *dir); 179externintfile_exists(const char*); 180 181externintis_inside_dir(const char*dir); 182externintdir_inside_of(const char*subdir,const char*dir); 183 184staticinlineintis_dot_or_dotdot(const char*name) 185{ 186return(name[0] =='.'&& 187(name[1] =='\0'|| 188(name[1] =='.'&& name[2] =='\0'))); 189} 190 191externintis_empty_dir(const char*dir); 192 193externvoidsetup_standard_excludes(struct dir_struct *dir); 194 195#define REMOVE_DIR_EMPTY_ONLY 01 196#define REMOVE_DIR_KEEP_NESTED_GIT 02 197#define REMOVE_DIR_KEEP_TOPLEVEL 04 198externintremove_dir_recursively(struct strbuf *path,int flag); 199 200/* tries to remove the path with empty directories along it, ignores ENOENT */ 201externintremove_path(const char*path); 202 203externintstrcmp_icase(const char*a,const char*b); 204externintstrncmp_icase(const char*a,const char*b,size_t count); 205externintfnmatch_icase(const char*pattern,const char*string,int flags); 206 207/* 208 * The prefix part of pattern must not contains wildcards. 209 */ 210#define GFNM_PATHNAME 1/* similar to FNM_PATHNAME */ 211#define GFNM_ONESTAR 2/* there is only _one_ wildcard, a star */ 212 213externintgit_fnmatch(const char*pattern,const char*string, 214int flags,int prefix); 215 216#endif