Browse code

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

Andrei Pelinescu-Onciul authored on 05/05/2009 11:51:40
Showing 2 changed files
... ...
@@ -28,6 +28,7 @@
28 28
  *               (str)undef="", (int)""=0, (int)"123"=123, (int)"abc"=0
29 29
  *              handle undef == expr, in function of the UNDEF_EQ_* defines.
30 30
  *              (andrei)
31
+ *  2009-05-05  casts operator for int & string (andrei)
31 32
  */
32 33
 
33 34
 /* special defines:
... ...
@@ -480,11 +481,13 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
480 480
 		case RVE_STRLEN_OP:
481 481
 		case RVE_STREMPTY_OP:
482 482
 		case RVE_DEFINED_OP:
483
+		case RVE_INT_OP:
483 484
 			return RV_INT;
484 485
 		case RVE_PLUS_OP:
485 486
 			/* '+' evaluates to the type of the left operand */
486 487
 			return rve_guess_type(rve->left.rve);
487 488
 		case RVE_CONCAT_OP:
489
+		case RVE_STR_OP:
488 490
 			return RV_STR;
489 491
 		case RVE_NONE_OP:
490 492
 			break;
... ...
@@ -522,6 +525,8 @@ int rve_is_constant(struct rval_expr* rve)
522 522
 		case RVE_STRLEN_OP:
523 523
 		case RVE_STREMPTY_OP:
524 524
 		case RVE_DEFINED_OP:
525
+		case RVE_INT_OP:
526
+		case RVE_STR_OP:
525 527
 			return rve_is_constant(rve->left.rve);
526 528
 		case RVE_MINUS_OP:
527 529
 		case RVE_MUL_OP:
... ...
@@ -579,6 +584,8 @@ static int rve_op_unary(enum rval_expr_op op)
579 579
 		case RVE_STRLEN_OP:
580 580
 		case RVE_STREMPTY_OP:
581 581
 		case RVE_DEFINED_OP:
582
+		case RVE_INT_OP:
583
+		case RVE_STR_OP:
582 584
 			return 1;
583 585
 		case RVE_MINUS_OP:
584 586
 		case RVE_MUL_OP:
... ...
@@ -781,6 +788,14 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
781 781
 				return 1;
782 782
 			}
783 783
 			break;
784
+		case RVE_INT_OP:
785
+			*type=RV_INT;
786
+			return 1;
787
+			break;
788
+		case RVE_STR_OP:
789
+			*type=RV_STR;
790
+			return 1;
791
+			break;
784 792
 		case RVE_NONE_OP:
785 793
 		default:
786 794
 			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,
1726 1726
 				break;
1727 1727
 			ret=int_intop1(res, rve->op, i1);
1728 1728
 			break;
1729
+		case RVE_INT_OP:
1730
+			ret=rval_expr_eval_int(h, msg, res, rve->left.rve);
1731
+			break;
1729 1732
 		case RVE_MUL_OP:
1730 1733
 		case RVE_DIV_OP:
1731 1734
 		case RVE_MINUS_OP:
... ...
@@ -1857,27 +1875,49 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1857 1857
 				}
1858 1858
 			}
1859 1859
 			break;
