[SR-Dev] git:andrei/switch: script parsing: while support

Andrei Pelinescu-Onciul andrei at iptel.org
Tue Feb 10 22:39:30 CET 2009


Module: sip-router
Branch: andrei/switch
Commit: d14a718fbaf2f737ea9206dc1d63ea8b3bdba294
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d14a718fbaf2f737ea9206dc1d63ea8b3bdba294

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Tue Feb 10 22:39:01 2009 +0100

script parsing: while support

- while() support
- improved config warning functions

---

 NEWS    |    4 ++++
 cfg.lex |    6 +++++-
 cfg.y   |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/NEWS b/NEWS
index 03852ee..bede08a 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,10 @@ config script changes:
       #!MAXCOMPAT
     where #!KAMAILIO is equivalent with #!OPENSER and #!ALL with #!MAXCOMPAT
   - support for kamailio style pvars
+  - C-like switch()/case (integer only)
+  - while()
+  - max_while_loops - maximum iterations allowed for a while, can be changed
+    at runtime. Default 100.
 
 
 
diff --git a/cfg.lex b/cfg.lex
index 13767b1..1323303 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -190,6 +190,7 @@ FORCE_SEND_SOCKET	"force_send_socket"
 SWITCH			"switch"
 CASE			"case"
 DEFAULT			"default"
+WHILE			"while"
 
 /*ACTION LVALUES*/
 URIHOST			"uri:host"
@@ -375,6 +376,7 @@ MCAST_TTL		"mcast_ttl"
 TOS			"tos"
 PMTU_DISCOVERY	"pmtu_discovery"
 KILL_TIMEOUT	"exit_timeout"|"ser_kill_timeout"
+MAX_WLOOPS		"max_while_loops"
 
 /* stun config variables */
 STUN_REFRESH_INTERVAL "stun_refresh_interval"
@@ -501,7 +503,7 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{SWITCH}	{ count(); yylval.strval=yytext; return SWITCH; }
 <INITIAL>{CASE}	{ count(); yylval.strval=yytext; return CASE; }
 <INITIAL>{DEFAULT}	{ count(); yylval.strval=yytext; return DEFAULT; }
-
+<INITIAL>{WHILE}	{ count(); yylval.strval=yytext; return WHILE; }
 
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
@@ -717,6 +719,8 @@ EAT_ABLE	[\ \t\b\r]
 									return PMTU_DISCOVERY; }
 <INITIAL>{KILL_TIMEOUT}			{	count(); yylval.strval=yytext;
 									return KILL_TIMEOUT; }
+<INITIAL>{MAX_WLOOPS}			{	count(); yylval.strval=yytext;
+									return MAX_WLOOPS; }
 <INITIAL>{SERVER_ID}  { count(); yylval.strval=yytext; return SERVER_ID;}
 <INITIAL>{CFG_DESCRIPTION}	{ count(); yylval.strval=yytext; return CFG_DESCRIPTION; }
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
diff --git a/cfg.y b/cfg.y
index 42f068a..e1758bf 100644
--- a/cfg.y
+++ b/cfg.y
@@ -184,6 +184,7 @@
 
 extern int yylex();
 static void yyerror(char* s, ...);
+static void yyerror_at(struct cfg_pos* pos, char* s, ...);
 static char* tmp;
 static int i_tmp;
 static unsigned u_tmp;
@@ -201,7 +202,8 @@ static struct action *mod_func_action;
 static struct lvalue* lval_tmp;
 static struct rvalue* rval_tmp;
 
-static void warn(char* s);
+static void warn(char* s, ...);
+static void warn_at(struct cfg_pos* pos, char* s, ...);
 static void get_cpos(struct cfg_pos* pos);
 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);
@@ -280,6 +282,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
 %token SWITCH
 %token CASE
 %token DEFAULT
+%token WHILE
 %token URIHOST
 %token URIPORT
 %token MAX_LEN
@@ -436,6 +439,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
 %token TOS
 %token PMTU_DISCOVERY
 %token KILL_TIMEOUT
