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 781
 <INITIAL>{BIN_OR}	{ count(); return BIN_OR;  }
781 782
 <INITIAL>{PLUS}		{ count(); return PLUS; }
782 783
 <INITIAL>{MINUS}	{ count(); return MINUS; }
784
+<INITIAL>{MODULO}	{ count(); return MODULO; }
783 785
 <INITIAL>{STRLEN}	{ count(); return STRLEN; }
784 786
 <INITIAL>{STREMPTY}	{ count(); return STREMPTY; }
785 787
 <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 2332
 		| rval_expr MINUS rval_expr		{$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
2332 2333
 		| rval_expr STAR rval_expr		{$$=mk_rve2(RVE_MUL_OP, $1, $3); }
2333 2334
 		| rval_expr SLASH rval_expr		{$$=mk_rve2(RVE_DIV_OP, $1, $3); }
2335
+		| rval_expr MODULO rval_expr	{$$=mk_rve2(RVE_MOD_OP, $1, $3); }
2334 2336
 		| rval_expr BIN_OR rval_expr	{$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
2335 2337
 		| rval_expr BIN_AND rval_expr	{$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
2336 2338
 		| rval_expr rve_cmpop %prec GT rval_expr { $$=mk_rve2( $2, $1, $3);}
... ...
@@ -2349,6 +2351,7 @@ rval_expr: rval						{ $$=$1;
2349 2351
 		| rval_expr MINUS error			{ $$=0; yyerror("bad expression"); }
2350 2352
 		| rval_expr STAR error			{ $$=0; yyerror("bad expression"); }
2351 2353
 		| rval_expr SLASH error			{ $$=0; yyerror("bad expression"); }
2354
+		| rval_expr MODULO error			{ $$=0; yyerror("bad expression"); }
2352 2355
 		| rval_expr BIN_OR error		{ $$=0; yyerror("bad expression"); }
2353 2356
 		| rval_expr BIN_AND error		{ $$=0; yyerror("bad expression"); }
2354 2357
 		| 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 532
 		case RVE_MINUS_OP:
532 533
 		case RVE_MUL_OP:
533 534
 		case RVE_DIV_OP:
535
+		case RVE_MOD_OP:
534 536
 		case RVE_BOR_OP:
535 537
 		case RVE_BAND_OP:
536 538
 		case RVE_LAND_OP:
... ...
@@ -590,6 +592,7 @@ static int rve_op_unary(enum rval_expr_op op)
590 592
 		case RVE_MINUS_OP:
591 593
 		case RVE_MUL_OP:
592 594
 		case RVE_DIV_OP:
595
+		case RVE_MOD_OP:
593 596
 		case RVE_BOR_OP:
594 597
 		case RVE_BAND_OP:
595 598
 		case RVE_LAND_OP:
... ...
@@ -659,6 +662,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
659 662
 		case RVE_MINUS_OP:
660 663
 		case RVE_MUL_OP:
661 664
 		case RVE_DIV_OP:
665
+		case RVE_MOD_OP:
662 666
 		case RVE_BOR_OP:
663 667
 		case RVE_BAND_OP:
664 668
 		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 1237
 			}
1234 1238
 			*res=v1/v2;
1235 1239
 			break;
1240
+		case RVE_MOD_OP:
1241
+			if (unlikely(v2==0)){
1242
+				ERR("rv mod by 0\n");
1243
+				return -1;
1244
+			}
1245
+			*res=v1%v2;
1246
+			break;
1236 1247
 		case RVE_BOR_OP:
1237 1248
 			*res=v1|v2;
1238 1249
 			break;
... ...
@@ -1746,6 +1757,7 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1746 1757
 			break;
1747 1758
 		case RVE_MUL_OP:
1748 1759
 		case RVE_DIV_OP:
1760
+		case RVE_MOD_OP:
1749 1761
 		case RVE_MINUS_OP:
1750 1762
 		case RVE_PLUS_OP:
1751 1763
 		case RVE_IPLUS_OP:
... ...
@@ -2018,6 +2030,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
2018 2030
 		case RVE_MINUS_OP:
2019 2031
 		case RVE_MUL_OP:
2020 2032
 		case RVE_DIV_OP:
2033
+		case RVE_MOD_OP:
2021 2034
 		case RVE_BOR_OP:
2022 2035
 		case RVE_BAND_OP:
2023 2036
 		case RVE_LAND_OP:
... ...
@@ -2123,6 +2136,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
2123 2136
 		case RVE_MINUS_OP:
2124 2137
 		case RVE_MUL_OP:
2125 2138
 		case RVE_DIV_OP:
2139
+		case RVE_MOD_OP:
2126 2140
 		case RVE_BOR_OP:
2127 2141
 		case RVE_BAND_OP:
2128 2142
 		case RVE_LAND_OP:
... ...
@@ -2389,6 +2403,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
2389 2403
 	switch(op){
2390 2404
 		case RVE_MUL_OP:
2391 2405
 		case RVE_DIV_OP:
2406
+		case RVE_MOD_OP:
2392 2407
 		case RVE_MINUS_OP:
2393 2408
 		case RVE_BOR_OP:
2394 2409
 		case RVE_BAND_OP:
... ...
@@ -2443,6 +2458,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
2443 2458
 			/* one operand expression => cannot be assoc. */
2444 2459
 			return 0;
2445 2460
 		case RVE_DIV_OP:
2461
+		case RVE_MOD_OP:
2446 2462
 		case RVE_MINUS_OP:
2447 2463
 			return 0;
2448 2464
 		case RVE_PLUS_OP:
... ...
@@ -2493,6 +2509,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
2493 2509
 			/* one operand expression => cannot be commut. */
2494 2510
 			return 0;
2495 2511
 		case RVE_DIV_OP:
2512
+		case RVE_MOD_OP:
2496 2513
 		case RVE_MINUS_OP:
2497 2514
 			return 0;
2498 2515
 		case RVE_PLUS_OP:
... ...
@@ -2888,6 +2905,21 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
2888 2905
 					}
2889 2906
 				}
2890 2907
 				break;
2908
+			case RVE_MOD_OP:
2909
+				if (i==0){
2910
+					if (ct_rve==rve->left.rve){
2911
+						/* 0 % $v -> 0 */
2912
+						if (rve_replace_with_ct_rv(rve, rv)<0)
2913
+							goto error;
2914
+						ret=1;
2915
+					}else{
2916
+						/* $v % 0 */
2917
+						ERR("RVE modulo by 0 at %d,%d\n",
2918
+								ct_rve->fpos.s_line, ct_rve->fpos.s_col);
2919
+					}
2920
+				}
2921
+				/* $v % 1 -> 0 ? */
2922
+				break;
2891 2923
 			case RVE_MINUS_OP:
2892 2924
 				if (i==0){
2893 2925
 					if (ct_rve==rve->right.rve){
... ...
@@ -3513,6 +3545,7 @@ int fix_rval_expr(void** p)
3513 3545
 			break;
3514 3546
 		case RVE_MUL_OP:
3515 3547
 		case RVE_DIV_OP:
3548
+		case RVE_MOD_OP:
3516 3549
 		case RVE_MINUS_OP:
3517 3550
 		case RVE_BOR_OP:
3518 3551
 		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 */