Commit 8532ed11 by Patrick Steinhardt

refdb_fs: convert reflog parsing to use parser

The refdb_fs code to parse the reflog currently uses a hand-rolled
parser. Convert it to use our `git_parse_ctx` structure instead.
parent d8233feb
...@@ -101,6 +101,16 @@ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base) ...@@ -101,6 +101,16 @@ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
return 0; return 0;
} }
int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx)
{
if (ctx->line_len < GIT_OID_HEXSZ)
return -1;
if ((git_oid_fromstrn(out, ctx->line, GIT_OID_HEXSZ)) < 0)
return -1;
git_parse_advance_chars(ctx, GIT_OID_HEXSZ);
return 0;
}
int git_parse_peek(char *out, git_parse_ctx *ctx, int flags) int git_parse_peek(char *out, git_parse_ctx *ctx, int flags)
{ {
size_t remain = ctx->line_len; size_t remain = ctx->line_len;
......
...@@ -50,6 +50,7 @@ int git_parse_advance_expected( ...@@ -50,6 +50,7 @@ int git_parse_advance_expected(
int git_parse_advance_ws(git_parse_ctx *ctx); int git_parse_advance_ws(git_parse_ctx *ctx);
int git_parse_advance_nl(git_parse_ctx *ctx); int git_parse_advance_nl(git_parse_ctx *ctx);
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base); int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);
int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx);
enum GIT_PARSE_PEEK_FLAGS { enum GIT_PARSE_PEEK_FLAGS {
GIT_PARSE_PEEK_SKIP_WHITESPACE = (1 << 0) GIT_PARSE_PEEK_SKIP_WHITESPACE = (1 << 0)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "futils.h" #include "futils.h"
#include "filebuf.h" #include "filebuf.h"
#include "pack.h" #include "pack.h"
#include "parse.h"
#include "reflog.h" #include "reflog.h"
#include "refdb.h" #include "refdb.h"
#include "iterator.h" #include "iterator.h"
...@@ -1651,67 +1652,53 @@ static int reflog_alloc(git_reflog **reflog, const char *name) ...@@ -1651,67 +1652,53 @@ static int reflog_alloc(git_reflog **reflog, const char *name)
static int reflog_parse(git_reflog *log, const char *buf, size_t buf_size) static int reflog_parse(git_reflog *log, const char *buf, size_t buf_size)
{ {
const char *ptr; git_parse_ctx parser = GIT_PARSE_CTX_INIT;
git_reflog_entry *entry; git_reflog_entry *entry = NULL;
#define seek_forward(_increase) do { \ if ((git_parse_ctx_init(&parser, buf, buf_size)) < 0)
if (_increase >= buf_size) { \ return -1;
git_error_set(GIT_ERROR_INVALID, "ran out of data while parsing reflog"); \
goto fail; \
} \
buf += _increase; \
buf_size -= _increase; \
} while (0)
while (buf_size > GIT_REFLOG_SIZE_MIN) {
entry = git__calloc(1, sizeof(git_reflog_entry));
GIT_ERROR_CHECK_ALLOC(entry);
entry->committer = git__calloc(1, sizeof(git_signature)); for (; parser.remain_len; git_parse_advance_line(&parser)) {
GIT_ERROR_CHECK_ALLOC(entry->committer); const char *sig;
char c;
if (git_oid_fromstrn(&entry->oid_old, buf, GIT_OID_HEXSZ) < 0) entry = git__calloc(1, sizeof(*entry));
goto fail; GIT_ERROR_CHECK_ALLOC(entry);
seek_forward(GIT_OID_HEXSZ + 1);
if (git_oid_fromstrn(&entry->oid_cur, buf, GIT_OID_HEXSZ) < 0) entry->committer = git__calloc(1, sizeof(*entry->committer));
goto fail; GIT_ERROR_CHECK_ALLOC(entry->committer);
seek_forward(GIT_OID_HEXSZ + 1);
ptr = buf; if (git_parse_advance_oid(&entry->oid_old, &parser) < 0 ||
git_parse_advance_expected(&parser, " ", 1) < 0 ||
git_parse_advance_oid(&entry->oid_cur, &parser) < 0)
goto error;
/* Seek forward to the end of the signature. */ sig = parser.line;
while (*buf && *buf != '\t' && *buf != '\n') while (git_parse_peek(&c, &parser, 0) == 0 && c != '\t' && c != '\n')
seek_forward(1); git_parse_advance_chars(&parser, 1);
if (git_signature__parse(entry->committer, &ptr, buf + 1, NULL, *buf) < 0) if (git_signature__parse(entry->committer, &sig, parser.line, NULL, 0) < 0)
goto fail; goto error;
if (*buf == '\t') { if (c == '\t') {
/* We got a message. Read everything till we reach LF. */ size_t len;
seek_forward(1); git_parse_advance_chars(&parser, 1);
ptr = buf;
while (*buf && *buf != '\n') len = parser.line_len;
seek_forward(1); if (parser.line[len - 1] == '\n')
len--;
entry->msg = git__strndup(ptr, buf - ptr); entry->msg = git__strndup(parser.line, len);
GIT_ERROR_CHECK_ALLOC(entry->msg); GIT_ERROR_CHECK_ALLOC(entry->msg);
} else }
entry->msg = NULL;
while (*buf && *buf == '\n' && buf_size > 1)
seek_forward(1);
if (git_vector_insert(&log->entries, entry) < 0) if (git_vector_insert(&log->entries, entry) < 0)
goto fail; goto error;
} }
return 0; return 0;
#undef seek_forward error:
fail:
git_reflog_entry__free(entry); git_reflog_entry__free(entry);
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment