diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-23 11:04:36 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-23 11:04:36 +0300 |
commit | 63da417be1dfe1366a4a8984770c06cbbadcda39 (patch) | |
tree | 69f23ed47f67790eb43491cfb314f54483721067 /src | |
parent | 24f55db22433621dc80a068583b4bf8886ae2603 (diff) | |
download | grecs-63da417be1dfe1366a4a8984770c06cbbadcda39.tar.gz grecs-63da417be1dfe1366a4a8984770c06cbbadcda39.tar.bz2 |
git: fix parser
Accept ; as a comment starter. Accept partially or fully quoted values.
Support the backslash escapes allowed by Git.
* src/git-parser.c (input): semicolon starts a comment, too.
(collect_substring): New function.
(collect_string): Rewrite via collect_substring.
(collect_value): New function.
(getvalue): Use collect_value.
Diffstat (limited to 'src')
-rw-r--r-- | src/git-parser.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/src/git-parser.c b/src/git-parser.c index 117a8fc..37eeab7 100644 --- a/src/git-parser.c +++ b/src/git-parser.c @@ -58,13 +58,13 @@ rawinput() } static int input() { rawinput(); - if (input_char == '#') { + if (input_char == '#' || input_char == ';') { while (rawinput() && input_char != '\n') ; } return input_char; } @@ -93,25 +93,41 @@ collect_tag() grecs_txtacc_grow_char(acc, input_char); grecs_txtacc_grow_char(acc, 0); tok.tag = grecs_txtacc_finish(acc, 0); } static void -collect_string() +collect_substring() { while (rawinput()) { if (input_char == '\\') { if (!input()) { grecs_error(&grecs_current_locus, 0, "unexpected EOF in string"); break; } + switch (input_char) { + case 'n': + input_char = '\n'; + break; + case 't': + input_char = '\t'; + break; + case 'b': + input_char = '\b'; + } } else if (input_char == '"') break; grecs_txtacc_grow_char(acc, input_char); } +} + +static void +collect_string() +{ + collect_substring(); grecs_txtacc_grow_char(acc, 0); tok.tag = grecs_txtacc_finish(acc, 0); } static void gettoken(void) @@ -181,23 +197,50 @@ gettoken(void) tok.chbuf[0] = input_char; tok.chbuf[1] = 0; tok.buf = tok.chbuf; tok.type = input_char; } +static void +collect_value() +{ + do { + if (input_char == '"') { + collect_substring(); + if (input_char == '"') + continue; + else + break; + } + if (input_char == '\\') { + if (!rawinput()) + break; + switch (input_char) { + case 'n': + input_char = '\n'; + break; + case 't': + input_char = '\t'; + break; + case 'b': + input_char = '\b'; + } + } + grecs_txtacc_grow_char(acc, input_char); + } while (input() && input_char != '\n'); +} + static struct grecs_value * getvalue() { int len; struct grecs_value *val = grecs_malloc(sizeof(*val)); while (input() && ISSPACE(input_char) && input_char != '\n') ; if (input_char != '\n') - do - grecs_txtacc_grow_char(acc, input_char); - while (input() && input_char != '\n'); + collect_value(); grecs_txtacc_grow_char(acc, 0); tok.type = TOK_VALUE; tok.buf = grecs_txtacc_finish(acc, 1); len = strlen(tok.buf); while (len > 0 && ISSPACE(tok.buf[len-1])) tok.buf[--len] = 0; |