[SR-Dev] git:andrei/type_conversion: core expr eval: internal == & != int and str only versions

Andrei Pelinescu-Onciul andrei at iptel.org
Tue Apr 28 19:54:14 CEST 2009


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

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Tue Apr 28 17:39:35 2009 +0200

core expr eval: internal == & != int and str only versions

- added RVE_IEQ_OP and RVE_IDIFF_OP - internal integer only
  (force argument conversion to int)  operators
- added RVE_STREQ and RVE_STRDIFF_OP - internal string only
  (force argument conversion to str) operators

---

 rvalue.c |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 rvalue.h |    6 +++
 2 files changed, 108 insertions(+), 9 deletions(-)

diff --git a/rvalue.c b/rvalue.c
index 2961ee9..36c6ef4 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -38,7 +38,7 @@
  *  UNDEF_EQ_UNDEF_TRUE  :  undef == something false except for undef==undef
  *                          which is true
  *  no UNDEF_EQ* define  :  undef == expr => convert undef to typeof(expr)
- *                          and perorm normal ==. undef == undef will be
+ *                          and perform normal ==. undef == undef will be
  *                          converted to string and it will be true
  *                          ("" == "")
  * NOTE: expr == undef, with defined(expr) is always evaluated this way:
@@ -411,6 +411,10 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_IPLUS_OP:
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
@@ -471,6 +475,10 @@ int rve_is_constant(struct rval_expr* rve)
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_PLUS_OP:
 		case RVE_IPLUS_OP:
 		case RVE_CONCAT_OP:
@@ -523,6 +531,10 @@ static int rve_op_unary(enum rval_expr_op op)
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_PLUS_OP:
 		case RVE_IPLUS_OP:
 		case RVE_CONCAT_OP:
@@ -585,6 +597,8 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
 		case RVE_GTE_OP:
 		case RVE_LT_OP:
 		case RVE_LTE_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
 		case RVE_IPLUS_OP:
 			*type=RV_INT;
 			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
@@ -665,6 +679,30 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
 				}
 			}
 			break;
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
+			*type=RV_INT;
+			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
+				if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
+									exp_t)){
+					if ((type2!=type1) && (type1!=RV_NONE) &&
+							(type2!=RV_NONE) &&
+							!(type1==RV_STR && type2==RV_INT)){
+						if (bad_rve) *bad_rve=rve->right.rve;
+						if (bad_t) *bad_t=type2;
+						if (exp_t) *exp_t=type1;
+						return 0;
+					}
+					if (type1==RV_INT){
+						if (bad_rve) *bad_rve=rve->left.rve;
+						if (bad_t) *bad_t=type1;
+						if (exp_t) *exp_t=RV_STR;
+						return 0;
+					}
+					return 1;
+				}
+			}
+			break;
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
@@ -1136,9 +1174,11 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
 			*res=v1 <= v2;
 			break;
 		case RVE_EQ_OP:
+		case RVE_IEQ_OP:
 			*res=v1 == v2;
 			break;
 		case RVE_DIFF_OP:
+		case RVE_IDIFF_OP:
 			*res=v1 != v2;
 			break;
 		case RVE_CONCAT_OP:
@@ -1157,12 +1197,19 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
 inline static int bool_strop2( enum rval_expr_op op, int* res,
 								str* s1, str* s2)
 {
-	if (s1->len!=s2->len)
-		*res= op==RVE_DIFF_OP;
-	else if (memcmp(s1->s, s2->s, s1->len)==0)
-		*res= op==RVE_EQ_OP;
-	else
-		*res= op==RVE_DIFF_OP;
+	switch(op){
+		case RVE_EQ_OP:
+		case RVE_STREQ_OP:
+			*res= (s1->len==s2->len) && (memcmp(s1->s, s2->s, s1->len)==0);
+			break;
+		case RVE_DIFF_OP:
+		case RVE_STRDIFF_OP:
+			*res= (s1->len!=s2->len) || (memcmp(s1->s, s2->s, s1->len)!=0);
+			break;
+		default:
+			BUG("rv unsupported intop %d\n", op);
+			return -1;
+	}
 	return 0;
 }
 
