Browse code

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

Andrei Pelinescu-Onciul authored on 28/04/2009 15:39:35
Showing 2 changed files
... ...
@@ -38,7 +38,7 @@
38 38
  *  UNDEF_EQ_UNDEF_TRUE  :  undef == something false except for undef==undef
39 39
  *                          which is true
40 40
  *  no UNDEF_EQ* define  :  undef == expr => convert undef to typeof(expr)
41
- *                          and perorm normal ==. undef == undef will be
41
+ *                          and perform normal ==. undef == undef will be
42 42
  *                          converted to string and it will be true
43 43
  *                          ("" == "")
44 44
  * 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)
411 411
 		case RVE_LTE_OP:
412 412
 		case RVE_EQ_OP:
413 413
 		case RVE_DIFF_OP:
414
+		case RVE_IEQ_OP:
415
+		case RVE_IDIFF_OP:
416
+		case RVE_STREQ_OP:
417
+		case RVE_STRDIFF_OP:
414 418
 		case RVE_IPLUS_OP:
415 419
 		case RVE_STRLEN_OP:
416 420
 		case RVE_STREMPTY_OP:
... ...
@@ -471,6 +475,10 @@ int rve_is_constant(struct rval_expr* rve)
471 471
 		case RVE_LTE_OP:
472 472
 		case RVE_EQ_OP:
473 473
 		case RVE_DIFF_OP:
474
+		case RVE_IEQ_OP:
475
+		case RVE_IDIFF_OP:
476
+		case RVE_STREQ_OP:
477
+		case RVE_STRDIFF_OP:
474 478
 		case RVE_PLUS_OP:
475 479
 		case RVE_IPLUS_OP:
476 480
 		case RVE_CONCAT_OP:
... ...
@@ -523,6 +531,10 @@ static int rve_op_unary(enum rval_expr_op op)
523 523
 		case RVE_LTE_OP:
524 524
 		case RVE_EQ_OP:
525 525
 		case RVE_DIFF_OP:
526
+		case RVE_IEQ_OP:
527
+		case RVE_IDIFF_OP:
528
+		case RVE_STREQ_OP:
529
+		case RVE_STRDIFF_OP:
526 530
 		case RVE_PLUS_OP:
527 531
 		case RVE_IPLUS_OP:
528 532
 		case RVE_CONCAT_OP:
... ...
@@ -585,6 +597,8 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
585 585
 		case RVE_GTE_OP:
586 586
 		case RVE_LT_OP:
587 587
 		case RVE_LTE_OP:
588
+		case RVE_IEQ_OP:
589
+		case RVE_IDIFF_OP:
588 590
 		case RVE_IPLUS_OP:
589 591
 			*type=RV_INT;
590 592
 			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,
665 665
 				}
666 666
 			}
667 667
 			break;
668
+		case RVE_STREQ_OP:
669
+		case RVE_STRDIFF_OP:
670
+			*type=RV_INT;
671
+			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
672
+				if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
673
+									exp_t)){
674
+					if ((type2!=type1) && (type1!=RV_NONE) &&
675
+							(type2!=RV_NONE) &&
676
+							!(type1==RV_STR && type2==RV_INT)){
677
+						if (bad_rve) *bad_rve=rve->right.rve;
678
+						if (bad_t) *bad_t=type2;
679
+						if (exp_t) *exp_t=type1;
680
+						return 0;
681
+					}
682
+					if (type1==RV_INT){
683
+						if (bad_rve) *bad_rve=rve->left.rve;
684
+						if (bad_t) *bad_t=type1;
685
+						if (exp_t) *exp_t=RV_STR;
686
+						return 0;
687
+					}
688
+					return 1;
689
+				}
690
+			}
691
+			break;
668 692
 		case RVE_STRLEN_OP:
669 693
 		case RVE_STREMPTY_OP:
670 694
 		case RVE_DEFINED_OP:
... ...
@@ -1136,9 +1174,11 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
1136 1136
 			*res=v1 <= v2;
1137 1137
 			break;
1138 1138
 		case RVE_EQ_OP:
1139
+		case RVE_IEQ_OP:
1139 1140
 			*res=v1 == v2;
1140 1141
 			break;
1141 1142
 		case RVE_DIFF_OP:
1143
+		case RVE_IDIFF_OP:
1142 1144
 			*res=v1 != v2;
1143 1145
 			break;
1144 1146
 		case RVE_CONCAT_OP:
... ...
@@ -1157,12 +1197,19 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
1157 1157
 inline static int bool_strop2( enum rval_expr_op op, int* res,
1158 1158
 								str* s1, str* s2)
