Skip to content

Commit 1d7c15a

Browse files
authored
Merge pull request libgit2#4310 from pks-t/pks/common-parser
Common parser interface
2 parents 46e1dab + 9e66590 commit 1d7c15a

File tree

8 files changed

+945
-943
lines changed

8 files changed

+945
-943
lines changed

src/config_file.c

Lines changed: 42 additions & 703 deletions
Large diffs are not rendered by default.

src/config_parse.c

Lines changed: 519 additions & 0 deletions
Large diffs are not rendered by default.

src/config_parse.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
8+
#include "common.h"
9+
#include "array.h"
10+
#include "oid.h"
11+
#include "parse.h"
12+
13+
static const char *git_config_escapes = "ntb\"\\";
14+
static const char *git_config_escaped = "\n\t\b\"\\";
15+
16+
typedef struct config_file {
17+
git_oid checksum;
18+
char *path;
19+
git_array_t(struct config_file) includes;
20+
} git_config_file;
21+
22+
typedef struct {
23+
struct config_file *file;
24+
git_parse_ctx ctx;
25+
} git_config_parser;
26+
27+
typedef int (*git_config_parser_section_cb)(
28+
git_config_parser *parser,
29+
const char *current_section,
30+
const char *line,
31+
size_t line_len,
32+
void *data);
33+
34+
typedef int (*git_config_parser_variable_cb)(
35+
git_config_parser *parser,
36+
const char *current_section,
37+
char *var_name,
38+
char *var_value,
39+
const char *line,
40+
size_t line_len,
41+
void *data);
42+
43+
typedef int (*git_config_parser_comment_cb)(
44+
git_config_parser *parser,
45+
const char *line,
46+
size_t line_len,
47+
void *data);
48+
49+
typedef int (*git_config_parser_eof_cb)(
50+
git_config_parser *parser,
51+
const char *current_section,
52+
void *data);
53+
54+
int git_config_parse(
55+
git_config_parser *parser,
56+
git_config_parser_section_cb on_section,
57+
git_config_parser_variable_cb on_variable,
58+
git_config_parser_comment_cb on_comment,
59+
git_config_parser_eof_cb on_eof,
60+
void *data);

