sparse-index: implement ensure_full_index()
[git] / pathspec.h
1 #ifndef PATHSPEC_H
2 #define PATHSPEC_H
3
4 struct index_state;
5
6 /* Pathspec magic */
7 #define PATHSPEC_FROMTOP        (1<<0)
8 #define PATHSPEC_MAXDEPTH       (1<<1)
9 #define PATHSPEC_LITERAL        (1<<2)
10 #define PATHSPEC_GLOB           (1<<3)
11 #define PATHSPEC_ICASE          (1<<4)
12 #define PATHSPEC_EXCLUDE        (1<<5)
13 #define PATHSPEC_ATTR           (1<<6)
14 #define PATHSPEC_ALL_MAGIC        \
15         (PATHSPEC_FROMTOP       | \
16          PATHSPEC_MAXDEPTH      | \
17          PATHSPEC_LITERAL       | \
18          PATHSPEC_GLOB          | \
19          PATHSPEC_ICASE         | \
20          PATHSPEC_EXCLUDE       | \
21          PATHSPEC_ATTR)
22
23 #define PATHSPEC_ONESTAR 1      /* the pathspec pattern satisfies GFNM_ONESTAR */
24
25 /**
26  * See glossary-context.txt for the syntax of pathspec.
27  * In memory, a pathspec set is represented by "struct pathspec" and is
28  * prepared by parse_pathspec().
29  */
30 struct pathspec {
31         int nr;
32         unsigned int has_wildcard:1;
33         unsigned int recursive:1;
34         unsigned int recurse_submodules:1;
35         unsigned magic;
36         int max_depth;
37         struct pathspec_item {
38                 char *match;
39                 char *original;
40                 unsigned magic;
41                 int len, prefix;
42                 int nowildcard_len;
43                 int flags;
44                 int attr_match_nr;
45                 struct attr_match {
46                         char *value;
47                         enum attr_match_mode {
48                                 MATCH_SET,
49                                 MATCH_UNSET,
50                                 MATCH_VALUE,
51                                 MATCH_UNSPECIFIED
52                         } match_mode;
53                 } *attr_match;
54                 struct attr_check *attr_check;
55         } *items;
56 };
57
58 #define GUARD_PATHSPEC(ps, mask) \
59         do { \
60                 if ((ps)->magic & ~(mask))             \
61                         die("BUG:%s:%d: unsupported magic %x",  \
62                             __FILE__, __LINE__, (ps)->magic & ~(mask)); \
63         } while (0)
64
65 /* parse_pathspec flags */
66 #define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
67 #define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
68 #define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */
69 /* die if a symlink is part of the given path's directory */
70 #define PATHSPEC_SYMLINK_LEADING_PATH (1<<3)
71 #define PATHSPEC_PREFIX_ORIGIN (1<<4)
72 #define PATHSPEC_KEEP_ORDER (1<<5)
73 /*
74  * For the callers that just need pure paths from somewhere else, not
75  * from command line. Global --*-pathspecs options are ignored. No
76  * magic is parsed in each pathspec either. If PATHSPEC_LITERAL is
77  * allowed, then it will automatically set for every pathspec.
78  */
79 #define PATHSPEC_LITERAL_PATH (1<<6)
80
81 /**
82  * Given command line arguments and a prefix, convert the input to
83  * pathspec. die() if any magic in magic_mask is used.
84  *
85  * Any arguments used are copied. It is safe for the caller to modify
86  * or free 'prefix' and 'args' after calling this function.
87  *
88  * - magic_mask specifies what features that are NOT supported by the following
89  * code. If a user attempts to use such a feature, parse_pathspec() can reject
90  * it early.
91  *
92  * - flags specifies other things that the caller wants parse_pathspec to
93  * perform.
94  *
95  * - prefix and args come from cmd_* functions
96  *
97  * parse_pathspec() helps catch unsupported features and reject them politely.
98  * At a lower level, different pathspec-related functions may not support the
99  * same set of features. Such pathspec-sensitive functions are guarded with
100  * GUARD_PATHSPEC(), which will die in an unfriendly way when an unsupported
101  * feature is requested.
102  *
103  * The command designers are supposed to make sure that GUARD_PATHSPEC() never
104  * dies. They have to make sure all unsupported features are caught by
105  * parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC() should
106  * give the designers all pathspec-sensitive codepaths and what features they
107  * support.
108  *
109  * A similar process is applied when a new pathspec magic is added. The designer
110  * lifts the GUARD_PATHSPEC restriction in the functions that support the new
111  * magic. At the same time (s)he has to make sure this new feature will be
112  * caught at parse_pathspec() in commands that cannot handle the new magic in
113  * some cases. grepping parse_pathspec() should help.
114  */
115 void parse_pathspec(struct pathspec *pathspec,
116                     unsigned magic_mask,
117                     unsigned flags,
118                     const char *prefix,
119                     const char **args);
120 /*
121  * Same as parse_pathspec() but uses file as input.
122  * When 'file' is exactly "-" it uses 'stdin' instead.
123  */
124 void parse_pathspec_file(struct pathspec *pathspec,
125                          unsigned magic_mask,
126                          unsigned flags,
127                          const char *prefix,
128                          const char *file,
129                          int nul_term_line);
130
131 void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
132 void clear_pathspec(struct pathspec *);
133
134 static inline int ps_strncmp(const struct pathspec_item *item,
135                              const char *s1, const char *s2, size_t n)
136 {
137         if (item->magic & PATHSPEC_ICASE)
138                 return strncasecmp(s1, s2, n);
139         else
140                 return strncmp(s1, s2, n);
141 }
142
143 static inline int ps_strcmp(const struct pathspec_item *item,
144                             const char *s1, const char *s2)
145 {
146         if (item->magic & PATHSPEC_ICASE)
147                 return strcasecmp(s1, s2);
148         else
149                 return strcmp(s1, s2);
150 }
151
152 void add_pathspec_matches_against_index(const struct pathspec *pathspec,
153                                         const struct index_state *istate,
154                                         char *seen);
155 char *find_pathspecs_matching_against_index(const struct pathspec *pathspec,
156                                             const struct index_state *istate);
157 int match_pathspec_attrs(const struct index_state *istate,
158                          const char *name, int namelen,
159                          const struct pathspec_item *item);
160
161 #endif /* PATHSPEC_H */