Module: sip-router Branch: master Commit: 333a3335217ece2e3d2f8089d854ba347f36b9af URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=333a3335...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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 */