Module: sip-router
Branch: andrei/switch
Commit: d14a718fbaf2f737ea9206dc1d63ea8b3bdba294
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d14a718…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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;