diff options
Diffstat (limited to 'src/libgit2/parse.c')
-rw-r--r-- | src/libgit2/parse.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/libgit2/parse.c b/src/libgit2/parse.c new file mode 100644 index 000000000..0a10758bf --- /dev/null +++ b/src/libgit2/parse.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#include "parse.h" + +int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len) +{ + if (content && content_len) { + ctx->content = content; + ctx->content_len = content_len; + } else { + ctx->content = ""; + ctx->content_len = 0; + } + + ctx->remain = ctx->content; + ctx->remain_len = ctx->content_len; + ctx->line = ctx->remain; + ctx->line_len = git__linenlen(ctx->line, ctx->remain_len); + ctx->line_num = 1; + + return 0; +} + +void git_parse_ctx_clear(git_parse_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->content = ""; +} + +void git_parse_advance_line(git_parse_ctx *ctx) +{ + ctx->line += ctx->line_len; + ctx->remain_len -= ctx->line_len; + ctx->line_len = git__linenlen(ctx->line, ctx->remain_len); + ctx->line_num++; +} + +void git_parse_advance_chars(git_parse_ctx *ctx, size_t char_cnt) +{ + ctx->line += char_cnt; + ctx->remain_len -= char_cnt; + ctx->line_len -= char_cnt; +} + +int git_parse_advance_expected( + git_parse_ctx *ctx, + const char *expected, + size_t expected_len) +{ + if (ctx->line_len < expected_len) + return -1; + + if (memcmp(ctx->line, expected, expected_len) != 0) + return -1; + + git_parse_advance_chars(ctx, expected_len); + return 0; +} + +int git_parse_advance_ws(git_parse_ctx *ctx) +{ + int ret = -1; + + while (ctx->line_len > 0 && + ctx->line[0] != '\n' && + git__isspace(ctx->line[0])) { + ctx->line++; + ctx->line_len--; + ctx->remain_len--; + ret = 0; + } + + return ret; +} + +int git_parse_advance_nl(git_parse_ctx *ctx) +{ + if (ctx->line_len != 1 || ctx->line[0] != '\n') + return -1; + + git_parse_advance_line(ctx); + return 0; +} + +int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base) +{ + const char *end; + int ret; + + if (ctx->line_len < 1 || !git__isdigit(ctx->line[0])) + return -1; + + if ((ret = git__strntol64(out, ctx->line, ctx->line_len, &end, base)) < 0) + return -1; + + git_parse_advance_chars(ctx, (end - ctx->line)); + 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) +{ + size_t remain = ctx->line_len; + const char *ptr = ctx->line; + + while (remain) { + char c = *ptr; + + if ((flags & GIT_PARSE_PEEK_SKIP_WHITESPACE) && + git__isspace(c)) { + remain--; + ptr++; + continue; + } + + *out = c; + return 0; + } + + return -1; +} |