@@ -1593,6 +1640,8 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
 		case RVE_GTE_OP:
 		case RVE_LT_OP:
 		case RVE_LTE_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
 			if (unlikely(
 					(ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
 				break;
@@ -1735,6 +1784,21 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
 		case RVE_DEFINED_OP:
 			ret=int_rve_defined(h, msg, res, rve->left.rve);
 			break;
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_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(h, msg, res, rve->op, rv1, 0, rv2, 0);
+			rval_destroy(rv1);
+			rval_destroy(rv2);
+			break;
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 			if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
@@ -1815,7 +1879,11 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
 		case RVE_IPLUS_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
@@ -1913,7 +1981,11 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
 		case RVE_IPLUS_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
@@ -2168,6 +2240,10 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
 		case RVE_IPLUS_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_CONCAT_OP:
 			break;
 		default:
@@ -2220,6 +2296,10 @@ static int rve_op_is_assoc(enum rval_expr_op op)
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 			return 0;
 	}
 	return 0;
@@ -2250,18 +2330,26 @@ static int rve_op_is_commutative(enum rval_expr_op op, enum rval_type type)
 		case RVE_MUL_OP:
 		case RVE_BAND_OP:
 		case RVE_BOR_OP:
-			return 1;
 		case RVE_LAND_OP:
 		case RVE_LOR_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 			return 1;
 		case RVE_GT_OP:
 		case RVE_GTE_OP:
 		case RVE_LT_OP:
 		case RVE_LTE_OP:
 		case RVE_EQ_OP:
+			return 0;
 		case RVE_DIFF_OP:
 		case RVE_CONCAT_OP:
-			return 0;
+#if !defined(UNDEF_EQ_ALWAYS_FALSE) && !defined(UNDEF_EQ_UNDEF_TRUE)
+			return 1;
+#else
+			return 0 /* asymmetrical undef handling */;
+#endif
 	}
 	return 0;
 }
@@ -2633,6 +2721,7 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
 				}
 				break;
 			case RVE_EQ_OP:
+			case RVE_STREQ_OP:
 				if (rv->v.s.len==0){
 					/* $v == "" -> strempty($v) 
 					   "" == $v -> strempty ($v) */
@@ -2973,6 +3062,10 @@ int fix_rval_expr(void** p)
 		case RVE_IPLUS_OP:
 		case RVE_EQ_OP:
 		case RVE_DIFF_OP:
+		case RVE_IEQ_OP:
+		case RVE_IDIFF_OP:
+		case RVE_STREQ_OP:
+		case RVE_STRDIFF_OP:
 		case RVE_CONCAT_OP:
 			ret=fix_rval_expr((void**)&rve->left.rve);
 			if (ret<0) return ret;
diff --git a/rvalue.h b/rvalue.h
index e99d1f8..f7fdcc1 100644
--- a/rvalue.h
+++ b/rvalue.h
@@ -23,6 +23,8 @@
  * History:
  * --------
  *  2008-11-30  initial version (andrei)
+ *  2009-04-28  added string and interger versions for the EQ and DIFF
+ *              operators (andrei)
  */
 
 #ifndef _rvalue_h_
@@ -59,6 +61,8 @@ enum rval_expr_op{
 	RVE_GTE_OP,   /*  2 members, returns left >= right */
 	RVE_LT_OP,    /*  2 members, returns left  < right */
 	RVE_LTE_OP,   /*  2 members, returns left <= right */
+	RVE_IEQ_OP, /*  2 members, int == version, returns left == right */
+	RVE_IDIFF_OP,/* 2 members, int != version, returns left != right */
 	RVE_IPLUS_OP, /* 2 members, integer +, returns int(a)+int(b) */
 	/* common int & str */
 	RVE_PLUS_OP,  /* generic plus (int or str) returns left + right */
@@ -68,6 +72,8 @@ enum rval_expr_op{
 	RVE_CONCAT_OP,/* 2 members, string concat, returns left . right (str)*/
 	RVE_STRLEN_OP, /* one member, string length:, returns strlen(val) (int)*/
 	RVE_STREMPTY_OP, /* one member, returns val=="" (bool) */
+	RVE_STREQ_OP,  /* 2 members, string == , returns left == right (bool)*/
+	RVE_STRDIFF_OP,/* 2 members, string != , returns left != right (bool)*/
 	/* avp, pvars a.s.o */
 	RVE_DEFINED_OP, /* one member, returns is_defined(val) (bool) */
 };




More information about the sr-dev mailing list