178
* depending on how line_termination is set.
179
*/
180
181
-static const char *parse_cmd_update(struct ref_transaction *transaction,
182
- const char *next, const char *end)
181
+static void parse_cmd_update(struct ref_transaction *transaction,
182
+ const char *next, const char *end)
183
{
184
struct strbuf err = STRBUF_INIT;
185
char *refname;
209
update_flags = default_flags;
210
free(refname);
211
strbuf_release(&err);
212
-
213
- return next;
212
}
213
216
-static const char *parse_cmd_create(struct ref_transaction *transaction,
217
- const char *next, const char *end)
214
+static void parse_cmd_create(struct ref_transaction *transaction,
215
+ const char *next, const char *end)
216
{
217
struct strbuf err = STRBUF_INIT;
218
char *refname;
239
update_flags = default_flags;
240
free(refname);
241
strbuf_release(&err);
244
-
245
- return next;
242
}
243
248
-static const char *parse_cmd_delete(struct ref_transaction *transaction,
249
- const char *next, const char *end)
244
+static void parse_cmd_delete(struct ref_transaction *transaction,
245
+ const char *next, const char *end)
246
{
247
struct strbuf err = STRBUF_INIT;
248
char *refname;
273
update_flags = default_flags;
274
free(refname);
275
strbuf_release(&err);
280
-
281
- return next;
276
}
277
284
-static const char *parse_cmd_verify(struct ref_transaction *transaction,
285
- const char *next, const char *end)
278
+static void parse_cmd_verify(struct ref_transaction *transaction,
279
+ const char *next, const char *end)
280
{
281
struct strbuf err = STRBUF_INIT;
282
char *refname;
300
update_flags = default_flags;
301
free(refname);
302
strbuf_release(&err);
309
-
310
- return next;
303
}
304
313
-static const char *parse_cmd_option(struct ref_transaction *transaction,
314
- const char *next, const char *end)
305
+static void parse_cmd_option(struct ref_transaction *transaction,
306
+ const char *next, const char *end)
307
{
308
const char *rest;
309
if (skip_prefix(next, "no-deref", &rest) && *rest == line_termination)
310
update_flags |= REF_NO_DEREF;
311
else
312
die("option unknown: %s", next);
321
- return rest;
313
}
314
315
static const struct parse_cmd {
316
const char *prefix;
326
- const char *(*fn)(struct ref_transaction *, const char *, const char *);
317
+ void (*fn)(struct ref_transaction *, const char *, const char *);
318
+ unsigned args;
319
} 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 },
320
+ { "update", parse_cmd_update, 3 },
321
+ { "create", parse_cmd_create, 2 },
322
+ { "delete", parse_cmd_delete, 2 },
323
+ { "verify", parse_cmd_verify, 2 },
324
+ { "option", parse_cmd_option, 1 },
325
};
326
327
static void update_refs_stdin(void)
328
{
329
struct strbuf input = STRBUF_INIT, err = STRBUF_INIT;
330
struct ref_transaction *transaction;
339
- const char *next;
340
- int i;
341
-
342
- if (strbuf_read(&input, 0, 1000) < 0)
343
- die_errno("could not read from stdin");
344
- next = input.buf;
331
+ int i, j;
332
333
transaction = ref_transaction_begin(&err);
334
if (!transaction)
335
die("%s", err.buf);
336
337
/* Read each line dispatch its command */
351
- while (next < input.buf + input.len) {
338
+ while (!strbuf_getwholeline(&input, stdin, line_termination)) {
339
const struct parse_cmd *cmd = NULL;
340
354
- if (*next == line_termination)
341
+ if (*input.buf == line_termination)
342
die("empty command in input");
356
- else if (isspace(*next))
357
- die("whitespace before command: %s", next);
343
+ else if (isspace(*input.buf))
344
+ die("whitespace before command: %s", input.buf);
345
346
for (i = 0; i < ARRAY_SIZE(command); i++) {
347
const char *prefix = command[i].prefix;
348
+ char c;
349
+
350
+ if (!starts_with(input.buf, prefix))
351
+ continue;
352
362
- if (!skip_prefix(next, prefix, &next) ||
363
- !skip_prefix(next, " ", &next))
353
+ /*
354
+ * If the command has arguments, verify that it's
355
+ * followed by a space. Otherwise, it shall be followed
356
+ * by a line terminator.
357
+ */
358
+ c = command[i].args ? ' ' : line_termination;
359
+ if (input.buf[strlen(prefix)] != c)
360
continue;
361
362
cmd = &command[i];
363
break;
364
}
365
if (!cmd)
370
- die("unknown command: %s", next);
366
+ die("unknown command: %s", input.buf);
367
+
368
+ /*
369
+ * Read additional arguments if NUL-terminated. Do not raise an
370
+ * error in case there is an early EOF to let the command
371
+ * handle missing arguments with a proper error message.
372
+ */
373
+ for (j = 1; line_termination == '\0' && j < cmd->args; j++)
374
+ if (strbuf_appendwholeline(&input, stdin, line_termination))
375
+ break;
376
372
- next = cmd->fn(transaction, next, input.buf + input.len);
373
- next++;
377
+ cmd->fn(transaction, input.buf + strlen(cmd->prefix) + !!cmd->args,
378
+ input.buf + input.len);
379
}
380
381
if (ref_transaction_commit(transaction, &err))