[sr-dev] git:master: core: added modulo operation

Daniel-Constantin Mierla miconda at gmail.com
Thu Jun 4 09:12:43 CEST 2009


Module: sip-router
Branch: master
Commit: 333a3335217ece2e3d2f8089d854ba347f36b9af
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=333a3335217ece2e3d2f8089d854ba347f36b9af

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Thu Jun  4 09:59:59 2009 +0300

core: added modulo operation

- a mod b - return the modulo result

---

 cfg.lex  |    2 ++
 cfg.y    |    5 ++++-
 rvalue.c |   33 +++++++++++++++++++++++++++++++++
 rvalue.h |    1 +
 4 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/cfg.lex b/cfg.lex
index ab30135..ef89626 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -246,6 +246,7 @@ LOG_OR		"or"|"||"
 BIN_OR          "|"
 PLUS	"+"
 MINUS	"-"
+MODULO	"mod"
 STRLEN	"strlen"
 STREMPTY	"strempty"
 DEFINED		"defined"
@@ -780,6 +781,7 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{BIN_OR}	{ count(); return BIN_OR;  }
 <INITIAL>{PLUS}		{ count(); return PLUS; }
 <INITIAL>{MINUS}	{ count(); return MINUS; }
+<INITIAL>{MODULO}	{ count(); return MODULO; }
 <INITIAL>{STRLEN}	{ count(); return STRLEN; }
 <INITIAL>{STREMPTY}	{ count(); return STREMPTY; }
 <INITIAL>{DEFINED}	{ count(); return DEFINED; }
diff --git a/cfg.y b/cfg.y
index 4729d03..ade8aaa 100644
--- a/cfg.y
+++ b/cfg.y
@@ -492,7 +492,7 @@ static int case_check_default(struct case_stms* stms);
 %left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
 %left GT LT GTE LTE
 %left PLUS MINUS
-%left STAR SLASH
+%left STAR SLASH MODULO
 %right NOT
 %right DEFINED
 %right INTCAST STRCAST
@@ -2315,6 +2315,7 @@ rve_op:		PLUS		{ $$=RVE_PLUS_OP; }
 		|	MINUS		{ $$=RVE_MINUS_OP; }
 		|	STAR		{ $$=RVE_MUL_OP; }
 		|	SLASH		{ $$=RVE_DIV_OP; }
+		|	MODULO		{ $$=RVE_MOD_OP; }
 	;
 */
 
@@ -2331,6 +2332,7 @@ rval_expr: rval						{ $$=$1;
 		| rval_expr MINUS rval_expr		{$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
 		| rval_expr STAR rval_expr		{$$=mk_rve2(RVE_MUL_OP, $1, $3); }
 		| rval_expr SLASH rval_expr		{$$=mk_rve2(RVE_DIV_OP, $1, $3); }
+		| rval_expr MODULO rval_expr	{$$=mk_rve2(RVE_MOD_OP, $1, $3); }
 		| rval_expr BIN_OR rval_expr	{$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
 		| rval_expr BIN_AND rval_expr	{$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
 		| rval_expr rve_cmpop %prec GT rval_expr { $$=mk_rve2( $2, $1, $3);}
@@ -2349,6 +2351,7 @@ rval_expr: rval						{ $$=$1;
 		| rval_expr MINUS error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr STAR error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr SLASH error			{ $$=0; yyerror("bad expression"); }
+		| rval_expr MODULO error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr BIN_OR error		{ $$=0; yyerror("bad expression"); }
 		| rval_expr BIN_AND error		{ $$=0; yyerror("bad expression"); }
 		| rval_expr rve_cmpop %prec GT error
diff --git a/rvalue.c b/rvalue.c
index 5bc7ca8..27ab268 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -462,6 +462,7 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
 		case RVE_MINUS_OP:
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
 		case RVE_LAND_OP:
@@ -531,6 +532,7 @@ int rve_is_constant(struct rval_expr* rve)
 		case RVE_MINUS_OP:
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
 		case RVE_LAND_OP:
@@ -590,6 +592,7 @@ static int rve_op_unary(enum rval_expr_op op)
 		case RVE_MINUS_OP:
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
 		case RVE_LAND_OP:
@@ -659,6 +662,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
 		case RVE_MINUS_OP:
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
 		case RVE_LAND_OP:
@@ -1233,6 +1237,13 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
 			}
 			*res=v1/v2;
 			break;
+		case RVE_MOD_OP:
+			if (unlikely(v2==0)){
+				ERR("rv mod by 0\n");
+				return -1;
+			}
+			*res=v1%v2;
+			break;
 		case RVE_BOR_OP:
 			*res=v1|v2;
 			break;
@@ -1746,6 +1757,7 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
 			break;
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_MINUS_OP:
 		case RVE_PLUS_OP:
 		case RVE_IPLUS_OP:
@@ -2018,6 +2030,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
 		case RVE_MINUS_OP:
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
 		case RVE_LAND_OP:
@@ -2123,6 +2136,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
 		case RVE_MINUS_OP:
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
 		case RVE_LAND_OP:
@@ -2389,6 +2403,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
 	switch(op){
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_MINUS_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
@@ -2443,6 +2458,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
 			/* one operand expression => cannot be assoc. */
 			return 0;
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_MINUS_OP:
 			return 0;
 		case RVE_PLUS_OP:
@@ -2493,6 +2509,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
 			/* one operand expression => cannot be commut. */
 			return 0;
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_MINUS_OP:
 			return 0;
 		case RVE_PLUS_OP:
@@ -2888,6 +2905,21 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
 					}
 				}
 				break;
+			case RVE_MOD_OP:
+				if (i==0){
+					if (ct_rve==rve->left.rve){
+						/* 0 % $v -> 0 */
+						if (rve_replace_with_ct_rv(rve, rv)<0)
+							goto error;
+						ret=1;
+					}else{
+						/* $v % 0 */
+						ERR("RVE modulo by 0 at %d,%d\n",
+								ct_rve->fpos.s_line, ct_rve->fpos.s_col);
+					}
+				}
+				/* $v % 1 -> 0 ? */
+				break;
 			case RVE_MINUS_OP:
 				if (i==0){
 					if (ct_rve==rve->right.rve){
@@ -3513,6 +3545,7 @@ int fix_rval_expr(void** p)
 			break;
 		case RVE_MUL_OP:
 		case RVE_DIV_OP:
+		case RVE_MOD_OP:
 		case RVE_MINUS_OP:
 		case RVE_BOR_OP:
 		case RVE_BAND_OP:
diff --git a/rvalue.h b/rvalue.h
index 652c902..f658c5e 100644
--- a/rvalue.h
+++ b/rvalue.h
@@ -53,6 +53,7 @@ enum rval_expr_op{
 	RVE_LNOT_OP,  /* one member evaluate as bool. : (!val)*/
 	RVE_MUL_OP,   /* 2 members, returns left * right */
 	RVE_DIV_OP,   /* 2 members, returns left / right */
+	RVE_MOD_OP,   /* 2 members, returns left % right */
 	RVE_MINUS_OP, /* 2 members, returns left - right */
 	RVE_BAND_OP,  /* 2 members, returns left | right */
 	RVE_BOR_OP,   /* 2 members, returns left & right */




More information about the sr-dev mailing list