src/diff_parse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ int git_diff_from_buffer(
8383
ctx = git_patch_parse_ctx_init(content, content_len, NULL);
8484
GITERR_CHECK_ALLOC(ctx);
8585

86-
while (ctx->remain_len) {
86+
while (ctx->parse_ctx.remain_len) {
8787
if ((error = git_patch_parse(&patch, ctx)) < 0)
8888
break;
8989

src/parse.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
#include "parse.h"
8+
9+
int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len)
10+
{
11+
if (content_len)
12+
ctx->content = content;
13+
else
14+
ctx->content = NULL;
15+
16+
ctx->content_len = content_len;
17+
ctx->remain = ctx->content;
18+
ctx->remain_len = ctx->content_len;
19+
ctx->line = ctx->remain;
20+
ctx->line_len = git__linenlen(ctx->line, ctx->remain_len);
21+
ctx->line_num = 1;
22+
23+
return 0;
24+
}
25+
26+
void git_parse_ctx_clear(git_parse_ctx *ctx)
27+
{
28+
memset(ctx, 0, sizeof(*ctx));
29+
}
30+
31+
void git_parse_advance_line(git_parse_ctx *ctx)
32+
{
33+
ctx->line += ctx->line_len;
34+
ctx->remain_len -= ctx->line_len;
35+
ctx->line_len = git__linenlen(ctx->line, ctx->remain_len);
36+
ctx->line_num++;
37+
}
38+
39+
void git_parse_advance_chars(git_parse_ctx *ctx, size_t char_cnt)
40+
{
41+
ctx->line += char_cnt;
42+
ctx->remain_len -= char_cnt;
43+
ctx->line_len -= char_cnt;
44+
}
45+
46+
int git_parse_advance_expected(
47+
git_parse_ctx *ctx,
48+
const char *expected,
49+
size_t expected_len)
50+
{
51+
if (ctx->line_len < expected_len)
52+
return -1;
53+
54+
if (memcmp(ctx->line, expected, expected_len) != 0)
55+
return -1;
56+
57+
git_parse_advance_chars(ctx, expected_len);
58+
return 0;
59+
}
60+
61+
int git_parse_advance_ws(git_parse_ctx *ctx)
62+
{
63+
int ret = -1;
64+
65+
while (ctx->line_len > 0 &&
66+
ctx->line[0] != '\n' &&
67+
git__isspace(ctx->line[0])) {
68+
ctx->line++;
69+
ctx->line_len--;
70+
ctx->remain_len--;
71+
ret = 0;
72+
}
73+
74+
return ret;
75+
}
76+
77+
int git_parse_advance_nl(git_parse_ctx *ctx)
78+
{
79+
if (ctx->line_len != 1 || ctx->line[0] != '\n')
80+
return -1;
81+
82+
git_parse_advance_line(ctx);
83+
return 0;
84+
}
85+
86+
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
87+
{
88+
const char *end;
89+
int ret;
90+
91+
if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]))
92+
return -1;
93+
94+
if ((ret = git__strntol64(out, ctx->line, ctx->line_len, &end, base)) < 0)
95+
return -1;
96+
97+
git_parse_advance_chars(ctx, (end - ctx->line));
98+
return 0;
99+
}
100+
101+
int git_parse_peek(char *out, git_parse_ctx *ctx, int flags)
102+
{
103+
size_t remain = ctx->line_len;
104+
const char *ptr = ctx->line;
105+
106+
while (remain) {
107+
char c = *ptr;
108+
109+
if ((flags & GIT_PARSE_PEEK_SKIP_WHITESPACE) &&
110+
git__isspace(c)) {
111+
remain--;
112+
ptr++;
113+
continue;
114+
}
115+
116+
*out = c;
117+
return 0;
118+
}
119+
120+
return -1;
121+
}

src/parse.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
#include "common.h"
8+
9+
typedef struct {
10+
/* Original content buffer */
11+
const char *content;
12+
size_t content_len;
13+
14+
/* The remaining (unparsed) buffer */
15+
const char *remain;
16+
size_t remain_len;
17+
18+
const char *line;
19+
size_t line_len;
20+
size_t line_num;
21+
} git_parse_ctx;
22+
23+
int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len);
24+
void git_parse_ctx_clear(git_parse_ctx *ctx);
25+
26+
#define git_parse_err(...) \
27+
( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )
28+
29+
#define git_parse_ctx_contains_s(ctx, str) \
30+
git_parse_ctx_contains(ctx, str, sizeof(str) - 1)
31+
32+
GIT_INLINE(bool) git_parse_ctx_contains(
33+
git_parse_ctx *ctx, const char *str, size_t len)
34+
{
35+
return (ctx->line_len >= len && memcmp(ctx->line, str, len) == 0);
36+
}
37+
38+
void git_parse_advance_line(git_parse_ctx *ctx);
39+
void git_parse_advance_chars(git_parse_ctx *ctx, size_t char_cnt);
40+
int git_parse_advance_expected(
41+
git_parse_ctx *ctx,
42+
const char *expected,
43+
size_t expected_len);
44+
45+
#define git_parse_advance_expected_str(ctx, str) \
46+
git_parse_advance_expected(ctx, str, strlen(str))
47+
48+
int git_parse_advance_ws(git_parse_ctx *ctx);
49+
int git_parse_advance_nl(git_parse_ctx *ctx);
50+
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);
51+
52+
enum GIT_PARSE_PEEK_FLAGS {
53+
GIT_PARSE_PEEK_SKIP_WHITESPACE = (1 << 0)
54+
};
55+
56+
int git_parse_peek(char *out, git_parse_ctx *ctx, int flags);

0 commit comments

Comments
 (0)