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 475
 		case RVE_LTE_OP:
472 476
 		case RVE_EQ_OP:
473 477
 		case RVE_DIFF_OP:
478
+		case RVE_IEQ_OP:
479
+		case RVE_IDIFF_OP:
480
+		case RVE_STREQ_OP:
481
+		case RVE_STRDIFF_OP:
474 482
 		case RVE_PLUS_OP:
475 483
 		case RVE_IPLUS_OP:
476 484
 		case RVE_CONCAT_OP:
... ...
@@ -523,6 +531,10 @@ static int rve_op_unary(enum rval_expr_op op)
523 531
 		case RVE_LTE_OP:
524 532
 		case RVE_EQ_OP:
525 533
 		case RVE_DIFF_OP:
534
+		case RVE_IEQ_OP:
535
+		case RVE_IDIFF_OP:
536
+		case RVE_STREQ_OP:
537
+		case RVE_STRDIFF_OP:
526 538
 		case RVE_PLUS_OP:
527 539
 		case RVE_IPLUS_OP:
528 540
 		case RVE_CONCAT_OP:
... ...
@@ -585,6 +597,8 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
585 597
 		case RVE_GTE_OP:
586 598
 		case RVE_LT_OP:
587 599
 		case RVE_LTE_OP:
600
+		case RVE_IEQ_OP:
601
+		case RVE_IDIFF_OP:
588 602
 		case RVE_IPLUS_OP:
589 603
 			*type=RV_INT;
590 604
 			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 679
 				}
666 680
 			}
667 681
 			break;
682
+		case RVE_STREQ_OP:
683
+		case RVE_STRDIFF_OP:
684
+			*type=RV_INT;
685
+			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
686
+				if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
687
+									exp_t)){
688
+					if ((type2!=type1) && (type1!=RV_NONE) &&
689
+							(type2!=RV_NONE) &&
690
+							!(type1==RV_STR && type2==RV_INT)){
691
+						if (bad_rve) *bad_rve=rve->right.rve;
692
+						if (bad_t) *bad_t=type2;
693
+						if (exp_t) *exp_t=type1;
694
+						return 0;
695
+					}
696
+					if (type1==RV_INT){
697
+						if (bad_rve) *bad_rve=rve->left.rve;
698
+						if (bad_t) *bad_t=type1;
699
+						if (exp_t) *exp_t=RV_STR;
700
+						return 0;
701
+					}
702
+					return 1;
703
+				}
704
+			}
705
+			break;
668 706
 		case RVE_STRLEN_OP:
669 707
 		case RVE_STREMPTY_OP:
670 708
 		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 1174
 			*res=v1 <= v2;
1137 1175
 			break;
1138 1176
 		case RVE_EQ_OP:
1177
+		case RVE_IEQ_OP:
1139 1178
 			*res=v1 == v2;
1140 1179
 			break;
1141 1180
 		case RVE_DIFF_OP:
1181
+		case RVE_IDIFF_OP:
1142 1182
 			*res=v1 != v2;
1143 1183
 			break;
1144 1184
 		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 1197
 inline static int bool_strop2( enum rval_expr_op op, int* res,
1158 1198
 								str* s1, str* s2)
1159 1199
 {
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;
1200
+	switch(op){
1201
+		case RVE_EQ_OP:
1202
+		case RVE_STREQ_OP:
1203
+			*res= (s1->len==s2->len) && (memcmp(s1->s, s2->s, s1->len)==0);
1204
+			break;
1205
+		case RVE_DIFF_OP:
1206
+		case RVE_STRDIFF_OP:
1207
+			*res= (s1->len!=s2->len) || (memcmp(s1->s, s2->s, s1->len)!=0);
1208
+			break;
1209
+		default:
1210
+			BUG("rv unsupported intop %d\n", op);
1211
+			return -1;
1212
+	}
1166 1213
 	return 0;
1167 1214
 }
1168 1215
 
... ...
@@ -1593,6 +1640,8 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1593 1640
 		case RVE_GTE_OP:
1594 1641
 		case RVE_LT_OP:
1595 1642
 		case RVE_LTE_OP:
1643
+		case RVE_IEQ_OP:
1644
+		case RVE_IDIFF_OP:
1596 1645
 			if (unlikely(
1597 1646
 					(ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
1598 1647
 				break;
... ...
@@ -1735,6 +1784,21 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1735 1784
 		case RVE_DEFINED_OP:
1736 1785
 			ret=int_rve_defined(h, msg, res, rve->left.rve);
1737 1786
 			break;
1787
+		case RVE_STREQ_OP:
1788
+		case RVE_STRDIFF_OP:
1789
+			if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1790
+				ret=-1;
1791
+				break;
1792
+			}
1793
+			if (unlikely((rv2=rval_expr_eval(h, msg, rve->right.rve))==0)){
1794
+				rval_destroy(rv1);
1795
+				ret=-1;
1796
+				break;
1797
+			}
1798
+			ret=rval_str_lop2(h, msg, res, rve->op, rv1, 0, rv2, 0);
1799
+			rval_destroy(rv1);
1800
+			rval_destroy(rv2);
1801
+			break;
1738 1802
 		case RVE_STRLEN_OP:
1739 1803
 		case RVE_STREMPTY_OP:
1740 1804
 			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 1879
 		case RVE_LTE_OP:
1816 1880
 		case RVE_EQ_OP:
1817 1881
 		case RVE_DIFF_OP:
1882
+		case RVE_IEQ_OP:
1883
+		case RVE_IDIFF_OP:
1818 1884
 		case RVE_IPLUS_OP:
1885
+		case RVE_STREQ_OP:
1886
+		case RVE_STRDIFF_OP:
1819 1887
 		case RVE_STRLEN_OP:
1820 1888
 		case RVE_STREMPTY_OP:
1821 1889
 		case RVE_DEFINED_OP:
... ...
@@ -1913,7 +1981,11 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1913 1981
 		case RVE_LTE_OP:
1914 1982
 		case RVE_EQ_OP:
1915 1983
 		case RVE_DIFF_OP:
1984
+		case RVE_IEQ_OP:
1985
+		case RVE_IDIFF_OP:
1916 1986
 		case RVE_IPLUS_OP:
1987
+		case RVE_STREQ_OP:
1988
+		case RVE_STRDIFF_OP:
1917 1989
 		case RVE_STRLEN_OP:
1918 1990
 		case RVE_STREMPTY_OP:
1919 1991
 		case RVE_DEFINED_OP:
... ...
@@ -2168,6 +2240,10 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
2168 2240
 		case RVE_IPLUS_OP:
2169 2241
 		case RVE_EQ_OP:
2170 2242
 		case RVE_DIFF_OP:
2243
+		case RVE_IEQ_OP:
2244
+		case RVE_IDIFF_OP:
2245
+		case RVE_STREQ_OP:
2246
+		case RVE_STRDIFF_OP:
2171 2247
 		case RVE_CONCAT_OP:
2172 2248
 			break;
2173 2249
 		default:
... ...
@@ -2220,6 +2296,10 @@ static int rve_op_is_assoc(enum rval_expr_op op)
2220 2296
 		case RVE_LTE_OP:
2221 2297
 		case RVE_EQ_OP:
2222 2298
 		case RVE_DIFF_OP:
2299
+		case RVE_IEQ_OP:
2300
+		case RVE_IDIFF_OP:
2301
+		case RVE_STREQ_OP:
2302
+		case RVE_STRDIFF_OP:
2223 2303
 			return 0;
2224 2304
 	}
2225 2305
 	return 0;
... ...
@@ -2250,18 +2330,26 @@ static int rve_op_is_commutative(enum rval_expr_op op, enum rval_type type)
2250 2330
 		case RVE_MUL_OP:
2251 2331
 		case RVE_BAND_OP:
2252 2332
 		case RVE_BOR_OP:
2253
-			return 1;
2254 2333
 		case RVE_LAND_OP:
2255 2334
 		case RVE_LOR_OP:
2335
+		case RVE_IEQ_OP:
2336
+		case RVE_IDIFF_OP:
2337
+		case RVE_STREQ_OP:
2338
+		case RVE_STRDIFF_OP:
2256 2339
 			return 1;
2257 2340
 		case RVE_GT_OP:
2258 2341
 		case RVE_GTE_OP:
2259 2342
 		case RVE_LT_OP:
2260 2343
 		case RVE_LTE_OP:
2261 2344
 		case RVE_EQ_OP:
2345
+			return 0;
2262 2346
 		case RVE_DIFF_OP:
2263 2347
 		case RVE_CONCAT_OP:
2264
-			return 0;
2348
+#if !defined(UNDEF_EQ_ALWAYS_FALSE) && !defined(UNDEF_EQ_UNDEF_TRUE)
2349
+			return 1;
2350
+#else
2351
+			return 0 /* asymmetrical undef handling */;
2352
+#endif
2265 2353
 	}
2266 2354
 	return 0;
2267 2355
 }
... ...
@@ -2633,6 +2721,7 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
2633 2721
 				}
2634 2722
 				break;
2635 2723
 			case RVE_EQ_OP:
2724
+			case RVE_STREQ_OP:
2636 2725
 				if (rv->v.s.len==0){
2637 2726
 					/* $v == "" -> strempty($v) 
2638 2727
 					   "" == $v -> strempty ($v) */
... ...
@@ -2973,6 +3062,10 @@ int fix_rval_expr(void** p)
2973 3062
 		case RVE_IPLUS_OP:
2974 3063
 		case RVE_EQ_OP:
2975 3064
 		case RVE_DIFF_OP:
3065
+		case RVE_IEQ_OP:
3066
+		case RVE_IDIFF_OP:
3067
+		case RVE_STREQ_OP:
3068
+		case RVE_STRDIFF_OP:
2976 3069
 		case RVE_CONCAT_OP:
2977 3070
 			ret=fix_rval_expr((void**)&rve->left.rve);
2978 3071
 			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 61
 	RVE_GTE_OP,   /*  2 members, returns left >= right */
60 62
 	RVE_LT_OP,    /*  2 members, returns left  < right */
61 63
 	RVE_LTE_OP,   /*  2 members, returns left <= right */
64
+	RVE_IEQ_OP, /*  2 members, int == version, returns left == right */
65
+	RVE_IDIFF_OP,/* 2 members, int != version, returns left != right */
62 66
 	RVE_IPLUS_OP, /* 2 members, integer +, returns int(a)+int(b) */
63 67
 	/* common int & str */
64 68
 	RVE_PLUS_OP,  /* generic plus (int or str) returns left + right */
... ...
@@ -68,6 +72,8 @@ enum rval_expr_op{
68 72
 	RVE_CONCAT_OP,/* 2 members, string concat, returns left . right (str)*/
69 73
 	RVE_STRLEN_OP, /* one member, string length:, returns strlen(val) (int)*/
70 74
 	RVE_STREMPTY_OP, /* one member, returns val=="" (bool) */
75
+	RVE_STREQ_OP,  /* 2 members, string == , returns left == right (bool)*/
76
+	RVE_STRDIFF_OP,/* 2 members, string != , returns left != right (bool)*/
71 77
 	/* avp, pvars a.s.o */
72 78
 	RVE_DEFINED_OP, /* one member, returns is_defined(val) (bool) */
73 79
 };