Merge branch 'sg/completion-zsh-workaround'
[git] / pathspec.h
1 #ifndef PATHSPEC_H
2 #define PATHSPEC_H
3
4 /* Pathspec magic */
5 #define PATHSPEC_FROMTOP        (1<<0)
6 #define PATHSPEC_MAXDEPTH       (1<<1)
7 #define PATHSPEC_LITERAL        (1<<2)
8 #define PATHSPEC_GLOB           (1<<3)
9 #define PATHSPEC_ICASE          (1<<4)
10 #define PATHSPEC_EXCLUDE        (1<<5)
11 #define PATHSPEC_ATTR           (1<<6)
12 #define PATHSPEC_ALL_MAGIC        \
13         (PATHSPEC_FROMTOP       | \
14          PATHSPEC_MAXDEPTH      | \
15          PATHSPEC_LITERAL       | \
16          PATHSPEC_GLOB          | \
17          PATHSPEC_ICASE         | \
18          PATHSPEC_EXCLUDE       | \
19          PATHSPEC_ATTR)
20
21 #define PATHSPEC_ONESTAR 1      /* the pathspec pattern satisfies GFNM_ONESTAR */
22
23 struct pathspec {
24         int nr;
25         unsigned int has_wildcard:1;
26         unsigned int recursive:1;
27         unsigned int recurse_submodules:1;
28         unsigned magic;
29         int max_depth;
30         struct pathspec_item {
31                 char *match;
32                 char *original;
33                 unsigned magic;
34                 int len, prefix;
35                 int nowildcard_len;
36                 int flags;
37                 int attr_match_nr;
38                 struct attr_match {
39                         char *value;
40                         enum attr_match_mode {
41                                 MATCH_SET,
42                                 MATCH_UNSET,
43                                 MATCH_VALUE,
44                                 MATCH_UNSPECIFIED
45                         } match_mode;
46                 } *attr_match;
47                 struct attr_check *attr_check;
48         } *items;
49 };
50
51 #define GUARD_PATHSPEC(ps, mask) \
52         do { \
53                 if ((ps)->magic & ~(mask))             \
54                         die("BUG:%s:%d: unsupported magic %x",  \
55                             __FILE__, __LINE__, (ps)->magic & ~(mask)); \
56         } while (0)
57
58 /* parse_pathspec flags */
59 #define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
60 #define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
61 #define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */
62 /* die if a symlink is part of the given path's directory */
63 #define PATHSPEC_SYMLINK_LEADING_PATH (1<<3)
64 #define PATHSPEC_PREFIX_ORIGIN (1<<4)
65 #define PATHSPEC_KEEP_ORDER (1<<5)
66 /*
67  * For the callers that just need pure paths from somewhere else, not
68  * from command line. Global --*-pathspecs options are ignored. No
69  * magic is parsed in each pathspec either. If PATHSPEC_LITERAL is
70  * allowed, then it will automatically set for every pathspec.
71  */
72 #define PATHSPEC_LITERAL_PATH (1<<6)
73
74 /*
75  * Given command line arguments and a prefix, convert the input to
76  * pathspec. die() if any magic in magic_mask is used.
77  *
78  * Any arguments used are copied. It is safe for the caller to modify
79  * or free 'prefix' and 'args' after calling this function.
80  */
81 extern void parse_pathspec(struct pathspec *pathspec,
82                            unsigned magic_mask,
83                            unsigned flags,
84                            const char *prefix,
85                            const char **args);
86 extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
87 extern void clear_pathspec(struct pathspec *);
88
89 static inline int ps_strncmp(const struct pathspec_item *item,
90                              const char *s1, const char *s2, size_t n)
91 {
92         if (item->magic & PATHSPEC_ICASE)
93                 return strncasecmp(s1, s2, n);
94         else
95                 return strncmp(s1, s2, n);
96 }
97
98 static inline int ps_strcmp(const struct pathspec_item *item,
99                             const char *s1, const char *s2)
100 {
101         if (item->magic & PATHSPEC_ICASE)
102                 return strcasecmp(s1, s2);
103         else
104                 return strcmp(s1, s2);
105 }
106
107 extern void add_pathspec_matches_against_index(const struct pathspec *pathspec,
108                                                const struct index_state *istate,
109                                                char *seen);
110 extern char *find_pathspecs_matching_against_index(const struct pathspec *pathspec,
111                                                    const struct index_state *istate);
112
113 #endif /* PATHSPEC_H */