Browse code

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)

Andrei Pelinescu-Onciul authored on 15/12/2008 22:13:20
Showing 4 changed files
... ...
@@ -200,6 +200,9 @@ static struct lvalue* lval_tmp;
200 200
 static struct rvalue* rval_tmp;
201 201
 
202 202
 static void warn(char* s);
203
+static void get_cpos(struct cfg_pos* pos);
204
+static void get_rve2_pos(struct cfg_pos* res,
205
+							struct cfg_pos* pos1, struct cfg_pos* pos2);
203 206
 static struct rval_expr* mk_rve_rval(enum rval_type, void* v);
204 207
 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1);
205 208
 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
... ...
@@ -2057,7 +2060,7 @@ rval_expr: rval						{ $$=$1;
2057 2057
 			{ $$=mk_rve2( $2, $1, $3);}
2058 2058
 		| rval_expr LOG_AND rval_expr	{ $$=mk_rve2(RVE_LAND_OP, $1, $3);}
2059 2059
 		| rval_expr LOG_OR rval_expr	{ $$=mk_rve2(RVE_LOR_OP, $1, $3);}
2060
-		| LPAREN rval_expr RPAREN		{ $$=$2; }
2060
+		| LPAREN rval_expr RPAREN		{ $$=$2;}
2061 2061
 		| rve_un_op %prec NOT error		{ yyerror("bad expression"); }
2062 2062
 		| rval_expr PLUS error			{ yyerror("bad expression"); }
2063 2063
 		| rval_expr MINUS error			{ yyerror("bad expression"); }
... ...
@@ -2551,6 +2554,16 @@ extern int column;
2551 2551
 extern int startcolumn;
2552 2552
 extern int startline;
2553 2553
 
2554
+
2555
+static void get_cpos(struct cfg_pos* pos)
2556
+{
2557
+	pos->s_line=startline;
2558
+	pos->e_line=line;
2559
+	pos->s_col=startcolumn;
2560
+	pos->e_col=column-1;
2561
+}
2562
+
2563
+
2554 2564
 static void warn(char* s)
2555 2565
 {
2556 2566
 	if (line!=startline)
... ...
@@ -2564,7 +2577,7 @@ static void warn(char* s)
2564 2564
 	cfg_warnings++;
2565 2565
 }
2566 2566
 
2567
-static void yyerror(char* format, ...)
2567
+static void yyerror_at(struct cfg_pos* p, char* format, ...)
2568 2568
 {
2569 2569
 	va_list ap;
2570 2570
 	char s[256];
... ...
@@ -2572,19 +2585,53 @@ static void yyerror(char* format, ...)
2572 2572
 	va_start(ap, format);
2573 2573
 	vsnprintf(s, sizeof(s), format, ap);
2574 2574
 	va_end(ap);
2575
-	if (line!=startline)
2575
+	if (p->e_line!=p->s_line)
2576 2576
 		LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d-%d,%d): %s\n", 
2577
-					startline, startcolumn, line, column-1, s);
2578
-	else if (startcolumn!=(column-1))
2577
+					p->s_line, p->s_col, p->e_line, p->e_col, s);
2578
+	else if (p->s_col!=p->e_col)
2579 2579
 		LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d-%d): %s\n", 
2580
-					startline, startcolumn, column-1, s);
2580
+					p->s_line, p->s_col, p->e_col, s);
2581 2581
 	else
2582 2582
 		LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d): %s\n", 
2583
-					startline, startcolumn, s);
2583
+					p->s_line, p->s_col, s);
2584 2584
 	cfg_errors++;
2585 2585
 }
2586 2586
 
2587 2587
 
