update-ref: organize commands in an array
We currently manually wire up all commands known to `git-update-ref --stdin`, making it harder than necessary to preprocess arguments after the command is determined. To make this more extensible, let's refactor the code to use an array of known commands instead. While this doesn't add a lot of value now, it is a preparatory step to implement line-wise reading of commands. As we're going to introduce commands without trailing spaces, this commit also moves whitespace parsing into the respective commands. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Apr 2, 2020 at 09:09 UTC
a65b8ac291d919c8f0c89f7397e03662020344ab
1 file changed
+29
-12
builtin/update-ref.c
+29
-12
@@ -310,7 +310,8 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
310
return next;
311
}
312
313
-static const char *parse_cmd_option(struct strbuf *input, const char *next)
313
+static const char *parse_cmd_option(struct ref_transaction *transaction,
314
+ struct strbuf *input, const char *next)
315
{
316
const char *rest;
317
if (skip_prefix(next, "no-deref", &rest) && *rest == line_termination)
@@ -320,33 +321,49 @@ static const char *parse_cmd_option(struct strbuf *input, const char *next)
321
return rest;
322
}
323
324
+static const struct parse_cmd {
325
+ const char *prefix;
326
+ const char *(*fn)(struct ref_transaction *, struct strbuf *, const char *);
327
+} command[] = {
328
+ { "update", parse_cmd_update },
329
+ { "create", parse_cmd_create },
330
+ { "delete", parse_cmd_delete },
331
+ { "verify", parse_cmd_verify },
332
+ { "option", parse_cmd_option },
333
+};
334
+
335
static void update_refs_stdin(struct ref_transaction *transaction)
336
{
337
struct strbuf input = STRBUF_INIT;
338
const char *next;
339
+ int i;
340
341
if (strbuf_read(&input, 0, 1000) < 0)
342
die_errno("could not read from stdin");
343
next = input.buf;
344
/* Read each line dispatch its command */
345
while (next < input.buf + input.len) {
346
+ const struct parse_cmd *cmd = NULL;
347
+
348
if (*next == line_termination)
349
die("empty command in input");
350
else if (isspace(*next))
351
die("whitespace before command: %s", next);
337
- else if (skip_prefix(next, "update ", &next))
338
- next = parse_cmd_update(transaction, &input, next);
339
- else if (skip_prefix(next, "create ", &next))
340
- next = parse_cmd_create(transaction, &input, next);
341
- else if (skip_prefix(next, "delete ", &next))
342
- next = parse_cmd_delete(transaction, &input, next);
343
- else if (skip_prefix(next, "verify ", &next))
344
- next = parse_cmd_verify(transaction, &input, next);
345
- else if (skip_prefix(next, "option ", &next))
346
- next = parse_cmd_option(&input, next);
347
- else
352
+
353
+ for (i = 0; i < ARRAY_SIZE(command); i++) {
354
+ const char *prefix = command[i].prefix;
355
+
356
+ if (!skip_prefix(next, prefix, &next) ||
357
+ !skip_prefix(next, " ", &next))
358
+ continue;
359
+
360
+ cmd = &command[i];
361
+ break;
362
+ }
363
+ if (!cmd)
364
die("unknown command: %s", next);
365
366
+ next = cmd->fn(transaction, &input, next);
367
next++;
368
}
369