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 580
 	return 0;
404 581
 rv_str:
405 582
 	/* rv is of string type => error */
406
-	ERR("string in int expression\n");
583
+	/* ERR("string in int expression\n"); */
407 584
 error:
408 585
 	return -1;
409 586
 }
... ...
@@ -672,6 +849,36 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
672 849
 			}
673 850
 			*res=v1/v2;
674 851
 			break;
852
+		case RVE_BOR_OP:
853
+			*res=v1|v2;
854
+			break;
855
+		case RVE_BAND_OP:
856
+			*res=v1&v2;
857
+			break;
858
+		case RVE_LAND_OP:
859
+			*res=v1 && v2;
860
+			break;
861
+		case RVE_LOR_OP:
862
+			*res=v1 || v2;
863
+			break;
864
+		case RVE_GT_OP:
865
+			*res=v1 > v2;
866
+			break;
867
+		case RVE_GTE_OP:
868
+			*res=v1 >= v2;
869
+			break;
870
+		case RVE_LT_OP:
871
+			*res=v1 < v2;
872
+			break;
873
+		case RVE_LTE_OP:
874
+			*res=v1 <= v2;
875
+			break;
876
+		case RVE_EQ_OP:
877
+			*res=v1 == v2;
878
+			break;
879
+		case RVE_DIFF_OP:
880
+			*res=v1 != v2;
881
+			break;
675 882
 		default:
676 883
 			BUG("rv unsupported intop %d\n", op);
677 884
 			return -1;
... ...
@@ -681,6 +888,20 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
681 888
 
682 889
 
683 890
 
891
+inline static int bool_strop2( enum rval_expr_op op, int* res,
892
+								str* s1, str* s2)
893
+{
894
+	if (s1->len!=s2->len)
895
+		*res= op==RVE_DIFF_OP;
896
+	else if (memcmp(s1->s, s2->s, s1->len)==0)
897
+		*res= op==RVE_EQ_OP;
898
+	else
899
+		*res= op==RVE_DIFF_OP;
900
+	return 0;
901
+}
902
+
903
+
904
+
684 905
 /** integer operation: ret= op v (returns a rvalue).
685 906
  * @return rvalue on success, 0 on error
686 907
  */
... ...
@@ -899,6 +1120,52 @@ error:
899 1120
 
900 1121
 
901 1122
 
