Browse code

script parsing: while support

- while() support
- improved config warning functions

Andrei Pelinescu-Onciul authored on 10/02/2009 21:39:01
Showing 3 changed files
... ...
@@ -17,6 +17,10 @@ config script changes:
17 17
       #!MAXCOMPAT
18 18
     where #!KAMAILIO is equivalent with #!OPENSER and #!ALL with #!MAXCOMPAT
19 19
   - support for kamailio style pvars
20
+  - C-like switch()/case (integer only)
21
+  - while()
22
+  - max_while_loops - maximum iterations allowed for a while, can be changed
23
+    at runtime. Default 100.
20 24
 
21 25
 
22 26
 
... ...
@@ -190,6 +190,7 @@ FORCE_SEND_SOCKET	"force_send_socket"
190 190
 SWITCH			"switch"
191 191
 CASE			"case"
192 192
 DEFAULT			"default"
193
+WHILE			"while"
193 194
 
194 195
 /*ACTION LVALUES*/
195 196
 URIHOST			"uri:host"
... ...
@@ -375,6 +376,7 @@ MCAST_TTL		"mcast_ttl"
375 376
 TOS			"tos"
376 377
 PMTU_DISCOVERY	"pmtu_discovery"
377 378
 KILL_TIMEOUT	"exit_timeout"|"ser_kill_timeout"
379
+MAX_WLOOPS		"max_while_loops"
378 380
 
379 381
 /* stun config variables */
380 382
 STUN_REFRESH_INTERVAL "stun_refresh_interval"
... ...
@@ -501,7 +503,7 @@ EAT_ABLE	[\ \t\b\r]
501 503
 <INITIAL>{SWITCH}	{ count(); yylval.strval=yytext; return SWITCH; }
502 504
 <INITIAL>{CASE}	{ count(); yylval.strval=yytext; return CASE; }
503 505
 <INITIAL>{DEFAULT}	{ count(); yylval.strval=yytext; return DEFAULT; }
504
-
506
+<INITIAL>{WHILE}	{ count(); yylval.strval=yytext; return WHILE; }
505 507
 
506 508
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
507 509
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
... ...
@@ -717,6 +719,8 @@ EAT_ABLE	[\ \t\b\r]
717 719
 									return PMTU_DISCOVERY; }
718 720
 <INITIAL>{KILL_TIMEOUT}			{	count(); yylval.strval=yytext;
719 721
 									return KILL_TIMEOUT; }
722
+<INITIAL>{MAX_WLOOPS}			{	count(); yylval.strval=yytext;
723
+									return MAX_WLOOPS; }
720 724
 <INITIAL>{SERVER_ID}  { count(); yylval.strval=yytext; return SERVER_ID;}
721 725
 <INITIAL>{CFG_DESCRIPTION}	{ count(); yylval.strval=yytext; return CFG_DESCRIPTION; }
722 726
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
... ...
@@ -184,6 +184,7 @@
184 184
 
185 185
 extern int yylex();
186 186
 static void yyerror(char* s, ...);
187
+static void yyerror_at(struct cfg_pos* pos, char* s, ...);
187 188
 static char* tmp;
188 189
 static int i_tmp;
189 190
 static unsigned u_tmp;
... ...
@@ -201,7 +202,8 @@ static struct action *mod_func_action;
201 202
 static struct lvalue* lval_tmp;
202 203
 static struct rvalue* rval_tmp;
203 204
 
204
-static void warn(char* s);
205
+static void warn(char* s, ...);
206
+static void warn_at(struct cfg_pos* pos, char* s, ...);
205 207
 static void get_cpos(struct cfg_pos* pos);
206 208
 static struct rval_expr* mk_rve_rval(enum rval_type, void* v);
207 209
 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1);
... ...
@@ -280,6 +282,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
280 282
 %token SWITCH
281 283
 %token CASE
282 284
 %token DEFAULT
285
+%token WHILE
283 286
 %token URIHOST
284 287
 %token URIPORT
285 288
 %token MAX_LEN
... ...
@@ -436,6 +439,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
436 439
 %token TOS
437 440
 %token PMTU_DISCOVERY
438 441
 %token KILL_TIMEOUT
442
+%token MAX_WLOOPS
439 443
 %token CFG_DESCRIPTION
440 444
 %token SERVER_ID
441 445
 
... ...
@@ -501,7 +505,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
501 505
 %type <intval> intno eint_op eint_op_onsend
502 506
 %type <intval> eip_op eip_op_onsend
503 507
 %type <action> action actions cmd fcmd if_cmd stm /*exp_stm*/ assign_action
504
-%type <action> switch_cmd
508
+%type <action> switch_cmd while_cmd
505 509
 %type <case_stms> single_case case_stms
506 510
 %type <ipaddr> ipv4 ipv6 ipv6addr ip