1860
-#if 0
1861
-		case RVE_MATCH_OP:
1862
-				if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1863
-					ret=-1;
1864
-					break;
1865
-				}
1866
-				if (unlikely((rv2=rval_expr_eval(h, msg,
1867
-													rve->right.rve))==0)){
1868
-					rval_destroy(rv1);
1869
-					ret=-1;
1870
-					break;
1871
-				}
1872
-				ret=rval_str_lop2(res, rve->op, rv1, 0, rv2, 0);
1860
+		case RVE_CONCAT_OP:
1861
+			/* eval expression => string */
1862
+			if (unlikely((rv1=rval_expr_eval(h, msg, rve))==0)){
1863
+				ret=-1;
1864
+				break;
1865
+			}
1866
+			/* conver to int */
1867
+			ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
1868
+			rval_destroy(rv1);
1869
+			break;
1870
+		case RVE_STR_OP:
1871
+			/* (str)expr => eval expression */
1872
+			rval_cache_init(&c1);
1873
+			if (unlikely((ret=rval_expr_eval_rvint(h, msg, &rv1, res,
1874
+													rve->left.rve, &c1))<0)){
1875
+				/* error */
1876
+				rval_cache_clean(&c1);
1877
+				break;
1878
+			}
1879
+			if (unlikely(rv1)){
1880
+				/* expr evaluated to string => (int)(str)v == (int)v */
1881
+				ret=rval_get_int(h, msg, res, rv1, &c1); /* convert to int */
1873 1882
 				rval_destroy(rv1);
1874
-				rval_destroy(rv2);
1883
+				rval_cache_clean(&c1);
1884
+			} /* else (rv1==0)
1885
+				 => expr evaluated to int => 
1886
+				 return (int)(str)v == (int)v => do nothing */
1875 1887
 			break;
1876
-#endif
1877
-		case RVE_CONCAT_OP:
1878
-			*res=0;
1879
-			ret=-1;
1888
+
1889
+#if 0
1890
+			/* same thing as above, but in a not optimized, easier to
1891
+			   understand way */
1892
+			/* 1. (str) expr => eval expr */
1893
+			if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1894
+				ret=-1;
1895
+				break;
1896
+			}
1897
+			/* 2. convert to str and then convert to int
1898
+			   but since (int)(str)v == (int)v skip over (str)v */
1899
+			ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
1900
+			rval_destroy(rv1);
1880 1901
 			break;
1902
+#endif
1881 1903
 		case RVE_DEFINED_OP:
1882 1904
 			ret=int_rve_defined(h, msg, res, rve->left.rve);
1883 1905
 			break;
... ...
@@ -1918,8 +1958,19 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1918 1918
 
1919 1919
 /** evals a rval expr. into an int or another rv(str).
1920 1920
  * WARNING: rv result (rv_res) must be rval_destroy()'ed if non-null
1921
- * (it might be a reference to another rval). The result can be 
1921
+ * (it might be a reference to another rval). The result can be
1922 1922
  * modified only if rv_chg_in_place() returns true.
1923
+ * @param res_rv - pointer to rvalue result, if non-null it means the 
1924
+ *                 expression evaluated to a non-int (str), which will be
1925
+ *                 stored here.
1926
+ * @param res_i  - pointer to int result, if res_rv==0 and the function
1927
+ *                 returns success => the result is an int which will be 
1928
+ *                 stored here.
1929
+ * @param rve    - expression that will be evaluated.
1930
+ * @param cache  - write-only value cache, it might be filled if non-null and
1931
+ *                 empty (rval_cache_init()). If non-null, it _must_ be 
1932
+ *                 rval_cache_clean()'ed when done. 
1933
+ *
1923 1934
  * @result  0 on success, -1 on error,  sets *res_rv or *res_i.
1924 1935
  */