1123
+/** bool operation on rval evaluated as strings.
1124
+ * Can use cached rvalues (c1 & c2).
1125
+ * @return 0 success, -1 on error
1126
+ */
1127
+inline static int rval_str_lop2(struct run_act_ctx* h,
1128
+						 struct sip_msg* msg,
1129
+						 int* res,
1130
+						 enum rval_expr_op op,
1131
+						 struct rvalue* l,
1132
+						 struct rval_cache* c1,
1133
+						 struct rvalue* r,
1134
+						 struct rval_cache* c2)
1135
+{
1136
+	struct rvalue* rv1;
1137
+	struct rvalue* rv2;
1138
+	int ret;
1139
+	
1140
+	rv2=rv1=0;
1141
+	ret=0;
1142
+	if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
1143
+		goto error;
1144
+	if ((rv2=rval_convert(h, msg, RV_STR, r, c2))==0)
1145
+		goto error;
1146
+	ret=bool_strop2(op, res, &rv1->v.s, &rv2->v.s);
1147
+	rval_destroy(rv1); 
1148
+	rval_destroy(rv2); 
1149
+	return ret;
1150
+error:
1151
+	rval_destroy(rv1); 
1152
+	rval_destroy(rv2); 
1153
+	return 0;
1154
+}
1155
+
1156
+
1157
+
1158
+/* forward decl. */
1159
+inline static int rval_expr_eval_rvint(struct run_act_ctx* h,
1160
+									   struct sip_msg* msg,
1161
+									   struct rvalue** res_rv,
1162
+									   int* res_i,
1163
+									   struct rval_expr* rve,
1164
+									   struct rval_cache* cache
1165
+									   );
1166
+
1167
+
1168
+
902 1169
 /** evals an integer expr  to an int.
903 1170
  * 
904 1171
  *  *res=(int)eval(rve)
... ...
@@ -908,7 +1175,11 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
908 1175
 						int* res, struct rval_expr* rve)
909 1176
 {
910 1177
 	int i1, i2, ret;
1178
+	struct rval_cache c1;
1179
+	struct rvalue* rv1;
1180
+	struct rvalue* rv2;
911 1181
 	
1182
+	ret=-1;
912 1183
 	switch(rve->op){
913 1184
 		case RVE_RVAL_OP:
914 1185
 			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 1196
 		case RVE_DIV_OP:
926 1197
 		case RVE_MINUS_OP:
927 1198
 		case RVE_PLUS_OP:
1199
+		case RVE_BOR_OP:
1200
+		case RVE_BAND_OP:
1201
+		case RVE_LAND_OP:
1202
+		case RVE_LOR_OP:
1203
+		case RVE_GT_OP:
1204
+		case RVE_GTE_OP:
1205
+		case RVE_LT_OP:
1206
+		case RVE_LTE_OP:
928 1207
 			if (unlikely(
929 1208
 					(ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
930 1209
 				break;
... ...
@@ -933,8 +1212,56 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
933 1212
 				break;
934 1213
 			ret=int_intop2(res, rve->op, i1, i2);
935 1214
 			break;
1215
+		case RVE_EQ_OP:
1216
+		case RVE_DIFF_OP:
1217
+			/* if left is string, eval left & right as string and
1218
+			   use string diff, else eval as int */
1219
+			rval_cache_init(&c1);
1220
+			if (unlikely( (ret=rval_expr_eval_rvint(h, msg, &rv1, &i1,
1221
+													rve->left.rve, &c1))<0)){
1222
+				rval_cache_clean(&c1);
1223
+				break;
1224
+			}
1225
+			if (likely(rv1==0)){
1226
+				/* int */
1227
+				rval_cache_clean(&c1);
1228
+				if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
1229
+														rve->right.rve)) <0) )
1230
+					break;
1231
+				ret=int_intop2(res, rve->op, i1, i2);
1232
+			}else{
1233
+				if (unlikely((rv2=rval_expr_eval(h, msg,
1234
+													rve->right.rve))==0)){
1235
+					rval_destroy(rv1);
1236
+					rval_cache_clean(&c1);
1237
+					ret=-1;
1238
+					break;
1239
+				}
1240
+				ret=rval_str_lop2(h, msg, res, rve->op, rv1, &c1, rv2, 0);
1241
+				rval_cache_clean(&c1);
1242
+				rval_destroy(rv1);
1243
+				rval_destroy(rv2);
1244
+			}
1245
+			break;
1246
+#if 0
1247
+		case RVE_MATCH_OP:
1248
+				if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
1249
+					ret=-1;
1250
+					break;
1251
+				}
1252
+				if (unlikely((rv2=rval_expr_eval(h, msg,
1253
+													rve->right.rve))==0)){
1254
+					rval_destroy(rv1);
1255
+					ret=-1;
1256
+					break;
1257
+				}
1258
+				ret=rval_str_lop2(res, rve->op, rv1, 0, rv2, 0);
1259
+				rval_destroy(rv1);
1260
+				rval_destroy(rv2);
1261
+			break;
1262
+#endif
936 1263
 		case RVE_NONE_OP:
937
-		default:
1264
+		/*default:*/
938 1265
 			BUG("invalid rval int expression operation %d\n", rve->op);
939 1266
 			ret=-1;
940 1267
 	};
... ...
@@ -943,6 +1270,115 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
943 1270
 
944 1271
 
945 1272
 
