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 2060
 			{ $$=mk_rve2( $2, $1, $3);}
2058 2061
 		| rval_expr LOG_AND rval_expr	{ $$=mk_rve2(RVE_LAND_OP, $1, $3);}
2059 2062
 		| rval_expr LOG_OR rval_expr	{ $$=mk_rve2(RVE_LOR_OP, $1, $3);}
2060
-		| LPAREN rval_expr RPAREN		{ $$=$2; }
2063
+		| LPAREN rval_expr RPAREN		{ $$=$2;}
2061 2064
 		| rve_un_op %prec NOT error		{ yyerror("bad expression"); }
2062 2065
 		| rval_expr PLUS error			{ yyerror("bad expression"); }
2063 2066
 		| rval_expr MINUS error			{ yyerror("bad expression"); }
... ...
@@ -2551,6 +2554,16 @@ extern int column;
2551 2554
 extern int startcolumn;
2552 2555
 extern int startline;
2553 2556
 
2557
+
2558
+static void get_cpos(struct cfg_pos* pos)
2559
+{
2560
+	pos->s_line=startline;
2561
+	pos->e_line=line;
2562
+	pos->s_col=startcolumn;
2563
+	pos->e_col=column-1;
2564
+}
2565
+
2566
+
2554 2567
 static void warn(char* s)
2555 2568
 {
2556 2569
 	if (line!=startline)
... ...
@@ -2564,7 +2577,7 @@ static void warn(char* s)
2564 2577
 	cfg_warnings++;
2565 2578
 }
2566 2579
 
2567
-static void yyerror(char* format, ...)
2580
+static void yyerror_at(struct cfg_pos* p, char* format, ...)
2568 2581
 {
2569 2582
 	va_list ap;
2570 2583
 	char s[256];
... ...
@@ -2572,19 +2585,53 @@ static void yyerror(char* format, ...)
2572 2585
 	va_start(ap, format);
2573 2586
 	vsnprintf(s, sizeof(s), format, ap);
2574 2587
 	va_end(ap);
2575
-	if (line!=startline)
2588
+	if (p->e_line!=p->s_line)
2576 2589
 		LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d-%d,%d): %s\n", 
2577
-					startline, startcolumn, line, column-1, s);
2578
-	else if (startcolumn!=(column-1))
2590
+					p->s_line, p->s_col, p->e_line, p->e_col, s);
2591
+	else if (p->s_col!=p->e_col)
2579 2592
 		LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d-%d): %s\n", 
2580
-					startline, startcolumn, column-1, s);
2593
+					p->s_line, p->s_col, p->e_col, s);
2581 2594
 	else
2582 2595
 		LOG(L_CRIT, "*** PARSE ERROR *** (%d,%d): %s\n", 
2583
-					startline, startcolumn, s);
2596
+					p->s_line, p->s_col, s);
2584 2597
 	cfg_errors++;
2585 2598
 }
2586 2599
 
2587 2600
 
2601
+static void yyerror(char* format, ...)
2602
+{
2603
+	va_list ap;
2604
+	char s[256];
2605
+	struct cfg_pos pos;
2606
+	
2607
+	get_cpos(&pos);
2608
+	va_start(ap, format);
2609
+	vsnprintf(s, sizeof(s), format, ap);
2610
+	va_end(ap);
2611
+	yyerror_at(&pos, s);
2612
+}
2613
+
2614
+
2615
+
2616
+static void get_rve2_pos(struct cfg_pos* res,
2617
+							struct cfg_pos* pos1, struct cfg_pos* pos2)
2618
+{
2619
+	*res=*pos1;
2620
+	if ((res->s_line == 0) || (res->s_line > pos2->s_line)){
2621
+		res->s_line=pos2->s_line;
2622
+		res->s_col=pos2->s_col;
2623
+	}else if ((res->s_line == pos2->s_line) && (res->s_col > pos2->s_col)){
2624
+		res->s_col=pos2->s_col;
2625
+	}
2626
+	if ((res->e_line == 0) || (res->e_line < pos2->e_line)){
2627
+		res->e_line=pos2->e_line;
2628
+		res->e_col=pos2->e_col;
2629
+	}else if ((res->e_line == pos2->e_line) && (res->e_col < pos2->e_col)){
2630
+		res->e_col=pos2->e_col;
2631
+	}
2632
+}
2633
+
2634
+
2588 2635
 /** mk_rval_expr_v wrapper.
2589 2636
  *  checks mk_rval_expr_v return value and sets the cfg. pos
2590 2637
  *  (line and column numbers)
... ...
@@ -2593,8 +2640,10 @@ static void yyerror(char* format, ...)
2593 2640
 static struct rval_expr* mk_rve_rval(enum rval_type type, void* v)
2594 2641
 {
2595 2642
 	struct rval_expr* ret;
2643
+	struct cfg_pos pos;
2596 2644
 
2597
-	ret=mk_rval_expr_v(type, v);
2645
+	get_cpos(&pos);
2646
+	ret=mk_rval_expr_v(type, v, &pos);
2598 2647
 	if (ret==0){
2599 2648
 		yyerror("internal error: failed to create rval expr");
2600 2649
 		/* YYABORT; */
