Browse code

script engine: more operators supported

- support for more operators
- more helper functions
- small fixes

Andrei Pelinescu-Onciul authored on 09/12/2008 15:13:03
Showing 2 changed files
... ...
@@ -34,7 +34,7 @@
34 34
 #define rv_ref(rv) ((rv)->refcnt++)
35 35
 
36 36
 /** unref rv and returns true if 0 */
37
-#define rv_unref(rv) (((rv)->refcnt--)==0)
37
+#define rv_unref(rv) ((--(rv)->refcnt)==0)
38 38
 
39 39
 
40 40
 inline static void rval_force_clean(struct rvalue* rv)
... ...
@@ -316,6 +316,183 @@ error:
316 316
 
317 317
 
318 318
 
319
+/** guess the type of an expression.
320
+  * @return RV_INT, RV_STR or RV_NONE (when type could not be found,
321
+  * e.g. avp or pvar)
322
+  */
323
+enum rval_type rve_guess_type( struct rval_expr* rve)
324
+{
325
+	switch(rve->op){
326
+		case RVE_RVAL_OP:
327
+			switch(rve->left.rval.type){
328
+				case RV_STR:
329
+				case RV_SEL:
330
+					return RV_STR;
331
+				case RV_INT:
332
+				case RV_BEXPR:
333
+				case RV_ACTION_ST:
334
+					return RV_INT;
335
+				case RV_PVAR:
336
+				case RV_AVP:
337
+				case RV_NONE:
338
+					return RV_NONE;
339
+			}
340
+			break;
341
+		case RVE_UMINUS_OP:
342
+		case RVE_BOOL_OP:
343
+		case RVE_LNOT_OP:
344
+		case RVE_MINUS_OP:
345
+		case RVE_MUL_OP:
346
+		case RVE_DIV_OP:
347
+		case RVE_BOR_OP:
348
+		case RVE_BAND_OP:
349
+		case RVE_LAND_OP:
350
+		case RVE_LOR_OP:
351
+		case RVE_GT_OP:
352
+		case RVE_GTE_OP:
353
+		case RVE_LT_OP:
354
+		case RVE_LTE_OP:
355
+		case RVE_EQ_OP:
356
+		case RVE_DIFF_OP:
357
+			return RV_INT;
358
+		case RVE_PLUS_OP:
359
+			/* '+' evaluates to the type of the left operand */
360
+			return rve_guess_type(rve->left.rve);
361
+		case RVE_NONE_OP:
362
+			break;
363
+	}
364
+	return RV_NONE;
365
+}
366
+
367
+
368
+
369
+/** returns true if expression is constant.
370
+  * @return 0 or 1 on
371
+  *  non constant type
372
+  */
373
+int rve_is_constant(struct rval_expr* rve)
374
+{
375
+	switch(rve->op){
376
+		case RVE_RVAL_OP:
377
+			switch(rve->left.rval.type){
378
+				case RV_STR:
379
+					return 1;
380
+				case RV_INT:
381
+					return 1;
382
+				case RV_SEL:
383
+				case RV_BEXPR:
384
+				case RV_ACTION_ST:
385
+				case RV_PVAR:
386
+				case RV_AVP:
387
+				case RV_NONE:
388
+					return 0;
389
+			}
390
+			break;
391
+		case RVE_UMINUS_OP:
392
+		case RVE_BOOL_OP:
393
+		case RVE_LNOT_OP:
394
+			return rve_is_constant(rve->left.rve);
395
+		case RVE_MINUS_OP:
396
+		case RVE_MUL_OP:
397
+		case RVE_DIV_OP:
398
+		case RVE_BOR_OP:
399
+		case RVE_BAND_OP:
400
+		case RVE_LAND_OP:
401
+		case RVE_LOR_OP:
402
+		case RVE_GT_OP:
403
+		case RVE_GTE_OP:
404
+		case RVE_LT_OP:
405
+		case RVE_LTE_OP:
406
+		case RVE_EQ_OP:
407
+		case RVE_DIFF_OP:
408
+		case RVE_PLUS_OP:
409
+			return rve_is_constant(rve->left.rve) &&
410
+					rve_is_constant(rve->right.rve);
411
+		case RVE_NONE_OP:
412
+			break;
413
+	}
414
+	return 0;
415
+}
416
+
417
+
418
+
419
+/** returns 1 if expression is valid (type-wise).
420
+  * @return 0 or 1  and sets *type to the resulting type
421
+  * (RV_INT, RV_STR or RV_NONE if it can be found only at runtime)
422
+  */
423
+int rve_check_type(enum rval_type* type, struct rval_expr* rve)
424
+{
425
+	enum rval_type type1, type2;
426
+	
427
+	switch(rve->op){
428
+		case RVE_RVAL_OP:
429
+			*type=rve_guess_type(rve);
430
+			return 1;
431
+		case RVE_UMINUS_OP:
432
+		case RVE_BOOL_OP:
433
+		case RVE_LNOT_OP:
434
+			*type=RV_INT;
435
+			if (rve_check_type(&type1, rve->left.rve)){
436
+				if (type1==RV_STR)
437
+					return 0;
438
+				return 1;
439
+			}
440
+			return 0;
441
+			break;
442
+		case RVE_MINUS_OP:
443
+		case RVE_MUL_OP:
444
+		case RVE_DIV_OP:
445
+		case RVE_BOR_OP:
446
+		case RVE_BAND_OP:
447
+		case RVE_LAND_OP:
448
+		case RVE_LOR_OP:
449
+		case RVE_GT_OP:
450
+		case RVE_GTE_OP:
451
+		case RVE_LT_OP:
452
+		case RVE_LTE_OP:
453
+			*type=RV_INT;
454
+			if (rve_check_type(&type1, rve->left.rve)){
455
+				if (type1==RV_STR)
456
+					return 0;
457
+				if (rve_check_type(&type2, rve->right.rve)){
458
+					if (type2==RV_STR)
459
+						return 0;
460
+					return 1;
461
+				}
462
+			}
463
+			return 0;
464
+		case RVE_EQ_OP:
465
+		case RVE_DIFF_OP:
466
+			*type=RV_INT;
467
+			if (rve_check_type(&type1, rve->left.rve)){
468
+				if (rve_check_type(&type2, rve->right.rve)){
469
+					if ((type2!=type1) && (type1!=RV_NONE) &&
470
+							(type2!=RV_NONE) && 
471
+							!(type1==RV_STR && type2==RV_INT))
472
+						return 0;
473
+					return 1;
474
+				}
475
+			}
476
+			return 0;
477
+		case RVE_PLUS_OP:
478
+			if (rve_check_type(&type1, rve->left.rve)){
479
+				if (rve_check_type(&type2, rve->right.rve)){
480
+					if ((type2!=type1) && (type1!=RV_NONE) &&
481
+							(type2!=RV_NONE) && 
482
+							!(type1==RV_STR && type2==RV_INT))
483
+						return 0;
484
+					*type=type1;
485
+					return 1;
486
+				}
487
+			}
488
+		case RVE_NONE_OP:
489
+			break;
490
+	}
491
+	return 0;
492
+}
493
+
494
+
495
+
319 496
 /** get the integer value of an rvalue.
320 497
   * *i=(int)rv
321 498
   * @return 0 on success, \<0 on error and EXPR_DROP on drop
... ...
@@ -403,7 +580,7 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
403 403
 	return 0;
404 404
 rv_str:
405 405
 	/* rv is of string type => error */
