refspec: introduce struct refspec
Introduce 'struct refspec', an abstraction around a collection of 'struct refspec_item's much like how 'struct pathspec' holds a collection of 'struct pathspec_item's. A refspec struct also contains an array of the original refspec strings which will be used to facilitate the migration to using this new abstraction throughout the code base. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brandon Williams committed
May 16, 2018 at 15:57 UTC
6d4c05785946e302e611be9ac1f5ca0b5ada9214
2 files changed
+89
refspec.c
+64
@@ -178,3 +178,67 @@ void free_refspec(int nr_refspec, struct refspec_item *refspec)
178
}
179
free(refspec);
180
}
181
+
182
+void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
183
+{
184
+ memset(item, 0, sizeof(*item));
185
+
186
+ if (!parse_refspec(item, refspec, fetch))
187
+ die("Invalid refspec '%s'", refspec);
188
+}
189
+
190
+void refspec_item_clear(struct refspec_item *item)
191
+{
192
+ FREE_AND_NULL(item->src);
193
+ FREE_AND_NULL(item->dst);
194
+ item->force = 0;
195
+ item->pattern = 0;
196
+ item->matching = 0;
197
+ item->exact_sha1 = 0;
198
+}
199
+
200
+void refspec_init(struct refspec *rs, int fetch)
201
+{
202
+ memset(rs, 0, sizeof(*rs));
203
+ rs->fetch = fetch;
204
+}
205
+
206
+void refspec_append(struct refspec *rs, const char *refspec)
207
+{
208
+ struct refspec_item item;
209
+
210
+ refspec_item_init(&item, refspec, rs->fetch);
211
+
212
+ ALLOC_GROW(rs->items, rs->nr + 1, rs->alloc);
213
+ rs->items[rs->nr++] = item;
214
+
215
+ ALLOC_GROW(rs->raw, rs->raw_nr + 1, rs->raw_alloc);
216
+ rs->raw[rs->raw_nr++] = xstrdup(refspec);
217
+}
218
+
219
+void refspec_appendn(struct refspec *rs, const char **refspecs, int nr)
220
+{
221
+ int i;
222
+ for (i = 0; i < nr; i++)
223
+ refspec_append(rs, refspecs[i]);
224
+}
225
+
226
+void refspec_clear(struct refspec *rs)
227
+{
228
+ int i;
229
+
230
+ for (i = 0; i < rs->nr; i++)
231
+ refspec_item_clear(&rs->items[i]);
232
+
233
+ FREE_AND_NULL(rs->items);
234
+ rs->alloc = 0;
235
+ rs->nr = 0;
236
+
237
+ for (i = 0; i < rs->raw_nr; i++)
238
+ free((char *)rs->raw[i]);
239
+ FREE_AND_NULL(rs->raw);
240
+ rs->raw_alloc = 0;
241
+ rs->raw_nr = 0;
242
+
243
+ rs->fetch = 0;
244
+}
refspec.h
+25
@@ -20,4 +20,29 @@ struct refspec_item *parse_push_refspec(int nr_refspec, const char **refspec);
20
21
void free_refspec(int nr_refspec, struct refspec_item *refspec);
22
23
+#define REFSPEC_FETCH 1
24
+#define REFSPEC_PUSH 0
25
+
26
+#define REFSPEC_INIT_FETCH { .fetch = REFSPEC_FETCH }
27
+#define REFSPEC_INIT_PUSH { .fetch = REFSPEC_PUSH }
28
+
29
+struct refspec {
30
+ struct refspec_item *items;
31
+ int alloc;
32
+ int nr;
33
+
34
+ const char **raw;
35
+ int raw_alloc;
36
+ int raw_nr;
37
+
38
+ int fetch;
39
+};
40
+
41
+void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch);
42
+void refspec_item_clear(struct refspec_item *item);
43
+void refspec_init(struct refspec *rs, int fetch);
44
+void refspec_append(struct refspec *rs, const char *refspec);
45
+void refspec_appendn(struct refspec *rs, const char **refspecs, int nr);
46
+void refspec_clear(struct refspec *rs);
47
+
48
#endif /* REFSPEC_H */