2207
return do_change_note_fanout(root, root, hex_sha1, 0, path, 0, fanout);
2208
}
2209
2210
+/*
2211
+ * Given a pointer into a string, parse a mark reference:
2212
+ *
2213
+ * idnum ::= ':' bigint;
2214
+ *
2215
+ * Return the first character after the value in *endptr.
2216
+ *
2217
+ * Complain if the following character is not what is expected,
2218
+ * either a space or end of the string.
2219
+ */
2220
+static uintmax_t parse_mark_ref(const char *p, char **endptr)
2221
+{
2222
+ uintmax_t mark;
2223
+
2224
+ assert(*p == ':');
2225
+ p++;
2226
+ mark = strtoumax(p, endptr, 10);
2227
+ if (*endptr == p)
2228
+ die("No value after ':' in mark: %s", command_buf.buf);
2229
+ return mark;
2230
+}
2231
+
2232
+/*
2233
+ * Parse the mark reference, and complain if this is not the end of
2234
+ * the string.
2235
+ */
2236
+static uintmax_t parse_mark_ref_eol(const char *p)
2237
+{
2238
+ char *end;
2239
+ uintmax_t mark;
2240
+
2241
+ mark = parse_mark_ref(p, &end);
2242
+ if (*end != '\0')
2243
+ die("Garbage after mark: %s", command_buf.buf);
2244
+ return mark;
2245
+}
2246
+
2247
+/*
2248
+ * Parse the mark reference, demanding a trailing space. Return a
2249
+ * pointer to the space.
2250
+ */
2251
+static uintmax_t parse_mark_ref_space(const char **p)
2252
+{
2253
+ uintmax_t mark;
2254
+ char *end;
2255
+
2256
+ mark = parse_mark_ref(*p, &end);
2257
+ if (*end != ' ')
2258
+ die("Missing space after mark: %s", command_buf.buf);
2259
+ *p = end;
2260
+ return mark;
2261
+}
2262
+
2263
static void file_change_m(struct branch *b)
2264
{
2265
const char *p = command_buf.buf + 2;
2288
}
2289
2290
if (*p == ':') {
2238
- char *x;
2239
- oe = find_mark(strtoumax(p + 1, &x, 10));
2291
+ oe = find_mark(parse_mark_ref_space(&p));
2292
hashcpy(sha1, oe->idx.sha1);
2241
- p = x;
2242
- } else if (!prefixcmp(p, "inline")) {
2293
+ } else if (!prefixcmp(p, "inline ")) {
2294
inline_data = 1;
2244
- p += 6;
2295
+ p += strlen("inline"); /* advance to space */
2296
} else {
2297
if (get_sha1_hex(p, sha1))
2247
- die("Invalid SHA1: %s", command_buf.buf);
2298
+ die("Invalid dataref: %s", command_buf.buf);
2299
oe = find_object(sha1);
2300
p += 40;
2301
+ if (*p != ' ')
2302
+ die("Missing space after SHA1: %s", command_buf.buf);
2303
}
2251
- if (*p++ != ' ')
2252
- die("Missing space after SHA1: %s", command_buf.buf);
2304
+ assert(*p == ' ');
2305
+ p++; /* skip space */
2306
2307
strbuf_reset(&uq);
2308
if (!unquote_c_style(&uq, p, &endp)) {
2460
/* Now parse the notemodify command. */
2461
/* <dataref> or 'inline' */
2462
if (*p == ':') {
2410
- char *x;
2411
- oe = find_mark(strtoumax(p + 1, &x, 10));
2463
+ oe = find_mark(parse_mark_ref_space(&p));
2464
hashcpy(sha1, oe->idx.sha1);
2413
- p = x;
2414
- } else if (!prefixcmp(p, "inline")) {
2465
+ } else if (!prefixcmp(p, "inline ")) {
2466
inline_data = 1;
2416
- p += 6;
2467
+ p += strlen("inline"); /* advance to space */
2468
} else {
2469
if (get_sha1_hex(p, sha1))
2419
- die("Invalid SHA1: %s", command_buf.buf);
2470
+ die("Invalid dataref: %s", command_buf.buf);
2471
oe = find_object(sha1);
2472
p += 40;
2473
+ if (*p != ' ')
2474
+ die("Missing space after SHA1: %s", command_buf.buf);
2475
}
2423
- if (*p++ != ' ')
2424
- die("Missing space after SHA1: %s", command_buf.buf);
2476
+ assert(*p == ' ');
2477
+ p++; /* skip space */
2478
2479
/* <committish> */
2480
s = lookup_branch(p);
2483
die("Can't add a note on empty branch.");
2484
hashcpy(commit_sha1, s->sha1);
2485
} else if (*p == ':') {
2433
- uintmax_t commit_mark = strtoumax(p + 1, NULL, 10);
2486
+ uintmax_t commit_mark = parse_mark_ref_eol(p);
2487
struct object_entry *commit_oe = find_mark(commit_mark);
2488
if (commit_oe->type != OBJ_COMMIT)
2489
die("Mark :%" PRIuMAX " not a commit", commit_mark);
2590
hashcpy(b->branch_tree.versions[0].sha1, t);
2591
hashcpy(b->branch_tree.versions[1].sha1, t);
2592
} else if (*from == ':') {
2540
- uintmax_t idnum = strtoumax(from + 1, NULL, 10);
2593
+ uintmax_t idnum = parse_mark_ref_eol(from);
2594
struct object_entry *oe = find_mark(idnum);
2595
if (oe->type != OBJ_COMMIT)
2596
die("Mark :%" PRIuMAX " not a commit", idnum);
2625
if (s)
2626
hashcpy(n->sha1, s->sha1);
2627
else if (*from == ':') {
2575
- uintmax_t idnum = strtoumax(from + 1, NULL, 10);
2628
+ uintmax_t idnum = parse_mark_ref_eol(from);
2629
struct object_entry *oe = find_mark(idnum);
2630
if (oe->type != OBJ_COMMIT)
2631
die("Mark :%" PRIuMAX " not a commit", idnum);
2788
type = OBJ_COMMIT;
2789
} else if (*from == ':') {
2790
struct object_entry *oe;
2738
- from_mark = strtoumax(from + 1, NULL, 10);
2791
+ from_mark = parse_mark_ref_eol(from);
2792
oe = find_mark(from_mark);
2793
type = oe->type;
2794
hashcpy(sha1, oe->idx.sha1);
2920
/* cat-blob SP <object> LF */
2921
p = command_buf.buf + strlen("cat-blob ");
2922
if (*p == ':') {
2870
- char *x;
2871
- oe = find_mark(strtoumax(p + 1, &x, 10));
2872
- if (x == p + 1)
2873
- die("Invalid mark: %s", command_buf.buf);
2923
+ oe = find_mark(parse_mark_ref_eol(p));
2924
if (!oe)
2925
die("Unknown mark: %s", command_buf.buf);
2876
- if (*x)
2877
- die("Garbage after mark: %s", command_buf.buf);
2926
hashcpy(sha1, oe->idx.sha1);
2927
} else {
2928
if (get_sha1_hex(p, sha1))
2881
- die("Invalid SHA1: %s", command_buf.buf);
2929
+ die("Invalid dataref: %s", command_buf.buf);
2930
if (p[40])
2931
die("Garbage after SHA1: %s", command_buf.buf);
2932
oe = find_object(sha1);
2992
struct object_entry *e;
2993
2994
if (**p == ':') { /* <mark> */
2947
- char *endptr;
2948
- e = find_mark(strtoumax(*p + 1, &endptr, 10));
2949
- if (endptr == *p + 1)
2950
- die("Invalid mark: %s", command_buf.buf);
2995
+ e = find_mark(parse_mark_ref_space(p));
2996
if (!e)
2997
die("Unknown mark: %s", command_buf.buf);
2953
- *p = endptr;
2998
hashcpy(sha1, e->idx.sha1);
2999
} else { /* <sha1> */
3000
if (get_sha1_hex(*p, sha1))
2957
- die("Invalid SHA1: %s", command_buf.buf);
3001
+ die("Invalid dataref: %s", command_buf.buf);
3002
e = find_object(sha1);
3003
*p += 40;
3004
}