406
-	ERR("string in int expression\n");
406
+	/* ERR("string in int expression\n"); */
407 407
 error:
408 408
 	return -1;
409 409
 }
... ...
@@ -672,6 +849,36 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
672 672
 			}
673 673
 			*res=v1/v2;
674 674
 			break;
675
+		case RVE_BOR_OP:
676
+			*res=v1|v2;
677
+			break;
678
+		case RVE_BAND_OP:
679
+			*res=v1&v2;
680
+			break;
681
+		case RVE_LAND_OP:
682
+			*res=v1 && v2;
683
+			break;
684
+		case RVE_LOR_OP:
685
+			*res=v1 || v2;
686
+			break;
687
+		case RVE_GT_OP:
688
+			*res=v1 > v2;
689
+			break;
690
+		case RVE_GTE_OP:
691
+			*res=v1 >= v2;
692
+			break;
693
+		case RVE_LT_OP:
694
+			*res=v1 < v2;
695
+			break;
696
+		case RVE_LTE_OP:
697
+			*res=v1 <= v2;
698
+			break;
699
+		case RVE_EQ_OP:
700
+			*res=v1 == v2;
701
+			break;
702
+		case RVE_DIFF_OP:
703
+			*res=v1 != v2;
704
+			break;
675 705
 		default:
676 706
 			BUG("rv unsupported intop %d\n", op);
677 707
 			return -1;
... ...
@@ -681,6 +888,20 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
681 681
 
682 682
 
683 683
 
684
+inline static int bool_strop2( enum rval_expr_op op, int* res,
685
+								str* s1, str* s2)
686
+{
687
+	if (s1->len!=s2->len)
688
+		*res= op==RVE_DIFF_OP;
689
+	else if (memcmp(s1->s, s2->s, s1->len)==0)
690
+		*res= op==RVE_EQ_OP;
691
+	else
692
+		*res= op==RVE_DIFF_OP;
693
+	return 0;
694
+}
695
+
696
+
697
+
684 698
 /** integer operation: ret= op v (returns a rvalue).
685 699
  * @return rvalue on success, 0 on error
686 700
  */
... ...
@@ -899,6 +1120,52 @@ error:
899 899
 
900 900
 
901 901
 
902
+/** bool operation on rval evaluated as strings.
903
+ * Can use cached rvalues (c1 & c2).
904
+ * @return 0 success, -1 on error
905
+ */
906
+inline static int rval_str_lop2(struct run_act_ctx* h,
907
+						 struct sip_msg* msg,
908
+						 int* res,
909
+						 enum rval_expr_op op,
910
+						 struct rvalue* l,
911
+						 struct rval_cache* c1,
912
+						 struct rvalue* r,
913
+						 struct rval_cache* c2)
914
+{
915
+	struct rvalue* rv1;
916
+	struct rvalue* rv2;
917
+	int ret;
918
+	
919
+	rv2=rv1=0;
920
+	ret=0;
921
+	if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
922
+		goto error;
923
+	if ((rv2=rval_convert(h, msg, RV_STR, r, c2))==0)
924
+		goto error;
925
+	ret=bool_strop2(op, res, &rv1->v.s, &rv2->v.s);
926
+	rval_destroy(rv1); 
927
+	rval_destroy(rv2); 
928
+	return ret;
929
+error:
930
+	rval_destroy(rv1); 
931
+	rval_destroy(rv2); 
932
+	return 0;
933
+}
934
+
935
+
936
+
937
+/* forward decl. */
938
+inline static int rval_expr_eval_rvint(struct run_act_ctx* h,
939
+									   struct sip_msg* msg,
940
+									   struct rvalue** res_rv,
941
+									   int* res_i,
942
+									   struct rval_expr* rve,
943
+									   struct rval_cache* cache
944
+									   );
945
+
946
+
947
+
902 948
 /** evals an integer expr  to an int.
903 949
  * 
904 950
  *  *res=(int)eval(rve)
... ...
@@ -908,7 +1175,11 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
908 908
 						int* res, struct rval_expr* rve)
909 909
 {
910 910
 	int i1, i2, ret;
911
+	struct rval_cache c1;
912
+	struct rvalue* rv1;
913
+	struct rvalue* rv2;
911 914
 	
915
+	ret=-1;
912 916
 	switch(rve->op){
913 917
 		case RVE_RVAL_OP:
914 918
 			ret=rval_get_int(h, msg, res,  &rve->left.rval, 0);
... ...
@@ -925,6 +1196,14 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
925 925
 		case RVE_DIV_OP:
926 926
 		case RVE_MINUS_OP:
927 927
 		case RVE_PLUS_OP:
928
+		case RVE_BOR_OP:
929
+		case RVE_BAND_OP:
930
+		case RVE_LAND_OP:
931
+		case RVE_LOR_OP:
932
+		case RVE_GT_OP:
933
+		case RVE_GTE_OP:
934
+		case RVE_LT_OP:
935
+		case RVE_LTE_OP:
928 936
 			if (unlikely(
929 937
 					(ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
930 938
 				break;
... ...
@@ -933,8 +1212,56 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
933 933
 				break;
934 934
 			ret=int_intop2(res, rve->op, i1, i2);
935 935
 			break;
936
+		case RVE_EQ_OP:
937
+		case RVE_DIFF_OP:
938
+			/* if left is string, eval left & right as string and
939
+			   use string diff, else eval as int */
940
+			rval_cache_init(&c1);
941
+			if (unlikely( (ret=rval_expr_eval_rvint(h, msg, &rv1, &i1,
942
+													rve->left.rve, &c1))<0)){
943
+				rval_cache_clean(&c1);
944
+				break;
945
+			}
946
+			if (likely(rv1==0)){
947
+				/* int */
948
+				rval_cache_clean(&c1);
949
+				if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
950
+														rve->right.rve)) <0) )
951
+					break;
952
+				ret=int_intop2(res, rve->op, i1, i2);
953
+			}else{
954
+				if (unlikely((rv2=rval_expr_eval(h, msg,
955
+													rve->right.rve))==0)){
956
+					rval_destroy(rv1);
957
+					rval_cache_clean(&c1);
958
+					ret=-1;
959
+					break;
960
+				}
961
+				ret=rval_str_lop2(h, msg, res, rve->op, rv1, &c1, rv2, 0);
962
+				rval_cache_clean(&c1);
963
+				rval_destroy(rv1);
964
+				rval_destroy(rv2);
965
+			}
966
+			break;
967
+#if 0
968
+		case RVE_MATCH_OP:
969
+				if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
970
+					ret=-1;
971
+					break;
972
+				}
973
+				if (unlikely((rv2=rval_expr_eval(h, msg,
974
+													rve->right.rve))==0)){
975
+					rval_destroy(rv1);
976
+					ret=-1;
977
+					break;
978
+				}
979
+				ret=rval_str_lop2(res, rve->op, rv1, 0, rv2, 0);
980
+				rval_destroy(rv1);
981
+				rval_destroy(rv2);
982
+			break;
983
+#endif
936 984
 		case RVE_NONE_OP:
