move struct pathspec and related functions to pathspec.[ch]
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Jul 14, 2013 at 15:35 UTC
64acde94efd2906c3e20560c31c2957ac0b242c4
13 files changed
+182
-169
archive.c
+1
@@ -5,6 +5,7 @@
5
#include "archive.h"
6
#include "parse-options.h"
7
#include "unpack-trees.h"
8
+#include "pathspec.h"
9
10
static char const * const archive_usage[] = {
11
N_("git archive [options] <tree-ish> [<path>...]"),
builtin/grep.c
+1
@@ -17,6 +17,7 @@
17
#include "grep.h"
18
#include "quote.h"
19
#include "dir.h"
20
+#include "pathspec.h"
21
22
static char const * const grep_usage[] = {
23
N_("git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"),
builtin/ls-files.c
+1
@@ -13,6 +13,7 @@
13
#include "parse-options.h"
14
#include "resolve-undo.h"
15
#include "string-list.h"
16
+#include "pathspec.h"
17
18
static int abbrev;
19
static int show_deleted;
builtin/ls-tree.c
+1
@@ -10,6 +10,7 @@
10
#include "quote.h"
11
#include "builtin.h"
12
#include "parse-options.h"
13
+#include "pathspec.h"
14
15
static int line_termination = '\n';
16
#define LS_RECURSIVE 1
builtin/update-index.c
+1
@@ -11,6 +11,7 @@
11
#include "refs.h"
12
#include "resolve-undo.h"
13
#include "parse-options.h"
14
+#include "pathspec.h"
15
16
/*
17
* Default to not allowing changes to the list of files. The
cache.h
+2
-20
@@ -189,6 +189,8 @@ struct cache_entry {
189
#error "CE_EXTENDED_FLAGS out of range"
190
#endif
191
192
+struct pathspec;
193
+
194
/*
195
* Copy the sha1 and stat state of a cache entry from one to
196
* another. But we never change the name, or the hash state!
@@ -489,28 +491,8 @@ extern void *read_blob_data_from_index(struct index_state *, const char *, unsig
491
extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
492
extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
493
492
-#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */
493
-
494
-struct pathspec {
495
- const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
496
- int nr;
497
- unsigned int has_wildcard:1;
498
- unsigned int recursive:1;
499
- int max_depth;
500
- struct pathspec_item {
501
- const char *match;
502
- int len;
503
- int nowildcard_len;
504
- int flags;
505
- } *items;
506
-};
507
-
508
-extern int init_pathspec(struct pathspec *, const char **);
509
-extern void free_pathspec(struct pathspec *);
494
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
495
512
-extern int limit_pathspec_to_literal(void);
513
-
496
#define HASH_WRITE_OBJECT 1
497
#define HASH_FORMAT_CHECK 2
498
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
diff.h
+1
@@ -5,6 +5,7 @@
5
#define DIFF_H
6
7
#include "tree-walk.h"
8
+#include "pathspec.h"
9
10
struct rev_info;
11
struct diff_options;
dir.c
+1
@@ -11,6 +11,7 @@
11
#include "dir.h"
12
#include "refs.h"
13
#include "wildmatch.h"
14
+#include "pathspec.h"
15
16
struct path_simplify {
17
int len;
pathspec.c
+150
@@ -99,3 +99,153 @@ void die_if_path_beyond_symlink(const char *path, const char *prefix)
99
die(_("'%s' is beyond a symbolic link"), path + len);
100
}
101
}
102
+
103
+/*
104
+ * Magic pathspec
105
+ *
106
+ * NEEDSWORK: These need to be moved to dir.h or even to a new
107
+ * pathspec.h when we restructure get_pathspec() users to use the
108
+ * "struct pathspec" interface.
109
+ *
110
+ * Possible future magic semantics include stuff like:
111
+ *
112
+ * { PATHSPEC_NOGLOB, '!', "noglob" },
113
+ * { PATHSPEC_ICASE, '\0', "icase" },
114
+ * { PATHSPEC_RECURSIVE, '*', "recursive" },
115
+ * { PATHSPEC_REGEXP, '\0', "regexp" },
116
+ *
117
+ */
118
+#define PATHSPEC_FROMTOP (1<<0)
119
+
120
+static struct pathspec_magic {
121
+ unsigned bit;
122
+ char mnemonic; /* this cannot be ':'! */
123
+ const char *name;
124
+} pathspec_magic[] = {
125
+ { PATHSPEC_FROMTOP, '/', "top" },
126
+};
127
+
128
+/*
129
+ * Take an element of a pathspec and check for magic signatures.
130
+ * Append the result to the prefix.
131
+ *
132
+ * For now, we only parse the syntax and throw out anything other than
133
+ * "top" magic.
134
+ *
135
+ * NEEDSWORK: This needs to be rewritten when we start migrating
136
+ * get_pathspec() users to use the "struct pathspec" interface. For
137
+ * example, a pathspec element may be marked as case-insensitive, but
138
+ * the prefix part must always match literally, and a single stupid
139
+ * string cannot express such a case.
140
+ */
141
+static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
142
+{
143
+ unsigned magic = 0;
144
+ const char *copyfrom = elt;
145
+ int i;
146
+
147
+ if (elt[0] != ':') {
148
+ ; /* nothing to do */
149
+ } else if (elt[1] == '(') {
150
+ /* longhand */
151
+ const char *nextat;
152
+ for (copyfrom = elt + 2;
153
+ *copyfrom && *copyfrom != ')';
154
+ copyfrom = nextat) {
155
+ size_t len = strcspn(copyfrom, ",)");
156
+ if (copyfrom[len] == ',')
157
+ nextat = copyfrom + len + 1;
158
+ else
159
+ /* handle ')' and '\0' */
160
+ nextat = copyfrom + len;
161
+ if (!len)
162
+ continue;
163
+ for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
164
+ if (strlen(pathspec_magic[i].name) == len &&
165
+ !strncmp(pathspec_magic[i].name, copyfrom, len)) {
166
+ magic |= pathspec_magic[i].bit;
167
+ break;
168
+ }
169
+ if (ARRAY_SIZE(pathspec_magic) <= i)
170
+ die("Invalid pathspec magic '%.*s' in '%s'",
171
+ (int) len, copyfrom, elt);
172
+ }
173
+ if (*copyfrom != ')')
174
+ die("Missing ')' at the end of pathspec magic in '%s'", elt);
175
+ copyfrom++;
176
+ } else {
177
+ /* shorthand */
178
+ for (copyfrom = elt + 1;
179
+ *copyfrom && *copyfrom != ':';
180
+ copyfrom++) {
181
+ char ch = *copyfrom;
182
+
183
+ if (!is_pathspec_magic(ch))
184
+ break;
185
+ for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
186
+ if (pathspec_magic[i].mnemonic == ch) {
187
+ magic |= pathspec_magic[i].bit;
188
+ break;
189
+ }
190
+ if (ARRAY_SIZE(pathspec_magic) <= i)
191
+ die("Unimplemented pathspec magic '%c' in '%s'",
192
+ ch, elt);
193
+ }
194
+ if (*copyfrom == ':')
195
+ copyfrom++;
196
+ }
197
+
198
+ if (magic & PATHSPEC_FROMTOP)
199
+ return xstrdup(copyfrom);
200
+ else
201
+ return prefix_path(prefix, prefixlen, copyfrom);
202
+}
203
+
204
+/*
205
+ * N.B. get_pathspec() is deprecated in favor of the "struct pathspec"
206
+ * based interface - see pathspec_magic above.
207
+ *
208
+ * Arguments:
209
+ * - prefix - a path relative to the root of the working tree
210
+ * - pathspec - a list of paths underneath the prefix path
211
+ *
212
+ * Iterates over pathspec, prepending each path with prefix,
213
+ * and return the resulting list.
214
+ *
215
+ * If pathspec is empty, return a singleton list containing prefix.
216
+ *
217
+ * If pathspec and prefix are both empty, return an empty list.
218
+ *
219
+ * This is typically used by built-in commands such as add.c, in order
220
+ * to normalize argv arguments provided to the built-in into a list of
221
+ * paths to process, all relative to the root of the working tree.
222
+ */
223
+const char **get_pathspec(const char *prefix, const char **pathspec)
224
+{
225
+ const char *entry = *pathspec;
226
+ const char **src, **dst;
227
+ int prefixlen;
228
+
229
+ if (!prefix && !entry)
230
+ return NULL;
231
+
232
+ if (!entry) {
233
+ static const char *spec[2];
234
+ spec[0] = prefix;
235
+ spec[1] = NULL;
236
+ return spec;
237
+ }
238
+
239
+ /* Otherwise we have to re-write the entries.. */
240
+ src = pathspec;
241
+ dst = pathspec;
242
+ prefixlen = prefix ? strlen(prefix) : 0;
243
+ while (*src) {
244
+ *(dst++) = prefix_pathspec(prefix, prefixlen, *src);
245
+ src++;
246
+ }
247
+ *dst = NULL;
248
+ if (!*pathspec)
249
+ return NULL;
250
+ return pathspec;
251
+}
pathspec.h
+21
@@ -1,6 +1,27 @@
1
#ifndef PATHSPEC_H
2
#define PATHSPEC_H
3
4
+#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */
5
+
6
+struct pathspec {
7
+ const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
8
+ int nr;
9
+ unsigned int has_wildcard:1;
10
+ unsigned int recursive:1;
11
+ int max_depth;
12
+ struct pathspec_item {
13
+ const char *match;
14
+ int len;
15
+ int nowildcard_len;
16
+ int flags;
17
+ } *items;
18
+};
19
+
20
+extern int init_pathspec(struct pathspec *, const char **);
21
+extern void free_pathspec(struct pathspec *);
22
+
23
+extern int limit_pathspec_to_literal(void);
24
+
25
extern char *find_pathspecs_matching_against_index(const char **pathspec);
26
extern void add_pathspec_matches_against_index(const char **pathspec, char *seen, int specs);
27
extern const char *check_path_for_gitlink(const char *path);
preload-index.c
+1
@@ -2,6 +2,7 @@
2
* Copyright (C) 2008 Linus Torvalds
3
*/
4
#include "cache.h"
5
+#include "pathspec.h"
6
7
#ifdef NO_PTHREADS
8
static void preload_index(struct index_state *index, const char **pathspec)
setup.c
-149
@@ -154,155 +154,6 @@ void verify_non_filename(const char *prefix, const char *arg)
154
"'git <command> [<revision>...] -- [<file>...]'", arg);
155
}
156
157
-/*
158
- * Magic pathspec
159
- *
160
- * NEEDSWORK: These need to be moved to dir.h or even to a new
161
- * pathspec.h when we restructure get_pathspec() users to use the
162
- * "struct pathspec" interface.
163
- *
164
- * Possible future magic semantics include stuff like:
165
- *
166
- * { PATHSPEC_NOGLOB, '!', "noglob" },
167
- * { PATHSPEC_ICASE, '\0', "icase" },
168
- * { PATHSPEC_RECURSIVE, '*', "recursive" },
169
- * { PATHSPEC_REGEXP, '\0', "regexp" },
170
- *
171
- */
172
-#define PATHSPEC_FROMTOP (1<<0)
173
-
174
-static struct pathspec_magic {
175
- unsigned bit;
176
- char mnemonic; /* this cannot be ':'! */
177
- const char *name;
178
-} pathspec_magic[] = {
179
- { PATHSPEC_FROMTOP, '/', "top" },
180
-};
181
-
182
-/*
183
- * Take an element of a pathspec and check for magic signatures.
184
- * Append the result to the prefix.
185
- *
186
- * For now, we only parse the syntax and throw out anything other than
187
- * "top" magic.
188
- *
189
- * NEEDSWORK: This needs to be rewritten when we start migrating
190
- * get_pathspec() users to use the "struct pathspec" interface. For
191
- * example, a pathspec element may be marked as case-insensitive, but
192
- * the prefix part must always match literally, and a single stupid
193
- * string cannot express such a case.
194
- */
195
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
196
-{
197
- unsigned magic = 0;
198
- const char *copyfrom = elt;
199
- int i;
200
-
201
- if (elt[0] != ':') {
202
- ; /* nothing to do */
203
- } else if (elt[1] == '(') {
204
- /* longhand */
205
- const char *nextat;
206
- for (copyfrom = elt + 2;
207
- *copyfrom && *copyfrom != ')';
208
- copyfrom = nextat) {
209
- size_t len = strcspn(copyfrom, ",)");
210
- if (copyfrom[len] == ',')
211
- nextat = copyfrom + len + 1;
212
- else
213
- /* handle ')' and '\0' */
214
- nextat = copyfrom + len;
215
- if (!len)
216
- continue;
217
- for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
218
- if (strlen(pathspec_magic[i].name) == len &&
219
- !strncmp(pathspec_magic[i].name, copyfrom, len)) {
220
- magic |= pathspec_magic[i].bit;
221
- break;
222
- }
223
- if (ARRAY_SIZE(pathspec_magic) <= i)
224
- die("Invalid pathspec magic '%.*s' in '%s'",
225
- (int) len, copyfrom, elt);
226
- }
227
- if (*copyfrom != ')')
228
- die("Missing ')' at the end of pathspec magic in '%s'", elt);
229
- copyfrom++;
230
- } else {
231
- /* shorthand */
232
- for (copyfrom = elt + 1;
233
- *copyfrom && *copyfrom != ':';
234
- copyfrom++) {
235
- char ch = *copyfrom;
236
-
237
- if (!is_pathspec_magic(ch))
238
- break;
239
- for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
240
- if (pathspec_magic[i].mnemonic == ch) {
241
- magic |= pathspec_magic[i].bit;
242
- break;
243
- }
244
- if (ARRAY_SIZE(pathspec_magic) <= i)
245
- die("Unimplemented pathspec magic '%c' in '%s'",
246
- ch, elt);
247
- }
248
- if (*copyfrom == ':')
249
- copyfrom++;
250
- }
251
-
252
- if (magic & PATHSPEC_FROMTOP)
253
- return xstrdup(copyfrom);
254
- else
255
- return prefix_path(prefix, prefixlen, copyfrom);
256
-}
257
-
258
-/*
259
- * N.B. get_pathspec() is deprecated in favor of the "struct pathspec"
260
- * based interface - see pathspec_magic above.
261
- *
262
- * Arguments:
263
- * - prefix - a path relative to the root of the working tree
264
- * - pathspec - a list of paths underneath the prefix path
265
- *
266
- * Iterates over pathspec, prepending each path with prefix,
267
- * and return the resulting list.
268
- *
269
- * If pathspec is empty, return a singleton list containing prefix.
270
- *
271
- * If pathspec and prefix are both empty, return an empty list.
272
- *
273
- * This is typically used by built-in commands such as add.c, in order
274
- * to normalize argv arguments provided to the built-in into a list of
275
- * paths to process, all relative to the root of the working tree.
276
- */
277
-const char **get_pathspec(const char *prefix, const char **pathspec)
278
-{
279
- const char *entry = *pathspec;
280
- const char **src, **dst;
281
- int prefixlen;
282
-
283
- if (!prefix && !entry)
284
- return NULL;
285
-
286
- if (!entry) {
287
- static const char *spec[2];
288
- spec[0] = prefix;
289
- spec[1] = NULL;
290
- return spec;
291
- }
292
-
293
- /* Otherwise we have to re-write the entries.. */
294
- src = pathspec;
295
- dst = pathspec;
296
- prefixlen = prefix ? strlen(prefix) : 0;
297
- while (*src) {
298
- *(dst++) = prefix_pathspec(prefix, prefixlen, *src);
299
- src++;
300
- }
301
- *dst = NULL;
302
- if (!*pathspec)
303
- return NULL;
304
- return pathspec;
305
-}
157
158
/*
159
* Test if it looks like we're at a git directory.
tree-walk.c
+1
@@ -3,6 +3,7 @@
3
#include "unpack-trees.h"
4
#include "dir.h"
5
#include "tree.h"
6
+#include "pathspec.h"
7
8
static const char *get_mode(const char *str, unsigned int *modep)
9
{