Module: sip-router
Branch: andrei/script_vars
Commit: 9a31872ccbd89266c5300a0f443f96b6a4934e6f
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9a31872…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Mon Dec 15 23:13:20 2008 +0100
script parsing: better expression error reporting
- report bad expression position on type mismatch
e.g.:
*** PARSE ERROR *** (42,8-18): bad expression: type
mismatch: str instead of int at (42,16)
---
cfg.y | 97 ++++++++++++++++++++++++++++++++++++++++++--------------
route_struct.h | 9 +++++
rvalue.c | 15 ++++++--
rvalue.h | 11 +++++--
4 files changed, 101 insertions(+), 31 deletions(-)
diff --git a/cfg.y b/cfg.y
index d6422f6..7ced7c1 100644
--- a/cfg.y
+++ b/cfg.y
@@ -200,6 +200,9 @@ static struct lvalue* lval_tmp;
static struct rvalue* rval_tmp;
static void warn(char* s);
+static void get_cpos(struct cfg_pos* pos);
+static void get_rve2_pos(struct cfg_pos* res,
+ struct cfg_pos* pos1, struct cfg_pos* pos2);
static struct rval_expr* mk_rve_rval(enum rval_type, void* v);
static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1);
static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
@@ -2057,7 +2060,7 @@ rval_expr: rval { $$=$1;
{ $$=mk_rve2( $2, $1, $3);}
| rval_expr LOG_AND rval_expr { $$=mk_rve2(RVE_LAND_OP, $1, $3);}
| rval_expr LOG_OR rval_expr { $$=mk_rve2(RVE_LOR_OP, $1, $3);}
- | LPAREN rval_expr RPAREN { $$=$2; }
+ | LPAREN rval_expr RPAREN { $$=$2;}
| rve_un_op %prec NOT error { yyerror("bad expression"); }
| rval_expr PLUS error { yyerror("bad expression"); }
| rval_expr MINUS error { yyerror("bad expression"); }
@@ -2551,6 +2554,16 @@ extern int column;
extern int startcolumn;
extern int startline;
+
+static void get_cpos(struct cfg_pos* pos)
+{
+ pos->s_line=startline;
+ pos->e_line=line;
+ pos->s_col=startcolumn;
+ pos->e_col=column-1;
+}
+
+
static void warn(char* s)
{
if (line!=startline)
@@ -2564,7 +2577,7 @@ static void warn(char* s)
cfg_warnings++;
}
-static void yyerror(char* format, ...)
+static void yyerror_at(struct cfg_pos* p, char* format, ...)
{
va_list ap;
char s[256];
@@ -2572,19 +2585,53 @@ static void yyerror(char* format, ...)
va_start(ap, format);
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
- if (line!=startline)
+ if (p->e_line!=p->s_line)
LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d-%d,%d): %s\n",
- startline, startcolumn, line, column-1, s);
- else if (startcolumn!=(column-1))
+ p->s_line, p->s_col, p->e_line, p->e_col, s);
+ else if (p->s_col!=p->e_col)
LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d-%d): %s\n",
- startline, startcolumn, column-1, s);
+ p->s_line, p->s_col, p->e_col, s);
else
LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d): %s\n",
- startline, startcolumn, s);
+ p->s_line, p->s_col, s);
cfg_errors++;
}
+static void yyerror(char* format, ...)
+{
+ va_list ap;
+ char s[256];
+ struct cfg_pos pos;
+
+ get_cpos(&pos);
+ va_start(ap, format);
+ vsnprintf(s, sizeof(s), format, ap);
+ va_end(ap);
+ yyerror_at(&pos, s);
+}
+
+
+
+static void get_rve2_pos(struct cfg_pos* res,
+ struct cfg_pos* pos1, struct cfg_pos* pos2)
+{
+ *res=*pos1;
+ if ((res->s_line == 0) || (res->s_line > pos2->s_line)){
+ res->s_line=pos2->s_line;
+ res->s_col=pos2->s_col;
+ }else if ((res->s_line == pos2->s_line) && (res->s_col >
pos2->s_col)){
+ res->s_col=pos2->s_col;
+ }
+ if ((res->e_line == 0) || (res->e_line < pos2->e_line)){
+ res->e_line=pos2->e_line;
+ res->e_col=pos2->e_col;
+ }else if ((res->e_line == pos2->e_line) && (res->e_col <
pos2->e_col)){
+ res->e_col=pos2->e_col;
+ }
+}
+
+
/** mk_rval_expr_v wrapper.
* checks mk_rval_expr_v return value and sets the cfg. pos
* (line and column numbers)
@@ -2593,8 +2640,10 @@ static void yyerror(char* format, ...)
static struct rval_expr* mk_rve_rval(enum rval_type type, void* v)
{
struct rval_expr* ret;
+ struct cfg_pos pos;
- ret=mk_rval_expr_v(type, v);
+ get_cpos(&pos);
+ ret=mk_rval_expr_v(type, v, &pos);
if (ret==0){
yyerror("internal error: failed to create rval expr");
/* YYABORT; */
@@ -2613,10 +2662,13 @@ static struct rval_expr* mk_rve1(enum rval_expr_op op, struct
rval_expr* rve1)
struct rval_expr* bad_rve;
enum rval_type type, bad_t, exp_t;
- ret=mk_rval_expr1(op, rve1);
+ if (rve1==0)
+ return 0;
+ ret=mk_rval_expr1(op, rve1, &rve1->fpos);
if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t,
&exp_t)!=1)){
- yyerror("bad expression: type mismatch (%s instead of %s)",
- rval_type_name(bad_t), rval_type_name(exp_t));
+ yyerror_at(&rve1->fpos, "bad expression: type mismatch"
+ " (%s instead of %s)", rval_type_name(bad_t),
+ rval_type_name(exp_t));
}
return ret;
}
@@ -2631,21 +2683,18 @@ static struct rval_expr* mk_rve2(enum rval_expr_op op, struct
rval_expr* rve1,
{
struct rval_expr* ret;
struct rval_expr* bad_rve;
- enum rval_type type, type1, type2, bad_t, exp_t;
+ enum rval_type type, bad_t, exp_t;
+ struct cfg_pos pos;
- ret=mk_rval_expr2(op, rve1, rve2);
+ if ((rve1==0) || (rve2==0))
+ return 0;
+ get_rve2_pos(&pos, &rve1->fpos, &rve2->fpos);
+ ret=mk_rval_expr2(op, rve1, rve2, &pos);
if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t,
&exp_t)!=1)){
- if (rve_check_type(&type1, rve1, &bad_rve, &bad_t, &exp_t)!=1)
- yyerror("bad expression: left side type mismatch"
- " (%s instead of %s)",
- rval_type_name(bad_t), rval_type_name(exp_t));
- else if (rve_check_type(&type2, rve2, &bad_rve, &bad_t, &exp_t)!=1)
- yyerror("bad expression: right side type mismatch"
- " (%s instead of %s)",
- rval_type_name(bad_t), rval_type_name(exp_t));
- else
- yyerror("bad expression: type mismatch (%s instead of %s)",
- rval_type_name(bad_t), rval_type_name(exp_t));
+ yyerror_at(&pos, "bad expression: type mismatch:"
+ " %s instead of %s at (%d,%d)",
+ rval_type_name(bad_t), rval_type_name(exp_t),
+ bad_rve->fpos.s_line, bad_rve->fpos.s_col);
}
return ret;
}
diff --git a/route_struct.h b/route_struct.h
index c27fef2..ba5046e 100644
--- a/route_struct.h
+++ b/route_struct.h
@@ -102,6 +102,15 @@ enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST,
PROXY_ST,
#define EXIT_R_F 1
#define RETURN_R_F 2
+
+struct cfg_pos{
+ int s_line;
+ int e_line;
+ unsigned short s_col;
+ unsigned short e_col;
+};
+
+
/* Expression operand */
union exp_op {
void* param;
diff --git a/rvalue.c b/rvalue.c
index c637dec..6f9b118 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -543,7 +543,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
if (rve_check_type(&type2, rve->right.rve, bad_rve,
bad_t, exp_t)){
if (type2==RV_STR){
- if (bad_rve) *bad_rve=rve->left.rve;
+ if (bad_rve) *bad_rve=rve->right.rve;
if (bad_t) *bad_t=type2;
if (exp_t) *exp_t=RV_INT;
return 0;
@@ -1597,9 +1597,11 @@ error:
*
* @param rv_type - rval type
* @param val - rval value
+ * @param pos - config position
* @return new pkg_malloc'ed rval_expr or 0 on error.
*/
-struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
+struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
+ struct cfg_pos* pos)
{
struct rval_expr* rve;
union rval_val v;
@@ -1649,6 +1651,7 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
}
rval_init(&rve->left.rval, rv_type, &v, flags);
rve->op=RVE_RVAL_OP;
+ if (pos) rve->fpos=*pos;
return rve;
}
@@ -1660,7 +1663,8 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
* @param rve1 - rval expr. on which the operator will act.
* @return new pkg_malloc'ed rval_expr or 0 on error.
*/
-struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
+struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
+ struct cfg_pos* pos)
{
struct rval_expr* ret;
@@ -1679,6 +1683,7 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct
rval_expr* rve1)
memset(ret, sizeof(*ret), 0);
ret->op=op;
ret->left.rve=rve1;
+ if (pos) ret->fpos=*pos;
return ret;
}
@@ -1692,7 +1697,8 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct
rval_expr* rve1)
* @return new pkg_malloc'ed rval_expr or 0 on error.
*/
struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
- struct rval_expr* rve2)
+ struct rval_expr* rve2,
+ struct cfg_pos* pos)
{
struct rval_expr* ret;
@@ -1723,6 +1729,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct
rval_expr* rve1,
ret->op=op;
ret->left.rve=rve1;
ret->right.rve=rve2;
+ if (pos) ret->fpos=*pos;
return ret;
}
diff --git a/rvalue.h b/rvalue.h
index 5a1c10b..f36f189 100644
--- a/rvalue.h
+++ b/rvalue.h
@@ -94,6 +94,7 @@ struct rvalue{
#define RV_RV_ALLOCED_F 2 /* free rv itself (pkg_free(rv)) */
#define RV_ALL_ALLOCED_F (RV_CNT_ALLOCED|RV_RV_ALLOCED)
+
struct rval_expr{
enum rval_expr_op op;
union{
@@ -104,6 +105,7 @@ struct rval_expr{
struct rval_expr* rve;
struct rvalue rval;
}right;
+ struct cfg_pos fpos;
};
@@ -193,12 +195,15 @@ char* rval_type_name(enum rval_type type);
/** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type
*/
-struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val);
+struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
+ struct cfg_pos* pos);
/** create a unary op. rval_expr.. */
-struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1);
+struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
+ struct cfg_pos* pos);
/** create a rval_expr. from 2 other rval exprs, using op. */
struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
- struct rval_expr* rve2);
+ struct rval_expr* rve2,
+ struct cfg_pos* pos);
/** fix a rval_expr. */
int fix_rval_expr(void** p);