937
-		default:
985
+		/*default:*/
938 986
 			BUG("invalid rval int expression operation %d\n", rve->op);
939 987
 			ret=-1;
940 988
 	};
... ...
@@ -943,6 +1270,115 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
943 943
 
944 944
 
945 945
 
946
+/** evals a rval expr. into an int or another rv(str).
947
+ * WARNING: rv result (rv_res) must be rval_destroy()'ed if non-null
948
+ * (it might be a reference to another rval). The result can be 
949
+ * modified only if rv_chg_in_place() returns true.
950
+ * @result  0 on success, -1 on error,  sets *res_rv or *res_i.
951
+ */
952
+inline static int rval_expr_eval_rvint(struct run_act_ctx* h,
953
+									   struct sip_msg* msg,
954
+									   struct rvalue** res_rv,
955
+									   int* res_i,
956
+									   struct rval_expr* rve,
957
+									   struct rval_cache* cache
958
+									   )
959
+{
960
+	struct rvalue* rv1;
961
+	struct rvalue* rv2;
962
+	struct rval_cache c1; /* local cache */
963
+	int ret;
964
+	int r, i, j;
965
+	enum rval_type type;
966
+	
967
+	rv1=0;
968
+	rv2=0;
969
+	switch(rve->op){
970
+		case RVE_RVAL_OP:
971
+			rv1=&rve->left.rval;
972
+			rv_ref(rv1);
973
+			type=rval_get_btype(h, msg, rv1, cache);
974
+			if (type==RV_INT){
975
+					r=rval_get_int(h, msg, res_i, rv1, cache);
976
+					if (unlikely(r<0)){
977
+						ERR("rval expression evaluation failed\n");
978
+						goto error;
979
+					}
980
+					*res_rv=0;
981
+					ret=0;
982
+			}else{
983
+				/* RV_STR, RV_PVAR, RV_AVP a.s.o => return rv1 and the 
984
+				   cached resolved value in cache*/
985
+					*res_rv=rv1;
986
+					rv_ref(rv1);
987
+					ret=0;
988
+			}
989
+			break;
990
+		case RVE_UMINUS_OP:
991
+		case RVE_BOOL_OP:
992
+		case RVE_LNOT_OP:
993
+		case RVE_MINUS_OP:
994
+		case RVE_MUL_OP:
995
+		case RVE_DIV_OP:
996
+		case RVE_BOR_OP:
997
+		case RVE_BAND_OP:
998
+		case RVE_LAND_OP:
999
+		case RVE_LOR_OP:
1000
+		case RVE_GT_OP:
1001
+		case RVE_GTE_OP:
1002
+		case RVE_LT_OP:
1003
+		case RVE_LTE_OP:
1004
+		case RVE_EQ_OP:
1005
+		case RVE_DIFF_OP:
1006
+			/* operator forces integer type */
1007
+			ret=rval_expr_eval_int(h, msg, res_i, rve);
1008
+			*res_rv=0;
1009
+			break;
1010
+		case RVE_PLUS_OP:
1011
+			rval_cache_init(&c1);
1012
+			r=rval_expr_eval_rvint(h, msg, &rv1, &i, rve->left.rve, &c1);
1013
+			if (unlikely(r<0)){
1014
+				ERR("rval expression evaluation failed\n");
1015
+				rval_cache_clean(&c1);
1016
+				goto error;
1017
+			}
1018
+			if (rv1==0){
1019
+				if (unlikely((r=rval_expr_eval_int(h, msg, &j,
1020
+														rve->right.rve))<0)){
1021
+						ERR("rval expression evaluation failed\n");
1022
+						rval_cache_clean(&c1);
1023
+						goto error;
1024
+				}
1025
+				int_intop2(res_i, rve->op, i, j);
1026
+				*res_rv=0;
1027
+			}else{
1028
+				rv2=rval_expr_eval(h, msg, rve->right.rve);
1029
+				if (unlikely(rv2==0)){
1030
+					ERR("rval expression evaluation failed\n");
1031
+					rval_cache_clean(&c1);
1032
+					goto error;
1033
+				}
1034
+				*res_rv=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
1035
+				ret=-(*res_rv==0);
1036
+			}
1037
+			rval_cache_clean(&c1);
1038
+			break;
1039
+		case RVE_NONE_OP:
1040
+		/*default:*/
1041
+			BUG("invalid rval expression operation %d\n", rve->op);
1042
+			goto error;
1043
+	};
1044
+	rval_destroy(rv1);
1045
+	rval_destroy(rv2);
1046
+	return ret;
1047
+error:
1048
+	rval_destroy(rv1);
1049
+	rval_destroy(rv2);
1050
+	return -1;
1051
+}
1052
+
1053
+
1054
+
946 1055
 /** evals a rval expr..
947 1056
  * WARNING: result must be rval_destroy()'ed if non-null (it might be
948 1057
  * a reference to another rval). The result can be modified only
... ...
@@ -973,6 +1409,16 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
973 973
 		case RVE_MINUS_OP:
974 974
 		case RVE_MUL_OP:
975 975
 		case RVE_DIV_OP:
976
+		case RVE_BOR_OP:
977
+		case RVE_BAND_OP:
978
+		case RVE_LAND_OP:
979
+		case RVE_LOR_OP:
980
+		case RVE_GT_OP:
981
+		case RVE_GTE_OP:
982
+		case RVE_LT_OP:
983
+		case RVE_LTE_OP:
984
+		case RVE_EQ_OP:
985
+		case RVE_DIFF_OP:
976 986
 			/* operator forces integer type */
