diff options
| author | Patrick Steinhardt <ps@pks.im> | 2017-11-11 15:30:43 +0000 |
|---|---|---|
| committer | Patrick Steinhardt <ps@pks.im> | 2017-11-11 17:06:20 +0000 |
| commit | ef1395f315ba137be64744a3a6b9d784db44fded (patch) | |
| tree | a4cb6e7f04fbfeeeddec26f5ace6e368bad3e455 /src/parse.c | |
| parent | 0393ecc6f8bb19e4ba55fd45e7bbde6596f9b334 (diff) | |
| download | libgit2-ef1395f315ba137be64744a3a6b9d784db44fded.tar.gz | |
parse: extract parse module
The `git_patch_parse_ctx` encapsulates both parser state as well as
options specific to patch parsing. To advance this state and keep it
consistent, we provide a few functions which handle advancing the
current position and accessing bytes of the patch contents. In fact,
these functions are quite generic and not related to patch-parsing by
themselves. Seeing that we have similar logic inside of other modules,
it becomes quite enticing to extract this functionality into its own
parser module.
To do so, we create a new module `parse` with a central struct called
`git_parse_ctx`. It encapsulates both the content that is to be parsed
as well as its lengths and the current position. `git_patch_parse_ctx`
now only contains this `parse_ctx` only, which is then accessed whenever
we need to touch the current parser. This is the first step towards
re-using this functionality across other modules which require parsing
functionality and remove code-duplication.
Diffstat (limited to 'src/parse.c')
| -rw-r--r-- | src/parse.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 000000000..f7365ef8d --- /dev/null +++ b/src/parse.c @@ -0,0 +1,81 @@ +/* + * 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_len) + ctx->content = content; + else + ctx->content = NULL; + + ctx->content_len = content_len; + ctx->remain = ctx->content; + ctx->remain_len = ctx->content_len; + + return 0; +} + +void git_parse_ctx_clear(git_parse_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +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; +} |