2588
+static void yyerror(char* format, ...)
2589
+{
2590
+	va_list ap;
2591
+	char s[256];
2592
+	struct cfg_pos pos;
2593
+	
2594
+	get_cpos(&pos);
2595
+	va_start(ap, format);
2596
+	vsnprintf(s, sizeof(s), format, ap);
2597
+	va_end(ap);
2598
+	yyerror_at(&pos, s);
2599
+}
2600
+
2601
+
2602
+
2603
+static void get_rve2_pos(struct cfg_pos* res,
2604
+							struct cfg_pos* pos1, struct cfg_pos* pos2)
2605
+{
2606
+	*res=*pos1;
2607
+	if ((res->s_line == 0) || (res->s_line > pos2->s_line)){
2608
+		res->s_line=pos2->s_line;
2609
+		res->s_col=pos2->s_col;
2610
+	}else if ((res->s_line == pos2->s_line) && (res->s_col > pos2->s_col)){
2611
+		res->s_col=pos2->s_col;
2612
+	}
2613
+	if ((res->e_line == 0) || (res->e_line < pos2->e_line)){
2614
+		res->e_line=pos2->e_line;
2615
+		res->e_col=pos2->e_col;
2616
+	}else if ((res->e_line == pos2->e_line) && (res->e_col < pos2->e_col)){
2617
+		res->e_col=pos2->e_col;
2618
+	}
2619
+}
2620
+
2621
+
2588 2622
 /** mk_rval_expr_v wrapper.
2589 2623
  *  checks mk_rval_expr_v return value and sets the cfg. pos
2590 2624
  *  (line and column numbers)
... ...
@@ -2593,8 +2640,10 @@ static void yyerror(char* format, ...)
2593 2593
 static struct rval_expr* mk_rve_rval(enum rval_type type, void* v)
2594 2594
 {
2595 2595
 	struct rval_expr* ret;
2596
+	struct cfg_pos pos;
2596 2597
 
2597
-	ret=mk_rval_expr_v(type, v);
2598
+	get_cpos(&pos);
2599
+	ret=mk_rval_expr_v(type, v, &pos);
2598 2600
 	if (ret==0){
2599 2601
 		yyerror("internal error: failed to create rval expr");
2600 2602
 		/* YYABORT; */
... ...
@@ -2613,10 +2662,13 @@ static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1)
2613 2613
 	struct rval_expr* bad_rve;
2614 2614
 	enum rval_type type, bad_t, exp_t;
2615 2615
 	
2616
-	ret=mk_rval_expr1(op, rve1);
2616
+	if (rve1==0)
2617
+		return 0;
2618
+	ret=mk_rval_expr1(op, rve1, &rve1->fpos);
2617 2619
 	if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
2618
-		yyerror("bad expression: type mismatch (%s instead of %s)",
2619
-					rval_type_name(bad_t), rval_type_name(exp_t));
2620
+		yyerror_at(&rve1->fpos, "bad expression: type mismatch"
2621
+					" (%s instead of %s)", rval_type_name(bad_t),
2622
+					rval_type_name(exp_t));
2620 2623
 	}
2621 2624
 	return ret;
2622 2625
 }
... ...
@@ -2631,21 +2683,18 @@ static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
2631 2631
 {
2632 2632
 	struct rval_expr* ret;
2633 2633
 	struct rval_expr* bad_rve;
2634
-	enum rval_type type, type1, type2, bad_t, exp_t;
2634
+	enum rval_type type, bad_t, exp_t;
2635
+	struct cfg_pos pos;
2635 2636
 	
2636
-	ret=mk_rval_expr2(op, rve1, rve2);
2637
+	if ((rve1==0) || (rve2==0))
2638
+		return 0;
2639
+	get_rve2_pos(&pos, &rve1->fpos, &rve2->fpos);
2640
+	ret=mk_rval_expr2(op, rve1, rve2, &pos);
2637 2641
 	if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
2638
-		if (rve_check_type(&type1, rve1, &bad_rve, &bad_t, &exp_t)!=1)
2639
-			yyerror("bad expression: left side type mismatch"
2640
-					" (%s instead of %s)",
2641
-					rval_type_name(bad_t), rval_type_name(exp_t));
2642
-		else if (rve_check_type(&type2, rve2, &bad_rve, &bad_t, &exp_t)!=1)
2643
-			yyerror("bad expression: right side type mismatch"
2644
-					" (%s instead of %s)",
2645
-					rval_type_name(bad_t), rval_type_name(exp_t));
2646
-		else
2647
-			yyerror("bad expression: type mismatch (%s instead of %s)",
2648
-					rval_type_name(bad_t), rval_type_name(exp_t));
2642
+		yyerror_at(&pos, "bad expression: type mismatch:"
2643
+						" %s instead of %s at (%d,%d)",
2644
+						rval_type_name(bad_t), rval_type_name(exp_t),
2645
+						bad_rve->fpos.s_line, bad_rve->fpos.s_col);
2649 2646
 	}
2650 2647
 	return ret;
2651 2648
 }
... ...
@@ -102,6 +102,15 @@ enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
102 102
 #define EXIT_R_F   1
103 103
 #define RETURN_R_F 2
104 104
 
105
+
106
+struct cfg_pos{
107
+	int s_line;
108
+	int e_line;
109
+	unsigned short s_col;
110
+	unsigned short e_col;
111
+};
112
+
113
+
105 114
 /* Expression operand */
