diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-03-29 03:19:50 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-03-29 03:19:50 +0200 |
commit | eb0c48b789bbf41745287adb6b2949f84e7e9171 (patch) | |
tree | 212f1156670e2f600d958116738425caa35d815e | |
parent | aadf0a94b436990202cd2f13f1fe8528a9fd183c (diff) | |
download | fastd-eb0c48b789bbf41745287adb6b2949f84e7e9171.tar fastd-eb0c48b789bbf41745287adb6b2949f84e7e9171.zip |
Config parse: add location tracking for nice error messages
-rw-r--r-- | src/config.c | 7 | ||||
-rw-r--r-- | src/config.l | 83 | ||||
-rw-r--r-- | src/config.y | 8 |
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); } |