1159 1159
 {
1160
-	if (s1->len!=s2->len)
1161
-		*res= op==RVE_DIFF_OP;
1162
-	else if (memcmp(s1->s, s2->s, s1->len)==0)
1163
-		*res= op==RVE_EQ_OP;
1164
-	else
1165
-		*res= op==RVE_DIFF_OP;
1160
+	switch(op){
1161
+		case RVE_EQ_OP:
1162
+		case RVE_STREQ_OP:
1163
+			*res= (s1->len==s2->len) && (memcmp(s1->s, s2->s, s1->len)==0);
1164
+			break;
1165
+		case RVE_DIFF_OP:
1166
+		case RVE_STRDIFF_OP:
1167
+			*res= (s1->len!=s2->len) || (memcmp(s1->s, s2->s, s1->len)!=0);
1168
+			break;
1169
+		default:
1170
+			BUG("rv unsupported intop %d\n", op);
1171
+			return -1;
1172
+	}
1166 1173
 	return 0;
1167 1174
 }
1168 1175
 
... ...
@@ -1593,6 +1640,8 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1593 1593
 		case RVE_GTE_OP:
1594 1594
 		case RVE_LT_OP:
1595 1595
 		case RVE_LTE_OP:
1596
+		case RVE_IEQ_OP:
1597
+		case RVE_IDIFF_OP:
1596 1598
 			if (unlikely(
1597 1599
 					(ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
1598 1600
 				break;
... ...
@@ -1735,6 +1784,21 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1735 1735
 		case RVE_DEFINED_OP:
1736 1736
 			ret=int_rve_defined(h, msg, res, rve->left.rve);
1737 1737
 			break;
1738
+		case RVE_STREQ_OP:
1739
+		case RVE_STRDIFF_OP:
1740
+			if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1741
+				ret=-1;
1742
+				break;
1743
+			}
1744
+			if (unlikely((rv2=rval_expr_eval(h, msg, rve->right.rve))==0)){
1745
+				rval_destroy(rv1);
1746
+				ret=-1;
1747
+				break;
1748
+			}
1749
+			ret=rval_str_lop2(h, msg, res, rve->op, rv1, 0, rv2, 0);
1750
+			rval_destroy(rv1);
1751
+			rval_destroy(rv2);
1752
+			break;
1738 1753
 		case RVE_STRLEN_OP:
1739 1754
 		case RVE_STREMPTY_OP:
1740 1755
 			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,
1815 1815
 		case RVE_LTE_OP:
1816 1816
 		case RVE_EQ_OP:
1817 1817
 		case RVE_DIFF_OP:
1818
+		case RVE_IEQ_OP:
1819
+		case RVE_IDIFF_OP:
1818 1820
 		case RVE_IPLUS_OP:
1821
+		case RVE_STREQ_OP:
1822
+		case RVE_STRDIFF_OP:
1819 1823
 		case RVE_STRLEN_OP:
1820 1824
 		case RVE_STREMPTY_OP:
1821 1825
 		case RVE_DEFINED_OP:
... ...
@@ -1913,7 +1981,11 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1913 1913
 		case RVE_LTE_OP:
1914 1914
 		case RVE_EQ_OP:
1915 1915
 		case RVE_DIFF_OP:
1916
+		case RVE_IEQ_OP:
1917
+		case RVE_IDIFF_OP:
1916 1918
 		case RVE_IPLUS_OP:
1919
+		case RVE_STREQ_OP:
1920
+		case RVE_STRDIFF_OP:
1917 1921
 		case RVE_STRLEN_OP:
1918 1922
 		case RVE_STREMPTY_OP:
1919 1923
 		case RVE_DEFINED_OP:
... ...
@@ -2168,6 +2240,10 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
2168 2168
 		case RVE_IPLUS_OP:
2169 2169
 		case RVE_EQ_OP:
2170 2170
 		case RVE_DIFF_OP:
2171
+		case RVE_IEQ_OP:
2172
+		case RVE_IDIFF_OP:
2173
+		case RVE_STREQ_OP:
2174
+		case RVE_STRDIFF_OP:
2171 2175
 		case RVE_CONCAT_OP:
2172 2176
 			break;
2173 2177
 		default:
... ...
@@ -2220,6 +2296,10 @@ static int rve_op_is_assoc(enum rval_expr_op op)
2220 2220
 		case RVE_LTE_OP:
2221 2221
 		case RVE_EQ_OP:
2222 2222
 		case RVE_DIFF_OP:
2223
+		case RVE_IEQ_OP:
2224
+		case RVE_IDIFF_OP:
2225
+		case RVE_STREQ_OP:
2226
+		case RVE_STRDIFF_OP:
2223 2227
 			return 0;
2224 2228
 	}
2225 2229
 	return 0;
... ...
@@ -2250,18 +2330,26 @@ static int rve_op_is_commutative(enum rval_expr_op op, enum rval_type type)
2250 2250
 		case RVE_MUL_OP:
2251 2251
 		case RVE_BAND_OP:
2252 2252
 		case RVE_BOR_OP:
2253
-			return 1;
2254 2253
 		case RVE_LAND_OP:
2255 2254
 		case RVE_LOR_OP:
2255
+		case RVE_IEQ_OP:
2256
+		case RVE_IDIFF_OP:
2257
+		case RVE_STREQ_OP:
2258
+		case RVE_STRDIFF_OP:
2256 2259
 			return 1;
2257 2260
 		case RVE_GT_OP:
2258 2261
 		case RVE_GTE_OP:
2259 2262
 		case RVE_LT_OP:
2260 2263
 		case RVE_LTE_OP:
2261 2264
 		case RVE_EQ_OP:
2265
+			return 0;
2262 2266
 		case RVE_DIFF_OP:
2263 2267
 		case RVE_CONCAT_OP:
2264
-			return 0;
2268
+#if !defined(UNDEF_EQ_ALWAYS_FALSE) && !defined(UNDEF_EQ_UNDEF_TRUE)
2269
+			return 1;
2270
+#else
2271
+			return 0 /* asymmetrical undef handling */;
2272
+#endif
2265 2273
 	}
