summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-03-29 03:19:50 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-03-29 03:19:50 +0200
commiteb0c48b789bbf41745287adb6b2949f84e7e9171 (patch)
tree212f1156670e2f600d958116738425caa35d815e
parentaadf0a94b436990202cd2f13f1fe8528a9fd183c (diff)
downloadfastd-eb0c48b789bbf41745287adb6b2949f84e7e9171.tar
fastd-eb0c48b789bbf41745287adb6b2949f84e7e9171.zip
Config parse: add location tracking for nice error messages
-rw-r--r--src/config.c7
-rw-r--r--src/config.l83
-rw-r--r--src/config.y8
3 files changed, 59 insertions, 39 deletions
diff --git a/src/config.c b/src/config.c
index b63ade9..8ba8c0a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -117,17 +117,18 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
int token;
YYSTYPE token_val;
+ YYLTYPE loc = {1, 0, 1, 0};
if (peer_config)
token = START_PEER_CONFIG;
else
token = START_CONFIG;
- while(fastd_config_push_parse(ps, token, &token_val, ctx, conf, depth+1) == YYPUSH_MORE) {
- token = fastd_config_yylex(&token_val, scanner);
+ while(fastd_config_push_parse(ps, token, &token_val, &loc, ctx, conf, filename, depth+1) == YYPUSH_MORE) {
+ token = fastd_config_yylex(&token_val, &loc, scanner);
if (token < 0)
- exit_error(ctx, "config error: %s", token_val.str);
+ exit_error(ctx, "config error: %s at %s:%i:%i", token_val.str, filename, loc.first_line, loc.first_column);
}
fastd_config_pstate_delete(ps);
diff --git a/src/config.l b/src/config.l
index eeb20ae..f232aee 100644
--- a/src/config.l
+++ b/src/config.l
@@ -27,6 +27,7 @@
%option prefix="fastd_config_yy"
%option noyywrap
%option bison-bridge
+%option bison-locations
%option reentrant
%top {
@@ -38,27 +39,37 @@
%s COMMENT
%%
+%{
+ #define UPDATE_LOCATION do { \
+ yylloc->first_line = yylloc->last_line; \
+ yylloc->first_column = yylloc->last_column+1; \
+ yylloc->last_column += yyleng; \
+ } while (0)
+%}
+
<INITIAL>{
-[0-9]+ { yylval->num = atoi(yytext); return TOK_INTEGER; }
-
-interface { return TOK_INTERFACE; }
-bind { return TOK_BIND; }
-mtu { return TOK_MTU; }
-mode { return TOK_MODE; }
-protocol { return TOK_PROTOCOL; }
-peer { return TOK_PEER; }
-address { return TOK_ADDRESS; }
-secret { return TOK_SECRET; }
-key { return TOK_KEY; }
-include { return TOK_INCLUDE; }
-as { return TOK_AS; }
-any { return TOK_ANY; }
-tap { return TOK_TAP; }
-tun { return TOK_TUN; }
-on { return TOK_ON; }
-up { return TOK_UP; }
+[0-9]+ { UPDATE_LOCATION; yylval->num = atoi(yytext); return TOK_INTEGER; }
+
+interface { UPDATE_LOCATION; return TOK_INTERFACE; }
+bind { UPDATE_LOCATION; return TOK_BIND; }
+mtu { UPDATE_LOCATION; return TOK_MTU; }
+mode { UPDATE_LOCATION; return TOK_MODE; }
+protocol { UPDATE_LOCATION; return TOK_PROTOCOL; }
+peer { UPDATE_LOCATION; return TOK_PEER; }
+address { UPDATE_LOCATION; return TOK_ADDRESS; }
+secret { UPDATE_LOCATION; return TOK_SECRET; }
+key { UPDATE_LOCATION; return TOK_KEY; }
+include { UPDATE_LOCATION; return TOK_INCLUDE; }
+as { UPDATE_LOCATION; return TOK_AS; }
+any { UPDATE_LOCATION; return TOK_ANY; }
+tap { UPDATE_LOCATION; return TOK_TAP; }
+tun { UPDATE_LOCATION; return TOK_TUN; }
+on { UPDATE_LOCATION; return TOK_ON; }
+up { UPDATE_LOCATION; return TOK_UP; }
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
+ UPDATE_LOCATION;
+
if (!inet_pton(AF_INET, yytext, &yylval->addr)) {
yylval->str = "invalid address";
return -1;
@@ -67,14 +78,17 @@ up { return TOK_UP; }
return TOK_ADDR;
}
-[;:\{\}] { return yytext[0]; }
+[;:\{\}] { UPDATE_LOCATION; return yytext[0]; }
-[ \t\n] ;
+[ \t] { yylloc->last_column++; }
+\n { yylloc->last_column = 0; yylloc->last_line++; }
}
-<INITIAL>\" BEGIN(STRING);
-<STRING>[^"\\]* yymore();
-<STRING>\\(.|\n) yymore();
+<INITIAL>\" { UPDATE_LOCATION; BEGIN(STRING); }
+<STRING>[^"\\\n] { yylloc->last_column++; yymore(); }
+<STRING>\n { yylloc->last_line++; yylloc->last_column = 0; yymore(); }
+<STRING>\\. { yylloc->last_column+=2; yymore(); }
+<STRING>\\\n { yylloc->last_line++; yylloc->last_column = 0; yymore(); }
<STRING>\" {
int i, esc = 0;
@@ -87,29 +101,32 @@ up { return TOK_UP; }
yytext[yyleng-esc-1] = 0;
yylval->str = strdup(yytext);
BEGIN(INITIAL);
+ yylloc->last_column++;
return TOK_STRING;
}
-<INITIAL>\[ BEGIN(ADDR6);
-<ADDR6>[^\]]+ {
+<INITIAL>\[ { UPDATE_LOCATION; BEGIN(ADDR6); }
+<ADDR6>[0-9a-fA-F:]+ {
+ yylloc->last_column += yyleng;
if (!inet_pton(AF_INET6, yytext, &yylval->addr6)) {
yylval->str = "invalid address";
return -1;
}
-
- return TOK_ADDR6;
}
-<ADDR6>\] BEGIN(INITIAL);
+<ADDR6>\] { yylloc->last_column++; BEGIN(INITIAL); return TOK_ADDR6; }
-<INITIAL>#.* /* ignore */
-<INITIAL>\/\/.* /* ignore */
+<INITIAL>#.* { yylloc->last_column += yyleng; }
+<INITIAL>\/\/.* { yylloc->last_column += yyleng; }
-<INITIAL>\/\* BEGIN(COMMENT);
-<COMMENT>\*\/ BEGIN(INITIAL);
-<COMMENT>.|\n /* ignore everything */
+<INITIAL>\/\* { UPDATE_LOCATION; BEGIN(COMMENT); }
+<COMMENT>\*\/ { yylloc->last_column += yyleng; BEGIN(INITIAL); }
+<COMMENT>. { yylloc->last_column++; }
+<COMMENT>\n { yylloc->last_line++; yylloc->last_column = 0; }
. {
+ yylloc->first_line = yylloc->last_line;
+ yylloc->first_column = yylloc->last_column+1;
yylval->str = "invalid character";
return -1;
}
diff --git a/src/config.y b/src/config.y
index 78c0833..1e75da8 100644
--- a/src/config.y
+++ b/src/config.y
@@ -27,8 +27,10 @@
%define api.pure
%define api.push-pull push
%name-prefix "fastd_config_"
+%locations
%parse-param {fastd_context *ctx}
%parse-param {fastd_config *conf}
+%parse-param {const char *filename}
%parse-param {int depth}
%code requires {
@@ -78,7 +80,7 @@
#include <stdint.h>
#include <peer.h>
- void fastd_config_error(fastd_context *ctx, fastd_config *conf, int depth, char *s);
+ void fastd_config_error(YYLTYPE *loc, fastd_context *ctx, fastd_config *conf, const char *filename, int depth, char *s);
extern fastd_protocol fastd_protocol_null;
@@ -237,6 +239,6 @@ port: TOK_INTEGER {
}
;
%%
-void fastd_config_error(fastd_context *ctx, fastd_config *conf, int depth, char *s) {
- exit_error(ctx, "config error: %s", s);
+void fastd_config_error(YYLTYPE *loc, fastd_context *ctx, fastd_config *conf, const char *filename, int depth, char *s) {
+ exit_error(ctx, "config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column);
}