summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org.ua>2011-06-26 12:18:29 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-06-26 18:23:42 (GMT)
commit440771ca0056eb20396e24f03d349a75ee1c9d22 (patch) (side-by-side diff)
tree3ec58a85e96d21a855ad3dcefaa8adc51039fc38 /src
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') (more/less context) (ignore whitespace changes)
-rw-r--r--src/Make.am2
-rw-r--r--src/bind-gram.y68
-rw-r--r--src/bind-lex.l58
-rw-r--r--src/diag.c18
-rw-r--r--src/format.c59
-rw-r--r--src/git-parser.c93
-rw-r--r--src/grecs-gram.y43
-rw-r--r--src/grecs-lex.l102
-rw-r--r--src/grecs-locus.h56
-rw-r--r--src/grecs.h45
-rw-r--r--src/join.c27
-rw-r--r--src/lookup.c54
-rw-r--r--src/meta1-gram.y37
-rw-r--r--src/meta1-lex.l27
-rw-r--r--src/parser.c5
-rw-r--r--src/path-parser.c172
-rw-r--r--src/preproc.c22
-rw-r--r--src/tree.c45
18 files changed, 629 insertions, 304 deletions
diff --git a/src/Make.am b/src/Make.am
index bc70edc..286bf4c 100644
--- a/src/Make.am
+++ b/src/Make.am
@@ -59,7 +59,7 @@ GRECS_SRC = \
$(GRECS_PARSER_GIT)\
$(GRECS_PARSER_META1)
-noinst_HEADERS =
+noinst_HEADERS = grecs-locus.h
EXTRA_DIST=\
grecs-gram.h\
diff --git a/src/bind-gram.y b/src/bind-gram.y
index c751ae1..e353a54 100644
--- a/src/bind-gram.y
+++ b/src/bind-gram.y
@@ -19,7 +19,8 @@
# include <config.h>
#endif
#include <grecs.h>
-#include <grecs-gram.h>
+#include <grecs-locus.h>
+#include <bind-gram.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
@@ -30,17 +31,16 @@ int yyerror(char *s);
static struct grecs_node *parse_tree;
extern int yy_flex_debug;
-extern int grecs_bind_new_source(const char *name);
+extern int grecs_bind_new_source(const char *name, grecs_locus_t *loc);
extern void grecs_bind_close_sources(void);
static struct grecs_value *stmtlist_to_value(struct grecs_node *node);
%}
+%error-verbose
+%locations
+
%union {
- struct {
- grecs_locus_t locus;
- char *string;
- } ident;
char *string;
grecs_value_t svalue, *pvalue;
struct grecs_list *list;
@@ -49,8 +49,7 @@ static struct grecs_value *stmtlist_to_value(struct grecs_node *node);
struct { struct grecs_node *head, *tail; } node_list;
}
-%token <ident> BIND_IDENT BIND_CONTROLS
-%token <string> BIND_STRING
+%token <string> BIND_STRING BIND_IDENT BIND_CONTROLS
%type <string> string
%type <svalue> value ctlsub
%type <pvalue> vallist tag
@@ -62,8 +61,7 @@ static struct grecs_value *stmtlist_to_value(struct grecs_node *node);
input : maybe_stmtlist
{
- parse_tree = grecs_node_create(grecs_node_root,
- &grecs_current_locus);
+ parse_tree = grecs_node_create(grecs_node_root, &@1);
parse_tree->v.texttab = grecs_text_table();
grecs_node_bind(parse_tree, $1, 1);
}
@@ -102,38 +100,44 @@ stmt : simple
simple : BIND_IDENT vallist ';'
{
- if (strcmp($1.string, "include") == 0 &&
+ if (strcmp($1, "include") == 0 &&
$2->type == GRECS_TYPE_STRING) {
- grecs_bind_new_source($2->v.string);
+ grecs_bind_new_source($2->v.string, &@1);
$$ = NULL;
} else {
- $$ = grecs_node_create(grecs_node_stmt, &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_stmt,
+ @1.beg, @2.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = $2;
}
}
| string ';'
{
- $$ = grecs_node_create(grecs_node_stmt,
- &grecs_current_locus);
+ $$ = grecs_node_create(grecs_node_stmt, &@1);
$$->ident = $1;
+ $$->idloc = @1;
$$->v.value = NULL;
}
| '!' string ';'
{
- $$ = grecs_node_create(grecs_node_stmt,
- &grecs_current_locus);
- $$->ident = grecs_strdup("!");
- $$->v.value = grecs_malloc(sizeof($$->v.value[0]));
- $$->v.value->type = GRECS_TYPE_STRING;
- $$->v.value->v.string = $2;
+ $$ = grecs_node_create_points(grecs_node_stmt,
+ @1.beg, @2.end);
+ $$->ident = grecs_strdup("!");
+ $$->idloc = @1;
+ $$->v.value = grecs_malloc(sizeof($$->v.value[0]));
+ $$->v.value->type = GRECS_TYPE_STRING;
+ $$->v.value->locus = @2;
+ $$->v.value->v.string = $2;
}
;
block : BIND_IDENT tag '{' maybe_stmtlist '}' ';'
{
- $$ = grecs_node_create(grecs_node_block, &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_block,
+ @1.beg, @5.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = $2;
grecs_node_bind($$, $4, 1);
}
@@ -151,8 +155,10 @@ block : BIND_IDENT tag '{' maybe_stmtlist '}' ';'
(127.0.0.1, 127.0.0.2), keys, (rndc-key))
*/
{
- $$ = grecs_node_create(grecs_node_stmt, &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_stmt,
+ @1.beg, @4.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = grecs_value_ptr_from_static(&$3);
}
;
@@ -176,6 +182,7 @@ vallist : vlist
$$ = grecs_malloc(sizeof($$[0]));
$$->type = GRECS_TYPE_ARRAY;
+ $$->locus = @1;
$$->v.arg.c = n;
$$->v.arg.v = grecs_calloc(n,
sizeof($$->v.arg.v[0]));
@@ -201,20 +208,19 @@ vlist : value
value : string
{
$$.type = GRECS_TYPE_STRING;
+ $$.locus = @1;
$$.v.string = $1;
}
;
string : BIND_STRING
| BIND_IDENT
- {
- $$ = $1.string;
- }
;
ctlsub : ctllist ';'
{
$$.type = GRECS_TYPE_LIST;
+ $$.locus = @1;
$$.v.list = $1;
}
;
@@ -240,7 +246,7 @@ ctllist : value
int
yyerror(char *s)
{
- grecs_error(&grecs_current_locus, 0, "%s", s);
+ grecs_error(&yylloc, 0, "%s", s);
return 0;
}
@@ -249,7 +255,7 @@ grecs_bind_parser(const char *name, int traceflags)
{
int rc;
- if (grecs_bind_new_source(name))
+ if (grecs_bind_new_source(name, NULL))
return NULL;
yy_flex_debug = traceflags & GRECS_TRACE_LEX;
yydebug = traceflags & GRECS_TRACE_GRAM;
diff --git a/src/bind-lex.l b/src/bind-lex.l
index 10df618..ef1598c 100644
--- a/src/bind-lex.l
+++ b/src/bind-lex.l
@@ -22,6 +22,7 @@
with Grecs. If not, see <http://www.gnu.org/licenses/>. */
#include <grecs.h>
+#include <grecs-locus.h>
#include <bind-gram.h>
#include <unistd.h>
#include <fcntl.h>
@@ -32,6 +33,14 @@
#include <wordsplit.h>
+#define YY_USER_ACTION do { \
+ if (YYSTATE == 0) { \
+ yylloc.beg = grecs_current_locus_point; \
+ yylloc.beg.col++; \
+ } \
+ grecs_current_locus_point.col += yyleng; \
+ yylloc.end = grecs_current_locus_point; \
+ } while (0);
%}
%x COMMENT STR
@@ -45,26 +54,27 @@ P [1-9][0-9]*
"/*" BEGIN(COMMENT);
<COMMENT>[^*\n]* /* eat anything that's not a '*' */
<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
-<COMMENT>\n ++grecs_current_locus.line;
+<COMMENT>\n grecs_locus_point_advance_line(grecs_current_locus_point);
<COMMENT>"*"+"/" BEGIN(INITIAL);
/* Line directive */
^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext,
- &grecs_current_locus,
+ &yylloc,
+ &grecs_current_locus_point,
NULL); }
^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext,
- &grecs_current_locus,
+ &yylloc,
+ &grecs_current_locus_point,
NULL); }
/* End-of-line comments */
-#.*\n { grecs_current_locus.line++; }
+#.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
#.* /* end-of-file comment */;
-"//".*\n { grecs_current_locus.line++; }
+"//".*\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
"//".* /* end-of-file comment */;
/* Identifiers */
{ID} { grecs_line_begin();
grecs_line_add(yytext, yyleng);
- yylval.ident.string = grecs_line_finish();
- yylval.ident.locus = grecs_current_locus;
- return strcmp(yylval.ident.string, "controls") == 0 ?
+ yylval.string = grecs_line_finish();
+ return strcmp(yylval.string, "controls") == 0 ?
BIND_CONTROLS : BIND_IDENT;
}
/* Strings */
@@ -97,19 +107,20 @@ P [1-9][0-9]*
return BIND_STRING; }
{WS} ;
/* Other tokens */
-\n { grecs_current_locus.line++; }
+\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
[,;{}()!] return yytext[0];
. { if (isascii(yytext[0]) && isprint(yytext[0]))
- grecs_error(&grecs_current_locus, 0,
+ grecs_error(&yylloc, 0,
_("stray character %c"), yytext[0]);
else
- grecs_error(&grecs_current_locus, 0, _("stray character \\%03o"),
- (unsigned char) yytext[0]); }
+ grecs_error(&yylloc, 0, _("stray character \\%03o"),
+ (unsigned char) yytext[0]); }
%%
struct bind_input_context {
ino_t i_node;
dev_t i_dev;
+ struct grecs_locus_point point;
grecs_locus_t locus; /* Current input location */
YY_BUFFER_STATE state;
FILE *input;
@@ -135,7 +146,7 @@ cmp_context(const void *a, const void *b)
}
static int
-_push_context(const char *name, ino_t i_node, dev_t i_dev)
+_push_context(const char *name, ino_t i_node, dev_t i_dev, grecs_locus_t *loc)
{
struct bind_input_context ctx, *pctx;
@@ -148,7 +159,7 @@ _push_context(const char *name, ino_t i_node, dev_t i_dev)
ctx.i_node = i_node;
pctx = grecs_list_locate(input_stack, &ctx);
if (pctx) {
- grecs_error(&grecs_current_locus, 0,
+ grecs_error(&yylloc, 0,
_("%s has already been included"), name);
grecs_error(&pctx->locus, 0,
_("this is where the previous inclusion occurred"));
@@ -158,7 +169,11 @@ _push_context(const char *name, ino_t i_node, dev_t i_dev)
pctx = grecs_malloc(sizeof(*pctx));
pctx->i_node = i_node;
pctx->i_dev = i_dev;
- pctx->locus = grecs_current_locus;
+ if (loc)
+ pctx->locus = *loc;
+ else
+ memset(&pctx->locus, 0, sizeof(pctx->locus)); /* FIXME */
+ pctx->point = grecs_current_locus_point;
pctx->state = YY_CURRENT_BUFFER;
pctx->input = yyin;
grecs_list_push(input_stack, pctx);
@@ -184,7 +199,7 @@ _pop_context()
}
i_node = pctx->i_node;
i_dev = pctx->i_dev;
- grecs_current_locus = pctx->locus;
+ grecs_current_locus_point = pctx->point;
yyin = pctx->input;
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(pctx->state);
@@ -199,10 +214,8 @@ yywrap()
}
int
-grecs_bind_new_source(const char *name)
+grecs_bind_new_source(const char *name, grecs_locus_t *loc)
{
- grecs_locus_t *loc = grecs_current_locus.file ?
- &grecs_current_locus : NULL;
struct stat st;
FILE *fp;
@@ -245,15 +258,16 @@ grecs_bind_new_source(const char *name)
grecs_free(cmd);
}
- if (_push_context(name, st.st_ino, st.st_dev)) {
+ if (_push_context(name, st.st_ino, st.st_dev, loc)) {
return 1;
}
i_node = st.st_ino;
i_dev = st.st_dev;
yyin = fp;
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
- 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;
return 0;
}
diff --git a/src/diag.c b/src/diag.c
index 89b38f4..e8b6940 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -18,17 +18,22 @@
# include <config.h>
#endif
#include <grecs.h>
+#include <grecs-locus.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
static void
-default_print_diag(grecs_locus_t *locus, int err, int errcode, const char *msg)
+default_print_diag(grecs_locus_t const *locus, int err, int errcode,
+ const char *msg)
{
fflush(stdout);
- if (locus)
- fprintf(stderr, "%s:%d: ", locus->file, locus->line);
+ if (locus) {
+ YY_LOCATION_PRINT(stderr, *locus);
+ fputc(':', stderr);
+ fputc(' ', stderr);
+ }
if (!err)
fprintf(stderr, "warning: ");
fprintf(stderr, "%s", msg);
@@ -37,11 +42,12 @@ default_print_diag(grecs_locus_t *locus, int err, int errcode, const char *msg)
fputc('\n', stderr);
}
-void (*grecs_print_diag_fun)(grecs_locus_t *, int, int, const char *msg) =
+void (*grecs_print_diag_fun)(grecs_locus_t const *, int, int,
+ const char *msg) =
default_print_diag;
void
-grecs_warning(grecs_locus_t *locus, int errcode, const char *fmt, ...)
+grecs_warning(grecs_locus_t const *locus, int errcode, const char *fmt, ...)
{
va_list ap;
char *buf = NULL;
@@ -56,7 +62,7 @@ grecs_warning(grecs_locus_t *locus, int errcode, const char *fmt, ...)
}
void
-grecs_error(grecs_locus_t *locus, int errcode, const char *fmt, ...)
+grecs_error(grecs_locus_t const *locus, int errcode, const char *fmt, ...)
{
va_list ap;
char *buf = NULL;
diff --git a/src/format.c b/src/format.c
index d65f712..f1a876f 100644
--- a/src/format.c
+++ b/src/format.c
@@ -31,7 +31,7 @@ grecs_data_type_string(enum grecs_data_type type)
switch (type) {
case grecs_type_void:
return "void";
-
+
case grecs_type_string:
return "string";
@@ -47,13 +47,13 @@ grecs_data_type_string(enum grecs_data_type type)
case grecs_type_time:
return "time";
-
+
case grecs_type_bool:
return "boolean";
-
+
case grecs_type_ipv4:
return "IPv4";
-
+
case grecs_type_cidr:
return "CIDR";
@@ -125,7 +125,7 @@ grecs_print_simple_statement(struct grecs_keyword *kwp, unsigned level,
FILE *stream)
{
const char *argstr;
-
+
if (kwp->docstring)
grecs_print_docstring(kwp->docstring, level, stream);
format_level(level, stream);
@@ -192,7 +192,33 @@ grecs_format_locus(grecs_locus_t *locus, struct grecs_format_closure *clos)
if (locus) {
char *str = NULL;
size_t size = 0;
- grecs_asprintf(&str, &size, "%s:%d", locus->file, locus->line);
+
+ if (locus->beg.col == 0)
+ grecs_asprintf(&str, &size, "%s:%u",
+ locus->beg.file,
+ locus->beg.line);
+ else if (strcmp(locus->beg.file, locus->end.file))
+ grecs_asprintf(&str, &size, "%s:%u.%u-%s:%u.%u",
+ locus->beg.file,
+ locus->beg.line, locus->beg.col,
+ locus->end.file,
+ locus->end.line, locus->end.col);
+ else if (locus->beg.line != locus->end.line)
+ grecs_asprintf(&str, &size, "%s:%u.%u-%u.%u",
+ locus->beg.file,
+ locus->beg.line, locus->beg.col,
+ locus->end.line, locus->end.col);
+ else if (locus->beg.col != locus->end.col)
+ grecs_asprintf(&str, &size, "%s:%u.%u-%u",
+ locus->beg.file,
+ locus->beg.line, locus->beg.col,
+ locus->end.col);
+ else
+ grecs_asprintf(&str, &size, "%s:%u.%u",
+ locus->beg.file,
+ locus->beg.line,
+ locus->beg.col);
+
clos->fmtfun(str, clos->data);
free(str);
}
@@ -203,7 +229,7 @@ grecs_format_node_path(struct grecs_node *node, int flags,
struct grecs_format_closure *clos)
{
char delim[2] = ".";
-
+
if (node->up)
grecs_format_node_path(node->up, flags, clos);
if (node->type == grecs_node_root)
@@ -277,7 +303,7 @@ grecs_format_node(struct grecs_node *node, int flags,
struct grecs_format_closure *clos)
{
const char *delim_str = NULL;
-
+
if (!(flags & _GRECS_NODE_MASK_OUTPUT)) {
errno = EINVAL;
return 1;
@@ -297,7 +323,18 @@ grecs_format_node(struct grecs_node *node, int flags,
case grecs_node_stmt:
if (flags & GRECS_NODE_FLAG_LOCUS) {
- grecs_format_locus(&node->locus, clos);
+ grecs_locus_t *locus;
+
+ if (flags & GRECS_NODE_FLAG_PATH) {
+ if (flags & GRECS_NODE_FLAG_VALUE)
+ locus = &node->locus;
+ else
+ locus = &node->idloc;
+ } else if (flags & GRECS_NODE_FLAG_VALUE)
+ locus = &node->v.value->locus;
+ else
+ locus = &node->locus;
+ grecs_format_locus(locus, clos);
delim_str = ": ";
}
if (flags & GRECS_NODE_FLAG_PATH) {
@@ -367,7 +404,3 @@ grecs_print_node(struct grecs_node *node, int flags, FILE *fp)
struct grecs_format_closure clos = { file_fmt, fp };
return grecs_format_node(node, flags, &clos);
}
-
-
-
-
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);
diff --git a/src/grecs-gram.y b/src/grecs-gram.y
index bbe3d5e..92de6b2 100644
--- a/src/grecs-gram.y
+++ b/src/grecs-gram.y
@@ -19,6 +19,7 @@
# include <config.h>
#endif
#include <grecs.h>
+#include <grecs-locus.h>
#include <grecs-gram.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -31,11 +32,10 @@ int yyerror(char *s);
static struct grecs_node *parse_tree;
%}
+%error-verbose
+%locations
+
%union {
- struct {
- grecs_locus_t locus;
- char *string;
- } ident;
char *string;
grecs_value_t svalue, *pvalue;
struct grecs_list *list;
@@ -44,8 +44,7 @@ static struct grecs_node *parse_tree;
struct { struct grecs_node *head, *tail; } node_list;
}
-%token <ident> IDENT
-%token <string> STRING QSTRING MSTRING
+%token <string> STRING QSTRING MSTRING IDENT
%type <string> string slist
%type <list> slist0
%type <svalue> value
@@ -58,8 +57,7 @@ static struct grecs_node *parse_tree;
input : maybe_stmtlist
{
- parse_tree = grecs_node_create(grecs_node_root,
- &grecs_current_locus);
+ parse_tree = grecs_node_create(grecs_node_root, &@1);
parse_tree->v.texttab = grecs_text_table();
grecs_node_bind(parse_tree, $1, 1);
}
@@ -92,25 +90,27 @@ stmt : simple
simple : IDENT vallist ';'
{
- $$ = grecs_node_create(grecs_node_stmt,
- &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_stmt,
+ @1.beg, @2.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = $2;
}
| IDENT ';'
{
- $$ = grecs_node_create(grecs_node_stmt,
- &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create(grecs_node_stmt, &@1);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = NULL;
}
;
block : IDENT tag '{' stmtlist '}' opt_sc
{
- $$ = grecs_node_create(grecs_node_block,
- &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_block,
+ @1.beg, @5.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = $2;
grecs_node_bind($$, $4.head, 1);
}
@@ -135,6 +135,7 @@ vallist : vlist
$$ = grecs_malloc(sizeof($$[0]));
$$->type = GRECS_TYPE_ARRAY;
+ $$->locus = @1;
$$->v.arg.c = n;
$$->v.arg.v = grecs_calloc(n,
sizeof($$->v.arg.v[0]));
@@ -160,25 +161,25 @@ vlist : value
value : string
{
$$.type = GRECS_TYPE_STRING;
+ $$.locus = @1;
$$.v.string = $1;
}
| list
{
$$.type = GRECS_TYPE_LIST;
+ $$.locus = @1;
$$.v.list = $1;
}
| MSTRING
{
$$.type = GRECS_TYPE_STRING;
+ $$.locus = @1;
$$.v.string = $1;
}
;
string : STRING
| IDENT
- {
- $$ = $1.string;
- }
| slist
;
@@ -244,7 +245,7 @@ opt_sc : /* empty */
int
yyerror(char *s)
{
- grecs_error(&grecs_current_locus, 0, "%s", s);
+ grecs_error(&yylloc, 0, "%s", s);
return 0;
}
diff --git a/src/grecs-lex.l b/src/grecs-lex.l
index 5ca4e31..ba7a386 100644
--- a/src/grecs-lex.l
+++ b/src/grecs-lex.l
@@ -2,7 +2,7 @@
%top {
#ifdef HAVE_CONFIG_H
# include <config.h>
-#endif
+#endif
}
%{
/* grecs - Gray's Extensible Configuration System
@@ -22,6 +22,7 @@
with Grecs. If not, see <http://www.gnu.org/licenses/>. */
#include <grecs.h>
+#include <grecs-locus.h>
#include <grecs-gram.h>
#include <unistd.h>
#include <fcntl.h>
@@ -37,7 +38,7 @@ static int multiline_unescape; /* Unescape here-document contents */
static int (*char_to_strip)(char); /* Strip matching characters of each
here-document line */
-grecs_locus_t grecs_current_locus; /* Input file location */
+struct grecs_locus_point grecs_current_locus_point; /* Input file location */
/* Line correction. Equals to the number of #line directives inserted into
the input by the preprocessor instance. The external preprocessor, if
any, counts these as input lines and therefore the line numbers in *its*
@@ -54,16 +55,23 @@ static int ident(void);
static int isemptystr(int off);
#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- do \
- { \
- if (grecs_preprocessor) \
- result = fread(buf, 1, max_size, yyin); \
- else \
- result = grecs_preproc_fill_buffer(buf, max_size); \
- } \
- while(0)
-
+#define YY_INPUT(buf,result,max_size) \
+ do { \
+ if (grecs_preprocessor) \
+ result = fread(buf, 1, max_size, yyin); \
+ else \
+ result = grecs_preproc_fill_buffer(buf, max_size); \
+ } while(0)
+
+#define YY_USER_ACTION do { \
+ if (YYSTATE == 0) { \
+ yylloc.beg = grecs_current_locus_point; \
+ yylloc.beg.col++; \
+ } \
+ grecs_current_locus_point.col += yyleng; \
+ yylloc.end = grecs_current_locus_point; \
+ } while (0);
+
%}
@@ -78,18 +86,21 @@ P [1-9][0-9]*
"/*" BEGIN(COMMENT);
<COMMENT>[^*\n]* /* eat anything that's not a '*' */
<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
-<COMMENT>\n ++grecs_current_locus.line;
+<COMMENT>\n grecs_locus_point_advance_line(grecs_current_locus_point);
<COMMENT>"*"+"/" BEGIN(INITIAL);
/* Line directive */
^[ \t]*#[ \t]*{P}[ \t]+\".*\".*\n { grecs_parse_line_directive_cpp(yytext,
- &grecs_current_locus,
+ &yylloc,
+ &grecs_current_locus_point,
&xlines); }
-^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext, &grecs_current_locus,
- &xlines); }
+^[ \t]*#[ \t]*line[ \t].*\n { grecs_parse_line_directive(yytext,
+ &yylloc,
+ &grecs_current_locus_point,
+ &xlines); }
/* End-of-line comments */
-#.*\n { grecs_current_locus.line++; }
+#.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
#.* /* end-of-file comment */;
-"//".*\n { grecs_current_locus.line++; }
+"//".*\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
"//".* /* end-of-file comment */;
/* Identifiers */
<INITIAL>{ID} return ident();
@@ -123,11 +134,12 @@ P [1-9][0-9]*
"<<"(-" "?)?\"{ID}\"[ \t]*#.*\n |
"<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n |
"<<"(-" "?)?\"{ID}\"[ \t]*\n {
- BEGIN(ML);
- multiline_begin(yytext+2);
- grecs_current_locus.line++; }
+ BEGIN(ML);
+ multiline_begin(yytext+2); }
/* Ignore m4 line statements */
-<ML>^"#line ".*\n { grecs_current_locus.line++; }
+<ML>^"#line ".*\n {
+ grecs_locus_point_advance_line(grecs_current_locus_point);
+}
<ML>.*\n { char *p = multiline_strip_tabs(yytext);
if (!strncmp(p, multiline_delimiter, multiline_delimiter_len)
@@ -136,20 +148,30 @@ P [1-9][0-9]*
multiline_delimiter = NULL;
BEGIN(INITIAL);
yylval.string = grecs_line_finish();
+
+ /* Update end pos */
+ yylloc.end.line--;
+ for (yylloc.end.col = 0,
+ p = yylval.string + strlen(yylval.string) - 1;
+ p > yylval.string && p[-1] != '\n';
+ yylloc.end.col++, p--);
+ if (yylloc.end.col == 0)
+ yylloc.end.col = 1;
return MSTRING;
}
- grecs_current_locus.line++;
+ grecs_locus_point_advance_line(grecs_current_locus_point);
multiline_add(p); }
{WS} ;
/* Other tokens */
-\n { grecs_current_locus.line++; }
+\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
[,;{}()] return yytext[0];
. { if (isascii(yytext[0]) && isprint(yytext[0]))
- grecs_error(&grecs_current_locus, 0,
+ grecs_error(&yylloc, 0,
_("stray character %c"), yytext[0]);
else
- grecs_error(&grecs_current_locus, 0, _("stray character \\%03o"),
- (unsigned char) yytext[0]); }
+ grecs_error(&yylloc, 0,
+ _("stray character \\%03o"),
+ (unsigned char) yytext[0]); }
%%
pid_t grecs_preproc_pid;
@@ -161,7 +183,7 @@ yywrap()
grecs_preproc_extrn_shutdown(grecs_preproc_pid);
else
grecs_preproc_done();
- grecs_current_locus.file = NULL;
+ grecs_current_locus_point.file = NULL;
return 1;
}
@@ -285,6 +307,11 @@ multiline_begin(char *p)
memcpy(multiline_delimiter, p, multiline_delimiter_len);
multiline_delimiter[multiline_delimiter_len] = 0;
grecs_line_begin();
+
+ /* Update locus */
+ grecs_locus_point_advance_line(grecs_current_locus_point);
+ yylloc.beg = grecs_current_locus_point;
+ yylloc.beg.col++;
}
static int
@@ -300,8 +327,7 @@ ident()
len = strlen(p);
str = grecs_malloc(len + 1);
strcpy(str, p);
- yylval.ident.locus = grecs_current_locus;
- yylval.ident.string = str;
+ yylval.string = str;
return IDENT;
}
@@ -315,7 +341,8 @@ grecs_value_ptr_from_static(grecs_value_t *input)
static int
-assign_locus(grecs_locus_t *ploc, char *name, char *line, size_t *pxlines)
+assign_locus(struct grecs_locus_point *ploc,
+ char *name, char *line, size_t *pxlines)
{
char *p;
@@ -325,11 +352,13 @@ assign_locus(grecs_locus_t *ploc, char *name, char *line, size_t *pxlines)
ploc->file = grecs_install_text(name);
}
ploc->line = strtoul(line, &p, 10) - (pxlines ? *pxlines : 0);
+ ploc->col = 0;
return *p != 0;
}
void
-grecs_parse_line_directive(char *text, grecs_locus_t *ploc, size_t *pxlines)
+grecs_parse_line_directive(char *text, grecs_locus_t *ploc,
+ struct grecs_locus_point *ppoint, size_t *pxlines)
{
int rc = 1;
struct wordsplit ws;
@@ -338,13 +367,13 @@ grecs_parse_line_directive(char *text, grecs_locus_t *ploc, size_t *pxlines)
grecs_error(ploc, 0, _("cannot parse #line line"));
else {
if (ws.ws_wordc == 2)
- rc = assign_locus(ploc, NULL,
+ rc = assign_locus(ppoint, NULL,
ws.ws_wordv[1], pxlines);
else if (ws.ws_wordc == 3)
- rc = assign_locus(ploc, ws.ws_wordv[2],
+ rc = assign_locus(ppoint, ws.ws_wordv[2],
ws.ws_wordv[1], pxlines);
else if (ws.ws_wordc == 4) {
- rc = assign_locus(ploc, ws.ws_wordv[2],
+ rc = assign_locus(ppoint, ws.ws_wordv[2],
ws.ws_wordv[1], 0);
if (pxlines && rc == 0) {
char *p;
@@ -365,6 +394,7 @@ grecs_parse_line_directive(char *text, grecs_locus_t *ploc, size_t *pxlines)
void
grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc,
+ struct grecs_locus_point *ppoint,
size_t *pxlines)
{
struct wordsplit ws;
@@ -375,7 +405,7 @@ grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc,
} else if (ws.ws_wordc < 3)
grecs_error(ploc, 0, _("invalid #line statement"));
else {
- if (assign_locus(ploc, ws.ws_wordv[2],
+ if (assign_locus(ppoint, ws.ws_wordv[2],
ws.ws_wordv[1], pxlines))
grecs_error(ploc, 0, _("malformed #line statement"));
}
diff --git a/src/grecs-locus.h b/src/grecs-locus.h
new file mode 100644
index 0000000..e23add2
--- a/dev/null
+++ b/src/grecs-locus.h
@@ -0,0 +1,56 @@
+/* grecs - Gray's Extensible Configuration System
+ Copyright (C) 2007-2011 Sergey Poznyakoff
+
+ Grecs is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ Grecs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Grecs. If not, see <http://www.gnu.org/licenses/>. */
+
+#define YYLTYPE grecs_locus_t
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (N) { \
+ (Current).beg = YYRHSLOC(Rhs, 1).beg; \
+ (Current).end = YYRHSLOC(Rhs, N).end; \
+ } else { \
+ (Current).beg = YYRHSLOC(Rhs, 0).end; \
+ (Current).end = (Current).beg; \
+ } \
+ } while (0)
+
+#define YY_LOCATION_PRINT(File, Loc) do { \
+ if ((Loc).beg.col == 0) \
+ fprintf(File, "%s:%u", \
+ (Loc).beg.file, \
+ (Loc).beg.line); \
+ else if (strcmp((Loc).beg.file, (Loc).end.file)) \
+ fprintf(File, "%s:%u.%u-%s:%u.%u", \
+ (Loc).beg.file, \
+ (Loc).beg.line, (Loc).beg.col, \
+ (Loc).end.file, \
+ (Loc).end.line, (Loc).end.col); \
+ else if ((Loc).beg.line != (Loc).end.line) \
+ fprintf(File, "%s:%u.%u-%u.%u", \
+ (Loc).beg.file, \
+ (Loc).beg.line, (Loc).beg.col, \
+ (Loc).end.line, (Loc).end.col); \
+ else if ((Loc).beg.col != (Loc).end.col) \
+ fprintf(File, "%s:%u.%u-%u", \
+ (Loc).beg.file, \
+ (Loc).beg.line, (Loc).beg.col, \
+ (Loc).end.col); \
+ else \
+ fprintf(File, "%s:%u.%u", \
+ (Loc).beg.file, \
+ (Loc).beg.line); \
+ } while (0)
+
diff --git a/src/grecs.h b/src/grecs.h
index 8bd70d1..1581791 100644
--- a/src/grecs.h
+++ b/src/grecs.h
@@ -51,9 +51,23 @@ struct grecs_version_info {
char *buffer;
};
-typedef struct {
+struct grecs_locus_point {
char *file;
- int line;
+ unsigned line;
+ unsigned col;
+};
+
+#define grecs_locus_point_advance_line(loc) do { \
+ (loc).line++; \
+ (loc).col = 0; \
+ } while (0)
+
+#define GRECS_LOCUS_POINT_EQ(a,b) \
+ ((strcmp((a)->file, (b)->file) == 0) && ((a)->line == (b)->line))
+
+typedef struct grecs_locus {
+ struct grecs_locus_point beg;
+ struct grecs_locus_point end;
} grecs_locus_t;
extern grecs_locus_t grecs_locus;
@@ -109,6 +123,7 @@ struct grecs_list {
typedef struct grecs_value {
int type;
+ grecs_locus_t locus;
union {
struct grecs_list *list;
char *string;
@@ -137,6 +152,7 @@ typedef struct grecs_node {
struct grecs_node *next;
struct grecs_node *prev;
char *ident;
+ grecs_locus_t idloc;
union {
struct grecs_value *value;
struct grecs_symtab *texttab;
@@ -192,12 +208,14 @@ void grecs_free(void *ptr);
grecs_value_t *grecs_value_ptr_from_static(grecs_value_t *input);
-extern void (*grecs_print_diag_fun)(grecs_locus_t *, int, int, const char*);
+extern void (*grecs_print_diag_fun)(grecs_locus_t const *, int, int, const char*);
-void grecs_warning(grecs_locus_t *locus, int errcode, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-void grecs_error(grecs_locus_t *locus, int errcode, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
+void grecs_warning(grecs_locus_t const *locus,
+ int errcode, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+void grecs_error(grecs_locus_t const *locus, int errcode,
+ const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
extern int grecs_trace_flags;
@@ -208,8 +226,10 @@ void grecs_gram_trace(int n);
void grecs_lex_trace(int n);
void grecs_parse_line_directive(char *text, grecs_locus_t *ploc,
+ struct grecs_locus_point *ppoint,
size_t *pxlines);
void grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc,
+ struct grecs_locus_point *ppoint,
size_t *pxlines);
@@ -251,7 +271,8 @@ void grecs_line_begin(void);
char *grecs_line_finish(void);
extern int grecs_string_convert(void *target, enum grecs_data_type type,
- const char *string, grecs_locus_t *locus);
+ const char *string,
+ grecs_locus_t const *locus);
extern void grecs_process_ident(struct grecs_keyword *kwp,
grecs_value_t *value,
void *base,
@@ -259,12 +280,15 @@ extern void grecs_process_ident(struct grecs_keyword *kwp,
struct grecs_node *grecs_node_create(enum grecs_node_type type,
grecs_locus_t *loc);
+struct grecs_node *grecs_node_create_points(enum grecs_node_type type,
+ struct grecs_locus_point beg,
+ struct grecs_locus_point end);
void grecs_node_bind(struct grecs_node *master, struct grecs_node *node,
int dn);
int grecs_node_eq(struct grecs_node *a, struct grecs_node *b);
-extern grecs_locus_t grecs_current_locus;
+extern struct grecs_locus_point grecs_current_locus_point;
extern int grecs_error_count;
extern int grecs_default_port;
@@ -450,7 +474,8 @@ struct grecs_node *grecs_find_node(struct grecs_node *node, const char *path);
struct grecs_node *grecs_node_from_path(const char *path, const char *value);
struct grecs_node *grecs_node_from_path_locus(const char *path,
const char *value,
- grecs_locus_t *locus);
+ grecs_locus_t *locus,
+ grecs_locus_t *vallocus);
int grecs_tree_reduce(struct grecs_node *node, struct grecs_keyword *kwd,
int flags);
diff --git a/src/join.c b/src/join.c
index fd7c3ad..29db5bf 100644
--- a/src/join.c
+++ b/src/join.c
@@ -21,6 +21,21 @@
#include <errno.h>
#include "grecs.h"
+static void
+reset_point(struct grecs_locus_point *point, struct grecs_symtab *st)
+{
+ struct grecs_syment *ent, key;
+ int install = 1;
+
+ if (!point->file)
+ return;
+ key.name = (char*) point->file;
+ ent = grecs_symtab_lookup_or_install(st, &key, &install);
+ if (!ent)
+ grecs_alloc_die();
+ point->file = ent->name;
+}
+
static enum grecs_tree_recurse_res
reset_locus(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
{
@@ -28,16 +43,8 @@ reset_locus(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
switch (op) {
case grecs_tree_recurse_set:
case grecs_tree_recurse_pre:
- if (node->locus.file) {
- struct grecs_syment *ent, key;
- int install = 1;
- key.name = (char*) node->locus.file;
- ent = grecs_symtab_lookup_or_install(st, &key,
- &install);
- if (!ent)
- grecs_alloc_die();
- node->locus.file = ent->name;
- }
+ reset_point(&node->locus.beg, st);
+ reset_point(&node->locus.end, st);
break;
default:
break;
diff --git a/src/lookup.c b/src/lookup.c
index f16e94b..2e737aa 100644
--- a/src/lookup.c
+++ b/src/lookup.c
@@ -199,7 +199,7 @@ parse_label(const char *str)
lst = grecs_value_list_create();
for (i = 0; i < ws.ws_wordc; i++) {
- struct grecs_value *p = grecs_malloc(sizeof(*p));
+ struct grecs_value *p = grecs_zalloc(sizeof(*p));
p->type = GRECS_TYPE_STRING;
p->v.string = ws.ws_wordv[i];
grecs_list_append(lst, p);
@@ -210,7 +210,7 @@ parse_label(const char *str)
} else {
if (wordsplit(str, &ws, WRDSF_DEFFLAGS))
return NULL;
- val = grecs_malloc(sizeof(*val));
+ val = grecs_zalloc(sizeof(*val));
if (ws.ws_wordc == 1) {
val->type = GRECS_TYPE_STRING;
val->v.string = ws.ws_wordv[0];
@@ -221,14 +221,14 @@ parse_label(const char *str)
sizeof(val->v.arg.v[0]));
for (i = 0; i < ws.ws_wordc; i++) {
val->v.arg.v[i] =
- grecs_malloc(sizeof(val->v.arg.v[0]));
+ grecs_zalloc(sizeof(*val->v.arg.v[0]));
val->v.arg.v[i]->type = GRECS_TYPE_STRING;
val->v.arg.v[i]->v.string = ws.ws_wordv[i];
}
}
- ws.ws_wordc = 0;
- wordsplit_free(&ws);
}
+ ws.ws_wordc = 0;
+ wordsplit_free(&ws);
return val;
}
@@ -244,15 +244,16 @@ split_cfg_path(const char *path, int *pargc, char ***pargv,
if (path[0] == '\\') {
argv = calloc(2, sizeof (*argv));
if (!argv)
- return ENOMEM;
+ return WRDSE_NOSPACE;
argv[0] = strdup(path + 1);
if (!argv[0]) {
free(argv);
- return ENOMEM;
+ return WRDSE_NOSPACE;
}
argv[1] = NULL;
argc = 1;
} else {
+ int rc;
struct wordsplit ws;
if (strchr("./:;,^~", path[0])) {
@@ -262,8 +263,10 @@ split_cfg_path(const char *path, int *pargc, char ***pargv,
}
ws.ws_delim = delim;
- if (wordsplit(path, &ws, WRDSF_DEFFLAGS|WRDSF_DELIM))
- return errno;
+ rc = wordsplit(path, &ws,
+ WRDSF_DELIM | WRDSF_DEFFLAGS);
+ if (rc)
+ return rc;
argc = ws.ws_wordc;
argv = ws.ws_wordv;
ws.ws_wordc = 0;
@@ -333,9 +336,25 @@ grecs_find_node(struct grecs_node *node, const char *path)
}
+static void
+fixup_loci(struct grecs_node *node,
+ grecs_locus_t const *plocus,
+ struct grecs_locus_point const *endp)
+{
+ grecs_locus_t loc = *plocus;
+
+ for (; node; node = node->down) {
+ node->idloc = loc;
+
+ node->locus = loc;
+ if (endp)
+ node->locus.end = *endp;
+ }
+}
+
struct grecs_node *
grecs_node_from_path_locus(const char *path, const char *value,
- grecs_locus_t *locus)
+ grecs_locus_t *plocus, grecs_locus_t *vallocus)
{
int rc;
int i;
@@ -346,10 +365,13 @@ grecs_node_from_path_locus(const char *path, const char *value,
rc = split_cfg_path(path, &argc, &argv, NULL);
if (rc)
return NULL;
- dn = grecs_node_create(grecs_node_stmt, locus);
+
+ dn = grecs_node_create(grecs_node_stmt, NULL);
dn->ident = argv[argc - 1];
if (value) {
struct grecs_value *gval = parse_label(value);
+ if (vallocus)
+ gval->locus = *vallocus;
dn->v.value = gval;
} else
dn->v.value = NULL;
@@ -371,7 +393,7 @@ grecs_node_from_path_locus(const char *path, const char *value,
break;
} while (*q);
- node = grecs_node_create(grecs_node_block, locus);
+ node = grecs_node_create(grecs_node_block, plocus);
node->ident = argv[i];
if (label)
node->v.value = label;
@@ -381,7 +403,11 @@ grecs_node_from_path_locus(const char *path, const char *value,
dn->up = node;
dn = node;
}
-
+
+ if (plocus)
+ fixup_loci(dn,
+ plocus, vallocus ? &vallocus->end : NULL);
+
free(argv);
return dn;
}
@@ -389,7 +415,7 @@ grecs_node_from_path_locus(const char *path, const char *value,
struct grecs_node *
grecs_node_from_path(const char *path, const char *value)
{
- return grecs_node_from_path_locus(path, value, NULL);
+ return grecs_node_from_path_locus(path, value, NULL, NULL);
}
diff --git a/src/meta1-gram.y b/src/meta1-gram.y
index 455c362..0fb6727 100644
--- a/src/meta1-gram.y
+++ b/src/meta1-gram.y
@@ -21,6 +21,7 @@
#include <errno.h>
#include <string.h>
#include "grecs.h"
+#include "grecs-locus.h"
int yylex(void);
int yyerror(char *s);
@@ -29,11 +30,10 @@ static struct grecs_node *parse_tree;
extern int yy_flex_debug;
%}
+%error-verbose
+%locations
+
%union {
- struct {
- grecs_locus_t locus;
- char *string;
- } ident;
char *string;
grecs_value_t svalue, *pvalue;
struct grecs_list *list;
@@ -41,8 +41,7 @@ extern int yy_flex_debug;
struct grecs_node *node;
}
-%token <ident> META1_IDENT
-%token <string> META1_STRING
+%token <string> META1_STRING META1_IDENT
%type <node> stmt simple block maybe_stmtlist
%type <node_list> stmtlist
%type <pvalue> tag value
@@ -53,8 +52,7 @@ extern int yy_flex_debug;
input : maybe_stmtlist
{
- parse_tree = grecs_node_create(grecs_node_root,
- &grecs_current_locus);
+ parse_tree = grecs_node_create(grecs_node_root, &@1);
parse_tree->v.texttab = grecs_text_table();
grecs_node_bind(parse_tree, $1, 1);
}
@@ -87,18 +85,20 @@ stmt : simple
simple : META1_IDENT '=' value opt_sc
{
- $$ = grecs_node_create(grecs_node_stmt,
- &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_stmt,
+ @1.beg, @3.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = $3;
}
;
block : META1_IDENT tag '{' stmtlist '}' opt_sc
{
- $$ = grecs_node_create(grecs_node_block,
- &$1.locus);
- $$->ident = $1.string;
+ $$ = grecs_node_create_points(grecs_node_block,
+ @1.beg, @5.end);
+ $$->ident = $1;
+ $$->idloc = @1;
$$->v.value = $2;
grecs_node_bind($$, $4.head, 1);
}
@@ -112,7 +112,7 @@ tag : /* empty */
{
$$ = grecs_malloc(sizeof($$[0]));
$$->type = GRECS_TYPE_STRING;
- $$->v.string = $1.string;
+ $$->v.string = $1;
}
;
@@ -120,20 +120,19 @@ value : string
{
$$ = grecs_malloc(sizeof($$[0]));
$$->type = GRECS_TYPE_STRING;
+ $$->locus = @1;
$$->v.string = $1;
}
| list
{
$$ = grecs_malloc(sizeof($$[0]));
$$->type = GRECS_TYPE_LIST;
+ $$->locus = @1;
$$->v.list = $1;
}
;
string : META1_IDENT
- {
- $$ = $1.string;
- }
| slist
;
@@ -193,7 +192,7 @@ opt_sc : /* empty */
int
yyerror(char *s)
{
- grecs_error(&grecs_current_locus, 0, "%s", s);
+ grecs_error(&yylloc, 0, "%s", s);
return 0;
}
diff --git a/src/meta1-lex.l b/src/meta1-lex.l
index cb2931d..04eddb5 100644
--- a/src/meta1-lex.l
+++ b/src/meta1-lex.l
@@ -23,6 +23,7 @@
# include <config.h>
#endif
#include "grecs.h"
+#include "grecs-locus.h"
#include "meta1-gram.h"
#include <ctype.h>
}
@@ -30,6 +31,15 @@
%{
static int yywrap(void);
static void meta1_line_add_unescape_hex(const char *text, size_t len);
+
+#define YY_USER_ACTION do { \
+ if (YYSTATE == 0) { \
+ yylloc.beg = grecs_current_locus_point; \
+ yylloc.beg.col++; \
+ } \
+ grecs_current_locus_point.col += yyleng; \
+ yylloc.end = grecs_current_locus_point; \
+ } while (0);
%}
%x COMMENT STR
@@ -39,10 +49,10 @@ X [0-9a-fA-F]
"/*" BEGIN (COMMENT);
<COMMENT>[^*\n]* /* eat anything that's not a '*' */
<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
-<COMMENT>\n ++grecs_current_locus.line;
+<COMMENT>\n grecs_locus_point_advance_line(grecs_current_locus_point);
<COMMENT>"*"+"/" BEGIN (INITIAL);
/* End-of-line comments */
-#.*\n { grecs_current_locus.line++; }
+#.*\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
#.* /* end-of-file comment */;
/* Number */
0[xX]{X}+ |
@@ -54,8 +64,7 @@ X [0-9a-fA-F]
/* Identifiers (unquoted strings) */
[a-zA-Z0-9_\./:\*-]+ { grecs_line_begin();
grecs_line_add(yytext, yyleng);
- yylval.ident.locus = grecs_current_locus;
- yylval.ident.string = grecs_line_finish();
+ yylval.string = grecs_line_finish();
return META1_IDENT; }
/* Quoted strings */
\"[^\\"\n]*\" { grecs_line_begin();
@@ -78,16 +87,16 @@ X [0-9a-fA-F]
yylval.string = grecs_line_finish();
return META1_STRING; }
<STR>[^\\"\n]*\n { BEGIN(INITIAL);
- grecs_error(&grecs_current_locus, 0,
+ grecs_error(&yylloc, 0,
_("newline in a string"));
- grecs_line_add (yytext, yyleng - 1);
- yylval.string = grecs_line_finish ();
+ grecs_line_add(yytext, yyleng - 1);
+ yylval.string = grecs_line_finish();
return META1_STRING; }
/* Other tokens */
[ \t\f][ \t\f]* ;
-\n { grecs_current_locus.line++; }
+\n { grecs_locus_point_advance_line(grecs_current_locus_point); }
[,;{}=] return yytext[0];
-. { grecs_error(&grecs_current_locus, 0,
+. { grecs_error(&yylloc, 0,
(isascii(yytext[0]) && isprint(yytext[0])) ?
_("stray character %c") :
_("stray character \\%03o"),
diff --git a/src/parser.c b/src/parser.c
index 5d8bdf3..4e315e5 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -56,7 +56,8 @@ struct grecs_node *
grecs_parse(const char *name)
{
grecs_error_count = 0;
- grecs_current_locus.file = grecs_install_text(name);
- grecs_current_locus.line = 0;
+ grecs_current_locus_point.file = grecs_install_text(name);
+ grecs_current_locus_point.line = 1;
+ grecs_current_locus_point.col = 0;
return grecs_parser_fun(name, grecs_trace_flags);
}
diff --git a/src/path-parser.c b/src/path-parser.c
index c66f8ca..f42ac60 100644
--- a/src/path-parser.c
+++ b/src/path-parser.c
@@ -23,17 +23,25 @@
#include <errno.h>
#include <grecs.h>
-static size_t
-trimnl(char *buf)
+static int
+next_char(FILE *infile)
{
- size_t len = strlen(buf);
-
- if (len && buf[len-1] == '\n') {
- buf[--len] = 0;
- if (len && buf[len-1] == '\r')
- buf[--len] = 0;
+ int c = fgetc(infile);
+ if (c == '\n')
+ grecs_locus_point_advance_line(grecs_current_locus_point);
+ else {
+ grecs_current_locus_point.col++;
+ if (c == '\\') {
+ int nc = fgetc(infile);
+ if (nc == '\n') {
+ grecs_locus_point_advance_line(grecs_current_locus_point);
+ c = fgetc(infile);
+ grecs_current_locus_point.col++;
+ } else
+ ungetc(nc, infile);
+ }
}
- return len;
+ return c;
}
struct grecs_node *
@@ -41,84 +49,126 @@ grecs_path_parser(const char *name, int traceflags)
{
struct grecs_node *root, *subtree = NULL, *node;
FILE *infile;
- char *buf = NULL;
- size_t size = 0;
struct grecs_txtacc *acc = NULL;
- char *prevptr = NULL;
- char *ptr, *p;
- int inquote, cont = 0;
+ char *kw, *val;
+ grecs_locus_t kwloc, valloc, rootloc;
+ int inquote;
+ int lookahead;
+ int err = 0;
+ unsigned prev_col;
infile = fopen(name, "r");
if (!infile) {
grecs_error(NULL, errno, _("cannot open `%s'"), name);
return NULL;
}
- grecs_current_locus.file = grecs_install_text(name);
- grecs_current_locus.line = 0;
+ grecs_current_locus_point.file = grecs_install_text(name);
+ grecs_current_locus_point.line = 1;
+ grecs_current_locus_point.col = 0;
+ rootloc.beg = grecs_current_locus_point;
+ rootloc.beg.col++;
+
+ acc = grecs_txtacc_create();
- while (grecs_getline(&buf, &size, infile) >= 0) {
- size_t len;
-
- ++grecs_current_locus.line;
- len = trimnl(buf);
- if (len && buf[len-1] == '\\') {
- if (!acc)
- acc = grecs_txtacc_create();
- else if (prevptr) {
- grecs_txtacc_free_string(acc, prevptr);
- prevptr = NULL;
+ while ((lookahead = next_char(infile)) > 0) {
+ while (1) {
+ while (lookahead == ' ' || lookahead == '\t')
+ lookahead = next_char(infile);
+
+ if (lookahead == '#') {
+ while ((lookahead = next_char(infile)) &&
+ lookahead != '\n')
+ ;
+ continue;
}
- grecs_txtacc_grow(acc, buf, len - 1);
- cont = 1;
- continue;
- } else {
- if (cont)
- ptr = prevptr = grecs_txtacc_finish(acc, 0);
- else
- ptr = buf;
- cont = 0;
+ break;
}
+
+ if (lookahead <= 0)
+ break;
+
+ kwloc.beg = grecs_current_locus_point;
- while (*ptr && (*ptr == ' ' || *ptr == '\t'))
- ptr++;
- if (!*ptr || *ptr == '#')
- continue;
inquote = 0;
- for (p = ptr; *p && *p != ':'; p++) {
+ for (; lookahead > 0 && lookahead != ':';
+ lookahead = next_char(infile)) {
if (inquote) {
- if (inquote == '"' && *p == '\\')
- p++;
- else if (*p == inquote)
+ if (inquote == '"' && lookahead == '\\') {
+ lookahead = next_char(infile);
+ if (lookahead <= 0)
+ break;
+ } else if (lookahead == inquote)
inquote = 0;
- } else if (*p == '\'' || *p == '"')
- inquote = *p;
+ } else if (lookahead == '\'' || lookahead == '"')
+ inquote = lookahead;
+ grecs_txtacc_grow_char(acc, lookahead);
}
- if (!*p) {
- grecs_error(&grecs_current_locus, 0,
- _("syntax error"));
- continue;
+
+ if (lookahead <= 0) {
+ grecs_error(&kwloc, 0, _("unexpected end of file"));
+ err = 1;
+ break;
}
- *p++ = 0;
- while (*p && (*p == ' ' || *p == '\t'))
- p++;
+
+ grecs_txtacc_grow_char(acc, 0);
+ kw = grecs_txtacc_finish(acc, 0);
+
+ kwloc.end = grecs_current_locus_point;
+ kwloc.end.col--;
+
+ while ((lookahead = next_char(infile)) > 0 &&
+ (lookahead == ' ' || lookahead == '\t'));
+
+ if (lookahead <= 0) {
+ grecs_error(&kwloc, 0, _("unexpected end of file"));
+ err = 1;
+ break;
+ }
+
+ valloc.beg = grecs_current_locus_point;
+ do {
+ grecs_txtacc_grow_char(acc, lookahead);
+ prev_col = grecs_current_locus_point.col;
+ } while ((lookahead = next_char(infile)) > 0 &&
+ lookahead != '\n');
+ valloc.end = grecs_current_locus_point;
+ valloc.end.line--;
+ valloc.end.col = prev_col;
+
+ grecs_txtacc_grow_char(acc, 0);
+ val = grecs_txtacc_finish(acc, 0);
+
+ node = grecs_node_from_path_locus(kw, val, &kwloc, &valloc);
+ if (!node) {
+ grecs_error(&kwloc, 0, _("parse error"));
+ err = 1;
+ break;
+ }
+ node->locus.end = valloc.end;
+ node->idloc = kwloc;
- node = grecs_node_from_path_locus(ptr, p,
- &grecs_current_locus);
if (!subtree)
subtree = node;
else
grecs_node_bind(subtree, node, 0);
+ grecs_txtacc_free_string(acc, kw);
+ grecs_txtacc_free_string(acc, val);
}
fclose(infile);
- free(buf);
grecs_txtacc_free(acc);
- root = grecs_node_create(grecs_node_root, &grecs_current_locus);
- root->v.texttab = grecs_text_table();
- grecs_node_bind(root, subtree, 1);
- grecs_tree_reduce(root, NULL, 0);
-
+ if (err) {
+ grecs_tree_free(subtree);
+ root = NULL;
+ } else {
+ rootloc.end = grecs_current_locus_point;
+ root = grecs_node_create(grecs_node_root, &rootloc);
+ root->v.texttab = grecs_text_table();
+ grecs_node_bind(root, subtree, 1);
+ grecs_tree_reduce(root, NULL, 0);
+ }
+
return root;
}
diff --git a/src/preproc.c b/src/preproc.c
index 1eeddd0..a5dda52 100644
--- a/src/preproc.c
+++ b/src/preproc.c
@@ -55,6 +55,7 @@ static size_t linebufsize = 0;
#define INFILE context_stack->infile
#define LOCUS context_stack->locus
+#define POINT context_stack->locus.beg
static char *linebuf;
static size_t bufsize;
@@ -123,8 +124,8 @@ pp_line_stmt()
if (grecs_asprintf(&linebufbase, &linebufsize,
"#line %lu \"%s\" %lu\n",
- (unsigned long) LOCUS.line,
- LOCUS.file, (unsigned long) context_stack->xlines))
+ (unsigned long) POINT.line,
+ POINT.file, (unsigned long) context_stack->xlines))
grecs_alloc_die();
ls_size = strlen(linebufbase);
@@ -211,7 +212,7 @@ grecs_preproc_fill_buffer(char *buf, size_t size)
}
if (!is_line && len > 0 && linebuf[len - 1] == '\n')
- LOCUS.line++;
+ POINT.line++;
}
return bufsize - size;
}
@@ -397,7 +398,7 @@ push_source(const char *name, int once)
return 1;
}
- if (LOCUS.file && STAT_ID_EQ(st, context_stack->id)) {
+ if (POINT.file && STAT_ID_EQ(st, context_stack->id)) {
grecs_error(&LOCUS, 0, _("Recursive inclusion"));
return 1;
}
@@ -431,10 +432,13 @@ push_source(const char *name, int once)
/* Push current context */
ctx = grecs_malloc(sizeof(*ctx));
- ctx->locus.file = grecs_install_text(name);
- ctx->locus.line = 1;
+ ctx->locus.beg.file = grecs_install_text(name);
+ ctx->locus.beg.line = 1;
+ ctx->locus.beg.col = 0;
+ ctx->locus.end.file = NULL;
+ ctx->locus.end.line = ctx->locus.end.col = 0;
ctx->xlines = 0;
- ctx->namelen = strlen(ctx->locus.file);
+ ctx->namelen = strlen(ctx->locus.beg.file);
ctx->id.i_node = st.st_ino;
ctx->id.device = st.st_dev;
ctx->infile = fp;
@@ -470,11 +474,11 @@ pop_source()
return 1;
}
- LOCUS.line++;
+ POINT.line++;
if (grecs_grecs__flex_debug)
fprintf(stderr, "Resuming file `%s' at line %lu\n",
- LOCUS.file, (unsigned long) LOCUS.line);
+ POINT.file, (unsigned long) POINT.line);
pp_line_stmt();
diff --git a/src/tree.c b/src/tree.c
index 58b34a5..6fdbb85 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -62,6 +62,18 @@ grecs_node_create(enum grecs_node_type type, grecs_locus_t *loc)
return np;
}
+struct grecs_node *
+grecs_node_create_points(enum grecs_node_type type,
+ struct grecs_locus_point beg,
+ struct grecs_locus_point end)
+{
+ grecs_locus_t loc;
+
+ loc.beg = beg;
+ loc.end = end;
+ return grecs_node_create(type, &loc);
+}
+
void
grecs_node_bind(struct grecs_node *master, struct grecs_node *node, int dn)
{
@@ -281,7 +293,7 @@ target_ptr(struct grecs_keyword *kwp, char *base)
}
static int
-string_to_bool(const char *string, int *pval, grecs_locus_t *locus)
+string_to_bool(const char *string, int *pval, grecs_locus_t const *locus)
{
if (strcmp(string, "yes") == 0
|| strcmp(string, "true") == 0
@@ -303,7 +315,8 @@ string_to_bool(const char *string, int *pval, grecs_locus_t *locus)
}
static int
-string_to_host(struct in_addr *in, const char *string, grecs_locus_t *locus)
+string_to_host(struct in_addr *in, const char *string,
+ grecs_locus_t const *locus)
{
if (inet_aton(string, in) == 0) {
struct hostent *hp;
@@ -318,7 +331,7 @@ string_to_host(struct in_addr *in, const char *string, grecs_locus_t *locus)
static int
string_to_sockaddr(struct grecs_sockaddr *sp, const char *string,
- grecs_locus_t *locus)
+ grecs_locus_t const *locus)
{
if (string[0] == '/') {
struct sockaddr_un s_un;
@@ -434,7 +447,7 @@ string_to_sockaddr(struct grecs_sockaddr *sp, const char *string,
break; \
if (x <= sum) \
{ \
- grecs_error(loc, 0, _("numeric overflow")); \
+ grecs_error(loc, 0, _("numeric overflow")); \
return 1; \
} \
else if (limit && x > limit) \
@@ -513,7 +526,7 @@ string_to_sockaddr(struct grecs_sockaddr *sp, const char *string,
int
grecs_string_convert(void *target, enum grecs_data_type type,
- const char *string, grecs_locus_t *locus)
+ const char *string, grecs_locus_t const *locus)
{
switch (type) {
case grecs_type_void:
@@ -568,7 +581,7 @@ grecs_string_convert(void *target, enum grecs_data_type type,
grecs_error(locus, 0, _("%s: not a valid IP address"),
string);
return 1;
- }
+ }
break;
case grecs_type_host:
@@ -707,7 +720,7 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value,
const grecs_value_t *vp = ep->data;
if (vp->type != GRECS_TYPE_STRING)
- grecs_error(locus, 0,
+ grecs_error(&vp->locus, 0,
_("%s: incompatible data type in list item #%d"),
kwp->ident, num);
else if (type == grecs_type_string)
@@ -716,9 +729,10 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value,
else {
void *ptr = grecs_malloc(size);
if (grecs_string_convert(ptr,
- type,
- vp->v.string,
- locus) == 0)
+ type,
+ vp->v.string,
+ &vp->locus)
+ == 0)
grecs_list_append(list, ptr);
else
grecs_free(ptr);
@@ -753,7 +767,8 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value,
else {
ptr = grecs_malloc(size);
if (grecs_string_convert(ptr, type,
- value->v.string, locus)) {
+ value->v.string,
+ &value->locus)) {
grecs_free(ptr);
grecs_list_free(list);
return;
@@ -763,8 +778,8 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value,
*(struct grecs_list**)target = list;
} else
grecs_string_convert(target, GRECS_TYPE(kwp->type),
- value->v.string,
- locus);
+ value->v.string,
+ &value->locus);
}
@@ -835,11 +850,11 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
case grecs_tree_recurse_set:
kwp = find_keyword(clos->cursect, node->ident);
if (!kwp) {
- grecs_error(&node->locus, 0, _("Unknown keyword"));
+ grecs_error(&node->idloc, 0, _("Unknown keyword"));
return grecs_tree_recurse_skip;
}
grecs_process_ident(kwp, node->v.value, CURRENT_BASE(clos),
- &node->locus);
+ &node->idloc);
break;
case grecs_tree_recurse_pre:

Return to:

Send suggestions and report system problems to the System administrator.