+%token MAX_WLOOPS
 %token CFG_DESCRIPTION
 %token SERVER_ID
 
@@ -501,7 +505,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
 %type <intval> intno eint_op eint_op_onsend
 %type <intval> eip_op eip_op_onsend
 %type <action> action actions cmd fcmd if_cmd stm /*exp_stm*/ assign_action
-%type <action> switch_cmd
+%type <action> switch_cmd while_cmd
 %type <case_stms> single_case case_stms
 %type <ipaddr> ipv4 ipv6 ipv6addr ip
 %type <ipnet> ipnet
@@ -1283,6 +1287,8 @@ assign_stm:
 	| PMTU_DISCOVERY error { yyerror("number expected"); }
 	| KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
 	| KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
+	| MAX_WLOOPS EQUAL NUMBER { default_core_cfg.max_while_loops=$3; }
+	| MAX_WLOOPS EQUAL error { yyerror("number expected"); }
 	| STUN_REFRESH_INTERVAL EQUAL NUMBER { IF_STUN(stun_refresh_interval=$3); }
 	| STUN_REFRESH_INTERVAL EQUAL error{ yyerror("number expected"); }
 	| STUN_ALLOW_STUN EQUAL NUMBER { IF_STUN(stun_allow_stun=$3); }
@@ -1773,6 +1779,7 @@ action:
 	fcmd SEMICOLON {$$=$1;}
 	| if_cmd {$$=$1;}
 	| switch_cmd {$$=$1;}
+	| while_cmd { $$=$1; }
 	| assign_action SEMICOLON {$$=$1;}
 	| SEMICOLON /* null action */ {$$=0;}
 	| fcmd error { $$=0; yyerror("bad command: missing ';'?"); }
@@ -1873,6 +1880,17 @@ switch_cmd:
 		{$$=0; yyerror ("bad switch body"); }
 ;
 
+while_cmd:
+	WHILE rval_expr stm {
+		if ($2){
+			if (rve_is_constant($2))
+				warn_at(&$2->fpos, "constant value in while(...)");
+		}else
+			yyerror_at(&$2->fpos, "bad while(...) expression");
+		$$=mk_action( WHILE_T, 2, RVE_ST, $2, ACTIONS_ST, $3);
+	}
+;
+
 /* class_id:
 	LBRACK ATTR_USER RBRACK { $$ = AVP_CLASS_USER; }
 	| LBRACK ATTR_DOMAIN RBRACK { $$ = AVP_CLASS_DOMAIN; }
@@ -2665,19 +2683,28 @@ static void get_cpos(struct cfg_pos* pos)
 }
 
 
-static void warn(char* s)
+static void warn_at(struct cfg_pos* p, char* format, ...)
 {
-	if (line!=startline)
+	va_list ap;
+	char s[256];
+	
+	va_start(ap, format);
+	vsnprintf(s, sizeof(s), format, ap);
+	va_end(ap);
+	if (p->e_line!=p->s_line)
 		LOG(L_WARN, "cfg. warning: (%d,%d-%d,%d): %s\n",
-					startline, startcolumn, line, column-1, s);
-	else if (startcolumn!=(column-1))
-		LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n", startline, startcolumn,
-					column-1, s);
+					p->s_line, p->s_col, p->e_line, p->e_col, s);
+	else if (p->s_col!=p->e_col)
+		LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n",
+					p->s_line, p->s_col, p->e_col, s);
 	else
-		LOG(L_WARN, "cfg. warning: (%d,%d): %s\n", startline, startcolumn, s);
+		LOG(L_WARN, "cfg. warning: (%d,%d): %s\n",
+				p->s_line, p->s_col, s);
 	cfg_warnings++;
 }
 
+
+
 static void yyerror_at(struct cfg_pos* p, char* format, ...)
 {
 	va_list ap;
@@ -2699,6 +2726,22 @@ static void yyerror_at(struct cfg_pos* p, char* format, ...)
 }
 
 
+
+static void warn(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);
+	warn_at(&pos, s);
+}
+
+
+
 static void yyerror(char* format, ...)
 {
 	va_list ap;




More information about the sr-dev mailing list