Browse code

core: added modulo operation

- a mod b - return the modulo result

Daniel-Constantin Mierla authored on 04/06/2009 06:59:59
Showing 4 changed files
... ...
@@ -246,6 +246,7 @@ LOG_OR		"or"|"||"
246 246
 BIN_OR          "|"
247 247
 PLUS	"+"
248 248
 MINUS	"-"
249
+MODULO	"mod"
249 250
 STRLEN	"strlen"
250 251
 STREMPTY	"strempty"
251 252
 DEFINED		"defined"
... ...
@@ -780,6 +781,7 @@ EAT_ABLE	[\ \t\b\r]
780 780
 <INITIAL>{BIN_OR}	{ count(); return BIN_OR;  }
781 781
 <INITIAL>{PLUS}		{ count(); return PLUS; }
782 782
 <INITIAL>{MINUS}	{ count(); return MINUS; }
783
+<INITIAL>{MODULO}	{ count(); return MODULO; }
783 784
 <INITIAL>{STRLEN}	{ count(); return STRLEN; }
784 785
 <INITIAL>{STREMPTY}	{ count(); return STREMPTY; }
785 786
 <INITIAL>{DEFINED}	{ count(); return DEFINED; }
... ...
@@ -492,7 +492,7 @@ static int case_check_default(struct case_stms* stms);
492 492
 %left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
493 493
 %left GT LT GTE LTE
494 494
 %left PLUS MINUS
495
-%left STAR SLASH
495
+%left STAR SLASH MODULO
496 496
 %right NOT
497 497
 %right DEFINED
498 498
 %right INTCAST STRCAST
... ...
@@ -2315,6 +2315,7 @@ rve_op:		PLUS		{ $$=RVE_PLUS_OP; }
2315 2315
 		|	MINUS		{ $$=RVE_MINUS_OP; }
2316 2316
 		|	STAR		{ $$=RVE_MUL_OP; }
2317 2317
 		|	SLASH		{ $$=RVE_DIV_OP; }
2318
+		|	MODULO		{ $$=RVE_MOD_OP; }
2318 2319
 	;
2319 2320
 */
2320 2321
 
