dir.hon commit Merge branch 'jk/maint-fast-import-doc-reorder' (a96e807)
   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 {
   9        unsigned int len;
  10        char 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 .gitignore file will be parsed into patterns which are then
  20 * appended to the relevant exclude_list (either EXC_DIRS or
  21 * EXC_FILE).  exclude_lists are also used to represent the list of
  22 * --exclude values passed via CLI args (EXC_CMDL).
  23 */
  24struct exclude_list {
  25        int nr;
  26        int alloc;
  27        struct exclude {
  28                const char *pattern;
  29                int patternlen;
  30                int nowildcardlen;
  31                const char *base;
  32                int baselen;
  33                int flags;
  34        } **excludes;
  35};
  36
  37/*
  38 * The contents of the per-directory exclude files are lazily read on
  39 * demand and then cached in memory, one per exclude_stack struct, in
  40 * order to avoid opening and parsing each one every time that
  41 * directory is traversed.
  42 */
  43struct exclude_stack {
  44        struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */
  45        char *filebuf; /* remember pointer to per-directory exclude file contents so we can free() */
  46        int baselen;
  47        int exclude_ix;
  48};
  49
  50struct dir_struct {
  51        int nr, alloc;
  52        int ignored_nr, ignored_alloc;
  53        enum {
  54                DIR_SHOW_IGNORED = 1<<0,
  55                DIR_SHOW_OTHER_DIRECTORIES = 1<<1,
  56                DIR_HIDE_EMPTY_DIRECTORIES = 1<<2,
  57                DIR_NO_GITLINKS = 1<<3,
  58                DIR_COLLECT_IGNORED = 1<<4
  59        } flags;
  60        struct dir_entry **entries;
  61        struct dir_entry **ignored;
  62
  63        /* Exclude info */
  64        const char *exclude_per_dir;
  65        struct exclude_list exclude_list[3];
  66        /*
  67         * We maintain three exclude pattern lists:
  68         * EXC_CMDL lists patterns explicitly given on the command line.
  69         * EXC_DIRS lists patterns obtained from per-directory ignore files.
  70         * EXC_FILE lists patterns from fallback ignore files.
  71         */
  72#define EXC_CMDL 0
  73#define EXC_DIRS 1
  74#define EXC_FILE 2
  75
  76        /*
  77         * Temporary variables which are used during loading of the
  78         * per-directory exclude lists.
  79         *
  80         * exclude_stack points to the top of the exclude_stack, and
  81         * basebuf contains the full path to the current
  82         * (sub)directory in the traversal.
  83         */
  84        struct exclude_stack *exclude_stack;
  85        char basebuf[PATH_MAX];
  86};
  87
  88#define MATCHED_RECURSIVELY 1
  89#define MATCHED_FNMATCH 2
  90#define MATCHED_EXACTLY 3
  91extern char *common_prefix(const char **pathspec);
  92extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
  93extern int match_pathspec_depth(const struct pathspec *pathspec,
  94                                const char *name, int namelen,
  95                                int prefix, char *seen);
  96extern int within_depth(const char *name, int namelen, int depth, int max_depth);
  97
  98extern int fill_directory(struct dir_struct *dir, const char **pathspec);
  99extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec);
 100
 101extern int is_excluded_from_list(const char *pathname, int pathlen, const char *basename,
 102                                 int *dtype, struct exclude_list *el);
 103struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len);
 104
 105/*
 106 * these implement the matching logic for dir.c:excluded_from_list and
 107 * attr.c:path_matches()
 108 */
 109extern int match_basename(const char *, int,
 110                          const char *, int, int, int);
 111extern int match_pathname(const char *, int,
 112                          const char *, int,
 113                          const char *, int, int, int);
 114
 115/*
 116 * The is_excluded() API is meant for callers that check each level of leading
 117 * directory hierarchies with is_excluded() to avoid recursing into excluded
 118 * directories.  Callers that do not do so should use this API instead.
 119 */
 120struct path_exclude_check {
 121        struct dir_struct *dir;
 122        struct exclude *exclude;
 123        struct strbuf path;
 124};
 125extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
 126extern void path_exclude_check_clear(struct path_exclude_check *);
 127extern struct exclude *last_exclude_matching_path(struct path_exclude_check *, const char *,
 128                                                  int namelen, int *dtype);
 129extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
 130
 131
 132extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
 133                                          char **buf_p, struct exclude_list *el, int check_index);
 134extern void add_excludes_from_file(struct dir_struct *, const char *fname);
 135extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen);
 136extern void add_exclude(const char *string, const char *base,
 137                        int baselen, struct exclude_list *el);
 138extern void clear_exclude_list(struct exclude_list *el);
 139extern int file_exists(const char *);
 140
 141extern int is_inside_dir(const char *dir);
 142extern int dir_inside_of(const char *subdir, const char *dir);
 143
 144static inline int is_dot_or_dotdot(const char *name)
 145{
 146        return (name[0] == '.' &&
 147                (name[1] == '\0' ||
 148                 (name[1] == '.' && name[2] == '\0')));
 149}
 150
 151extern int is_empty_dir(const char *dir);
 152
 153extern void setup_standard_excludes(struct dir_struct *dir);
 154
 155#define REMOVE_DIR_EMPTY_ONLY 01
 156#define REMOVE_DIR_KEEP_NESTED_GIT 02
 157#define REMOVE_DIR_KEEP_TOPLEVEL 04
 158extern int remove_dir_recursively(struct strbuf *path, int flag);
 159
 160/* tries to remove the path with empty directories along it, ignores ENOENT */
 161extern int remove_path(const char *path);
 162
 163extern int strcmp_icase(const char *a, const char *b);
 164extern int strncmp_icase(const char *a, const char *b, size_t count);
 165extern int fnmatch_icase(const char *pattern, const char *string, int flags);
 166
 167/*
 168 * The prefix part of pattern must not contains wildcards.
 169 */
 170#define GFNM_PATHNAME 1         /* similar to FNM_PATHNAME */
 171#define GFNM_ONESTAR  2         /* there is only _one_ wildcard, a star */
 172
 173extern int git_fnmatch(const char *pattern, const char *string,
 174                       int flags, int prefix);
 175
 176#endif