... ...
@@ -2613,10 +2662,13 @@ static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1)
2613 2662
 	struct rval_expr* bad_rve;
2614 2663
 	enum rval_type type, bad_t, exp_t;
2615 2664
 	
2616
-	ret=mk_rval_expr1(op, rve1);
2665
+	if (rve1==0)
2666
+		return 0;
2667
+	ret=mk_rval_expr1(op, rve1, &rve1->fpos);
2617 2668
 	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));
2669
+		yyerror_at(&rve1->fpos, "bad expression: type mismatch"
2670
+					" (%s instead of %s)", rval_type_name(bad_t),
2671
+					rval_type_name(exp_t));
2620 2672
 	}
2621 2673
 	return ret;
2622 2674
 }
... ...
@@ -2631,21 +2683,18 @@ static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
2631 2683
 {
2632 2684
 	struct rval_expr* ret;
2633 2685
 	struct rval_expr* bad_rve;
2634
-	enum rval_type type, type1, type2, bad_t, exp_t;
2686
+	enum rval_type type, bad_t, exp_t;
2687
+	struct cfg_pos pos;
2635 2688
 	
2636
-	ret=mk_rval_expr2(op, rve1, rve2);
2689
+	if ((rve1==0) || (rve2==0))
2690
+		return 0;
2691
+	get_rve2_pos(&pos, &rve1->fpos, &rve2->fpos);
2692
+	ret=mk_rval_expr2(op, rve1, rve2, &pos);
2637 2693
 	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));
2694
+		yyerror_at(&pos, "bad expression: type mismatch:"
2695
+						" %s instead of %s at (%d,%d)",
2696
+						rval_type_name(bad_t), rval_type_name(exp_t),
2697
+						bad_rve->fpos.s_line, bad_rve->fpos.s_col);
2649 2698
 	}
2650 2699
 	return ret;
2651 2700
 }
... ...
@@ -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 1651
 	}
1650 1652
 	rval_init(&rve->left.rval, rv_type, &v, flags);
1651 1653
 	rve->op=RVE_RVAL_OP;
1654
+	if (pos) rve->fpos=*pos;
1652 1655
 	return rve;
1653 1656
 }
1654 1657
 
... ...
@@ -1660,7 +1663,8 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val)
1660 1663
  * @param rve1 - rval expr. on which the operator will act.
1661 1664
  * @return new pkg_malloc'ed rval_expr or 0 on error.
1662 1665
  */
1663
-struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
1666
+struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
1667
+								struct cfg_pos* pos)
1664 1668
 {
1665 1669
 	struct rval_expr* ret;
1666 1670
 	
... ...
@@ -1679,6 +1683,7 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
1679 1683
 	memset(ret, sizeof(*ret), 0);
1680 1684
 	ret->op=op;
1681 1685
 	ret->left.rve=rve1;
1686
+	if (pos) ret->fpos=*pos;
1682 1687
 	return ret;
1683 1688
 }
1684 1689
 
... ...
@@ -1692,7 +1697,8 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1)
1692 1697
  * @return new pkg_malloc'ed rval_expr or 0 on error.
1693 1698
  */
1694 1699
 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
1695
-													  struct rval_expr* rve2)
1700
+													  struct rval_expr* rve2,
1701
+													  struct cfg_pos* pos)
1696 1702
 {
1697 1703
 	struct rval_expr* ret;
1698 1704
 	
... ...
@@ -1723,6 +1729,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
1723 1729
 	ret->op=op;
1724 1730
 	ret->left.rve=rve1;
1725 1731
 	ret->right.rve=rve2;
1732
+	if (pos) ret->fpos=*pos;
1726 1733
 	return ret;
1727 1734
 }
1728 1735
 
... ...
@@ -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 105
 		struct rval_expr* rve;
105 106
 		struct rvalue rval;
106 107
 	}right;
108
+	struct cfg_pos fpos;
107 109
 };
108 110
 
109 111
 
... ...
@@ -193,12 +195,15 @@ char* rval_type_name(enum rval_type type);
193 195
 
194 196
 /** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type
195 197
   */
196
-struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val);
198
+struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
199
+									struct cfg_pos* pos);
197 200
 /** create a unary op. rval_expr.. */
198
-struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1);
201
+struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
202
+									struct cfg_pos* pos);
199 203
 /** create a rval_expr. from 2 other rval exprs, using op. */
200 204
 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
201
-													  struct rval_expr* rve2);
205
+													  struct rval_expr* rve2,
206
+													  struct cfg_pos* pos);
202 207
 
203 208
 /** fix a rval_expr. */
204 209
 int fix_rval_expr(void** p);