2266 2274
 	return 0;
2267 2275
 }
... ...
@@ -2633,6 +2721,7 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
2633 2633
 				}
2634 2634
 				break;
2635 2635
 			case RVE_EQ_OP:
2636
+			case RVE_STREQ_OP:
2636 2637
 				if (rv->v.s.len==0){
2637 2638
 					/* $v == "" -> strempty($v) 
2638 2639
 					   "" == $v -> strempty ($v) */
... ...
@@ -2973,6 +3062,10 @@ int fix_rval_expr(void** p)
2973 2973
 		case RVE_IPLUS_OP:
2974 2974
 		case RVE_EQ_OP:
2975 2975
 		case RVE_DIFF_OP:
2976
+		case RVE_IEQ_OP:
2977
+		case RVE_IDIFF_OP:
2978
+		case RVE_STREQ_OP:
2979
+		case RVE_STRDIFF_OP:
2976 2980
 		case RVE_CONCAT_OP:
2977 2981
 			ret=fix_rval_expr((void**)&rve->left.rve);
2978 2982
 			if (ret<0) return ret;
... ...
@@ -23,6 +23,8 @@
23 23
  * History:
24 24
  * --------
25 25
  *  2008-11-30  initial version (andrei)
26
+ *  2009-04-28  added string and interger versions for the EQ and DIFF
27
+ *              operators (andrei)
26 28
  */
27 29
 
28 30
 #ifndef _rvalue_h_
... ...
@@ -59,6 +61,8 @@ enum rval_expr_op{
59 59
 	RVE_GTE_OP,   /*  2 members, returns left >= right */
60 60
 	RVE_LT_OP,    /*  2 members, returns left  < right */
61 61
 	RVE_LTE_OP,   /*  2 members, returns left <= right */
62
+	RVE_IEQ_OP, /*  2 members, int == version, returns left == right */
63
+	RVE_IDIFF_OP,/* 2 members, int != version, returns left != right */
62 64
 	RVE_IPLUS_OP, /* 2 members, integer +, returns int(a)+int(b) */
63 65
 	/* common int & str */
64 66
 	RVE_PLUS_OP,  /* generic plus (int or str) returns left + right */
... ...
@@ -68,6 +72,8 @@ enum rval_expr_op{
68 68
 	RVE_CONCAT_OP,/* 2 members, string concat, returns left . right (str)*/
69 69
 	RVE_STRLEN_OP, /* one member, string length:, returns strlen(val) (int)*/
70 70
 	RVE_STREMPTY_OP, /* one member, returns val=="" (bool) */
71
+	RVE_STREQ_OP,  /* 2 members, string == , returns left == right (bool)*/
72
+	RVE_STRDIFF_OP,/* 2 members, string != , returns left != right (bool)*/
71 73
 	/* avp, pvars a.s.o */
72 74
 	RVE_DEFINED_OP, /* one member, returns is_defined(val) (bool) */
73 75
 };