1925 1936
 int rval_expr_eval_rvint(			   struct run_act_ctx* h,
... ...
@@ -1986,6 +2037,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
1986 1986
 		case RVE_STRLEN_OP:
1987 1987
 		case RVE_STREMPTY_OP:
1988 1988
 		case RVE_DEFINED_OP:
1989
+		case RVE_INT_OP:
1989 1990
 			/* operator forces integer type */
1990 1991
 			ret=rval_expr_eval_int(h, msg, res_i, rve);
1991 1992
 			*res_rv=0;
... ...
@@ -2020,6 +2072,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
2020 2020
 			rval_cache_clean(&c1);
2021 2021
 			break;
2022 2022
 		case RVE_CONCAT_OP:
2023
+		case RVE_STR_OP:
2023 2024
 			*res_rv=rval_expr_eval(h, msg, rve);
2024 2025
 			ret=-(*res_rv==0);
2025 2026
 			break;
... ...
@@ -2089,6 +2142,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
2089 2089
 		case RVE_STRLEN_OP:
2090 2090
 		case RVE_STREMPTY_OP:
2091 2091
 		case RVE_DEFINED_OP:
2092
+		case RVE_INT_OP:
2092 2093
 			/* operator forces integer type */
2093 2094
 			r=rval_expr_eval_int(h, msg, &i, rve);
2094 2095
 			if (likely(r==0)){
... ...
@@ -2168,6 +2222,14 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
2168 2168
 			}
2169 2169
 			ret=rval_str_add2(h, msg, rv1, 0, rv2, 0);
2170 2170
 			break;
2171
+		case RVE_STR_OP:
2172
+			rv1=rval_expr_eval(h, msg, rve->left.rve);
2173
+			if (unlikely(rv1==0)){
2174
+				ERR("rval expression evaluation failed\n");
2175
+				goto error;
2176
+			}
2177
+			ret=rval_convert(h, msg, RV_STR, rv1, 0);
2178
+			break;
2171 2179
 		case RVE_NONE_OP:
2172 2180
 		/*default:*/
2173 2181
 			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,
2292 2292
 		case RVE_STRLEN_OP:
2293 2293
 		case RVE_STREMPTY_OP:
2294 2294
 		case RVE_DEFINED_OP:
2295
+		case RVE_INT_OP:
2296
+		case RVE_STR_OP:
2295 2297
 			break;
2296 2298
 		default:
2297 2299
 			BUG("unsupported unary operator %d\n", op);
... ...
@@ -2374,6 +2438,8 @@ static int rve_op_is_assoc(enum rval_expr_op op)
2374 2374
 		case RVE_STRLEN_OP:
2375 2375
 		case RVE_STREMPTY_OP:
2376 2376
 		case RVE_DEFINED_OP:
2377
+		case RVE_INT_OP:
2378
+		case RVE_STR_OP:
2377 2379
 			/* one operand expression => cannot be assoc. */
2378 2380
 			return 0;
2379 2381
 		case RVE_DIV_OP:
... ...
@@ -2422,6 +2488,8 @@ static int rve_op_is_commutative(enum rval_expr_op op)
2422 2422
 		case RVE_STRLEN_OP:
2423 2423
 		case RVE_STREMPTY_OP:
2424 2424
 		case RVE_DEFINED_OP:
2425
+		case RVE_INT_OP:
2426
+		case RVE_STR_OP:
2425 2427
 			/* one operand expression => cannot be commut. */
2426 2428
 			return 0;
2427 2429
 		case RVE_DIV_OP:
... ...
@@ -3291,6 +3359,8 @@ int fix_rval_expr(void** p)
3291 3291
 		case RVE_STRLEN_OP:
3292 3292
 		case RVE_STREMPTY_OP:
3293 3293
 		case RVE_DEFINED_OP:
3294
+		case RVE_INT_OP:
3295
+		case RVE_STR_OP:
3294 3296
 			ret=fix_rval_expr((void**)&rve->left.rve);
3295 3297
 			if (ret<0) return ret;
3296 3298
 			break;
... ...
@@ -25,6 +25,7 @@
25 25
  *  2008-11-30  initial version (andrei)
26 26
  *  2009-04-28  added string and interger versions for the EQ and DIFF
27 27
  *              operators (andrei)
28
+ *  2009-05-05  casts operator for int & string (andrei)
28 29
  */
29 30
 
30 31
 #ifndef _rvalue_h_
... ...
@@ -77,6 +78,8 @@ enum rval_expr_op{
77 77
 	RVE_MATCH_OP,  /* 2 members, string ~),  returns left matches re(right) */
78 78
 	/* avp, pvars a.s.o */
79 79
 	RVE_DEFINED_OP, /* one member, returns is_defined(val) (bool) */
80
+	RVE_INT_OP,   /* one member, returns (int)val  (int) */
81
+	RVE_STR_OP    /* one member, returns (str)val  (str) */
80 82
 };
81 83
 
82 84