Skip to content

Commit 252f2ee

Browse files
committed
parse: implement and use git_parse_advance_digit
The patch parsing code has multiple recurring patterns where we want to parse an actual number. Create a new function `git_parse_advance_digit` and use it to avoid code duplication.
1 parent 65dcb64 commit 252f2ee

3 files changed

Lines changed: 25 additions & 19 deletions

File tree

src/parse.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,18 @@ int git_parse_advance_nl(git_parse_ctx *ctx)
7979
git_parse_advance_line(ctx);
8080
return 0;
8181
}
82+
83+
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
84+
{
85+
const char *end;
86+
int ret;
87+
88+
if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]))
89+
return -1;
90+
91+
if ((ret = git__strntol64(out, ctx->line, ctx->line_len, &end, base)) < 0)
92+
return -1;
93+
94+
git_parse_advance_chars(ctx, (end - ctx->line));
95+
return 0;
96+
}

src/parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ int git_parse_advance_expected(
4747

4848
int git_parse_advance_ws(git_parse_ctx *ctx);
4949
int git_parse_advance_nl(git_parse_ctx *ctx);
50+
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);

src/patch_parse.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -102,24 +102,17 @@ static int parse_header_git_newpath(
102102

103103
static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx)
104104
{
105-
const char *end;
106-
int32_t m;
107-
int ret;
105+
int64_t m;
108106

109-
if (ctx->parse_ctx.line_len < 1 || !git__isdigit(ctx->parse_ctx.line[0]))
107+
if ((git_parse_advance_digit(&m, &ctx->parse_ctx, 8)) < 0)
110108
return git_parse_err("invalid file mode at line %"PRIuZ, ctx->parse_ctx.line_num);
111109

112-
if ((ret = git__strntol32(&m, ctx->parse_ctx.line, ctx->parse_ctx.line_len, &end, 8)) < 0)
113-
return ret;
114-
115110
if (m > UINT16_MAX)
116111
return -1;
117112

118113
*mode = (uint16_t)m;
119114

120-
git_parse_advance_chars(&ctx->parse_ctx, (end - ctx->parse_ctx.line));
121-
122-
return ret;
115+
return 0;
123116
}
124117

125118
static int parse_header_oid(
@@ -258,19 +251,15 @@ static int parse_header_copyto(
258251

259252
static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx)
260253
{
261-
int32_t val;
262-
const char *end;
254+
int64_t val;
263255

264-
if (ctx->parse_ctx.line_len < 1 || !git__isdigit(ctx->parse_ctx.line[0]) ||
265-
git__strntol32(&val, ctx->parse_ctx.line, ctx->parse_ctx.line_len, &end, 10) < 0)
256+
if (git_parse_advance_digit(&val, &ctx->parse_ctx, 10) < 0)
266257
return -1;
267258

268-
git_parse_advance_chars(&ctx->parse_ctx, (end - ctx->parse_ctx.line));
269-
270259
if (git_parse_advance_expected_str(&ctx->parse_ctx, "%") < 0)
271260
return -1;
272261

273-
if (val > 100)
262+
if (val < 0 || val > 100)
274263
return -1;
275264

276265
*out = val;
@@ -457,7 +446,7 @@ static int parse_int(int *out, git_patch_parse_ctx *ctx)
457446
{
458447
git_off_t num;
459448

460-
if (parse_number(&num, ctx) < 0 || !git__is_int(num))
449+
if (git_parse_advance_digit(&num, &ctx->parse_ctx, 10) < 0 || !git__is_int(num))
461450
return -1;
462451

463452
*out = (int)num;
@@ -687,7 +676,8 @@ static int parse_patch_binary_side(
687676
goto done;
688677
}
689678

690-
if (parse_number(&len, ctx) < 0 || git_parse_advance_nl(&ctx->parse_ctx) < 0 || len < 0) {
679+
if (git_parse_advance_digit(&len, &ctx->parse_ctx, 10) < 0 ||
680+
git_parse_advance_nl(&ctx->parse_ctx) < 0 || len < 0) {
691681
error = git_parse_err("invalid binary size at line %"PRIuZ, ctx->parse_ctx.line_num);
692682
goto done;
693683
}

0 commit comments

Comments
 (0)