977 987
 			r=rval_expr_eval_int(h, msg, &i, rve);
978 988
 			if (likely(r==0)){
... ...
@@ -988,31 +1434,6 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
988 988
 				goto error;
989 989
 			}
990 990
 			break;
991
-#if 0
992
-		case RVE_UMINUS_OP:
993
-		case RVE_BOOL_OP:
994
-		case RVE_LNOT_OP:
995
-			rv1=rval_expr_eval(h, msg, rve->left.rve);
996
-			if (likely(rv1)){
997
-				ret=rv_intop1(op, rv1, 0);
998
-				rval_destroy(rv1);
999
-				return ret;
1000
-			}else{
1001
-				ERR("rval expression evaluation failed\n");
1002
-				goto error;
1003
-			}
1004
-			break;
1005
-		case RVE_MUL_OP:
1006
-		case RVE_DIV_OP:
1007
-			rv1=rval_expr_eval(h, msg, rve->left.rve);
1008
-			rv2=rval_expr_eval(h, msg, rve->right.rve);
1009
-			if (unlikely(rv1==0 || rv2==0)){
1010
-				ERR("rval expression evaluation failed\n");
1011
-				goto error;
1012
-			}
1013
-			ret=rv_intop2(rve->op, rv1, 0, rv2, 0);
1014
-			break;
1015
-#endif
1016 991
 		case RVE_PLUS_OP:
1017 992
 			rv1=rval_expr_eval(h, msg, rve->left.rve);
1018 993
 			if (unlikely(rv1==0)){
... ...
@@ -1034,12 +1455,13 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1034 1034
 						ERR("rval expression evaluation failed\n");
1035 1035
 						goto error;
1036 1036
 					}
