Module: sip-router
Branch: master
Commit: 14839e8ff8da792974058779dc0cf4daf4181ac5
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=14839e8…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Wed May 6 11:10:48 2009 +0200
Splitting fix_sock_str into socket2str and fix_sock_str
This patch splits fix_sock_str into two function, socket2str and
fix_sock_str. The function socket2str is exported and can be used
to print the socket into a pre-allocated memory buffer. Function
fix_sock_str allocates the memory buffer and calls socket2str
internally.
The primary consumer of this change is the serial forking code in
tm module.
This patch also defines a new macro called MAX_SOCKET_STR which
evaluates to the maximum size of textual representation of any
socket.
---
socket_info.c | 73 ++++++++++++++++++++++++++++++++++++++++----------------
socket_info.h | 7 +++++
2 files changed, 59 insertions(+), 21 deletions(-)
diff --git a/socket_info.c b/socket_info.c
index ac2c82f..93c453a 100644
--- a/socket_info.c
+++ b/socket_info.c
@@ -298,6 +298,50 @@ static char* get_proto_name(unsigned short proto)
}
}
+/** Convert socket to its textual representation.
+ *
+ * This function converts the transport protocol, the IP address and the port
+ * number in a comma delimited string of form proto:ip:port. The resulting
+ * string is NOT zero terminated
+ *
+ * @param s is a pointer to the destination memory buffer
+ * @param len is a pointer to an integer variable. Initially the variable
+ * should contain the size of the buffer in s. The value of the variable
+ * will be changed to the length of the resulting string on success and
+ * to the desired size of the destination buffer if it is too small
+ * @param si is a pointer to the socket_info structure to be printed
+ * @return -1 on error and 0 on success
+ */
+int socket2str(char* s, int* len, struct socket_info* si)
+{
+ str proto;
+ int l;
+
+ proto.s = get_proto_name(si->proto);
+ proto.len = strlen(proto.s);
+
+ l = proto.len + si->address_str.len + si->port_no_str.len + 2;
+
+ if (*len < l) {
+ ERR("socket2str: Destionation buffer too short\n");
+ *len = l;
+ return -1;
+ }
+
+ memcpy(s, proto.s, proto.len);
+ s += proto.len;
+ *s = ':'; s++;
+ memcpy(s, si->address_str.s, si->address_str.len);
+ s += si->address_str.len;
+ *s = ':'; s++;
+ memcpy(s, si->port_no_str.s, si->port_no_str.len);
+ s += si->port_no_str.len;
+
+ *len = l;
+ return 0;
+}
+
+
/* Fill si->sock_str with string representing the socket_info structure,
* format of the string is 'proto:address:port'. Returns 0 on success and
@@ -305,33 +349,20 @@ static char* get_proto_name(unsigned short proto)
*/
static int fix_sock_str(struct socket_info* si)
{
- char* p;
- str proto;
+ int len = MAX_SOCKET_STR;
if (si->sock_str.s) pkg_free(si->sock_str.s);
- proto.s = get_proto_name(si->proto);
- proto.len = strlen(proto.s);
-
- si->sock_str.len = proto.len + si->address_str.len +
- si->port_no_str.len + 2;
-
- si->sock_str.s = pkg_malloc(si->sock_str.len + 1);
+ si->sock_str.s = pkg_malloc(len + 1);
if (si->sock_str.s == NULL) {
- LOG(L_ERR, "fix_sock_str: No pkg memory left\n");
+ ERR("fix_sock_str: No memory left\n");
return -1;
}
- p = si->sock_str.s;
- memcpy(p, proto.s, proto.len);
- p += proto.len;
- *p = ':'; p++;
- memcpy(p, si->address_str.s, si->address_str.len);
- p += si->address_str.len;
- *p = ':'; p++;
- memcpy(p, si->port_no_str.s, si->port_no_str.len);
- p += si->port_no_str.len;
- *p = '\0';
-
+ if (socket2str(si->sock_str.s, &len, si) < 0) {
+ BUG("fix_sock_str: Error in socket2str\n");
+ return -1;
+ }
+ si->sock_str.s[len] = '\0';
return 0;
}
diff --git a/socket_info.h b/socket_info.h
index ebe051a..4179869 100644
--- a/socket_info.h
+++ b/socket_info.h
@@ -43,6 +43,13 @@
#include "dprint.h"
#include "globals.h"
+/* This macro evaluates to the maximum length of string buffer needed to print
+ * the text description of any socket, not counting the terminating zero added
+ * by socket2str */
+#define MAX_SOCKET_STR (sizeof("unknown") - 1 + IP_ADDR_MAX_STR_SIZE + \
+ INT2STR_MAX_LEN + 2)
+
+int socket2str(char* s, int* len, struct socket_info* si);
/* struct socket_info is defined in ip_addr.h */
Module: sip-router
Branch: master
Commit: 0b3019f699dfb999be04572d4c35a613b6032435
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0b3019f…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Tue May 5 13:51:40 2009 +0200
core expr. eval: support for int & str casts
- new internal operators for force-casting to int or str
- fix int conversion failure for v1 str_concat v2
---
rvalue.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++-----------
rvalue.h | 3 ++
2 files changed, 92 insertions(+), 19 deletions(-)
diff --git a/rvalue.c b/rvalue.c
index c332173..db30fda 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -28,6 +28,7 @@
* (str)undef="", (int)""=0, (int)"123"=123, (int)"abc"=0
* handle undef == expr, in function of the UNDEF_EQ_* defines.
* (andrei)
+ * 2009-05-05 casts operator for int & string (andrei)
*/
/* special defines:
@@ -480,11 +481,13 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
return RV_INT;
case RVE_PLUS_OP:
/* '+' evaluates to the type of the left operand */
return rve_guess_type(rve->left.rve);
case RVE_CONCAT_OP:
+ case RVE_STR_OP:
return RV_STR;
case RVE_NONE_OP:
break;
@@ -522,6 +525,8 @@ int rve_is_constant(struct rval_expr* rve)
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
+ case RVE_STR_OP:
return rve_is_constant(rve->left.rve);
case RVE_MINUS_OP:
case RVE_MUL_OP:
@@ -579,6 +584,8 @@ static int rve_op_unary(enum rval_expr_op op)
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
+ case RVE_STR_OP:
return 1;
case RVE_MINUS_OP:
case RVE_MUL_OP:
@@ -781,6 +788,14 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
return 1;
}
break;
+ case RVE_INT_OP:
+ *type=RV_INT;
+ return 1;
+ break;
+ case RVE_STR_OP:
+ *type=RV_STR;
+ return 1;
+ break;
case RVE_NONE_OP:
default:
BUG("unexpected rve op %d\n", rve->op);
@@ -1726,6 +1741,9 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
break;
ret=int_intop1(res, rve->op, i1);
break;
+ case RVE_INT_OP:
+ ret=rval_expr_eval_int(h, msg, res, rve->left.rve);
+ break;
case RVE_MUL_OP:
case RVE_DIV_OP:
case RVE_MINUS_OP:
@@ -1857,27 +1875,49 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
}
}
break;
-#if 0
- case RVE_MATCH_OP:
- if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
- ret=-1;
- break;
- }
- if (unlikely((rv2=rval_expr_eval(h, msg,
- rve->right.rve))==0)){
- rval_destroy(rv1);
- ret=-1;
- break;
- }
- ret=rval_str_lop2(res, rve->op, rv1, 0, rv2, 0);
+ case RVE_CONCAT_OP:
+ /* eval expression => string */
+ if (unlikely((rv1=rval_expr_eval(h, msg, rve))==0)){
+ ret=-1;
+ break;
+ }
+ /* conver to int */
+ ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
+ rval_destroy(rv1);
+ break;
+ case RVE_STR_OP:
+ /* (str)expr => eval expression */
+ rval_cache_init(&c1);
+ if (unlikely((ret=rval_expr_eval_rvint(h, msg, &rv1, res,
+ rve->left.rve, &c1))<0)){
+ /* error */
+ rval_cache_clean(&c1);
+ break;
+ }
+ if (unlikely(rv1)){
+ /* expr evaluated to string => (int)(str)v == (int)v */
+ ret=rval_get_int(h, msg, res, rv1, &c1); /* convert to int */
rval_destroy(rv1);
- rval_destroy(rv2);
+ rval_cache_clean(&c1);
+ } /* else (rv1==0)
+ => expr evaluated to int =>
+ return (int)(str)v == (int)v => do nothing */
break;
-#endif
- case RVE_CONCAT_OP:
- *res=0;
- ret=-1;
+
+#if 0
+ /* same thing as above, but in a not optimized, easier to
+ understand way */
+ /* 1. (str) expr => eval expr */
+ if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
+ ret=-1;
+ break;
+ }
+ /* 2. convert to str and then convert to int
+ but since (int)(str)v == (int)v skip over (str)v */
+ ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
+ rval_destroy(rv1);
break;
+#endif
case RVE_DEFINED_OP:
ret=int_rve_defined(h, msg, res, rve->left.rve);
break;
@@ -1918,8 +1958,19 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
/** evals a rval expr. into an int or another rv(str).
* WARNING: rv result (rv_res) must be rval_destroy()'ed if non-null
- * (it might be a reference to another rval). The result can be
+ * (it might be a reference to another rval). The result can be
* modified only if rv_chg_in_place() returns true.
+ * @param res_rv - pointer to rvalue result, if non-null it means the
+ * expression evaluated to a non-int (str), which will be
+ * stored here.
+ * @param res_i - pointer to int result, if res_rv==0 and the function
+ * returns success => the result is an int which will be
+ * stored here.
+ * @param rve - expression that will be evaluated.
+ * @param cache - write-only value cache, it might be filled if non-null and
+ * empty (rval_cache_init()). If non-null, it _must_ be
+ * rval_cache_clean()'ed when done.
+ *
* @result 0 on success, -1 on error, sets *res_rv or *res_i.
*/
int rval_expr_eval_rvint( struct run_act_ctx* h,
@@ -1986,6 +2037,7 @@ int rval_expr_eval_rvint( struct run_act_ctx* h,
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
/* operator forces integer type */
ret=rval_expr_eval_int(h, msg, res_i, rve);
*res_rv=0;
@@ -2020,6 +2072,7 @@ int rval_expr_eval_rvint( struct run_act_ctx* h,
rval_cache_clean(&c1);
break;
case RVE_CONCAT_OP:
+ case RVE_STR_OP:
*res_rv=rval_expr_eval(h, msg, rve);
ret=-(*res_rv==0);
break;
@@ -2089,6 +2142,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
/* operator forces integer type */
r=rval_expr_eval_int(h, msg, &i, rve);
if (likely(r==0)){
@@ -2168,6 +2222,14 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
}
ret=rval_str_add2(h, msg, rv1, 0, rv2, 0);
break;
+ case RVE_STR_OP:
+ rv1=rval_expr_eval(h, msg, rve->left.rve);
+ if (unlikely(rv1==0)){
+ ERR("rval expression evaluation failed\n");
+ goto error;
+ }
+ ret=rval_convert(h, msg, RV_STR, rv1, 0);
+ break;
case RVE_NONE_OP:
/*default:*/
BUG("invalid rval expression operation %d\n", rve->op);
@@ -2292,6 +2354,8 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
+ case RVE_STR_OP:
break;
default:
BUG("unsupported unary operator %d\n", op);
@@ -2374,6 +2438,8 @@ static int rve_op_is_assoc(enum rval_expr_op op)
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
+ case RVE_STR_OP:
/* one operand expression => cannot be assoc. */
return 0;
case RVE_DIV_OP:
@@ -2422,6 +2488,8 @@ static int rve_op_is_commutative(enum rval_expr_op op)
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
+ case RVE_STR_OP:
/* one operand expression => cannot be commut. */
return 0;
case RVE_DIV_OP:
@@ -3291,6 +3359,8 @@ int fix_rval_expr(void** p)
case RVE_STRLEN_OP:
case RVE_STREMPTY_OP:
case RVE_DEFINED_OP:
+ case RVE_INT_OP:
+ case RVE_STR_OP:
ret=fix_rval_expr((void**)&rve->left.rve);
if (ret<0) return ret;
break;
diff --git a/rvalue.h b/rvalue.h
index c48d1e8..652c902 100644
--- a/rvalue.h
+++ b/rvalue.h
@@ -25,6 +25,7 @@
* 2008-11-30 initial version (andrei)
* 2009-04-28 added string and interger versions for the EQ and DIFF
* operators (andrei)
+ * 2009-05-05 casts operator for int & string (andrei)
*/
#ifndef _rvalue_h_
@@ -77,6 +78,8 @@ enum rval_expr_op{
RVE_MATCH_OP, /* 2 members, string ~), returns left matches re(right) */
/* avp, pvars a.s.o */
RVE_DEFINED_OP, /* one member, returns is_defined(val) (bool) */
+ RVE_INT_OP, /* one member, returns (int)val (int) */
+ RVE_STR_OP /* one member, returns (str)val (str) */
};
Module: sip-router
Branch: master
Commit: 7f2853ad287f90736dba35d6bc370922a77fbac7
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7f2853a…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Tue May 5 19:19:54 2009 +0200
script parsing: if (non-int) not any longer an error
An if expression that does not evaluate to int is not any longer
considered a parse error. It will generate a warning, but sr will
start.
This allows backward compatible if (@select) or if($avp).
---
cfg.y | 17 ++++++++++-------
route.c | 4 ++++
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/cfg.y b/cfg.y
index 21e81a1..5897914 100644
--- a/cfg.y
+++ b/cfg.y
@@ -1858,13 +1858,13 @@ action:
;
if_cmd:
IF rval_expr stm {
- if (rval_expr_int_check($2)==0){
+ if (rval_expr_int_check($2)>=0){
warn_ct_rve($2, "if");
}
$$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, NOSUBTYPE, 0);
}
| IF rval_expr stm ELSE stm {
- if (rval_expr_int_check($2)==0){
+ if (rval_expr_int_check($2)>=0){
warn_ct_rve($2, "if");
}
$$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, ACTIONS_ST, $5);
@@ -2806,7 +2806,8 @@ static void warn_at(struct cfg_pos* p, char* format, ...)
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
if (p->e_line!=p->s_line)
- LOG(L_WARN, "warning in config file, from line %d, column %d to line %d, column %d: %s\n",
+ LOG(L_WARN, "warning in config file, from line %d, column %d to"
+ " line %d, column %d: %s\n",
p->s_line, p->s_col, p->e_line, p->e_col, s);
else if (p->s_col!=p->e_col)
LOG(L_WARN, "warning in config file, line %d, column %d-%d: %s\n",
@@ -2828,7 +2829,8 @@ static void yyerror_at(struct cfg_pos* p, char* format, ...)
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
if (p->e_line!=p->s_line)
- LOG(L_CRIT, "parse error in config file, from line %d, column %d to line %d, column %d: %s\n",
+ LOG(L_CRIT, "parse error in config file, from line %d, column %d"
+ " to line %d, column %d: %s\n",
p->s_line, p->s_col, p->e_line, p->e_col, s);
else if (p->s_col!=p->e_col)
LOG(L_CRIT, "parse error in config file, line %d, column %d-%d: %s\n",
@@ -2948,7 +2950,7 @@ static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
/** check if the expression is an int.
* if the expression does not evaluate to an int return -1 and
* log an error.
- * @return 0 on success, -1 on error */
+ * @return 0 success, no warnings; 1 success but warnings; -1 on error */
static int rval_expr_int_check(struct rval_expr *rve)
{
struct rval_expr* bad_rve;
@@ -2967,8 +2969,9 @@ static int rval_expr_int_check(struct rval_expr *rve)
yyerror("BUG: unexpected null \"bad\" expression\n");
return -1;
}else if (type!=RV_INT && type!=RV_NONE){
- yyerror_at(&rve->fpos, "invalid expression type, int expected\n");
- return -1;
+ warn_at(&rve->fpos, "non-int expression (you might want to use"
+ " casts)\n");
+ return 1;
}
return 0;
}
diff --git a/route.c b/route.c
index 4ba116a..8d8c7db 100644
--- a/route.c
+++ b/route.c
@@ -712,12 +712,16 @@ int fix_actions(struct action* a)
rve->fpos.s_line, rve->fpos.s_col);
return E_UNSPEC;
}
+ /* it's not an error anymore to have non-int in an if,
+ only a script warning (to allow backward compat. stuff
+ like if (@ruri)
if (rve_type!=RV_INT && rve_type!=RV_NONE){
LOG(L_ERR, "fix_actions: invalid expression (%d,%d):"
" bad type, integer expected\n",
rve->fpos.s_line, rve->fpos.s_col);
return E_UNSPEC;
}
+ */
if ((ret=fix_rval_expr((void**)&rve))<0)
return ret;
}
Module: sip-router
Branch: master
Commit: 9c3327d5742b1f8280b159c7ea228b95bb2e8f35
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9c3327d…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Tue May 5 16:15:01 2009 +0200
core expr: optimizations fixes for $v op 0|1 -> $v
- fix missing cast for the $v <op> c -> $v optimizations
(e.g. $v - 0 -> $v, 1 * $v -> $v): instead of replacing
$v <op> c with $v use (type_of(<op>)) $v. $v without the cast
to the type produced by the operator is used now only when
type_of($v)==type_of(<op>).
E.g.: 1 * $v -> (int)$v
1 * ($v/$w) -> $v/$w ($v/$w produces always an int, so no
need for the cast)
Bug example: 1*"2"+3 was optimized to "2"+3 == "23" instead of
(int)"2"+3 == 5.
- better debugging messages
---
rvalue.c | 370 +++++++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 257 insertions(+), 113 deletions(-)
Diff: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commitdiff;h=9c3…
Module: sip-router
Branch: master
Commit: e41bc0575e8a4c22dfd7fbd2b6ae923f3c634a85
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e41bc05…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Tue May 5 19:43:18 2009 +0200
core: type casts support in the script
Support for casts added: (int) and (str).
E.g.: (int)$v ; (str)$v+"test".
---
NEWS | 5 +++--
cfg.lex | 4 ++++
cfg.y | 5 +++++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index ed1ab96..460d70c 100644
--- a/NEWS
+++ b/NEWS
@@ -6,13 +6,14 @@ $Id$
sip-router changes
core:
+ - type casts operators: (int), (str).
- new operators eq, ne for string compares and ieq, ine for interger
compares. The names are not yet final (use them at your own risk).
Future version might use ==/!= only for ints (ieq/ine) and eq/ne for
strings (under debate).
They are almost equivalent to == or !=, but they force the conversion
- of their operands (eq to string and ieq to int), allowing among other
- things better type checking on startup and more optimizations.
+ of their operands (eq to string and ieq to int), allowing among other
+ things better type checking on startup and more optimizations.
Non equiv. examples: 0 == "" (true) is not equivalent to 0 eq ""
(false: it evaluates to "0" eq ""). "a" ieq "b" (true: (int)"a" is 0
and (int)"b" is 0) is not equivalent to "a" == "b" (false).
diff --git a/cfg.lex b/cfg.lex
index b599d13..167fc95 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -252,6 +252,8 @@ STREQ eq
INTEQ ieq
STRDIFF ne
INTDIFF ine
+INTCAST \(int\)
+STRCAST \(str\)
/* Attribute specification */
ATTR_MARK "%"
@@ -783,6 +785,8 @@ EAT_ABLE [\ \t\b\r]
<INITIAL>{INTEQ} { count(); return INTEQ; }
<INITIAL>{STRDIFF} { count(); return STRDIFF; }
<INITIAL>{INTDIFF} { count(); return INTDIFF; }
+<INITIAL>{INTCAST} { count(); return INTCAST; }
+<INITIAL>{STRCAST} { count(); return STRCAST; }
<INITIAL>{SELECT_MARK} { count(); state = SELECT_S; BEGIN(SELECT); return SELECT_MARK; }
<SELECT>{ID} { count(); addstr(&s_buf, yytext, yyleng);
diff --git a/cfg.y b/cfg.y
index 5897914..8480434 100644
--- a/cfg.y
+++ b/cfg.y
@@ -494,6 +494,7 @@ static int case_check_default(struct case_stms* stms);
%left STAR SLASH
%right NOT
%right DEFINED
+%right INTCAST STRCAST
%left DOT
/* no precedence, they use () */
@@ -2269,6 +2270,8 @@ rval_expr: rval { $$=$1;
*/
}
| rve_un_op %prec NOT rval_expr {$$=mk_rve1($1, $2); }
+ | INTCAST rval_expr {$$=mk_rve1(RVE_INT_OP, $2); }
+ | STRCAST rval_expr {$$=mk_rve1(RVE_STR_OP, $2); }
| rval_expr PLUS rval_expr {$$=mk_rve2(RVE_PLUS_OP, $1, $3); }
| rval_expr MINUS rval_expr {$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
| rval_expr STAR rval_expr {$$=mk_rve2(RVE_MUL_OP, $1, $3); }
@@ -2285,6 +2288,8 @@ rval_expr: rval { $$=$1;
| STREMPTY LPAREN rval_expr RPAREN {$$=mk_rve1(RVE_STREMPTY_OP, $3);}
| DEFINED rval_expr { $$=mk_rve1(RVE_DEFINED_OP, $2);}
| rve_un_op %prec NOT error { $$=0; yyerror("bad expression"); }
+ | INTCAST error { $$=0; yyerror("bad expression"); }
+ | STRCAST error { $$=0; yyerror("bad expression"); }
| rval_expr PLUS error { yyerror("bad expression"); }
| rval_expr MINUS error { yyerror("bad expression"); }
| rval_expr STAR error { yyerror("bad expression"); }
Module: sip-router
Branch: master
Commit: c1111cb2ca9f5782c06158c8d57884ef65dfef38
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c1111cb…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Mon May 4 22:23:59 2009 +0200
core expr. eval: fix fixup/optimization bug
In some cases some ref'ed rvals were replaced in-place, messing up
the refcnt.
---
rvalue.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/rvalue.c b/rvalue.c
index 976945a..c332173 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -3002,7 +3002,7 @@ static int rve_optimize(struct rval_expr* rve)
if (rve->op == RVE_RVAL_OP) /* if rval, nothing to do */
return 0;
if (rve_is_constant(rve)){
- if ((rv=rval_expr_eval(0, 0, rve))==0){
+ if ((rv=rval_expr_eval_new(0, 0, rve))==0){
ERR("optimization failure, bad expression\n");
goto error;
}
@@ -3035,7 +3035,7 @@ static int rve_optimize(struct rval_expr* rve)
}
/* $v - a => $v + (-a) (easier to optimize)*/
if ((rve->op==RVE_MINUS_OP) && (rve_is_constant(rve->right.rve))){
- if ((rv=rval_expr_eval(0, 0, rve->right.rve))==0){
+ if ((rv=rval_expr_eval_new(0, 0, rve->right.rve))==0){
ERR("optimization failure, bad expression\n");
goto error;
}
@@ -3114,7 +3114,7 @@ static int rve_optimize(struct rval_expr* rve)
" +(+($v, a), b) when typeof(a)==INT\n");
return 0;
}
- if ((rv=rval_expr_eval(0, 0, &tmp_rve))==0){
+ if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
ERR("optimization failure, bad expression\n");
goto error;
}
@@ -3146,7 +3146,7 @@ static int rve_optimize(struct rval_expr* rve)
cases are caught by rve_op_is_commutative()
(in this case type will be typeof(a)) => ok only if
typeof(a) is int) */
- if ((rv=rval_expr_eval(0, 0, &tmp_rve))==0){
+ if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
ERR("optimization failure, bad expression\n");
goto error;
}
@@ -3188,7 +3188,7 @@ static int rve_optimize(struct rval_expr* rve)
cases are caught by rve_op_is_commutative()
(in this case type will be typeof(a)) => ok only if
typeof(a) is int) */
- if ((rv=rval_expr_eval(0, 0, &tmp_rve))==0){
+ if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
ERR("optimization failure, bad expression\n");
goto error;
}
@@ -3224,7 +3224,7 @@ static int rve_optimize(struct rval_expr* rve)
" +(a, +(b, $v)) when typeof(a)!=typeof(b)\n");
return 0;
}
- if ((rv=rval_expr_eval(0, 0, &tmp_rve))==0){
+ if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
ERR("optimization failure, bad expression\n");
goto error;
}