aboutsummaryrefslogtreecommitdiff
path: root/src/git-parser.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-06-26 15:18:29 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-06-26 21:23:42 +0300
commit440771ca0056eb20396e24f03d349a75ee1c9d22 (patch)
tree3ec58a85e96d21a855ad3dcefaa8adc51039fc38 /src/git-parser.c
parent4c1959a4848c30206de3be4b16bdf04b650daae8 (diff)
downloadgrecs-440771ca0056eb20396e24f03d349a75ee1c9d22.tar.gz
grecs-440771ca0056eb20396e24f03d349a75ee1c9d22.tar.bz2
Keep track of columns in the node and value locations. Improve error diagnostics.
* src/grecs.h (grecs_locus_point): New struct. (grecs_locus_point_advance_line): New macro. (grecs_locus_t): Redesign. (grecs_value) <locus>: New member. (grecs_node) <idloc>: New member. (grecs_print_diag_fun): Change signature. (grecs_warning,grecs_error): Change signature. (grecs_parse_line_directive) (grecs_parse_line_directive_cpp) (grecs_string_convert): Change signature. (grecs_current_locus): Remove. (grecs_current_locus_point): New extern. * src/grecs-locus.h: New file. * src/Make.am (noinst_HEADERS): Add grecs-locus.h. * src/join.c (reset_locus): Rewrite. * src/lookup.c: Initialize new members of grecs_value and grecs_node. (split_cfg_path): Return wrdse error code. (grecs_node_from_path_locus): Take two grecs_locus_t arguments. Make sure all created nodes have their locus members properly initialized. * src/parser.c (grecs_parse): Initialize grecs_current_locus_point. * src/tree.c (grecs_node_create_points): New function. (string_to_bool,string_to_host,string_to_sockaddr) (grecs_string_convert): Change signatures. Be more precise in what locus to report. * src/diag.c (default_print_diag): Use YY_LOCATION_PRINT to output locus. (grecs_print_diag_fun): Change signature. (grecs_warning,grecs_error): Change signature. * src/format.c (grecs_format_locus): Rewrite. (grecs_format_node): Be more precise in what locus is being output. * src/bind-gram.y: Keep track of locations. Turn on error-verbose mode. * src/grecs-gram.y: Likewise. * src/meta1-gram.y: Likewise. * src/bind-lex.l: Keep track of locations. * src/git-parser.c: Likewise. * src/grecs-lex.l: Likewise. * src/meta1-lex.l: Likewise. * src/path-parser.c: Likewise. * src/preproc.c: Likewise. * tests/gcf1.conf: Untabify. * tests/format01.at: Reflect changes in the output. * tests/join.at: Likewise. * tests/set.at: Likewise. * tests/locus-bind.at: New testcase. * tests/locus-git.at: New testcase. * tests/locus-meta1.at: New testcase. * tests/locus00.at: New testcase. * tests/locus01.at: New testcase. * tests/locus02.at: New testcase. * tests/path-locus.at: New testcase.
Diffstat (limited to 'src/git-parser.c')
-rw-r--r--src/git-parser.c93
1 files changed, 68 insertions, 25 deletions
diff --git a/src/git-parser.c b/src/git-parser.c
index 4ab64be..e332704 100644
--- a/src/git-parser.c
+++ b/src/git-parser.c
@@ -40,6 +40,8 @@ struct token {
char chbuf[2];
int putback;
struct grecs_list *path;
+ grecs_locus_t loc;
+ unsigned prev_col;
} tok;
#define ISSPACE(c) (strchr(" \t\r\f\n", c) != NULL)
@@ -52,10 +54,13 @@ rawinput()
if (!infile || feof(infile))
return input_char = 0;
input_char = fgetc(infile);
- if (input_char == '\n')
- grecs_current_locus.line++;
- else if (input_char < 0)
+ if (input_char == '\n') {
+ tok.prev_col = grecs_current_locus_point.col;
+ grecs_locus_point_advance_line(grecs_current_locus_point);
+ } else if (input_char < 0)
input_char == 0;
+ else
+ grecs_current_locus_point.col++;
return input_char;
}
@@ -75,8 +80,12 @@ unput()
{
if (!input_char)
return;
- if (input_char == '\n')
- grecs_current_locus.line--;
+ if (input_char == '\n') {
+ grecs_current_locus_point.line--;
+ grecs_current_locus_point.col = tok.prev_col;
+ } else
+ grecs_current_locus_point.col--;
+
ungetc(input_char, infile);
}
@@ -113,7 +122,7 @@ collect_substring()
while (rawinput()) {
if (input_char == '\\') {
if (!input()) {
- grecs_error(&grecs_current_locus, 0,
+ grecs_error(&tok.loc, 0,
"unexpected EOF in string");
break;
}
@@ -133,21 +142,39 @@ collect_substring()
}
}
+#define endpoint(t,adj) do { \
+ (t).loc.end = grecs_current_locus_point; \
+ if (adj) { \
+ if (input_char == '\n') \
+ (t).loc.end.col = (t).prev_col; \
+ else \
+ (t).loc.end.col -= (adj); \
+ } \
+ } while (0)
+
static void
gettoken(void)
{
int putback = tok.putback;
tok.putback = 0;
- if (putback)
+ if (putback) {
+ if (putback == '\n')
+ grecs_locus_point_advance_line(grecs_current_locus_point);
+ else
+ grecs_current_locus_point.col++;
return;
-
+ }
+
tok.buf = NULL;
/* Skip whitespace */
while (input() && ISSPACE(input_char))
;
+ tok.loc.beg = grecs_current_locus_point;
+
if (input_char <= 0) {
tok.type = TOK_EOF;
+ endpoint(tok, 0);
return;
}
@@ -171,7 +198,8 @@ gettoken(void)
}
if (input_char == TOK_EOF) {
- grecs_error(&grecs_current_locus, 0,
+ endpoint(tok, 0);
+ grecs_error(&tok.loc, 0,
"unexpected EOF in section header");
tok.type = TOK_ERR;
return;
@@ -179,7 +207,8 @@ gettoken(void)
if (input_char == ']')
break;
if (input_char == '\n') {
- grecs_error(&grecs_current_locus, 0,
+ endpoint(tok, 1);
+ grecs_error(&tok.loc, 0,
"unexpect newline in in section header");
tok.type = TOK_ERR;
return;
@@ -197,7 +226,8 @@ gettoken(void)
dot_delimited = input_char == '.';
else if (dot_delimited == 1) {
if (input_char != '.' && input_char != ']') {
- grecs_error(&grecs_current_locus, 0,
+ endpoint(tok, 1);
+ grecs_error(&tok.loc, 0,
"unexpected character in section header");
tok.type = TOK_ERR;
return;
@@ -207,10 +237,10 @@ gettoken(void)
p = grecs_txtacc_finish(acc, 0);
grecs_list_append(tok.path, p);
}
-
+
+ endpoint(tok, 1);
if (grecs_list_size(tok.path) == 0) {
- grecs_error(&grecs_current_locus, 0,
- "empty section header");
+ grecs_error(&tok.loc, 0, "empty section header");
tok.type = TOK_ERR;
return;
}
@@ -227,6 +257,7 @@ gettoken(void)
unput();
grecs_txtacc_grow_char(acc, 0);
tok.buf = grecs_txtacc_finish(acc, 0);
+ endpoint(tok, 0);
return;
}
@@ -234,6 +265,7 @@ gettoken(void)
tok.chbuf[1] = 0;
tok.buf = tok.chbuf;
tok.type = input_char;
+ endpoint(tok, 0);
}
static void
@@ -270,10 +302,18 @@ getvalue()
{
int len;
struct grecs_value *val = grecs_malloc(sizeof(*val));
+
while (input() && ISSPACE(input_char) && input_char != '\n')
;
+
+ val->locus.beg = grecs_current_locus_point;
+
if (input_char != '\n')
collect_value();
+ val->locus.end = grecs_current_locus_point;
+ val->locus.end.line--;
+ val->locus.end.col = tok.prev_col;
+
grecs_txtacc_grow_char(acc, 0);
tok.type = TOK_VALUE;
tok.buf = grecs_txtacc_finish(acc, 1);
@@ -296,28 +336,30 @@ read_statement(struct grecs_node *parent)
return 0;
}
if (tok.type != TOK_KEYWORD) {
- grecs_error(&grecs_current_locus, 0, "syntax error");
+ grecs_error(&tok.loc, 0, "syntax error");
error_recovery();
return 1;
}
- node = grecs_node_create(grecs_node_stmt, &grecs_current_locus);
+ node = grecs_node_create(grecs_node_stmt, &tok.loc);
node->ident = grecs_strdup(tok.buf);
-
+ node->idloc = tok.loc;
+
gettoken();
if (tok.type == TOK_EOF) {
- grecs_error(&grecs_current_locus, 0, "unexpected EOF");
+ grecs_error(&tok.loc, 0, "unexpected EOF");
grecs_node_free(node);
return 0;
}
if (tok.type != TOK_EQ) {
- grecs_error(&grecs_current_locus, 0,
+ grecs_error(&tok.loc, 0,
"expected `=', but found `%s'", tok.buf);
error_recovery();
grecs_node_free(node);
return 1;
}
node->v.value = getvalue();
+ node->locus.end = node->v.value->locus.end;
grecs_node_bind(parent, node, 1);
return 1;
}
@@ -339,8 +381,7 @@ create_subsection_node(struct grecs_node *root)
char *ident = ep->data;
p = grecs_find_node(root, ident);
if (!p) {
- p = grecs_node_create(grecs_node_block,
- &grecs_current_locus);
+ p = grecs_node_create(grecs_node_block, &tok.loc);
p->ident = grecs_strdup(ident);
grecs_node_bind(root, p, 1);
}
@@ -361,7 +402,7 @@ read_section(struct grecs_node *parent)
} else if (tok.type == TOK_KEYWORD) {
read_statement(parent);
} else {
- grecs_error(&grecs_current_locus, 0, "syntax error");
+ grecs_error(&tok.loc, 0, "syntax error");
error_recovery();
}
return 1;
@@ -378,15 +419,17 @@ grecs_git_parser(const char *name, int traceflags)
grecs_error(NULL, errno, _("cannot open `%s'"), name);
return NULL;
}
- grecs_current_locus.file = grecs_install_text(name);
- grecs_current_locus.line = 1;
+ grecs_current_locus_point.file = grecs_install_text(name);
+ grecs_current_locus_point.line = 1;
+ grecs_current_locus_point.col = 0;
acc = grecs_txtacc_create();
tok.path = grecs_list_create();
- root = grecs_node_create(grecs_node_root, &grecs_current_locus);
+ root = grecs_node_create(grecs_node_root, &tok.loc);
while (read_section(root))
;
+ root->locus.end = grecs_current_locus_point;
fclose(infile);
grecs_txtacc_free(acc);
grecs_list_free(tok.path);

Return to:

Send suggestions and report system problems to the System administrator.