1037
+					int_intop2(&r, rve->op, i, j);
1037 1038
 					if (rv_chg_in_place(rv1)){
1038
-						rv1->v.l=i+j;
1039
+						rv1->v.l=r;
1039 1040
 						ret=rv1;
1040 1041
 						rv_ref(ret);
1041 1042
 					}else{
1042
-						v.l=i+j;
1043
+						v.l=r;
1043 1044
 						ret=rval_new(RV_INT, &v, 0);
1044 1045
 						if (unlikely(ret==0)){
1045 1046
 							rval_cache_clean(&c1);
... ...
@@ -1066,7 +1488,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1066 1066
 			rval_cache_clean(&c1);
1067 1067
 			break;
1068 1068
 		case RVE_NONE_OP:
1069
-		default:
1069
+		/*default:*/
1070 1070
 			BUG("invalid rval expression operation %d\n", rve->op);
1071 1071
 			goto error;
1072 1072
 	};
... ...
@@ -1188,7 +1610,17 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
1188 1188
 		case RVE_MUL_OP:
1189 1189
 		case RVE_DIV_OP:
1190 1190
 		case RVE_MINUS_OP:
1191
+		case RVE_BOR_OP:
1192
+		case RVE_BAND_OP:
1193
+		case RVE_LAND_OP:
1194
+		case RVE_LOR_OP:
1195
+		case RVE_GT_OP:
1196
+		case RVE_GTE_OP:
1197
+		case RVE_LT_OP:
1198
+		case RVE_LTE_OP:
1191 1199
 		case RVE_PLUS_OP:
1200
+		case RVE_EQ_OP:
1201
+		case RVE_DIFF_OP:
1192 1202
 			break;
1193 1203
 		default:
1194 1204
 			BUG("unsupported operator %d\n", op);
... ...
@@ -1215,8 +1647,6 @@ static int rve_can_optimize_int(struct rval_expr* rve)
1215 1215
 {
1216 1216
 	if (rve->op == RVE_RVAL_OP)
1217 1217
 		return 0;
1218
-	DBG("rve_can_optimize_int: left %d, right %d\n", 
1219
-			rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
1220 1218
 	if (rve->left.rve->op != RVE_RVAL_OP)
1221 1219
 		return 0;
1222 1220
 	if (rve->left.rve->left.rval.type!=RV_INT)
... ...
@@ -1227,6 +1657,8 @@ static int rve_can_optimize_int(struct rval_expr* rve)
1227 1227
 		if (rve->right.rve->left.rval.type!=RV_INT)
1228 1228
 			return 0;
1229 1229
 	}
1230
+	DBG("rve_can_optimize_int: left %d, right %d\n", 
1231
+			rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
1230 1232
 	return 1;
1231 1233
 }
1232 1234
 
... ...
@@ -1289,10 +1721,9 @@ static int fix_rval(struct rvalue* rv)
1289 1289
 			return 0;
1290 1290
 		case RV_NONE:
1291 1291
 			BUG("uninitialized rvalue\n");
1292
-			break;
1293
-		default:
1294
-			BUG("unknown rvalue type %d\n", rv->type);
1292
+			return -1;
1295 1293
 	}
1294
+	BUG("unknown rvalue type %d\n", rv->type);
1296 1295
 	return -1;
1297 1296
 }
1298 1297
 
... ...
@@ -1333,7 +1764,17 @@ int fix_rval_expr(void** p)
1333 1333
 		case RVE_MUL_OP:
1334 1334
 		case RVE_DIV_OP:
1335 1335
 		case RVE_MINUS_OP:
1336
+		case RVE_BOR_OP:
1337
+		case RVE_BAND_OP:
1338
+		case RVE_LAND_OP:
1339
+		case RVE_LOR_OP:
1340
+		case RVE_GT_OP:
1341
+		case RVE_GTE_OP:
1342
+		case RVE_LT_OP:
1343
+		case RVE_LTE_OP:
1336 1344
 		case RVE_PLUS_OP:
1345
+		case RVE_EQ_OP:
1346
+		case RVE_DIFF_OP:
1337 1347
 			ret=fix_rval_expr((void**)&rve->left.rve);
1338 1348
 			if (ret<0) return ret;
1339 1349
 			ret=fix_rval_expr((void**)&rve->right.rve);