... ...
@@ -2331,6 +2332,7 @@ rval_expr: rval						{ $$=$1;
2331 2331
 		| rval_expr MINUS rval_expr		{$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
2332 2332
 		| rval_expr STAR rval_expr		{$$=mk_rve2(RVE_MUL_OP, $1, $3); }
2333 2333
 		| rval_expr SLASH rval_expr		{$$=mk_rve2(RVE_DIV_OP, $1, $3); }
2334
+		| rval_expr MODULO rval_expr	{$$=mk_rve2(RVE_MOD_OP, $1, $3); }
2334 2335
 		| rval_expr BIN_OR rval_expr	{$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
2335 2336
 		| rval_expr BIN_AND rval_expr	{$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
2336 2337
 		| rval_expr rve_cmpop %prec GT rval_expr { $$=mk_rve2( $2, $1, $3);}
... ...
@@ -2349,6 +2351,7 @@ rval_expr: rval						{ $$=$1;
2349 2349
 		| rval_expr MINUS error			{ $$=0; yyerror("bad expression"); }
2350 2350
 		| rval_expr STAR error			{ $$=0; yyerror("bad expression"); }
2351 2351
 		| rval_expr SLASH error			{ $$=0; yyerror("bad expression"); }
2352
+		| rval_expr MODULO error			{ $$=0; yyerror("bad expression"); }
2352 2353
 		| rval_expr BIN_OR error		{ $$=0; yyerror("bad expression"); }
2353 2354
 		| rval_expr BIN_AND error		{ $$=0; yyerror("bad expression"); }
2354 2355
 		| rval_expr rve_cmpop %prec GT error
... ...
@@ -462,6 +462,7 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
462 462
 		case RVE_MINUS_OP:
463 463
 		case RVE_MUL_OP:
464 464
 		case RVE_DIV_OP:
465
+		case RVE_MOD_OP:
465 466
 		case RVE_BOR_OP:
466 467
 		case RVE_BAND_OP:
467 468
 		case RVE_LAND_OP:
... ...
@@ -531,6 +532,7 @@ int rve_is_constant(struct rval_expr* rve)
531 531
 		case RVE_MINUS_OP:
532 532
 		case RVE_MUL_OP:
533 533
 		case RVE_DIV_OP:
534
+		case RVE_MOD_OP:
534 535
 		case RVE_BOR_OP:
535 536
 		case RVE_BAND_OP:
536 537
 		case RVE_LAND_OP:
... ...
@@ -590,6 +592,7 @@ static int rve_op_unary(enum rval_expr_op op)
590 590
 		case RVE_MINUS_OP:
591 591
 		case RVE_MUL_OP:
592 592
 		case RVE_DIV_OP:
593
+		case RVE_MOD_OP:
593 594
 		case RVE_BOR_OP:
594 595
 		case RVE_BAND_OP:
595 596
 		case RVE_LAND_OP:
... ...
@@ -659,6 +662,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
659 659
 		case RVE_MINUS_OP:
660 660
 		case RVE_MUL_OP:
661 661
 		case RVE_DIV_OP:
662
+		case RVE_MOD_OP:
662 663
 		case RVE_BOR_OP:
663 664
 		case RVE_BAND_OP:
664 665
 		case RVE_LAND_OP:
... ...
@@ -1233,6 +1237,13 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
1233 1233
 			}
1234 1234
 			*res=v1/v2;
1235 1235
 			break;
1236
+		case RVE_MOD_OP:
1237
+			if (unlikely(v2==0)){
1238
+				ERR("rv mod by 0\n");
1239
+				return -1;
1240
+			}
1241
+			*res=v1%v2;
1242
+			break;
1236 1243
 		case RVE_BOR_OP:
1237 1244
 			*res=v1|v2;
1238 1245
 			break;
... ...
@@ -1746,6 +1757,7 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1746 1746
 			break;
1747 1747
 		case RVE_MUL_OP:
1748 1748
 		case RVE_DIV_OP:
1749
+		case RVE_MOD_OP:
1749 1750
 		case RVE_MINUS_OP:
1750 1751
 		case RVE_PLUS_OP:
1751 1752
 		case RVE_IPLUS_OP:
... ...
@@ -2018,6 +2030,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
2018 2018
 		case RVE_MINUS_OP:
2019 2019
 		case RVE_MUL_OP:
2020 2020
 		case RVE_DIV_OP:
2021
+		case RVE_MOD_OP:
2021 2022
 		case RVE_BOR_OP:
2022 2023
 		case RVE_BAND_OP:
2023 2024
 		case RVE_LAND_OP:
... ...
@@ -2123,6 +2136,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
2123 2123
 		case RVE_MINUS_OP:
2124 2124
 		case RVE_MUL_OP:
2125 2125
 		case RVE_DIV_OP:
2126
+		case RVE_MOD_OP:
2126 2127
 		case RVE_BOR_OP:
2127 2128
 		case RVE_BAND_OP:
2128 2129
 		case RVE_LAND_OP:
... ...
@@ -2389,6 +2403,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
2389 2389
 	switch(op){
2390 2390
 		case RVE_MUL_OP:
2391 2391
 		case RVE_DIV_OP:
2392
+		case RVE_MOD_OP:
2392 2393
 		case RVE_MINUS_OP:
2393 2394
 		case RVE_BOR_OP:
2394 2395
 		case RVE_BAND_OP:
... ...
@@ -2443,6 +2458,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
2443 2443
 			/* one operand expression => cannot be assoc. */
2444 2444
 			return 0;
2445 2445
 		case RVE_DIV_OP:
2446
+		case RVE_MOD_OP:
2446 2447
 		case RVE_MINUS_OP:
2447 2448
 			return 0;
2448 2449
 		case RVE_PLUS_OP:
... ...
@@ -2493,6 +2509,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
2493 2493
 			/* one operand expression => cannot be commut. */
2494 2494
 			return 0;
2495 2495
 		case RVE_DIV_OP:
2496
+		case RVE_MOD_OP:
2496 2497
 		case RVE_MINUS_OP:
2497 2498
 			return 0;
2498 2499
 		case RVE_PLUS_OP:
... ...
@@ -2888,6 +2905,21 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
2888 2888
 					}
2889 2889
 				}
2890 2890
 				break;
2891
+			case RVE_MOD_OP:
2892
+				if (i==0){
2893
+					if (ct_rve==rve->left.rve){
2894
+						/* 0 % $v -> 0 */
2895
+						if (rve_replace_with_ct_rv(rve, rv)<0)
2896
+							goto error;
2897
+						ret=1;
2898
+					}else{
2899
+						/* $v % 0 */
2900
+						ERR("RVE modulo by 0 at %d,%d\n",
2901
+								ct_rve->fpos.s_line, ct_rve->fpos.s_col);
2902
+					}
2903
+				}
2904
+				/* $v % 1 -> 0 ? */
2905
+				break;
2891 2906
 			case RVE_MINUS_OP:
2892 2907
 				if (i==0){
2893 2908
 					if (ct_rve==rve->right.rve){
... ...
@@ -3513,6 +3545,7 @@ int fix_rval_expr(void** p)
3513 3513
 			break;
3514 3514
 		case RVE_MUL_OP:
3515 3515
 		case RVE_DIV_OP:
3516
+		case RVE_MOD_OP:
3516 3517
 		case RVE_MINUS_OP:
3517 3518
 		case RVE_BOR_OP:
3518 3519
 		case RVE_BAND_OP:
... ...
@@ -53,6 +53,7 @@ enum rval_expr_op{
53 53
 	RVE_LNOT_OP,  /* one member evaluate as bool. : (!val)*/
54 54
 	RVE_MUL_OP,   /* 2 members, returns left * right */
55 55
 	RVE_DIV_OP,   /* 2 members, returns left / right */
56
+	RVE_MOD_OP,   /* 2 members, returns left % right */
56 57
 	RVE_MINUS_OP, /* 2 members, returns left - right */
57 58
 	RVE_BAND_OP,  /* 2 members, returns left | right */
58 59
 	RVE_BOR_OP,   /* 2 members, returns left & right */