1273
+/** evals a rval expr. into an int or another rv(str).
1274
+ * WARNING: rv result (rv_res) must be rval_destroy()'ed if non-null
1275
+ * (it might be a reference to another rval). The result can be 
1276
+ * modified only if rv_chg_in_place() returns true.
1277
+ * @result  0 on success, -1 on error,  sets *res_rv or *res_i.
1278
+ */
1279
+inline static int rval_expr_eval_rvint(struct run_act_ctx* h,
1280
+									   struct sip_msg* msg,
1281
+									   struct rvalue** res_rv,
1282
+									   int* res_i,
1283
+									   struct rval_expr* rve,
1284
+									   struct rval_cache* cache
1285
+									   )
1286
+{
1287
+	struct rvalue* rv1;
1288
+	struct rvalue* rv2;
1289
+	struct rval_cache c1; /* local cache */
1290
+	int ret;
1291
+	int r, i, j;
1292
+	enum rval_type type;
1293
+	
1294
+	rv1=0;
1295
+	rv2=0;
1296
+	switch(rve->op){
1297
+		case RVE_RVAL_OP:
1298
+			rv1=&rve->left.rval;
1299
+			rv_ref(rv1);
1300
+			type=rval_get_btype(h, msg, rv1, cache);
1301
+			if (type==RV_INT){
1302
+					r=rval_get_int(h, msg, res_i, rv1, cache);
1303
+					if (unlikely(r<0)){
1304
+						ERR("rval expression evaluation failed\n");
1305
+						goto error;
1306
+					}
1307
+					*res_rv=0;
1308
+					ret=0;
1309
+			}else{
1310
+				/* RV_STR, RV_PVAR, RV_AVP a.s.o => return rv1 and the 
1311
+				   cached resolved value in cache*/
1312
+					*res_rv=rv1;
1313
+					rv_ref(rv1);
1314
+					ret=0;
1315
+			}
1316
+			break;
1317
+		case RVE_UMINUS_OP:
1318
+		case RVE_BOOL_OP:
1319
+		case RVE_LNOT_OP:
1320
+		case RVE_MINUS_OP:
1321
+		case RVE_MUL_OP:
1322
+		case RVE_DIV_OP:
1323
+		case RVE_BOR_OP:
1324
+		case RVE_BAND_OP:
1325
+		case RVE_LAND_OP:
1326
+		case RVE_LOR_OP:
1327
+		case RVE_GT_OP:
1328
+		case RVE_GTE_OP:
1329
+		case RVE_LT_OP:
1330
+		case RVE_LTE_OP:
1331
+		case RVE_EQ_OP:
1332
+		case RVE_DIFF_OP:
1333
+			/* operator forces integer type */
1334
+			ret=rval_expr_eval_int(h, msg, res_i, rve);
1335
+			*res_rv=0;
1336
+			break;
1337
+		case RVE_PLUS_OP:
1338
+			rval_cache_init(&c1);
1339
+			r=rval_expr_eval_rvint(h, msg, &rv1, &i, rve->left.rve, &c1);
1340
+			if (unlikely(r<0)){
1341
+				ERR("rval expression evaluation failed\n");
1342
+				rval_cache_clean(&c1);
1343
+				goto error;
1344
+			}
1345
+			if (rv1==0){
1346
+				if (unlikely((r=rval_expr_eval_int(h, msg, &j,
1347
+														rve->right.rve))<0)){
1348
+						ERR("rval expression evaluation failed\n");
1349
+						rval_cache_clean(&c1);
1350
+						goto error;
1351
+				}
1352
+				int_intop2(res_i, rve->op, i, j);
1353
+				*res_rv=0;
1354
+			}else{
1355
+				rv2=rval_expr_eval(h, msg, rve->right.rve);
1356
+				if (unlikely(rv2==0)){
1357
+					ERR("rval expression evaluation failed\n");
1358
+					rval_cache_clean(&c1);
1359
+					goto error;
1360
+				}
1361
+				*res_rv=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
1362
+				ret=-(*res_rv==0);
1363
+			}
1364
+			rval_cache_clean(&c1);
1365
+			break;
1366
+		case RVE_NONE_OP:
1367
+		/*default:*/
1368
+			BUG("invalid rval expression operation %d\n", rve->op);
1369
+			goto error;
1370
+	};
1371
+	rval_destroy(rv1);
1372
+	rval_destroy(rv2);
1373
+	return ret;
1374
+error:
1375
+	rval_destroy(rv1);
1376
+	rval_destroy(rv2);
1377
+	return -1;
1378
+}
1379
+
1380
+
1381
+
946 1382
 /** evals a rval expr..
947 1383
  * WARNING: result must be rval_destroy()'ed if non-null (it might be
948 1384
  * 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 1409
 		case RVE_MINUS_OP:
974 1410
 		case RVE_MUL_OP:
975 1411
 		case RVE_DIV_OP:
1412
+		case RVE_BOR_OP:
1413
+		case RVE_BAND_OP:
1414
+		case RVE_LAND_OP:
1415
+		case RVE_LOR_OP:
1416
+		case RVE_GT_OP:
1417
+		case RVE_GTE_OP:
1418
+		case RVE_LT_OP:
1419
+		case RVE_LTE_OP:
1420
+		case RVE_EQ_OP:
1421
+		case RVE_DIFF_OP:
976 1422
 			/* operator forces integer type */