... ...
@@ -1353,8 +1794,8 @@ int fix_rval_expr(void** p)
1353 1353
 		v.l=i;
1354 1354
 		rval_init(&rve->left.rval, RV_INT, &v, 0);
1355 1355
 		rval_init(&rve->right.rval, RV_NONE, 0, 0);
1356
-		rve->op=RVE_RVAL_OP;
1357 1356
 		DBG("FIXUP RVE: optimized int rve/rves (op %d) to %d\n", rve->op, i);
1357
+		rve->op=RVE_RVAL_OP;
1358 1358
 	}else if (rve_can_optimize_str(rve)){
1359 1359
 		if ((rv=rval_expr_eval(0, 0, rve))==0){
1360 1360
 			BUG("unexpected failure\n");
... ...
@@ -1369,9 +1810,9 @@ int fix_rval_expr(void** p)
1369 1369
 		rve_destroy(rve->right.rve);
1370 1370
 		rval_init(&rve->left.rval, RV_STR, &v, RV_CNT_ALLOCED_F);
1371 1371
 		rval_init(&rve->right.rval, RV_NONE, 0, 0);
1372
-		rve->op=RVE_RVAL_OP;
1373 1372
 		DBG("FIXUP RVE: optimized str rves (op %d) to %.*s\n",
1374 1373
 				rve->op, v.s.len, v.s.s);
1374
+		rve->op=RVE_RVAL_OP;
1375 1375
 	}
1376 1376
 	return 0;
1377 1377
 }
... ...
@@ -49,10 +49,20 @@ enum rval_expr_op{
49 49
 	RVE_BOOL_OP,  /* one member evaluate as bool. : (val!=0)*/
50 50
 	RVE_LNOT_OP,  /* one member evaluate as bool. : (!val)*/
51 51
 	RVE_MUL_OP,   /* 2 members, returns left * right */
52
-	RVE_DIV_OP,   /* 2 memebers, returns left / right */
53
-	RVE_MINUS_OP, /* 2 memebers, returns left - right */
52
+	RVE_DIV_OP,   /* 2 members, returns left / right */
53
+	RVE_MINUS_OP, /* 2 members, returns left - right */
54
+	RVE_BAND_OP,  /* 2 members, returns left | right */
55
+	RVE_BOR_OP,   /* 2 members, returns left & right */
56
+	RVE_LAND_OP,  /* 2 members, returns left && right */
57
+	RVE_LOR_OP,   /* 2 members, returns left || right */
58
+	RVE_GT_OP,    /*  2 members, returns left > right */
59
+	RVE_GTE_OP,   /*  2 members, returns left >= right */
60
+	RVE_LT_OP,    /*  2 members, returns left  < right */
61
+	RVE_LTE_OP,   /*  2 members, returns left <= right */
54 62
 	/* common int & str */
55
-	RVE_PLUS_OP  /* 2 members, returns left + right */
63
+	RVE_PLUS_OP,  /* 2 members, returns left + right  (int or str)*/
64
+	RVE_EQ_OP,    /*  2 members, returns left == right  (int)*/
65
+	RVE_DIFF_OP,  /*  2 members, returns left != right  (int)*/
56 66
 	/* str only */
57 67
 };
58 68
 
... ...
@@ -152,6 +162,11 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg, int* i,
152 152
 int rval_get_str(struct run_act_ctx* h, struct sip_msg* msg,
153 153
 								str* s, struct rvalue* rv,
154 154
 								struct rval_cache* cache);
155
+/** get the string value of an rv in a tmp variable */
156
+int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
157
+								str* tmpv, struct rvalue* rv,
158
+								struct rval_cache* cache,
159
+								struct rval_cache* tmp_cache);
155 160
 
156 161
 /** evals an integer expr  to an int. */
157 162
 int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
... ...
@@ -160,8 +175,14 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
160 160
 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
161 161
 								struct rval_expr* rve);
162 162
 
163
+/** guess the type of an expression.  */
164
+enum rval_type rve_guess_type(struct rval_expr* rve);
165
+/** returns true if expression is constant. */
166
+int rve_is_constant(struct rval_expr* rve);
167
+/** returns 1 if expression is valid (type-wise).*/
168
+int rve_check_type(enum rval_type* type, struct rval_expr* rve);
163 169
 
164
-/** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type.
170
+/** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type
165 171
   */
166 172
 struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val);
167 173
 /** create a unary op. rval_expr.. */