507 511
 %type <ipnet> ipnet
... ...
@@ -1283,6 +1287,8 @@ assign_stm:
1283 1287
 	| PMTU_DISCOVERY error { yyerror("number expected"); }
1284 1288
 	| KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
1285 1289
 	| KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
1290
+	| MAX_WLOOPS EQUAL NUMBER { default_core_cfg.max_while_loops=$3; }
1291
+	| MAX_WLOOPS EQUAL error { yyerror("number expected"); }
1286 1292
 	| STUN_REFRESH_INTERVAL EQUAL NUMBER { IF_STUN(stun_refresh_interval=$3); }
1287 1293
 	| STUN_REFRESH_INTERVAL EQUAL error{ yyerror("number expected"); }
1288 1294
 	| STUN_ALLOW_STUN EQUAL NUMBER { IF_STUN(stun_allow_stun=$3); }
... ...
@@ -1773,6 +1779,7 @@ action:
1773 1779
 	fcmd SEMICOLON {$$=$1;}
1774 1780
 	| if_cmd {$$=$1;}
1775 1781
 	| switch_cmd {$$=$1;}
1782
+	| while_cmd { $$=$1; }
1776 1783
 	| assign_action SEMICOLON {$$=$1;}
1777 1784
 	| SEMICOLON /* null action */ {$$=0;}
1778 1785
 	| fcmd error { $$=0; yyerror("bad command: missing ';'?"); }
... ...
@@ -1873,6 +1880,17 @@ switch_cmd:
1873 1880
 		{$$=0; yyerror ("bad switch body"); }
1874 1881
 ;
1875 1882
 
1883
+while_cmd:
1884
+	WHILE rval_expr stm {
1885
+		if ($2){
1886
+			if (rve_is_constant($2))
1887
+				warn_at(&$2->fpos, "constant value in while(...)");
1888
+		}else
1889
+			yyerror_at(&$2->fpos, "bad while(...) expression");
1890
+		$$=mk_action( WHILE_T, 2, RVE_ST, $2, ACTIONS_ST, $3);
1891
+	}
1892
+;
1893
+
1876 1894
 /* class_id:
1877 1895
 	LBRACK ATTR_USER RBRACK { $$ = AVP_CLASS_USER; }
1878 1896
 	| LBRACK ATTR_DOMAIN RBRACK { $$ = AVP_CLASS_DOMAIN; }
... ...
@@ -2665,19 +2683,28 @@ static void get_cpos(struct cfg_pos* pos)
2665 2683
 }
2666 2684
 
2667 2685
 
2668
-static void warn(char* s)
2686
+static void warn_at(struct cfg_pos* p, char* format, ...)
2669 2687
 {
2670
-	if (line!=startline)
2688
+	va_list ap;
2689
+	char s[256];
2690
+	
2691
+	va_start(ap, format);
2692
+	vsnprintf(s, sizeof(s), format, ap);
2693
+	va_end(ap);
2694
+	if (p->e_line!=p->s_line)
2671 2695
 		LOG(L_WARN, "cfg. warning: (%d,%d-%d,%d): %s\n",
2672
-					startline, startcolumn, line, column-1, s);
2673
-	else if (startcolumn!=(column-1))
2674
-		LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n", startline, startcolumn,
2675
-					column-1, s);
2696
+					p->s_line, p->s_col, p->e_line, p->e_col, s);
2697
+	else if (p->s_col!=p->e_col)
2698
+		LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n",
2699
+					p->s_line, p->s_col, p->e_col, s);
2676 2700
 	else
2677
-		LOG(L_WARN, "cfg. warning: (%d,%d): %s\n", startline, startcolumn, s);
2701
+		LOG(L_WARN, "cfg. warning: (%d,%d): %s\n",
2702
+				p->s_line, p->s_col, s);
2678 2703
 	cfg_warnings++;
2679 2704
 }
2680 2705
 
2706
+
2707
+
2681 2708
 static void yyerror_at(struct cfg_pos* p, char* format, ...)
2682 2709
 {
2683 2710
 	va_list ap;
... ...
@@ -2699,6 +2726,22 @@ static void yyerror_at(struct cfg_pos* p, char* format, ...)
2699 2726
 }
2700 2727
 
2701 2728
 
2729
+
2730
+static void warn(char* format, ...)
2731
+{
2732
+	va_list ap;
2733
+	char s[256];
2734
+	struct cfg_pos pos;
2735
+	
2736
+	get_cpos(&pos);
2737
+	va_start(ap, format);
2738
+	vsnprintf(s, sizeof(s), format, ap);
2739
+	va_end(ap);
2740
+	warn_at(&pos, s);
2741
+}
2742
+
2743
+
2744
+
2702 2745
 static void yyerror(char* format, ...)
2703 2746
 {
2704 2747
 	va_list ap;