106 115
 union exp_op {
107 116
 	void* param;
... ...
@@ -543,7 +543,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
543 543
 				if (rve_check_type(&type2, rve->right.rve, bad_rve,
544 544
 									bad_t, exp_t)){
545 545
 					if (type2==RV_STR){
546
-						if (bad_rve) *bad_rve=rve->left.rve;
546
+						if (bad_rve) *bad_rve=rve->right.rve;
547 547
 						if (bad_t) *bad_t=type2;
548 548
 						if (exp_t) *exp_t=RV_INT;
549 549
 						return 0;
... ...
@@ -1597,9 +1597,11 @@ error:
1597 1597
  *
1598 1598
  * @param rv_type - rval type
1599 1599
  * @param val     - rval value
1600
+ * @param pos     - config position
1600 1601
  * @return new pkg_malloc'ed rval_expr or 0 on error.
1601 1602
  */
1602
-struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
1603
+struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val, 
1604
+									struct cfg_pos* pos)
1603 1605
 {
1604 1606
 	struct rval_expr* rve;
1605 1607
 	union rval_val v;
... ...
@@ -1649,6 +1651,7 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
1649 1649
 	}
1650 1650
 	rval_init(&rve->left.rval, rv_type, &v, flags);
1651 1651
 	rve->op=RVE_RVAL_OP;
1652
+	if (pos) rve->fpos=*pos;
1652 1653
 	return rve;
1653 1654
 }
1654 1655
 
... ...
@@ -1660,7 +1663,8 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
1660 1660
  * @param rve1 - rval expr. on which the operator will act.
1661 1661
  * @return new pkg_malloc'ed rval_expr or 0 on error.
1662 1662
  */
1663
-struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
1663
+struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
1664
+								struct cfg_pos* pos)
1664 1665
 {
1665 1666
 	struct rval_expr* ret;
1666 1667
 	
... ...
@@ -1679,6 +1683,7 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
1679 1679
 	memset(ret, sizeof(*ret), 0);
1680 1680
 	ret->op=op;
1681 1681
 	ret->left.rve=rve1;
1682
+	if (pos) ret->fpos=*pos;
1682 1683
 	return ret;
1683 1684
 }
1684 1685
 
... ...
@@ -1692,7 +1697,8 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
1692 1692
  * @return new pkg_malloc'ed rval_expr or 0 on error.
1693 1693
  */
1694 1694
 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
1695
-													  struct rval_expr* rve2)
1695
+													  struct rval_expr* rve2,
1696
+													  struct cfg_pos* pos)
1696 1697
 {
1697 1698
 	struct rval_expr* ret;
1698 1699
 	
... ...
@@ -1723,6 +1729,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
1723 1723
 	ret->op=op;
1724 1724
 	ret->left.rve=rve1;
1725 1725
 	ret->right.rve=rve2;
1726
+	if (pos) ret->fpos=*pos;
1726 1727
 	return ret;
1727 1728
 }
1728 1729
 
... ...
@@ -94,6 +94,7 @@ struct rvalue{
94 94
 #define RV_RV_ALLOCED_F   2  /* free rv itself (pkg_free(rv)) */
95 95
 #define RV_ALL_ALLOCED_F  (RV_CNT_ALLOCED|RV_RV_ALLOCED)
96 96
 
97
+
97 98
 struct rval_expr{
98 99
 	enum rval_expr_op op;
99 100
 	union{
... ...
@@ -104,6 +105,7 @@ struct rval_expr{
104 104
 		struct rval_expr* rve;
105 105
 		struct rvalue rval;
106 106
 	}right;
107
+	struct cfg_pos fpos;
107 108
 };
108 109
 
109 110
 
... ...
@@ -193,12 +195,15 @@ char* rval_type_name(enum rval_type type);
193 193
 
194 194
 /** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type
195 195
   */
196
-struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val);
196
+struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
197
+									struct cfg_pos* pos);
197 198
 /** create a unary op. rval_expr.. */
198
-struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1);
199
+struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
200
+									struct cfg_pos* pos);
199 201
 /** create a rval_expr. from 2 other rval exprs, using op. */
200 202
 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
201
-													  struct rval_expr* rve2);
203
+													  struct rval_expr* rve2,
204
+													  struct cfg_pos* pos);
202 205
 
203 206
 /** fix a rval_expr. */
204 207
 int fix_rval_expr(void** p);