977 1423
 			r=rval_expr_eval_int(h, msg, &i, rve);
978 1424
 			if (likely(r==0)){
... ...
@@ -988,31 +1434,6 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
988 1434
 				goto error;
989 1435
 			}
990 1436
 			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 1437
 		case RVE_PLUS_OP:
1017 1438
 			rv1=rval_expr_eval(h, msg, rve->left.rve);
1018 1439
 			if (unlikely(rv1==0)){
... ...
@@ -1034,12 +1455,13 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1034 1455
 						ERR("rval expression evaluation failed\n");
1035 1456
 						goto error;
1036 1457
 					}
1458
+					int_intop2(&r, rve->op, i, j);
1037 1459
 					if (rv_chg_in_place(rv1)){
1038
-						rv1->v.l=i+j;
1460
+						rv1->v.l=r;
1039 1461
 						ret=rv1;
1040 1462
 						rv_ref(ret);
1041 1463
 					}else{
1042
-						v.l=i+j;
1464
+						v.l=r;
1043 1465
 						ret=rval_new(RV_INT, &v, 0);
1044 1466
 						if (unlikely(ret==0)){
1045 1467
 							rval_cache_clean(&c1);
... ...
@@ -1066,7 +1488,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
1066 1488
 			rval_cache_clean(&c1);
1067 1489
 			break;
1068 1490
 		case RVE_NONE_OP:
1069
-		default:
1491
+		/*default:*/
1070 1492
 			BUG("invalid rval expression operation %d\n", rve->op);
1071 1493
 			goto error;
1072 1494
 	};
... ...
@@ -1188,7 +1610,17 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
1188 1610
 		case RVE_MUL_OP:
1189 1611
 		case RVE_DIV_OP:
1190 1612
 		case RVE_MINUS_OP:
1613
+		case RVE_BOR_OP:
1614
+		case RVE_BAND_OP:
1615
+		case RVE_LAND_OP:
1616
+		case RVE_LOR_OP:
1617
+		case RVE_GT_OP:
1618
+		case RVE_GTE_OP:
1619
+		case RVE_LT_OP:
1620
+		case RVE_LTE_OP:
1191 1621
 		case RVE_PLUS_OP:
1622
+		case RVE_EQ_OP:
1623
+		case RVE_DIFF_OP:
1192 1624
 			break;
1193 1625
 		default:
1194 1626
 			BUG("unsupported operator %d\n", op);
... ...
@@ -1215,8 +1647,6 @@ static int rve_can_optimize_int(struct rval_expr* rve)
1215 1647
 {
1216 1648
 	if (rve->op == RVE_RVAL_OP)
1217 1649
 		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 1650
 	if (rve->left.rve->op != RVE_RVAL_OP)
1221 1651
 		return 0;
1222 1652
 	if (rve->left.rve->left.rval.type!=RV_INT)
... ...
@@ -1227,6 +1657,8 @@ static int rve_can_optimize_int(struct rval_expr* rve)
1227 1657
 		if (rve->right.rve->left.rval.type!=RV_INT)
1228 1658
 			return 0;
1229 1659
 	}
1660
+	DBG("rve_can_optimize_int: left %d, right %d\n", 
1661
+			rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
1230 1662
 	return 1;
1231 1663
 }
1232 1664
 
... ...
@@ -1289,10 +1721,9 @@ static int fix_rval(struct rvalue* rv)
1289 1721
 			return 0;
1290 1722
 		case RV_NONE:
1291 1723
 			BUG("uninitialized rvalue\n");
1292
-			break;
1293
-		default:
1294
-			BUG("unknown rvalue type %d\n", rv->type);
1724
+			return -1;
1295 1725
 	}
1726
+	BUG("unknown rvalue type %d\n", rv->type);
1296 1727
 	return -1;
1297 1728
 }
1298 1729
 
... ...
@@ -1333,7 +1764,17 @@ int fix_rval_expr(void** p)
1333 1764
 		case RVE_MUL_OP:
1334 1765
 		case RVE_DIV_OP:
1335 1766
 		case RVE_MINUS_OP:
1767
+		case RVE_BOR_OP:
1768
+		case RVE_BAND_OP:
1769
+		case RVE_LAND_OP:
1770
+		case RVE_LOR_OP:
1771
+		case RVE_GT_OP:
1772
+		case RVE_GTE_OP:
1773
+		case RVE_LT_OP:
1774
+		case RVE_LTE_OP:
1336 1775
 		case RVE_PLUS_OP:
1776
+		case RVE_EQ_OP:
1777
+		case RVE_DIFF_OP:
1337 1778
 			ret=fix_rval_expr((void**)&rve->left.rve);
1338 1779
 			if (ret<0) return ret;
1339 1780
 			ret=fix_rval_expr((void**)&rve->right.rve);
... ...
@@ -1353,8 +1794,8 @@ int fix_rval_expr(void** p)
1353 1794
 		v.l=i;
1354 1795
 		rval_init(&rve->left.rval, RV_INT, &v, 0);
1355 1796
 		rval_init(&rve->right.rval, RV_NONE, 0, 0);
1356
-		rve->op=RVE_RVAL_OP;
1357 1797
 		DBG("FIXUP RVE: optimized int rve/rves (op %d) to %d\n", rve->op, i);
1798
+		rve->op=RVE_RVAL_OP;
1358 1799
 	}else if (rve_can_optimize_str(rve)){
1359 1800
 		if ((rv=rval_expr_eval(0, 0, rve))==0){
1360 1801
 			BUG("unexpected failure\n");
... ...
@@ -1369,9 +1810,9 @@ int fix_rval_expr(void** p)
1369 1810
 		rve_destroy(rve->right.rve);
1370 1811
 		rval_init(&rve->left.rval, RV_STR, &v, RV_CNT_ALLOCED_F);
1371 1812
 		rval_init(&rve->right.rval, RV_NONE, 0, 0);
1372
-		rve->op=RVE_RVAL_OP;
1373 1813
 		DBG("FIXUP RVE: optimized str rves (op %d) to %.*s\n",
1374 1814
 				rve->op, v.s.len, v.s.s);
1815
+		rve->op=RVE_RVAL_OP;
1375 1816
 	}
1376 1817
 	return 0;
1377 1818
 }
... ...
@@ -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 162
 int rval_get_str(struct run_act_ctx* h, struct sip_msg* msg,
153 163
 								str* s, struct rvalue* rv,
154 164
 								struct rval_cache* cache);
165
+/** get the string value of an rv in a tmp variable */
166
+int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
167
+								str* tmpv, struct rvalue* rv,
168
+								struct rval_cache* cache,
169
+								struct rval_cache* tmp_cache);
155 170
 
156 171
 /** evals an integer expr  to an int. */
157 172
 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 175
 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
161 176
 								struct rval_expr* rve);
162 177
 
178
+/** guess the type of an expression.  */
179
+enum rval_type rve_guess_type(struct rval_expr* rve);
180
+/** returns true if expression is constant. */
181
+int rve_is_constant(struct rval_expr* rve);
182
+/** returns 1 if expression is valid (type-wise).*/
183
+int rve_check_type(enum rval_type* type, struct rval_expr* rve);
163 184
 
164
-/** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type.
185
+/** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type
165 186
   */
166 187
 struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val);
167 188
 /** create a unary op. rval_expr.. */