00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include "rvalue.h"
00065
00066 #include <stdlib.h>
00067
00068
00069 #define RV_STR2INT_VERBOSE_ERR
00070
00071
00072
00073 #define RV_STR2INT_ERR
00074
00075
00076
00077
00078 #define RVAL_GET_INT_ERR_WARN
00079
00080
00081
00082
00083
00084
00085 #define RVAL_GET_INT_ERR_IGN
00086
00087
00088
00089 #define RV_STR_EXTRA 80
00090
00091 #define rv_ref(rv) ((rv)->refcnt++)
00092
00094 #define rv_unref(rv) ((--(rv)->refcnt)==0)
00095
00096
00097 inline static void rval_force_clean(struct rvalue* rv)
00098 {
00099 if (rv->flags & RV_CNT_ALLOCED_F){
00100 switch(rv->type){
00101 case RV_STR:
00102 pkg_free(rv->v.s.s);
00103 rv->v.s.s=0;
00104 rv->v.s.len=0;
00105 break;
00106 default:
00107 BUG("RV_CNT_ALLOCED_F not supported for type %d\n", rv->type);
00108 }
00109 rv->flags&=~RV_CNT_ALLOCED_F;
00110 }
00111 if (rv->flags & RV_RE_ALLOCED_F){
00112 if (rv->v.re.regex){
00113 if (unlikely(rv->type!=RV_STR || !(rv->flags & RV_RE_F))){
00114 BUG("RV_RE_ALLOCED_F not supported for type %d or "
00115 "bad flags %x\n", rv->type, rv->flags);
00116 }
00117 regfree(rv->v.re.regex);
00118 pkg_free(rv->v.re.regex);
00119 rv->v.re.regex=0;
00120 }
00121 rv->flags&=~(RV_RE_ALLOCED_F|RV_RE_F);
00122 }
00123 }
00124
00125
00126
00130 void rval_destroy(struct rvalue* rv)
00131 {
00132 if (rv && rv_unref(rv)){
00133 rval_force_clean(rv);
00134
00135 if ((rv->flags & RV_RE_F) && rv->v.re.regex){
00136 if (unlikely(rv->type!=RV_STR))
00137 BUG("RV_RE_F not supported for type %d\n", rv->type);
00138 regfree(rv->v.re.regex);
00139 }
00140 if (rv->flags & RV_RV_ALLOCED_F){
00141 pkg_free(rv);
00142 }
00143 }
00144 }
00145
00146
00147
00148 void rval_clean(struct rvalue* rv)
00149 {
00150 if (rv_unref(rv))
00151 rval_force_clean(rv);
00152 }
00153
00154
00155
00156 void rve_destroy(struct rval_expr* rve)
00157 {
00158 if (rve){
00159 if (rve->op==RVE_RVAL_OP){
00160 if (rve->left.rval.refcnt){
00161 if (rve->left.rval.refcnt==1)
00162 rval_destroy(&rve->left.rval);
00163 else
00164 BUG("rval expr rval with invalid refcnt: %d (%d,%d-%d,%d)"
00165 "\n", rve->left.rval.refcnt,
00166 rve->fpos.s_line, rve->fpos.s_col,
00167 rve->fpos.e_line, rve->fpos.e_col);
00168 }
00169 if (rve->right.rval.refcnt){
00170 if (rve->right.rval.refcnt==1)
00171 rval_destroy(&rve->right.rval);
00172 else
00173 BUG("rval expr rval with invalid refcnt: %d (%d,%d-%d,%d)"
00174 "\n", rve->right.rval.refcnt,
00175 rve->fpos.s_line, rve->fpos.s_col,
00176 rve->fpos.e_line, rve->fpos.e_col);
00177 }
00178 }else{
00179 if (rve->left.rve)
00180 rve_destroy(rve->left.rve);
00181 if (rve->right.rve)
00182 rve_destroy(rve->right.rve);
00183 }
00184 pkg_free(rve);
00185 }
00186 }
00187
00188
00189
00190 void rval_cache_clean(struct rval_cache* rvc)
00191 {
00192 if ((rvc->cache_type==RV_CACHE_PVAR) && (rvc->val_type!=RV_NONE)){
00193 pv_value_destroy(&rvc->c.pval);
00194 }
00195 rvc->cache_type=RV_CACHE_EMPTY;
00196 rvc->val_type=RV_NONE;
00197 }
00198
00199
00200 #define rv_chg_in_place(rv) ((rv)->refcnt==1)
00201
00202
00203
00208 void rval_init(struct rvalue* rv, enum rval_type t, union rval_val* v,
00209 int flags)
00210 {
00211 rv->flags=flags;
00212 rv->refcnt=1;
00213 rv->type=t;
00214 if (v){
00215 rv->v=*v;
00216 }else{
00217 memset (&rv->v, 0, sizeof(rv->v));
00218 }
00219 }
00220
00221
00222
00230 struct rvalue* rval_new_empty(int extra_size)
00231 {
00232 struct rvalue* rv;
00233 int size;
00234
00235 size=ROUND_LONG(sizeof(*rv)-sizeof(rv->buf)+extra_size);
00236 rv=pkg_malloc(size);
00237 if (likely(rv)){
00238 rv->bsize=size-sizeof(*rv)-sizeof(rv->buf);
00239 rv->flags=RV_RV_ALLOCED_F;
00240 rv->refcnt=1;
00241 rv->type=RV_NONE;
00242 }
00243 return rv;
00244 }
00245
00246
00247
00256 struct rvalue* rval_new_str(str* s, int extra_size)
00257 {
00258 struct rvalue* rv;
00259
00260 rv=rval_new_empty(extra_size+s->len+1);
00261 if (likely(rv)){
00262 rv->type=RV_STR;
00263 rv->v.s.s=&rv->buf[0];
00264 rv->v.s.len=s->len;
00265 memcpy(rv->v.s.s, s->s, s->len);
00266 rv->v.s.s[s->len]=0;
00267 }
00268 return rv;
00269 }
00270
00271
00272
00279 struct rvalue* rval_new_re(str* s)
00280 {
00281 struct rvalue* rv;
00282 long offs;
00283
00284 offs=(long)&((struct rvalue*)0)->buf[0];
00285
00286
00287 rv=rval_new_empty(ROUND_POINTER(offs)-offs+sizeof(*rv->v.re.regex)+
00288 s->len+1);
00289 if (likely(rv)){
00290 rv->type=RV_STR;
00291
00292
00293 rv->v.re.regex=(regex_t*)((char*)&rv->buf[0]+ROUND_POINTER(offs)-offs);
00294 rv->v.s.s=(char*)rv->v.re.regex+sizeof(*rv->v.re.regex);
00295 rv->v.s.len=s->len;
00296 memcpy(rv->v.s.s, s->s, s->len);
00297 rv->v.s.s[s->len]=0;
00298
00299
00300 if (unlikely(regcomp(rv->v.re.regex, s->s,
00301 REG_EXTENDED|REG_NOSUB|REG_ICASE))){
00302
00303 pkg_free(rv);
00304 rv=0;
00305 }else
00306 rv->flags|=RV_RE_F;
00307 }
00308 return rv;
00309 }
00310
00311
00312
00317 char* rval_type_name(enum rval_type type)
00318 {
00319 switch(type){
00320 case RV_NONE:
00321 return "none";
00322 case RV_INT:
00323 return "int";
00324 case RV_STR:
00325 return "str";
00326 case RV_BEXPR:
00327 return "bexpr_t";
00328 case RV_ACTION_ST:
00329 return "action_t";
00330 case RV_PVAR:
00331 return "pvar";
00332 case RV_AVP:
00333 return "avp";
00334 break;
00335 case RV_SEL:
00336 return "select";
00337 }
00338 return "error_unknown_type";
00339 }
00340
00341
00342
00351 struct rvalue* rval_new(enum rval_type t, union rval_val* v, int extra_size)
00352 {
00353 struct rvalue* rv;
00354
00355 if (t==RV_STR && v && v->s.s)
00356 return rval_new_str(&v->s, extra_size);
00357 rv=rval_new_empty(extra_size);
00358 if (likely(rv)){
00359 rv->type=t;
00360 if (likely(v && t!=RV_STR)){
00361 rv->v=*v;
00362 }else if (t==RV_STR){
00363 rv->v.s.s=&rv->buf[0];
00364 rv->v.s.len=0;
00365 if (likely(extra_size)) rv->v.s.s[0]=0;
00366 }else
00367 memset (&rv->v, 0, sizeof(rv->v));
00368 }
00369 return rv;
00370 }
00371
00372
00373
00389 inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
00390 struct sip_msg* msg,
00391 struct rvalue* rv,
00392 struct rval_cache* val_cache)
00393 {
00394 avp_t* r_avp;
00395 int_str tmp_avp_val;
00396 int_str* avpv;
00397 pv_value_t tmp_pval;
00398 pv_value_t* pv;
00399 enum rval_type tmp;
00400 enum rval_type* ptype;
00401
00402 switch(rv->type){
00403 case RV_INT:
00404 case RV_STR:
00405 return rv->type;
00406 case RV_BEXPR:
00407 case RV_ACTION_ST:
00408 return RV_INT;
00409 case RV_PVAR:
00410 if (likely(val_cache && val_cache->cache_type==RV_CACHE_EMPTY)){
00411 pv=&val_cache->c.pval;
00412 val_cache->cache_type=RV_CACHE_PVAR;
00413 }else{
00414 val_cache=0;
00415 pv=&tmp_pval;
00416 }
00417 memset(pv, 0, sizeof(tmp_pval));
00418 if (likely(pv_get_spec_value(msg, &rv->v.pvs, pv)==0)){
00419 if (pv->flags & PV_TYPE_INT){
00420 if (likely(val_cache!=0))
00421 val_cache->val_type=RV_INT;
00422 else
00423 pv_value_destroy(pv);
00424 return RV_INT;
00425 }else if (pv->flags & PV_VAL_STR){
00426 if (likely(val_cache!=0))
00427 val_cache->val_type=RV_STR;
00428 else
00429 pv_value_destroy(pv);
00430 return RV_STR;
00431 }else{
00432 pv_value_destroy(pv);
00433 if (likely(val_cache!=0))
00434 val_cache->val_type=RV_NONE;
00435 goto error;
00436 }
00437 }else{
00438 if (likely(val_cache!=0))
00439 val_cache->val_type=RV_NONE;
00440 goto error;
00441 }
00442 break;
00443 case RV_AVP:
00444 if (likely(val_cache && val_cache->cache_type==RV_CACHE_EMPTY)){
00445 ptype=&val_cache->val_type;
00446 avpv=&val_cache->c.avp_val;
00447 val_cache->cache_type=RV_CACHE_AVP;
00448 }else{
00449 ptype=&tmp;
00450 avpv=&tmp_avp_val;
00451 }
00452 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
00453 avpv, rv->v.avps.index);
00454 if (likely(r_avp)){
00455 if (r_avp->flags & AVP_VAL_STR){
00456 *ptype=RV_STR;
00457 return RV_STR;
00458 }else{
00459 *ptype=RV_INT;
00460 return RV_INT;
00461 }
00462 }else{
00463 *ptype=RV_NONE;
00464 goto error;
00465 }
00466 break;
00467 case RV_SEL:
00468 return RV_STR;
00469 default:
00470 BUG("rv type %d not handled\n", rv->type);
00471 }
00472 error:
00473 return RV_NONE;
00474 }
00475
00476
00477
00482 enum rval_type rve_guess_type( struct rval_expr* rve)
00483 {
00484 switch(rve->op){
00485 case RVE_RVAL_OP:
00486 switch(rve->left.rval.type){
00487 case RV_STR:
00488 case RV_SEL:
00489 return RV_STR;
00490 case RV_INT:
00491 case RV_BEXPR:
00492 case RV_ACTION_ST:
00493 return RV_INT;
00494 case RV_PVAR:
00495 case RV_AVP:
00496 case RV_NONE:
00497 return RV_NONE;
00498 }
00499 break;
00500 case RVE_UMINUS_OP:
00501 case RVE_BOOL_OP:
00502 case RVE_LNOT_OP:
00503 case RVE_BNOT_OP:
00504 case RVE_MINUS_OP:
00505 case RVE_MUL_OP:
00506 case RVE_DIV_OP:
00507 case RVE_MOD_OP:
00508 case RVE_BOR_OP:
00509 case RVE_BAND_OP:
00510 case RVE_BXOR_OP:
00511 case RVE_BLSHIFT_OP:
00512 case RVE_BRSHIFT_OP:
00513 case RVE_LAND_OP:
00514 case RVE_LOR_OP:
00515 case RVE_GT_OP:
00516 case RVE_GTE_OP:
00517 case RVE_LT_OP:
00518 case RVE_LTE_OP:
00519 case RVE_EQ_OP:
00520 case RVE_DIFF_OP:
00521 case RVE_IEQ_OP:
00522 case RVE_IDIFF_OP:
00523 case RVE_STREQ_OP:
00524 case RVE_STRDIFF_OP:
00525 case RVE_MATCH_OP:
00526 case RVE_IPLUS_OP:
00527 case RVE_STRLEN_OP:
00528 case RVE_STREMPTY_OP:
00529 case RVE_DEFINED_OP:
00530 case RVE_INT_OP:
00531 return RV_INT;
00532 case RVE_PLUS_OP:
00533
00534 return rve_guess_type(rve->left.rve);
00535 case RVE_CONCAT_OP:
00536 case RVE_STR_OP:
00537 return RV_STR;
00538 case RVE_NONE_OP:
00539 break;
00540 }
00541 return RV_NONE;
00542 }
00543
00544
00545
00550 int rve_is_constant(struct rval_expr* rve)
00551 {
00552 switch(rve->op){
00553 case RVE_RVAL_OP:
00554 switch(rve->left.rval.type){
00555 case RV_STR:
00556 return 1;
00557 case RV_INT:
00558 return 1;
00559 case RV_SEL:
00560 case RV_BEXPR:
00561 case RV_ACTION_ST:
00562 case RV_PVAR:
00563 case RV_AVP:
00564 case RV_NONE:
00565 return 0;
00566 }
00567 break;
00568 case RVE_UMINUS_OP:
00569 case RVE_BOOL_OP:
00570 case RVE_LNOT_OP:
00571 case RVE_BNOT_OP:
00572 case RVE_STRLEN_OP:
00573 case RVE_STREMPTY_OP:
00574 case RVE_DEFINED_OP:
00575 case RVE_INT_OP:
00576 case RVE_STR_OP:
00577 return rve_is_constant(rve->left.rve);
00578 case RVE_MINUS_OP:
00579 case RVE_MUL_OP:
00580 case RVE_DIV_OP:
00581 case RVE_MOD_OP:
00582 case RVE_BOR_OP:
00583 case RVE_BAND_OP:
00584 case RVE_BXOR_OP:
00585 case RVE_BLSHIFT_OP:
00586 case RVE_BRSHIFT_OP:
00587 case RVE_LAND_OP:
00588 case RVE_LOR_OP:
00589 case RVE_GT_OP:
00590 case RVE_GTE_OP:
00591 case RVE_LT_OP:
00592 case RVE_LTE_OP:
00593 case RVE_EQ_OP:
00594 case RVE_DIFF_OP:
00595 case RVE_IEQ_OP:
00596 case RVE_IDIFF_OP:
00597 case RVE_STREQ_OP:
00598 case RVE_STRDIFF_OP:
00599 case RVE_MATCH_OP:
00600 case RVE_PLUS_OP:
00601 case RVE_IPLUS_OP:
00602 case RVE_CONCAT_OP:
00603 return rve_is_constant(rve->left.rve) &&
00604 rve_is_constant(rve->right.rve);
00605 case RVE_NONE_OP:
00606 break;
00607 }
00608 return 0;
00609 }
00610
00611
00612
00617 int rve_has_side_effects(struct rval_expr* rve)
00618 {
00619 return !rve_is_constant(rve);
00620 }
00621
00622
00623
00627 static int rve_op_unary(enum rval_expr_op op)
00628 {
00629 switch(op){
00630 case RVE_RVAL_OP:
00631 return -1;
00632 case RVE_UMINUS_OP:
00633 case RVE_BOOL_OP:
00634 case RVE_LNOT_OP:
00635 case RVE_BNOT_OP:
00636 case RVE_STRLEN_OP:
00637 case RVE_STREMPTY_OP:
00638 case RVE_DEFINED_OP:
00639 case RVE_INT_OP:
00640 case RVE_STR_OP:
00641 return 1;
00642 case RVE_MINUS_OP:
00643 case RVE_MUL_OP:
00644 case RVE_DIV_OP:
00645 case RVE_MOD_OP:
00646 case RVE_BOR_OP:
00647 case RVE_BAND_OP:
00648 case RVE_BXOR_OP:
00649 case RVE_BLSHIFT_OP:
00650 case RVE_BRSHIFT_OP:
00651 case RVE_LAND_OP:
00652 case RVE_LOR_OP:
00653 case RVE_GT_OP:
00654 case RVE_GTE_OP:
00655 case RVE_LT_OP:
00656 case RVE_LTE_OP:
00657 case RVE_EQ_OP:
00658 case RVE_DIFF_OP:
00659 case RVE_IEQ_OP:
00660 case RVE_IDIFF_OP:
00661 case RVE_STREQ_OP:
00662 case RVE_STRDIFF_OP:
00663 case RVE_MATCH_OP:
00664 case RVE_PLUS_OP:
00665 case RVE_IPLUS_OP:
00666 case RVE_CONCAT_OP:
00667 return 0;
00668 case RVE_NONE_OP:
00669 return -1;
00670 break;
00671 }
00672 return 0;
00673 }
00674
00675
00676
00690 int rve_check_type(enum rval_type* type, struct rval_expr* rve,
00691 struct rval_expr** bad_rve,
00692 enum rval_type* bad_t,
00693 enum rval_type* exp_t)
00694 {
00695 enum rval_type type1, type2;
00696
00697 switch(rve->op){
00698 case RVE_RVAL_OP:
00699 *type=rve_guess_type(rve);
00700 return 1;
00701 case RVE_UMINUS_OP:
00702 case RVE_BOOL_OP:
00703 case RVE_LNOT_OP:
00704 case RVE_BNOT_OP:
00705 *type=RV_INT;
00706 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00707 if (type1==RV_STR){
00708 if (bad_rve) *bad_rve=rve->left.rve;
00709 if (bad_t) *bad_t=type1;
00710 if (exp_t) *exp_t=RV_INT;
00711 return 0;
00712 }
00713 return 1;
00714 }
00715 return 0;
00716 break;
00717 case RVE_MINUS_OP:
00718 case RVE_MUL_OP:
00719 case RVE_DIV_OP:
00720 case RVE_MOD_OP:
00721 case RVE_BOR_OP:
00722 case RVE_BAND_OP:
00723 case RVE_BXOR_OP:
00724 case RVE_BLSHIFT_OP:
00725 case RVE_BRSHIFT_OP:
00726 case RVE_LAND_OP:
00727 case RVE_LOR_OP:
00728 case RVE_GT_OP:
00729 case RVE_GTE_OP:
00730 case RVE_LT_OP:
00731 case RVE_LTE_OP:
00732 case RVE_IEQ_OP:
00733 case RVE_IDIFF_OP:
00734 case RVE_IPLUS_OP:
00735 *type=RV_INT;
00736 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00737 if (type1==RV_STR){
00738 if (bad_rve) *bad_rve=rve->left.rve;
00739 if (bad_t) *bad_t=type1;
00740 if (exp_t) *exp_t=RV_INT;
00741 return 0;
00742 }
00743 if (rve_check_type(&type2, rve->right.rve, bad_rve,
00744 bad_t, exp_t)){
00745 if (type2==RV_STR){
00746 if (bad_rve) *bad_rve=rve->right.rve;
00747 if (bad_t) *bad_t=type2;
00748 if (exp_t) *exp_t=RV_INT;
00749 return 0;
00750 }
00751 return 1;
00752 }
00753 }
00754 return 0;
00755 case RVE_EQ_OP:
00756 case RVE_DIFF_OP:
00757 *type=RV_INT;
00758 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00759 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
00760 exp_t)){
00761 if ((type2!=type1) && (type1!=RV_NONE) &&
00762 (type2!=RV_NONE) &&
00763 !(type1==RV_STR && type2==RV_INT)){
00764 if (bad_rve) *bad_rve=rve->right.rve;
00765 if (bad_t) *bad_t=type2;
00766 if (exp_t) *exp_t=type1;
00767 return 0;
00768 }
00769 return 1;
00770 }
00771 }
00772 return 0;
00773 case RVE_PLUS_OP:
00774 *type=RV_NONE;
00775 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00776 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
00777 exp_t)){
00778 if ((type2!=type1) && (type1!=RV_NONE) &&
00779 (type2!=RV_NONE) &&
00780 !(type1==RV_STR && type2==RV_INT)){
00781 if (bad_rve) *bad_rve=rve->right.rve;
00782 if (bad_t) *bad_t=type2;
00783 if (exp_t) *exp_t=type1;
00784 return 0;
00785 }
00786 *type=type1;
00787 return 1;
00788 }
00789 }
00790 break;
00791 case RVE_CONCAT_OP:
00792 *type=RV_STR;
00793 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00794 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
00795 exp_t)){
00796 if ((type2!=type1) && (type1!=RV_NONE) &&
00797 (type2!=RV_NONE) &&
00798 !(type1==RV_STR && type2==RV_INT)){
00799 if (bad_rve) *bad_rve=rve->right.rve;
00800 if (bad_t) *bad_t=type2;
00801 if (exp_t) *exp_t=type1;
00802 return 0;
00803 }
00804 if (type1==RV_INT){
00805 if (bad_rve) *bad_rve=rve->left.rve;
00806 if (bad_t) *bad_t=type1;
00807 if (exp_t) *exp_t=RV_STR;
00808 return 0;
00809 }
00810 return 1;
00811 }
00812 }
00813 break;
00814 case RVE_STREQ_OP:
00815 case RVE_STRDIFF_OP:
00816 case RVE_MATCH_OP:
00817 *type=RV_INT;
00818 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00819 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
00820 exp_t)){
00821 if ((type2!=type1) && (type1!=RV_NONE) &&
00822 (type2!=RV_NONE) &&
00823 !(type1==RV_STR && type2==RV_INT)){
00824 if (bad_rve) *bad_rve=rve->right.rve;
00825 if (bad_t) *bad_t=type2;
00826 if (exp_t) *exp_t=type1;
00827 return 0;
00828 }
00829 if (type1==RV_INT){
00830 if (bad_rve) *bad_rve=rve->left.rve;
00831 if (bad_t) *bad_t=type1;
00832 if (exp_t) *exp_t=RV_STR;
00833 return 0;
00834 }
00835 return 1;
00836 }
00837 }
00838 break;
00839 case RVE_STRLEN_OP:
00840 case RVE_STREMPTY_OP:
00841 case RVE_DEFINED_OP:
00842 *type=RV_INT;
00843 if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
00844 if (type1==RV_INT){
00845 if (bad_rve) *bad_rve=rve->left.rve;
00846 if (bad_t) *bad_t=type1;
00847 if (exp_t) *exp_t=RV_STR;
00848 return 0;
00849 }
00850 return 1;
00851 }
00852 break;
00853 case RVE_INT_OP:
00854 *type=RV_INT;
00855 return 1;
00856 break;
00857 case RVE_STR_OP:
00858 *type=RV_STR;
00859 return 1;
00860 break;
00861 case RVE_NONE_OP:
00862 default:
00863 BUG("unexpected rve op %d (%d,%d-%d,%d)\n", rve->op,
00864 rve->fpos.s_line, rve->fpos.s_col,
00865 rve->fpos.e_line, rve->fpos.e_col);
00866 if (bad_rve) *bad_rve=rve;
00867 if (bad_t) *bad_t=RV_NONE;
00868 if (exp_t) *exp_t=RV_STR;
00869 break;
00870 }
00871 return 0;
00872 }
00873
00874
00875
00889 int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
00890 int* i, struct rvalue* rv,
00891 struct rval_cache* cache)
00892 {
00893 avp_t* r_avp;
00894 int_str avp_val;
00895 pv_value_t pval;
00896 str tmp;
00897 str* s;
00898 int r, ret;
00899 int destroy_pval;
00900
00901 destroy_pval=0;
00902 s=0;
00903 ret=0;
00904 switch(rv->type){
00905 case RV_INT:
00906 *i=rv->v.l;
00907 break;
00908 case RV_STR:
00909 s=&rv->v.s;
00910 goto rv_str;
00911 case RV_BEXPR:
00912 *i=eval_expr(h, rv->v.bexpr, msg);
00913 if (*i==EXPR_DROP){
00914 *i=0;
00915 return EXPR_DROP;
00916 }
00917 break;
00918 case RV_ACTION_ST:
00919 if (rv->v.action) {
00920 *i=(run_actions_safe(h, rv->v.action, msg)>0);
00921 h->run_flags &= ~(RETURN_R_F|BREAK_R_F);
00922
00923 } else
00924 *i=0;
00925 break;
00926 case RV_SEL:
00927 r=run_select(&tmp, &rv->v.sel, msg);
00928 if (unlikely(r!=0)){
00929 if (r<0)
00930 goto eval_error;
00931 else
00932 goto undef;
00933 }
00934 s=&tmp;
00935 goto rv_str;
00936 case RV_AVP:
00937 if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
00938 if (likely(cache->val_type==RV_INT)){
00939 *i=cache->c.avp_val.n;
00940 }else if (cache->val_type==RV_STR){
00941 s=&cache->c.avp_val.s;
00942 goto rv_str;
00943 }else if (cache->val_type==RV_NONE)
00944 goto undef;
00945 else goto error_cache;
00946 }else{
00947 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
00948 &avp_val, rv->v.avps.index);
00949 if (likely(r_avp)){
00950 if (unlikely(r_avp->flags & AVP_VAL_STR)){
00951 s=&avp_val.s;
00952 goto rv_str;
00953 }else{
00954 *i=avp_val.n;
00955 }
00956 }else{
00957 goto undef;
00958 }
00959 }
00960 break;
00961 case RV_PVAR:
00962 if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
00963 if (likely((cache->val_type==RV_INT) ||
00964 (cache->c.pval.flags & PV_VAL_INT))){
00965 *i=cache->c.pval.ri;
00966 }else if (cache->val_type==RV_STR){
00967 s=&cache->c.pval.rs;
00968 goto rv_str;
00969 }else if (cache->val_type==RV_NONE)
00970 goto undef;
00971 else goto error_cache;
00972 }else{
00973 memset(&pval, 0, sizeof(pval));
00974 if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
00975 if (likely(pval.flags & PV_VAL_INT)){
00976 *i=pval.ri;
00977 pv_value_destroy(&pval);
00978 }else if (likely(pval.flags & PV_VAL_STR)){
00979 destroy_pval=1;
00980 s=&pval.rs;
00981 goto rv_str;
00982 }else{
00983
00984
00985 pv_value_destroy(&pval);
00986 goto undef;
00987 }
00988 }else{
00989 goto eval_error;
00990 }
00991 }
00992 break;
00993 default:
00994 BUG("rv type %d not handled\n", rv->type);
00995 goto error;
00996 }
00997 return ret;
00998 undef:
00999 eval_error:
01000
01001 *i=0;
01002 return 0;
01003 rv_str:
01004
01005
01006 if (likely(s->len==0)) *i=0;
01007 else if (unlikely(str2sint(s, i)!=0)){
01008
01009 *i=0;
01010 #ifdef RV_STR2INT_VERBOSE_ERR
01011 WARN("automatic string to int conversion for \"%.*s\" failed\n",
01012 s->len, ZSW(s->s));
01013
01014 #endif
01015 #ifdef RV_STR2INT_ERR
01016 ret=-1;
01017 #endif
01018 }
01019 if (destroy_pval)
01020 pv_value_destroy(&pval);
01021 return ret;
01022 error_cache:
01023 BUG("invalid cached value:cache type %d, value type %d\n",
01024 cache?cache->cache_type:0, cache?cache->val_type:0);
01025 error:
01026 if (destroy_pval)
01027 pv_value_destroy(&pval);
01028 *i=0;
01029 return -1;
01030 }
01031
01032
01033
01035 #define RVE_LOG(lev, rve, txt) \
01036 LOG((lev), txt " (%d,%d-%d,%d)\n", \
01037 (rve)->fpos.s_line, rve->fpos.s_col, \
01038 (rve)->fpos.e_line, rve->fpos.e_col )
01039
01040
01049 #if defined RVAL_GET_INT_ERR_WARN && defined RVAL_GET_INT_ERR_IGN
01050 #define rval_get_int_handle_ret(ret, txt, rve) \
01051 do { \
01052 if (unlikely((ret)<0)) { \
01053 RVE_LOG(L_WARN, rve, txt); \
01054 (ret)=0; \
01055 } \
01056 }while(0)
01057 #elif defined RVAL_GET_INT_ERR_WARN
01058 #define rval_get_int_handle_ret(ret, txt, rve) \
01059 do { \
01060 if (unlikely((ret)<0)) \
01061 RVE_LOG(L_WARN, rve, txt); \
01062 }while(0)
01063 #elif defined RVAL_GET_INT_ERR_IGN
01064 #define rval_get_int_handle_ret(ret, txt, rve) \
01065 do { \
01066 if (unlikely((ret)<0)) \
01067 (ret)=0; \
01068 } while(0)
01069 #else
01070 #define rval_get_int_handle_ret(ret, txt, rve)
01071 #endif
01072
01073
01074
01075
01076
01077
01102 int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
01103 str* tmpv, struct rvalue* rv,
01104 struct rval_cache* cache,
01105 struct rval_cache* tmp_cache)
01106 {
01107 avp_t* r_avp;
01108 int i;
01109
01110 switch(rv->type){
01111 case RV_INT:
01112 tmpv->s=sint2strbuf(rv->v.l, tmp_cache->i2s,
01113 sizeof(tmp_cache->i2s), &tmpv->len);
01114 tmp_cache->cache_type = RV_CACHE_INT2STR;
01115 break;
01116 case RV_STR:
01117 *tmpv=rv->v.s;
01118 break;
01119 case RV_ACTION_ST:
01120 if (rv->v.action) {
01121 i=(run_actions_safe(h, rv->v.action, msg)>0);
01122 h->run_flags &= ~(RETURN_R_F|BREAK_R_F);
01123
01124 } else
01125 i=0;
01126 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
01127 sizeof(tmp_cache->i2s), &tmpv->len);
01128 tmp_cache->cache_type = RV_CACHE_INT2STR;
01129 break;
01130 case RV_BEXPR:
01131 i=eval_expr(h, rv->v.bexpr, msg);
01132 if (i==EXPR_DROP){
01133 i=0;
01134 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
01135 sizeof(tmp_cache->i2s), &tmpv->len);
01136 tmp_cache->cache_type = RV_CACHE_INT2STR;
01137 return EXPR_DROP;
01138 }
01139 tmpv->s=sint2strbuf(i, tmp_cache->i2s, sizeof(tmp_cache->i2s),
01140 &tmpv->len);
01141 tmp_cache->cache_type = RV_CACHE_INT2STR;
01142 break;
01143 case RV_SEL:
01144 i=run_select(tmpv, &rv->v.sel, msg);
01145 if (unlikely(i!=0)){
01146 if (i<0){
01147 goto eval_error;
01148 }else {
01149 goto undef;
01150 }
01151 }
01152 break;
01153 case RV_AVP:
01154 if (likely(cache && cache->cache_type==RV_CACHE_AVP)){
01155 if (likely(cache->val_type==RV_STR)){
01156 *tmpv=cache->c.avp_val.s;
01157 }else if (cache->val_type==RV_INT){
01158 i=cache->c.avp_val.n;
01159 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
01160 sizeof(tmp_cache->i2s), &tmpv->len);
01161 tmp_cache->cache_type = RV_CACHE_INT2STR;
01162 }else if (cache->val_type==RV_NONE){
01163 goto undef;
01164 }else goto error_cache;
01165 }else{
01166 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
01167 &tmp_cache->c.avp_val,
01168 rv->v.avps.index);
01169 if (likely(r_avp)){
01170 if (likely(r_avp->flags & AVP_VAL_STR)){
01171 tmp_cache->cache_type=RV_CACHE_AVP;
01172 tmp_cache->val_type=RV_STR;
01173 *tmpv=tmp_cache->c.avp_val.s;
01174 }else{
01175 i=tmp_cache->c.avp_val.n;
01176 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
01177 sizeof(tmp_cache->i2s), &tmpv->len);
01178 tmp_cache->cache_type = RV_CACHE_INT2STR;
01179 }
01180 }else goto undef;
01181 }
01182 break;
01183 case RV_PVAR:
01184 if (likely(cache && cache->cache_type==RV_CACHE_PVAR)){
01185 if (likely(cache->val_type==RV_STR)){
01186 *tmpv=cache->c.pval.rs;
01187 }else if (cache->val_type==RV_INT){
01188 i=cache->c.pval.ri;
01189 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
01190 sizeof(tmp_cache->i2s), &tmpv->len);
01191 tmp_cache->cache_type = RV_CACHE_INT2STR;
01192 }else if (cache->val_type==RV_NONE){
01193 goto undef;
01194 }else goto error_cache;
01195 }else{
01196 memset(&tmp_cache->c.pval, 0, sizeof(tmp_cache->c.pval));
01197 if (likely(pv_get_spec_value(msg, &rv->v.pvs,
01198 &tmp_cache->c.pval)==0)){
01199 if (likely(tmp_cache->c.pval.flags & PV_VAL_STR)){
01200
01201
01202
01203 tmp_cache->cache_type=RV_CACHE_PVAR;
01204 tmp_cache->val_type=RV_STR;
01205 *tmpv=tmp_cache->c.pval.rs;
01206 }else if (likely(tmp_cache->c.pval.flags & PV_VAL_INT)){
01207 i=tmp_cache->c.pval.ri;
01208 pv_value_destroy(&tmp_cache->c.pval);
01209 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
01210 sizeof(tmp_cache->i2s), &tmpv->len);
01211 tmp_cache->cache_type = RV_CACHE_INT2STR;
01212 }else{
01213
01214
01215 pv_value_destroy(&tmp_cache->c.pval);
01216 goto undef;
01217 }
01218 }else{
01219 goto eval_error;
01220 }
01221 }
01222 break;
01223 default:
01224 BUG("rv type %d not handled\n", rv->type);
01225 goto error;
01226 }
01227 return 0;
01228 undef:
01229 eval_error:
01230
01231 tmpv->s="";
01232 tmpv->len=0;
01233 return 0;
01234 error_cache:
01235 BUG("invalid cached value:cache type %d, value type %d\n",
01236 cache?cache->cache_type:0, cache?cache->val_type:0);
01237 error:
01238 tmpv->s="";
01239 tmpv->len=0;
01240 return -1;
01241 }
01242
01243
01244
01250 int rval_get_str(struct run_act_ctx* h, struct sip_msg* msg,
01251 str* s, struct rvalue* rv,
01252 struct rval_cache* cache)
01253 {
01254 str tmp;
01255 struct rval_cache tmp_cache;
01256
01257 rval_cache_init(&tmp_cache);
01258 if (unlikely(rval_get_tmp_str(h, msg, &tmp, rv, cache, &tmp_cache)<0))
01259 goto error;
01260 s->s=pkg_malloc(tmp.len+1);
01261 if (unlikely(s->s==0)){
01262 ERR("memory allocation error\n");
01263 goto error;
01264 }
01265 s->len=tmp.len;
01266 memcpy(s->s, tmp.s, tmp.len);
01267 s->s[tmp.len]=0;
01268 rval_cache_clean(&tmp_cache);
01269 return 0;
01270 error:
01271 rval_cache_clean(&tmp_cache);
01272 return -1;
01273 }
01274
01275
01276
01294 struct rvalue* rval_convert(struct run_act_ctx* h, struct sip_msg* msg,
01295 enum rval_type type, struct rvalue* v,
01296 struct rval_cache* c)
01297 {
01298 int i;
01299 struct rval_cache tmp_cache;
01300 str tmp;
01301 struct rvalue* ret;
01302 union rval_val val;
01303
01304 if (v->type==type){
01305 rv_ref(v);
01306 return v;
01307 }
01308 switch(type){
01309 case RV_INT:
01310 if (unlikely(rval_get_int(h, msg, &i, v, c) < 0))
01311 return 0;
01312 val.l=i;
01313 return rval_new(RV_INT, &val, 0);
01314 case RV_STR:
01315 rval_cache_init(&tmp_cache);
01316 if (unlikely(rval_get_tmp_str(h, msg, &tmp, v, c, &tmp_cache) < 0))
01317 {
01318 rval_cache_clean(&tmp_cache);
01319 return 0;
01320 }
01321 ret=rval_new_str(&tmp, RV_STR_EXTRA);
01322 rval_cache_clean(&tmp_cache);
01323 return ret;
01324 case RV_NONE:
01325 default:
01326 BUG("unsupported conversion to type %d\n", type);
01327 return 0;
01328 }
01329 return 0;
01330 }
01331
01332
01333
01337 inline static int int_intop1(int* res, enum rval_expr_op op, int v)
01338 {
01339 switch(op){
01340 case RVE_UMINUS_OP:
01341 *res=-v;
01342 break;
01343 case RVE_BOOL_OP:
01344 *res=!!v;
01345 break;
01346 case RVE_LNOT_OP:
01347 *res=!v;
01348 break;
01349 case RVE_BNOT_OP:
01350 *res=~v;
01351 break;
01352 default:
01353 BUG("rv unsupported intop1 %d\n", op);
01354 return -1;
01355 }
01356 return 0;
01357 }
01358
01359
01360
01364 inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
01365 {
01366 switch(op){
01367 case RVE_PLUS_OP:
01368 case RVE_IPLUS_OP:
01369 *res=v1+v2;
01370 break;
01371 case RVE_MINUS_OP:
01372 *res=v1-v2;
01373 break;
01374 case RVE_MUL_OP:
01375 *res=v1*v2;
01376 break;
01377 case RVE_DIV_OP:
01378 if (unlikely(v2==0)){
01379 ERR("rv div by 0\n");
01380 return -1;
01381 }
01382 *res=v1/v2;
01383 break;
01384 case RVE_MOD_OP:
01385 if (unlikely(v2==0)){
01386 ERR("rv mod by 0\n");
01387 return -1;
01388 }
01389 *res=v1%v2;
01390 break;
01391 case RVE_BOR_OP:
01392 *res=v1|v2;
01393 break;
01394 case RVE_BAND_OP:
01395 *res=v1&v2;
01396 break;
01397 case RVE_BXOR_OP:
01398 *res=v1^v2;
01399 break;
01400 case RVE_BLSHIFT_OP:
01401 *res=v1<<v2;
01402 break;
01403 case RVE_BRSHIFT_OP:
01404 *res=v1>>v2;
01405 break;
01406 case RVE_LAND_OP:
01407 *res=v1 && v2;
01408 break;
01409 case RVE_LOR_OP:
01410 *res=v1 || v2;
01411 break;
01412 case RVE_GT_OP:
01413 *res=v1 > v2;
01414 break;
01415 case RVE_GTE_OP:
01416 *res=v1 >= v2;
01417 break;
01418 case RVE_LT_OP:
01419 *res=v1 < v2;
01420 break;
01421 case RVE_LTE_OP:
01422 *res=v1 <= v2;
01423 break;
01424 case RVE_EQ_OP:
01425 case RVE_IEQ_OP:
01426 *res=v1 == v2;
01427 break;
01428 case RVE_DIFF_OP:
01429 case RVE_IDIFF_OP:
01430 *res=v1 != v2;
01431 break;
01432 case RVE_CONCAT_OP:
01433 *res=0;
01434
01435 return -1;
01436 default:
01437 BUG("rv unsupported intop %d\n", op);
01438 return -1;
01439 }
01440 return 0;
01441 }
01442
01443
01444
01449 inline static int bool_rvstrop2( enum rval_expr_op op, int* res,
01450 struct rvalue* rv1, struct rvalue* rv2)
01451 {
01452 str* s1;
01453 str* s2;
01454 regex_t tmp_re;
01455
01456 s1=&rv1->v.s;
01457 s2=&rv2->v.s;
01458 switch(op){
01459 case RVE_EQ_OP:
01460 case RVE_STREQ_OP:
01461 *res= (s1->len==s2->len) && (memcmp(s1->s, s2->s, s1->len)==0);
01462 break;
01463 case RVE_DIFF_OP:
01464 case RVE_STRDIFF_OP:
01465 *res= (s1->len!=s2->len) || (memcmp(s1->s, s2->s, s1->len)!=0);
01466 break;
01467 case RVE_MATCH_OP:
01468 if (likely(rv2->flags & RV_RE_F)){
01469 *res=(regexec(rv2->v.re.regex, rv1->v.s.s, 0, 0, 0)==0);
01470 }else{
01471
01472 if (unlikely(regcomp(&tmp_re, s2->s,
01473 REG_EXTENDED|REG_NOSUB|REG_ICASE))){
01474
01475 ERR("Bad regular expression \"%s\"\n", s2->s);
01476 goto error;
01477 }
01478 *res=(regexec(&tmp_re, s1->s, 0, 0, 0)==0);
01479 regfree(&tmp_re);
01480 }
01481 break;
01482 default:
01483 BUG("rv unsupported intop %d\n", op);
01484 goto error;
01485 }
01486 return 0;
01487 error:
01488 *res=0;
01489 return -1;
01490 }
01491
01492
01493
01497 inline static int int_strop1(int* res, enum rval_expr_op op, str* s1)
01498 {
01499 switch(op){
01500 case RVE_STRLEN_OP:
01501 *res=s1->len;
01502 break;
01503 case RVE_STREMPTY_OP:
01504 *res=(s1->len==0);
01505 break;
01506 default:
01507 BUG("rv unsupported int_strop1 %d\n", op);
01508 *res=0;
01509 return -1;
01510 }
01511 return 0;
01512 }
01513
01514
01515
01519 inline static struct rvalue* rval_intop1(struct run_act_ctx* h,
01520 struct sip_msg* msg,
01521 enum rval_expr_op op,
01522 struct rvalue* v)
01523 {
01524 struct rvalue* rv2;
01525 struct rvalue* ret;
01526 int i;
01527
01528 i=0;
01529 rv2=rval_convert(h, msg, RV_INT, v, 0);
01530 if (unlikely(rv2==0)){
01531 ERR("rval int conversion failed\n");
01532 goto error;
01533 }
01534 if (unlikely(int_intop1(&i, op, rv2->v.l)<0))
01535 goto error;
01536 if (rv_chg_in_place(rv2)){
01537 ret=rv2;
01538 rv_ref(ret);
01539 }else if (rv_chg_in_place(v)){
01540 ret=v;
01541 rv_ref(ret);
01542 }else{
01543 ret=rval_new(RV_INT, &rv2->v, 0);
01544 if (unlikely(ret==0)){
01545 ERR("eval out of memory\n");
01546 goto error;
01547 }
01548 }
01549 rval_destroy(rv2);
01550 ret->v.l=i;
01551 return ret;
01552 error:
01553 rval_destroy(rv2);
01554 return 0;
01555 }
01556
01557
01558
01562 inline static struct rvalue* rval_intop2(struct run_act_ctx* h,
01563 struct sip_msg* msg,
01564 enum rval_expr_op op,
01565 struct rvalue* l,
01566 struct rvalue* r)
01567 {
01568 struct rvalue* rv1;
01569 struct rvalue* rv2;
01570 struct rvalue* ret;
01571 int i;
01572
01573 rv2=rv1=0;
01574 ret=0;
01575 if ((rv1=rval_convert(h, msg, RV_INT, l, 0))==0)
01576 goto error;
01577 if ((rv2=rval_convert(h, msg, RV_INT, r, 0))==0)
01578 goto error;
01579 if (unlikely(int_intop2(&i, op, rv1->v.l, rv2->v.l)<0))
01580 goto error;
01581 if (rv_chg_in_place(rv1)){
01582
01583 ret=rv1;
01584 rv_ref(ret);
01585 }else if (rv_chg_in_place(rv2)){
01586
01587 ret=rv2;
01588 rv_ref(ret);
01589 }else if ((l->type==RV_INT) && (rv_chg_in_place(l))){
01590 ret=l;
01591 rv_ref(ret);
01592 } else if ((r->type==RV_INT) && (rv_chg_in_place(r))){
01593 ret=r;
01594 rv_ref(ret);
01595 }else{
01596 ret=rval_new(RV_INT, &rv1->v, 0);
01597 if (unlikely(ret==0)){
01598 ERR("rv eval out of memory\n");
01599 goto error;
01600 }
01601 }
01602 rval_destroy(rv1);
01603 rval_destroy(rv2);
01604 ret->v.l=i;
01605 return ret;
01606 error:
01607 rval_destroy(rv1);
01608 rval_destroy(rv2);
01609 return 0;
01610 }
01611
01612
01613
01618 inline static struct rvalue* rval_str_add2(struct run_act_ctx* h,
01619 struct sip_msg* msg,
01620 struct rvalue* l,
01621 struct rval_cache* c1,
01622 struct rvalue* r,
01623 struct rval_cache* c2
01624 )
01625 {
01626 struct rvalue* rv1;
01627 struct rvalue* rv2;
01628 struct rvalue* ret;
01629 str* s1;
01630 str* s2;
01631 str tmp;
01632 short flags;
01633 int len;
01634
01635 rv2=rv1=0;
01636 ret=0;
01637 flags=0;
01638 s1=0;
01639 s2=0;
01640 if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
01641 goto error;
01642 if ((rv2=rval_convert(h, msg, RV_STR, r, c2))==0)
01643 goto error;
01644
01645 len=rv1->v.s.len + rv2->v.s.len + 1 ;
01646
01647 if (rv_chg_in_place(rv1) && (rv1->bsize>=len)){
01648
01649 ret=rv1;
01650 rv_ref(ret);
01651 s2=&rv2->v.s;
01652 if (ret->v.s.s == &ret->buf[0]) s1=0;
01653 else{
01654 tmp=ret->v.s;
01655 flags=ret->flags;
01656 ret->flags &= ~RV_CNT_ALLOCED_F;
01657 ret->v.s.s=&ret->buf[0];
01658 ret->v.s.len=0;
01659 s1=&tmp;
01660 }
01661 }else if (rv_chg_in_place(rv2) && (rv2->bsize>=len)){
01662
01663 ret=rv2;
01664 rv_ref(ret);
01665 s1=&rv1->v.s;
01666 if (ret->v.s.s == &ret->buf[0])
01667 s2=&ret->v.s;
01668 else{
01669 tmp=ret->v.s;
01670 flags=ret->flags;
01671 ret->flags &= ~RV_CNT_ALLOCED_F;
01672 ret->v.s.s=&ret->buf[0];
01673 ret->v.s.len=0;
01674 s2=&tmp;
01675 }
01676 }else if ((l->type==RV_STR) && (rv_chg_in_place(l)) && (l->bsize>=len)){
01677 ret=l;
01678 rv_ref(ret);
01679 s2=&rv2->v.s;
01680 if (ret->v.s.s == &ret->buf[0]) s1=0;
01681 else{
01682 tmp=ret->v.s;
01683 flags=ret->flags;
01684 ret->flags &= ~RV_CNT_ALLOCED_F;
01685 ret->v.s.s=&ret->buf[0];
01686 ret->v.s.len=0;
01687 s1=&tmp;
01688 }
01689 } else if ((r->type==RV_STR) && (rv_chg_in_place(r) && (r->bsize>=len))){
01690 ret=r;
01691 rv_ref(ret);
01692 s1=&rv1->v.s;
01693 if (ret->v.s.s == &ret->buf[0])
01694 s2=&ret->v.s;
01695 else{
01696 tmp=ret->v.s;
01697 flags=ret->flags;
01698 ret->flags &= ~RV_CNT_ALLOCED_F;
01699 ret->v.s.s=&ret->buf[0];
01700 ret->v.s.len=0;
01701 s2=&tmp;
01702 }
01703 }else{
01704 ret=rval_new(RV_STR, &rv1->v, len + RV_STR_EXTRA);
01705 if (unlikely(ret==0)){
01706 ERR("rv eval out of memory\n");
01707 goto error;
01708 }
01709 s1=0;
01710 s2=&rv2->v.s;
01711 }
01712
01713 memmove(ret->buf+rv1->v.s.len, s2->s, s2->len);
01714 if (s1){
01715 memcpy(ret->buf, s1->s, s1->len);
01716 }
01717 ret->v.s.len=rv1->v.s.len+s2->len;
01718 ret->v.s.s[ret->v.s.len]=0;
01719
01720 if (flags & RV_CNT_ALLOCED_F)
01721 pkg_free(tmp.s);
01722 rval_destroy(rv1);
01723 rval_destroy(rv2);
01724 return ret;
01725 error:
01726 rval_destroy(rv1);
01727 rval_destroy(rv2);
01728 return 0;
01729 }
01730
01731
01732
01737 inline static int rval_str_lop2(struct run_act_ctx* h,
01738 struct sip_msg* msg,
01739 int* res,
01740 enum rval_expr_op op,
01741 struct rvalue* l,
01742 struct rval_cache* c1,
01743 struct rvalue* r,
01744 struct rval_cache* c2)
01745 {
01746 struct rvalue* rv1;
01747 struct rvalue* rv2;
01748 int ret;
01749
01750 rv2=rv1=0;
01751 ret=0;
01752 if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
01753 goto error;
01754 if ((rv2=rval_convert(h, msg, RV_STR, r, c2))==0)
01755 goto error;
01756 ret=bool_rvstrop2(op, res, rv1, rv2);
01757 rval_destroy(rv1);
01758 rval_destroy(rv2);
01759 return ret;
01760 error:
01761 rval_destroy(rv1);
01762 rval_destroy(rv2);
01763 return 0;
01764 }
01765
01766
01767
01781 inline static int rval_int_strop1(struct run_act_ctx* h,
01782 struct sip_msg* msg,
01783 int* res,
01784 enum rval_expr_op op,
01785 struct rvalue* l,
01786 struct rval_cache* c1)
01787 {
01788 struct rvalue* rv1;
01789 int ret;
01790
01791 rv1=0;
01792 ret=0;
01793 if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
01794 goto error;
01795 ret=int_strop1(res, op, &rv1->v.s);
01796 rval_destroy(rv1);
01797 return ret;
01798 error:
01799 *res=0;
01800 rval_destroy(rv1);
01801 return -1;
01802 }
01803
01804
01805
01819 inline static int rv_defined(struct run_act_ctx* h,
01820 struct sip_msg* msg, int* res,
01821 struct rvalue* rv, struct rval_cache* cache)
01822 {
01823 avp_t* r_avp;
01824 int_str avp_val;
01825 pv_value_t pval;
01826 str tmp;
01827
01828 *res=1;
01829 switch(rv->type){
01830 case RV_SEL:
01831 if (unlikely(cache && cache->cache_type==RV_CACHE_SELECT)){
01832 *res=(cache->val_type!=RV_NONE);
01833 }else
01834
01835
01836 *res=(run_select(&tmp, &rv->v.sel, msg)==0);
01837 break;
01838 case RV_AVP:
01839 if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
01840 *res=(cache->val_type!=RV_NONE);
01841 }else{
01842 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
01843 &avp_val, rv->v.avps.index);
01844 if (unlikely(r_avp==0)){
01845 *res=0;
01846 }
01847 }
01848 break;
01849 case RV_PVAR:
01850
01851 if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
01852 *res=(cache->val_type!=RV_NONE);
01853 }else{
01854 memset(&pval, 0, sizeof(pval));
01855 if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
01856 if ((pval.flags & PV_VAL_NULL) &&
01857 ! (pval.flags & (PV_VAL_INT|PV_VAL_STR))){
01858 *res=0;
01859 }
01860 pv_value_destroy(&pval);
01861 }else{
01862 *res=0;
01863 }
01864 }
01865 break;
01866 case RV_NONE:
01867 *res=0;
01868 break;
01869 default:
01870 break;
01871 }
01872 return 0;
01873 }
01874
01875
01884 inline static int int_rve_defined(struct run_act_ctx* h,
01885 struct sip_msg* msg, int* res,
01886 struct rval_expr* rve)
01887 {
01888
01889
01890 if (likely(rve->op==RVE_RVAL_OP))
01891 return rv_defined(h, msg, res, &rve->left.rval, 0);
01892 *res=1;
01893 return 0;
01894 }
01895
01896
01897
01903 int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
01904 int* res, struct rval_expr* rve)
01905 {
01906 int i1, i2, ret;
01907 struct rval_cache c1, c2;
01908 struct rvalue* rv1;
01909 struct rvalue* rv2;
01910
01911 ret=-1;
01912 switch(rve->op){
01913 case RVE_RVAL_OP:
01914 ret=rval_get_int(h, msg, res, &rve->left.rval, 0);
01915 rval_get_int_handle_ret(ret, "rval expression conversion to int"
01916 " failed", rve);
01917 break;
01918 case RVE_UMINUS_OP:
01919 case RVE_BOOL_OP:
01920 case RVE_LNOT_OP:
01921 case RVE_BNOT_OP:
01922 if (unlikely(
01923 (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
01924 break;
01925 ret=int_intop1(res, rve->op, i1);
01926 break;
01927 case RVE_INT_OP:
01928 ret=rval_expr_eval_int(h, msg, res, rve->left.rve);
01929 break;
01930 case RVE_MUL_OP:
01931 case RVE_DIV_OP:
01932 case RVE_MOD_OP:
01933 case RVE_MINUS_OP:
01934 case RVE_PLUS_OP:
01935 case RVE_IPLUS_OP:
01936 case RVE_BOR_OP:
01937 case RVE_BAND_OP:
01938 case RVE_BXOR_OP:
01939 case RVE_BLSHIFT_OP:
01940 case RVE_BRSHIFT_OP:
01941 case RVE_GT_OP:
01942 case RVE_GTE_OP:
01943 case RVE_LT_OP:
01944 case RVE_LTE_OP:
01945 case RVE_IEQ_OP:
01946 case RVE_IDIFF_OP:
01947 if (unlikely(
01948 (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
01949 break;
01950 if (unlikely(
01951 (ret=rval_expr_eval_int(h, msg, &i2, rve->right.rve)) <0) )
01952 break;
01953 ret=int_intop2(res, rve->op, i1, i2);
01954 break;
01955 case RVE_LAND_OP:
01956 if (unlikely(
01957 (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
01958 break;
01959 if (i1==0){
01960 *res=0;
01961 }else{
01962 if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
01963 rve->right.rve)) <0) )
01964 break;
01965 *res=i1 && i2;
01966 }
01967 ret=0;
01968 break;
01969 case RVE_LOR_OP:
01970 if (unlikely(
01971 (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
01972 break;
01973 if (i1){
01974 *res=1;
01975 }else{
01976 if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
01977 rve->right.rve)) <0) )
01978 break;
01979 *res=i1 || i2;
01980 }
01981 ret=0;
01982 break;
01983 case RVE_EQ_OP:
01984 case RVE_DIFF_OP:
01985
01986
01987
01988
01989
01990 rval_cache_init(&c1);
01991 if (unlikely( (ret=rval_expr_eval_rvint(h, msg, &rv1, &i1,
01992 rve->left.rve, &c1))<0)){
01993
01994 rval_cache_clean(&c1);
01995 break;
01996 }
01997 if (likely(rv1==0)){
01998
01999 rval_cache_clean(&c1);
02000 if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
02001 rve->right.rve)) <0) )
02002 break;
02003 ret=int_intop2(res, rve->op, i1, i2);
02004 }else{
02005
02006
02007 if (unlikely( c1.cache_type!=RV_CACHE_EMPTY &&
02008 c1.val_type==RV_NONE)){
02009 #ifdef UNDEF_EQ_ALWAYS_FALSE
02010
02011
02012 ret=(rve->op==RVE_DIFF_OP);
02013 #elif defined UNDEF_EQ_UNDEF_TRUE
02014
02015
02016 if (int_rve_defined(h, msg, &i2, rve->right.rve)<0){
02017
02018 rval_cache_clean(&c1);
02019 rval_destroy(rv1);
02020 break;
02021 }
02022 ret=(!i2) ^ (rve->op==RVE_DIFF_OP);
02023 #else
02024
02025
02026 rval_cache_init(&c2);
02027 if (unlikely( (ret=rval_expr_eval_rvint(h, msg, &rv2, &i2,
02028 rve->right.rve, &c2))<0)){
02029
02030 rval_cache_clean(&c1);
02031 rval_cache_clean(&c2);
02032 rval_destroy(rv1);
02033 break;
02034 }
02035 if (rv2==0){
02036
02037 ret=int_intop2(res, rve->op, 0 , i2);
02038 }else{
02039
02040 ret=rval_str_lop2(h, msg, res, rve->op, rv1, &c1,
02041 rv2, &c2);
02042 rval_cache_clean(&c2);
02043 rval_destroy(rv2);
02044 }
02045 #endif
02046 rval_cache_clean(&c1);
02047 rval_destroy(rv1);
02048 }else{
02049
02050
02051 if (unlikely((rv2=rval_expr_eval(h, msg,
02052 rve->right.rve))==0)){
02053
02054 rval_destroy(rv1);
02055 rval_cache_clean(&c1);
02056 break;
02057 }
02058 ret=rval_str_lop2(h, msg, res, rve->op, rv1, &c1, rv2, 0);
02059 rval_cache_clean(&c1);
02060 rval_destroy(rv1);
02061 rval_destroy(rv2);
02062 }
02063 }
02064 break;
02065 case RVE_CONCAT_OP:
02066
02067 if (unlikely((rv1=rval_expr_eval(h, msg, rve))==0)){
02068 ret=-1;
02069 break;
02070 }
02071
02072 ret=rval_get_int(h, msg, res, rv1, 0);
02073 rval_get_int_handle_ret(ret, "rval expression conversion to int"
02074 " failed", rve);
02075 rval_destroy(rv1);
02076 break;
02077 case RVE_STR_OP:
02078
02079 rval_cache_init(&c1);
02080 if (unlikely((ret=rval_expr_eval_rvint(h, msg, &rv1, res,
02081 rve->left.rve, &c1))<0)){
02082
02083 rval_cache_clean(&c1);
02084 break;
02085 }
02086 if (unlikely(rv1)){
02087
02088 ret=rval_get_int(h, msg, res, rv1, &c1);
02089 rval_get_int_handle_ret(ret, "rval expression conversion"
02090 " to int failed", rve);
02091 rval_destroy(rv1);
02092 rval_cache_clean(&c1);
02093 }
02094
02095
02096 break;
02097
02098 #if 0
02099
02100
02101
02102 if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
02103 ret=-1;
02104 break;
02105 }
02106
02107
02108 ret=rval_get_int(h, msg, res, rv1, 0);
02109 rval_destroy(rv1);
02110 break;
02111 #endif
02112 case RVE_DEFINED_OP:
02113 ret=int_rve_defined(h, msg, res, rve->left.rve);
02114 break;
02115 case RVE_STREQ_OP:
02116 case RVE_STRDIFF_OP:
02117 case RVE_MATCH_OP:
02118 if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
02119 ret=-1;
02120 break;
02121 }
02122 if (unlikely((rv2=rval_expr_eval(h, msg, rve->right.rve))==0)){
02123 rval_destroy(rv1);
02124 ret=-1;
02125 break;
02126 }
02127 ret=rval_str_lop2(h, msg, res, rve->op, rv1, 0, rv2, 0);
02128 rval_destroy(rv1);
02129 rval_destroy(rv2);
02130 break;
02131 case RVE_STRLEN_OP:
02132 case RVE_STREMPTY_OP:
02133 if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
02134 ret=-1;
02135 break;
02136 }
02137 ret=rval_int_strop1(h, msg, res, rve->op, rv1, 0);
02138 rval_destroy(rv1);
02139 break;
02140 case RVE_NONE_OP:
02141
02142 BUG("invalid rval int expression operation %d (%d,%d-%d,%d)\n",
02143 rve->op, rve->fpos.s_line, rve->fpos.s_col,
02144 rve->fpos.e_line, rve->fpos.e_col);
02145 ret=-1;
02146 };
02147 return ret;
02148 }
02149
02150
02151
02169 int rval_expr_eval_rvint( struct run_act_ctx* h,
02170 struct sip_msg* msg,
02171 struct rvalue** res_rv,
02172 int* res_i,
02173 struct rval_expr* rve,
02174 struct rval_cache* cache
02175 )
02176 {
02177 struct rvalue* rv1;
02178 struct rvalue* rv2;
02179 struct rval_cache c1;
02180 int ret;
02181 int r, i, j;
02182 enum rval_type type;
02183
02184 rv1=0;
02185 rv2=0;
02186 ret=-1;
02187 switch(rve->op){
02188 case RVE_RVAL_OP:
02189 rv1=&rve->left.rval;
02190 rv_ref(rv1);
02191 type=rval_get_btype(h, msg, rv1, cache);
02192 if (type==RV_INT){
02193 r=rval_get_int(h, msg, res_i, rv1, cache);
02194 rval_get_int_handle_ret(r, "rval expression conversion"
02195 " to int failed", rve);
02196 *res_rv=0;
02197 ret=r;
02198 }else{
02199
02200
02201 *res_rv=rv1;
02202 rv_ref(rv1);
02203 ret=0;
02204 }
02205 break;
02206 case RVE_UMINUS_OP:
02207 case RVE_BOOL_OP:
02208 case RVE_LNOT_OP:
02209 case RVE_BNOT_OP:
02210 case RVE_MINUS_OP:
02211 case RVE_MUL_OP:
02212 case RVE_DIV_OP:
02213 case RVE_MOD_OP:
02214 case RVE_BOR_OP:
02215 case RVE_BAND_OP:
02216 case RVE_BXOR_OP:
02217 case RVE_BLSHIFT_OP:
02218 case RVE_BRSHIFT_OP:
02219 case RVE_LAND_OP:
02220 case RVE_LOR_OP:
02221 case RVE_GT_OP:
02222 case RVE_GTE_OP:
02223 case RVE_LT_OP:
02224 case RVE_LTE_OP:
02225 case RVE_EQ_OP:
02226 case RVE_DIFF_OP:
02227 case RVE_IEQ_OP:
02228 case RVE_IDIFF_OP:
02229 case RVE_IPLUS_OP:
02230 case RVE_STREQ_OP:
02231 case RVE_STRDIFF_OP:
02232 case RVE_MATCH_OP:
02233 case RVE_STRLEN_OP:
02234 case RVE_STREMPTY_OP:
02235 case RVE_DEFINED_OP:
02236 case RVE_INT_OP:
02237
02238 ret=rval_expr_eval_int(h, msg, res_i, rve);
02239 *res_rv=0;
02240 break;
02241 case RVE_PLUS_OP:
02242 rval_cache_init(&c1);
02243 r=rval_expr_eval_rvint(h, msg, &rv1, &i, rve->left.rve, &c1);
02244 if (unlikely(r<0)){
02245 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02246 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
02247 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col
02248 );
02249 rval_cache_clean(&c1);
02250 goto error;
02251 }
02252 if (rv1==0){
02253 if (unlikely((r=rval_expr_eval_int(h, msg, &j,
02254 rve->right.rve))<0)){
02255 ERR("rval expression evaluation failed (%d,%d-%d,%d)"
02256 "\n", rve->right.rve->fpos.s_line,
02257 rve->right.rve->fpos.s_col,
02258 rve->right.rve->fpos.e_line,
02259 rve->right.rve->fpos.e_col);
02260 rval_cache_clean(&c1);
02261 goto error;
02262 }
02263 ret=int_intop2(res_i, rve->op, i, j);
02264 *res_rv=0;
02265 }else{
02266 rv2=rval_expr_eval(h, msg, rve->right.rve);
02267 if (unlikely(rv2==0)){
02268 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02269 rve->right.rve->fpos.s_line,
02270 rve->right.rve->fpos.s_col,
02271 rve->right.rve->fpos.e_line,
02272 rve->right.rve->fpos.e_col);
02273 rval_cache_clean(&c1);
02274 goto error;
02275 }
02276 *res_rv=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
02277 ret=-(*res_rv==0);
02278 }
02279 rval_cache_clean(&c1);
02280 break;
02281 case RVE_CONCAT_OP:
02282 case RVE_STR_OP:
02283 *res_rv=rval_expr_eval(h, msg, rve);
02284 ret=-(*res_rv==0);
02285 break;
02286 case RVE_NONE_OP:
02287
02288 BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
02289 rve->op, rve->fpos.s_line, rve->fpos.s_col,
02290 rve->fpos.e_line, rve->fpos.e_col);
02291 goto error;
02292 };
02293 rval_destroy(rv1);
02294 rval_destroy(rv2);
02295 return ret;
02296 error:
02297 rval_destroy(rv1);
02298 rval_destroy(rv2);
02299 return -1;
02300 }
02301
02302
02303
02314 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
02315 struct rval_expr* rve)
02316 {
02317 struct rvalue* rv1;
02318 struct rvalue* rv2;
02319 struct rvalue* ret;
02320 struct rval_cache c1;
02321 union rval_val v;
02322 int r, i, j;
02323 enum rval_type type;
02324
02325 rv1=0;
02326 rv2=0;
02327 ret=0;
02328 switch(rve->op){
02329 case RVE_RVAL_OP:
02330 rv_ref(&rve->left.rval);
02331 return &rve->left.rval;
02332 break;
02333 case RVE_UMINUS_OP:
02334 case RVE_BOOL_OP:
02335 case RVE_LNOT_OP:
02336 case RVE_BNOT_OP:
02337 case RVE_MINUS_OP:
02338 case RVE_MUL_OP:
02339 case RVE_DIV_OP:
02340 case RVE_MOD_OP:
02341 case RVE_BOR_OP:
02342 case RVE_BAND_OP:
02343 case RVE_BXOR_OP:
02344 case RVE_BLSHIFT_OP:
02345 case RVE_BRSHIFT_OP:
02346 case RVE_LAND_OP:
02347 case RVE_LOR_OP:
02348 case RVE_GT_OP:
02349 case RVE_GTE_OP:
02350 case RVE_LT_OP:
02351 case RVE_LTE_OP:
02352 case RVE_EQ_OP:
02353 case RVE_DIFF_OP:
02354 case RVE_IEQ_OP:
02355 case RVE_IDIFF_OP:
02356 case RVE_IPLUS_OP:
02357 case RVE_STREQ_OP:
02358 case RVE_STRDIFF_OP:
02359 case RVE_MATCH_OP:
02360 case RVE_STRLEN_OP:
02361 case RVE_STREMPTY_OP:
02362 case RVE_DEFINED_OP:
02363 case RVE_INT_OP:
02364
02365 r=rval_expr_eval_int(h, msg, &i, rve);
02366 if (likely(r==0)){
02367 v.l=i;
02368 ret=rval_new(RV_INT, &v, 0);
02369 if (unlikely(ret==0)){
02370 ERR("rv eval int expression: out of memory\n");
02371 goto error;
02372 }
02373 return ret;
02374 }else{
02375 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02376 rve->fpos.s_line, rve->fpos.s_col,
02377 rve->fpos.e_line, rve->fpos.e_col);
02378 goto error;
02379 }
02380 break;
02381 case RVE_PLUS_OP:
02382 rv1=rval_expr_eval(h, msg, rve->left.rve);
02383 if (unlikely(rv1==0)){
02384 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02385 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
02386 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
02387 goto error;
02388 }
02389 rval_cache_init(&c1);
02390 type=rval_get_btype(h, msg, rv1, &c1);
02391 switch(type){
02392 case RV_INT:
02393 r=rval_get_int(h, msg, &i, rv1, &c1);
02394 rval_get_int_handle_ret(r, "rval expression left side "
02395 "conversion to int failed",
02396 rve);
02397 if (unlikely(r<0)){
02398 rval_cache_clean(&c1);
02399 goto error;
02400 }
02401 if (unlikely((r=rval_expr_eval_int(h, msg, &j,
02402 rve->right.rve))<0)){
02403 rval_cache_clean(&c1);
02404 ERR("rval expression evaluation failed (%d,%d-%d,%d):"
02405 " could not evaluate right side to int\n",
02406 rve->fpos.s_line, rve->fpos.s_col,
02407 rve->fpos.e_line, rve->fpos.e_col);
02408 goto error;
02409 }
02410 int_intop2(&r, rve->op, i, j);
02411 if (rv_chg_in_place(rv1)){
02412 rv1->v.l=r;
02413 ret=rv1;
02414 rv_ref(ret);
02415 }else{
02416 v.l=r;
02417 ret=rval_new(RV_INT, &v, 0);
02418 if (unlikely(ret==0)){
02419 rval_cache_clean(&c1);
02420 ERR("rv eval int expression: out of memory\n");
02421 goto error;
02422 }
02423 }
02424 break;
02425 case RV_STR:
02426 case RV_NONE:
02427 rv2=rval_expr_eval(h, msg, rve->right.rve);
02428 if (unlikely(rv2==0)){
02429 ERR("rval expression evaluation failed (%d,%d-%d,%d)"
02430 "\n", rve->right.rve->fpos.s_line,
02431 rve->right.rve->fpos.s_col,
02432 rve->right.rve->fpos.e_line,
02433 rve->right.rve->fpos.e_col);
02434 rval_cache_clean(&c1);
02435 goto error;
02436 }
02437 ret=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
02438 break;
02439 default:
02440 BUG("rv unsupported basic type %d (%d,%d-%d,%d)\n", type,
02441 rve->fpos.s_line, rve->fpos.s_col,
02442 rve->fpos.e_line, rve->fpos.e_col);
02443 }
02444 rval_cache_clean(&c1);
02445 break;
02446 case RVE_CONCAT_OP:
02447 rv1=rval_expr_eval(h, msg, rve->left.rve);
02448 if (unlikely(rv1==0)){
02449 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02450 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
02451 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
02452 goto error;
02453 }
02454 rv2=rval_expr_eval(h, msg, rve->right.rve);
02455 if (unlikely(rv2==0)){
02456 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02457 rve->right.rve->fpos.s_line,
02458 rve->right.rve->fpos.s_col,
02459 rve->right.rve->fpos.e_line,
02460 rve->right.rve->fpos.e_col);
02461 goto error;
02462 }
02463 ret=rval_str_add2(h, msg, rv1, 0, rv2, 0);
02464 break;
02465 case RVE_STR_OP:
02466 rv1=rval_expr_eval(h, msg, rve->left.rve);
02467 if (unlikely(rv1==0)){
02468 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
02469 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
02470 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
02471 goto error;
02472 }
02473 ret=rval_convert(h, msg, RV_STR, rv1, 0);
02474 break;
02475 case RVE_NONE_OP:
02476
02477 BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
02478 rve->op, rve->fpos.s_line, rve->fpos.s_col,
02479 rve->fpos.e_line, rve->fpos.e_col);
02480 goto error;
02481 };
02482 rval_destroy(rv1);
02483 rval_destroy(rv2);
02484 return ret;
02485 error:
02486 rval_destroy(rv1);
02487 rval_destroy(rv2);
02488 return 0;
02489 }
02490
02491
02492
02501 struct rvalue* rval_expr_eval_new(struct run_act_ctx* h, struct sip_msg* msg,
02502 struct rval_expr* rve)
02503 {
02504 struct rvalue* ret;
02505 struct rvalue* rv;
02506
02507 ret=rval_expr_eval(h, msg, rve);
02508 if (ret && !rv_chg_in_place(ret)){
02509 rv=ret;
02510
02511 ret=rval_new(rv->type, &rv->v, 0);
02512 rval_destroy(rv);
02513 }
02514 return ret;
02515 }
02516
02517
02518
02526 struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
02527 struct cfg_pos* pos)
02528 {
02529 struct rval_expr* rve;
02530 union rval_val v;
02531 str* s;
02532 int flags;
02533
02534 rve=pkg_malloc(sizeof(*rve));
02535 if (rve==0)
02536 return 0;
02537 memset(rve, 0, sizeof(*rve));
02538 flags=0;
02539 switch(rv_type){
02540 case RV_INT:
02541 v.l=(long)val;
02542 break;
02543 case RV_STR:
02544 s=(str*)val;
02545 v.s.s=pkg_malloc(s->len+1 );
02546 if (v.s.s==0){
02547 ERR("memory allocation failure\n");
02548 return 0;
02549 }
02550 v.s.len=s->len;
02551 memcpy(v.s.s, s->s, s->len);
02552 v.s.s[s->len]=0;
02553 flags=RV_CNT_ALLOCED_F;
02554 break;
02555 case RV_AVP:
02556 v.avps=*(avp_spec_t*)val;
02557 break;
02558 case RV_PVAR:
02559 v.pvs=*(pv_spec_t*)val;
02560 break;
02561 case RV_SEL:
02562 v.sel=*(select_t*)val;
02563 break;
02564 case RV_BEXPR:
02565 v.bexpr=(struct expr*)val;
02566 break;
02567 case RV_ACTION_ST:
02568 v.action=(struct action*)val;
02569 break;
02570 default:
02571 BUG("unsupported rv type %d\n", rv_type);
02572 pkg_free(rve);
02573 return 0;
02574 }
02575 rval_init(&rve->left.rval, rv_type, &v, flags);
02576 rve->op=RVE_RVAL_OP;
02577 if (pos) rve->fpos=*pos;
02578 return rve;
02579 }
02580
02581
02582
02591 struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
02592 struct cfg_pos* pos)
02593 {
02594 struct rval_expr* ret;
02595
02596 switch(op){
02597 case RVE_UMINUS_OP:
02598 case RVE_BOOL_OP:
02599 case RVE_LNOT_OP:
02600 case RVE_BNOT_OP:
02601 case RVE_STRLEN_OP:
02602 case RVE_STREMPTY_OP:
02603 case RVE_DEFINED_OP:
02604 case RVE_INT_OP:
02605 case RVE_STR_OP:
02606 break;
02607 default:
02608 BUG("unsupported unary operator %d\n", op);
02609 return 0;
02610 }
02611 ret=pkg_malloc(sizeof(*ret));
02612 if (ret==0)
02613 return 0;
02614 memset(ret, 0, sizeof(*ret));
02615 ret->op=op;
02616 ret->left.rve=rve1;
02617 if (pos) ret->fpos=*pos;
02618 return ret;
02619 }
02620
02621
02622
02632 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
02633 struct rval_expr* rve2,
02634 struct cfg_pos* pos)
02635 {
02636 struct rval_expr* ret;
02637
02638 switch(op){
02639 case RVE_MUL_OP:
02640 case RVE_DIV_OP:
02641 case RVE_MOD_OP:
02642 case RVE_MINUS_OP:
02643 case RVE_BOR_OP:
02644 case RVE_BAND_OP:
02645 case RVE_BXOR_OP:
02646 case RVE_BLSHIFT_OP:
02647 case RVE_BRSHIFT_OP:
02648 case RVE_LAND_OP:
02649 case RVE_LOR_OP:
02650 case RVE_GT_OP:
02651 case RVE_GTE_OP:
02652 case RVE_LT_OP:
02653 case RVE_LTE_OP:
02654 case RVE_PLUS_OP:
02655 case RVE_IPLUS_OP:
02656 case RVE_EQ_OP:
02657 case RVE_DIFF_OP:
02658 case RVE_IEQ_OP:
02659 case RVE_IDIFF_OP:
02660 case RVE_STREQ_OP:
02661 case RVE_STRDIFF_OP:
02662 case RVE_MATCH_OP:
02663 case RVE_CONCAT_OP:
02664 break;
02665 default:
02666 BUG("unsupported operator %d\n", op);
02667 return 0;
02668 }
02669 ret=pkg_malloc(sizeof(*ret));
02670 if (ret==0)
02671 return 0;
02672 memset(ret, 0, sizeof(*ret));
02673 ret->op=op;
02674 ret->left.rve=rve1;
02675 ret->right.rve=rve2;
02676 if (pos) ret->fpos=*pos;
02677 return ret;
02678 }
02679
02680
02681
02683 static int rve_op_is_assoc(enum rval_expr_op op)
02684 {
02685 switch(op){
02686 case RVE_NONE_OP:
02687 case RVE_RVAL_OP:
02688 case RVE_UMINUS_OP:
02689 case RVE_BOOL_OP:
02690 case RVE_LNOT_OP:
02691 case RVE_BNOT_OP:
02692 case RVE_STRLEN_OP:
02693 case RVE_STREMPTY_OP:
02694 case RVE_DEFINED_OP:
02695 case RVE_INT_OP:
02696 case RVE_STR_OP:
02697
02698 return 0;
02699 case RVE_DIV_OP:
02700 case RVE_MOD_OP:
02701 case RVE_MINUS_OP:
02702 case RVE_BLSHIFT_OP:
02703 case RVE_BRSHIFT_OP:
02704 return 0;
02705 case RVE_PLUS_OP:
02706
02707
02708 return 0;
02709 case RVE_IPLUS_OP:
02710 case RVE_CONCAT_OP:
02711 case RVE_MUL_OP:
02712 case RVE_BAND_OP:
02713 case RVE_BOR_OP:
02714 case RVE_BXOR_OP:
02715 return 1;
02716 case RVE_LAND_OP:
02717 case RVE_LOR_OP:
02718 return 1;
02719 case RVE_GT_OP:
02720 case RVE_GTE_OP:
02721 case RVE_LT_OP:
02722 case RVE_LTE_OP:
02723 case RVE_EQ_OP:
02724 case RVE_DIFF_OP:
02725 case RVE_IEQ_OP:
02726 case RVE_IDIFF_OP:
02727 case RVE_STREQ_OP:
02728 case RVE_STRDIFF_OP:
02729 case RVE_MATCH_OP:
02730 return 0;
02731 }
02732 return 0;
02733 }
02734
02735
02736
02738 static int rve_op_is_commutative(enum rval_expr_op op)
02739 {
02740 switch(op){
02741 case RVE_NONE_OP:
02742 case RVE_RVAL_OP:
02743 case RVE_UMINUS_OP:
02744 case RVE_BOOL_OP:
02745 case RVE_LNOT_OP:
02746 case RVE_BNOT_OP:
02747 case RVE_STRLEN_OP:
02748 case RVE_STREMPTY_OP:
02749 case RVE_DEFINED_OP:
02750 case RVE_INT_OP:
02751 case RVE_STR_OP:
02752
02753 return 0;
02754 case RVE_DIV_OP:
02755 case RVE_MOD_OP:
02756 case RVE_MINUS_OP:
02757 case RVE_BLSHIFT_OP:
02758 case RVE_BRSHIFT_OP:
02759 return 0;
02760 case RVE_PLUS_OP:
02761
02762
02763
02764 return 0;
02765 case RVE_IPLUS_OP:
02766 case RVE_MUL_OP:
02767 case RVE_BAND_OP:
02768 case RVE_BOR_OP:
02769 case RVE_BXOR_OP:
02770 case RVE_LAND_OP:
02771 case RVE_LOR_OP:
02772 case RVE_IEQ_OP:
02773 case RVE_IDIFF_OP:
02774 case RVE_STREQ_OP:
02775 case RVE_STRDIFF_OP:
02776 return 1;
02777 case RVE_GT_OP:
02778 case RVE_GTE_OP:
02779 case RVE_LT_OP:
02780 case RVE_LTE_OP:
02781 case RVE_CONCAT_OP:
02782 case RVE_MATCH_OP:
02783 return 0;
02784 case RVE_DIFF_OP:
02785 case RVE_EQ_OP:
02786
02787
02788
02789
02790 return 0 ;
02791 }
02792 return 0;
02793 }
02794
02795
02796 #if 0
02797
02802 static int rve_can_optimize_int(struct rval_expr* rve)
02803 {
02804 if (scr_opt_lev<1)
02805 return 0;
02806 if (rve->op == RVE_RVAL_OP)
02807 return 0;
02808 if (rve->left.rve->op != RVE_RVAL_OP)
02809 return 0;
02810 if (rve->left.rve->left.rval.type!=RV_INT)
02811 return 0;
02812 if (rve->right.rve){
02813 if (rve->right.rve->op != RVE_RVAL_OP)
02814 return 0;
02815 if (rve->right.rve->left.rval.type!=RV_INT)
02816 return 0;
02817 }
02818 DBG("rve_can_optimize_int: left %d, right %d\n",
02819 rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
02820 return 1;
02821 }
02822
02823
02824
02830 static int rve_can_optimize_str(struct rval_expr* rve)
02831 {
02832 if (scr_opt_lev<1)
02833 return 0;
02834 if (rve->op == RVE_RVAL_OP)
02835 return 0;
02836 DBG("rve_can_optimize_str: left %d, right %d\n",
02837 rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
02838 if (rve->left.rve->op != RVE_RVAL_OP)
02839 return 0;
02840 if (rve->left.rve->left.rval.type!=RV_STR)
02841 return 0;
02842 if (rve->right.rve){
02843 if (rve->right.rve->op != RVE_RVAL_OP)
02844 return 0;
02845 if ((rve->right.rve->left.rval.type!=RV_STR) &&
02846 (rve->right.rve->left.rval.type!=RV_INT))
02847 return 0;
02848 }
02849 return 1;
02850 }
02851 #endif
02852
02853
02854
02855 static int fix_rval(struct rvalue* rv)
02856 {
02857 DBG("RV fixing type %d\n", rv->type);
02858 switch(rv->type){
02859 case RV_INT:
02860
02861 DBG("RV is int: %d\n", (int)rv->v.l);
02862 return 0;
02863 case RV_STR:
02864
02865 DBG("RV is str: \"%s\"\n", rv->v.s.s);
02866 return 0;
02867 case RV_BEXPR:
02868 return fix_expr(rv->v.bexpr);
02869 case RV_ACTION_ST:
02870 return fix_actions(rv->v.action);
02871 case RV_SEL:
02872 if (resolve_select(&rv->v.sel)<0){
02873 ERR("Unable to resolve select\n");
02874 print_select(&rv->v.sel);
02875 }
02876 return 0;
02877 case RV_AVP:
02878
02879 return 0;
02880 case RV_PVAR:
02881
02882 return 0;
02883 case RV_NONE:
02884 BUG("uninitialized rvalue\n");
02885 return -1;
02886 }
02887 BUG("unknown rvalue type %d\n", rv->type);
02888 return -1;
02889 }
02890
02891
02892
02904 static int rve_replace_with_val(struct rval_expr* rve, enum rval_type type,
02905 union rval_val* v, int flags)
02906 {
02907 int refcnt;
02908
02909 refcnt=1;
02910 if (rve->op!=RVE_RVAL_OP){
02911 rve_destroy(rve->left.rve);
02912 if (rve_op_unary(rve->op)==0)
02913 rve_destroy(rve->right.rve);
02914 }else{
02915 if (rve->left.rval.refcnt!=1){
02916 BUG("trying to replace a referenced rval! (refcnt=%d)\n",
02917 rve->left.rval.refcnt);
02918
02919 refcnt=rve->left.rval.refcnt;
02920 abort();
02921 }
02922 rval_destroy(&rve->left.rval);
02923 }
02924 rval_init(&rve->left.rval, type, v, flags);
02925 rve->left.rval.refcnt=refcnt;
02926 rval_init(&rve->right.rval, RV_NONE, 0, 0);
02927 rve->op=RVE_RVAL_OP;
02928 return 0;
02929 }
02930
02931
02932
02937 static int rve_replace_with_ct_rv(struct rval_expr* rve, struct rvalue* rv)
02938 {
02939 enum rval_type type;
02940 int flags;
02941 int i;
02942 union rval_val v;
02943
02944 type=rv->type;
02945 flags=0;
02946 if (rv->type==RV_INT){
02947 if (rval_get_int(0, 0, &i, rv, 0)!=0){
02948 BUG("unexpected int evaluation failure (%d,%d-%d,%d)\n",
02949 rve->fpos.s_line, rve->fpos.s_col,
02950 rve->fpos.e_line, rve->fpos.e_col);
02951 return -1;
02952 }
02953 v.l=i;
02954 }else if(rv->type==RV_STR){
02955 if (rval_get_str(0, 0, &v.s, rv, 0)<0){
02956 BUG("unexpected str evaluation failure(%d,%d-%d,%d)\n",
02957 rve->fpos.s_line, rve->fpos.s_col,
02958 rve->fpos.e_line, rve->fpos.e_col);
02959 return -1;
02960 }
02961 flags|=RV_CNT_ALLOCED_F;
02962 }else{
02963 BUG("unknown constant expression type %d (%d,%d-%d,%d)\n", rv->type,
02964 rve->fpos.s_line, rve->fpos.s_col,
02965 rve->fpos.e_line, rve->fpos.e_col);
02966 return -1;
02967 }
02968 return rve_replace_with_val(rve, type, &v, flags);
02969 }
02970
02971
02972
02976 static int fix_match_rve(struct rval_expr* rve)
02977 {
02978 struct rvalue* rv;
02979 regex_t* re;
02980 union rval_val v;
02981 int flags;
02982 int ret;
02983
02984 rv=0;
02985 v.s.s=0;
02986 v.re.regex=0;
02987
02988 ret=fix_rval_expr((void*)rve->left.rve);
02989 if (ret<0) return ret;
02990
02991
02992 if (rve_is_constant(rve->right.rve)){
02993 if ((rve_guess_type(rve->right.rve)!=RV_STR)){
02994 ERR("fixup failure(%d,%d-%d,%d): left side of =~ is not string"
02995 " (%d,%d)\n", rve->fpos.s_line, rve->fpos.s_col,
02996 rve->fpos.e_line, rve->fpos.e_col,
02997 rve->right.rve->fpos.s_line,
02998 rve->right.rve->fpos.s_col);
02999 goto error;
03000 }
03001 if ((rv=rval_expr_eval(0, 0, rve->right.rve))==0){
03002 ERR("fixup failure(%d,%d-%d,%d): bad RE expression\n",
03003 rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
03004 rve->right.rve->fpos.e_line, rve->right.rve->fpos.e_col);
03005 goto error;
03006 }
03007 if (rval_get_str(0, 0, &v.s, rv, 0)<0){
03008 BUG("fixup unexpected failure (%d,%d-%d,%d)\n",
03009 rve->fpos.s_line, rve->fpos.s_col,
03010 rve->fpos.e_line, rve->fpos.e_col);
03011 goto error;
03012 }
03013
03014 rval_destroy(rv);
03015 rv=0;
03016 re=pkg_malloc(sizeof(*re));
03017 if (re==0){
03018 ERR("out of memory\n");
03019 goto error;
03020 }
03021
03022 if (regcomp(re, v.s.s, REG_EXTENDED|REG_NOSUB|REG_ICASE)){
03023 pkg_free(re);
03024 ERR("Bad regular expression \"%s\"(%d,%d-%d,%d)\n", v.s.s,
03025 rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
03026 rve->right.rve->fpos.e_line, rve->right.rve->fpos.e_col);
03027 goto error;
03028 }
03029 v.re.regex=re;
03030 flags=RV_RE_F|RV_RE_ALLOCED_F|RV_CNT_ALLOCED_F;
03031 if (rve_replace_with_val(rve->right.rve, RV_STR, &v, flags)<0)
03032 goto error;
03033 }else{
03034
03035 return fix_rval_expr((void*)rve->right.rve);
03036 }
03037 return 0;
03038 error:
03039 if (rv) rval_destroy(rv);
03040 if (v.s.s) pkg_free(v.s.s);
03041 if (v.re.regex){
03042 regfree(v.re.regex);
03043 pkg_free(v.re.regex);
03044 }
03045 return -1;
03046 }
03047
03048
03049
03056 static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
03057 {
03058 struct rvalue* rv;
03059 struct rval_expr* ct_rve;
03060 struct rval_expr* v_rve;
03061 int i;
03062 int ret;
03063 enum rval_expr_op op;
03064 struct cfg_pos pos;
03065 int right;
03066 int dbg;
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076 #define replace_rve_type_cast(e, v, ctype) \
03077 do{\
03078 if ( rve_guess_type((v)) == RV_##ctype ){\
03079
03080 \
03081 pos=(e)->fpos; \
03082 *(e)=*(v); \
03083 (e)->fpos=pos; \
03084 pkg_free((v)); \
03085 }else{\
03086 \
03087 (e)->op=RVE_##ctype##_OP; \
03088 (e)->left.rve=(v); \
03089 (e)->right.rve=0; \
03090 }\
03091 }while(0)
03092
03093
03094 #define replace_int_rve(e, v) replace_rve_type_cast(e, v, INT)
03095
03096 #define replace_str_rve(e, v) replace_rve_type_cast(e, v, STR)
03097
03098
03099 rv=0;
03100 ret=0;
03101 right=0;
03102 dbg=1;
03103
03104 if (rve_is_constant(rve->right.rve)){
03105 ct_rve=rve->right.rve;
03106 v_rve=rve->left.rve;
03107 right=1;
03108 }else if (rve_is_constant(rve->left.rve)){
03109 ct_rve=rve->left.rve;
03110 v_rve=rve->right.rve;
03111 right=0;
03112 }else
03113 return 0;
03114
03115
03116
03117
03118 if ((rv=rval_expr_eval_new(0, 0, ct_rve))==0){
03119 ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
03120 ct_rve->fpos.s_line, ct_rve->fpos.s_col,
03121 ct_rve->fpos.e_line, ct_rve->fpos.e_col);
03122 goto error;
03123 }
03124 op=rve->op;
03125 if (rv->type==RV_INT){
03126 i=rv->v.l;
03127 switch(op){
03128 case RVE_MUL_OP:
03129 if (i==0){
03130
03131
03132 if (rve_replace_with_ct_rv(rve, rv)<0)
03133 goto error;
03134 ret=1;
03135 }else if (i==1){
03136
03137
03138 rve_destroy(ct_rve);
03139 replace_int_rve(rve, v_rve);
03140 ret=1;
03141 }
03142 break;
03143 case RVE_DIV_OP:
03144 if (i==0){
03145 if (ct_rve==rve->left.rve){
03146
03147 if (rve_replace_with_ct_rv(rve, rv)<0)
03148 goto error;
03149 ret=1;
03150 }else{
03151
03152 ERR("RVE divide by 0 at %d,%d\n",
03153 ct_rve->fpos.s_line, ct_rve->fpos.s_col);
03154 }
03155 }else if (i==1){
03156 if (ct_rve==rve->right.rve){
03157
03158 rve_destroy(ct_rve);
03159 replace_int_rve(rve, v_rve);
03160 ret=1;
03161 }
03162 }
03163 break;
03164 case RVE_MOD_OP:
03165 if (i==0){
03166 if (ct_rve==rve->left.rve){
03167
03168 if (rve_replace_with_ct_rv(rve, rv)<0)
03169 goto error;
03170 ret=1;
03171 }else{
03172
03173 ERR("RVE modulo by 0 at %d,%d\n",
03174 ct_rve->fpos.s_line, ct_rve->fpos.s_col);
03175 }
03176 }
03177
03178 break;
03179 case RVE_MINUS_OP:
03180 if (i==0){
03181 if (ct_rve==rve->right.rve){
03182
03183 rve_destroy(ct_rve);
03184 replace_int_rve(rve, v_rve);
03185 ret=1;
03186 }
03187
03188 }
03189 break;
03190 case RVE_BAND_OP:
03191 if (i==0){
03192
03193
03194 if (rve_replace_with_ct_rv(rve, rv)<0)
03195 goto error;
03196 ret=1;
03197 }
03198
03199
03200 break;
03201 case RVE_BOR_OP:
03202 if (i==0){
03203
03204
03205 rve_destroy(ct_rve);
03206 replace_int_rve(rve, v_rve);
03207 ret=1;
03208 }
03209 break;
03210 case RVE_LAND_OP:
03211 if (i==0){
03212
03213
03214 if (rve_replace_with_ct_rv(rve, rv)<0)
03215 goto error;
03216 ret=1;
03217 }else if (i==1){
03218
03219
03220 rve_destroy(ct_rve);
03221 replace_int_rve(rve, v_rve);
03222 ret=1;
03223 }
03224 break;
03225 case RVE_LOR_OP:
03226 if (i==1){
03227
03228
03229 if (rve_replace_with_ct_rv(rve, rv)<0)
03230 goto error;
03231 ret=1;
03232 }else if (i==0){
03233
03234
03235 rve_destroy(ct_rve);
03236 replace_int_rve(rve, v_rve);
03237 ret=1;
03238 }
03239 break;
03240 case RVE_PLUS_OP:
03241 case RVE_IPLUS_OP:
03242
03243
03244
03245
03246
03247 if ((i==0) && ((op==RVE_IPLUS_OP) || (rve_type==RV_INT))){
03248
03249
03250 rve_destroy(ct_rve);
03251 replace_int_rve(rve, v_rve);
03252 ret=1;
03253 }
03254 break;
03255 default:
03256
03257 break;
03258 }
03259
03260 if (ret==1 && dbg){
03261 if (right){
03262 if (rve->op==RVE_RVAL_OP){
03263 if (rve->left.rval.type==RV_INT)
03264 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03265 " op%d($v, %d) -> %d\n",
03266 rve->fpos.s_line, rve->fpos.s_col,
03267 rve->fpos.e_line, rve->fpos.e_col,
03268 op, i, (int)rve->left.rval.v.l);
03269 else
03270 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03271 " op%d($v, %d) -> $v (rval)\n",
03272 rve->fpos.s_line, rve->fpos.s_col,
03273 rve->fpos.e_line, rve->fpos.e_col,
03274 op, i);
03275 }else if (rve->op==RVE_INT_OP){
03276 if (rve->left.rve->op==RVE_RVAL_OP &&
03277 rve->left.rve->left.rval.type==RV_INT)
03278 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03279 " op%d($v, %d) -> (int)%d\n",
03280 rve->fpos.s_line, rve->fpos.s_col,
03281 rve->fpos.e_line, rve->fpos.e_col,
03282 op, i, (int)rve->left.rve->left.rval.v.l);
03283 else
03284 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03285 " op%d($v, %d) -> (int)$v\n",
03286 rve->fpos.s_line, rve->fpos.s_col,
03287 rve->fpos.e_line, rve->fpos.e_col,
03288 op, i);
03289 }else{
03290 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03291 " op%d($v, %d) -> $v\n",
03292 rve->fpos.s_line, rve->fpos.s_col,
03293 rve->fpos.e_line, rve->fpos.e_col,
03294 op, i);
03295 }
03296 }else{
03297 if (rve->op==RVE_RVAL_OP){
03298 if (rve->left.rval.type==RV_INT)
03299 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03300 " op%d(%d, $v) -> %d\n",
03301 rve->fpos.s_line, rve->fpos.s_col,
03302 rve->fpos.e_line, rve->fpos.e_col,
03303 op, i, (int)rve->left.rval.v.l);
03304 else
03305 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03306 " op%d(%d, $v) -> $v (rval)\n",
03307 rve->fpos.s_line, rve->fpos.s_col,
03308 rve->fpos.e_line, rve->fpos.e_col,
03309 op, i);
03310 }else if (rve->op==RVE_INT_OP){
03311 if (rve->left.rve->op==RVE_RVAL_OP &&
03312 rve->left.rve->left.rval.type==RV_INT)
03313 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03314 " op%d(%d, $v) -> (int)%d\n",
03315 rve->fpos.s_line, rve->fpos.s_col,
03316 rve->fpos.e_line, rve->fpos.e_col,
03317 op, i, (int)rve->left.rve->left.rval.v.l);
03318 else
03319 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03320 " op%d(%d, $v) -> (int)$v\n",
03321 rve->fpos.s_line, rve->fpos.s_col,
03322 rve->fpos.e_line, rve->fpos.e_col,
03323 op, i);
03324 }else{
03325 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03326 " op%d(%d, $v) -> $v\n",
03327 rve->fpos.s_line, rve->fpos.s_col,
03328 rve->fpos.e_line, rve->fpos.e_col,
03329 op, i);
03330 }
03331 }
03332 }
03333 }else if (rv->type==RV_STR){
03334 switch(op){
03335 case RVE_CONCAT_OP:
03336 if (rv->v.s.len==0){
03337
03338
03339 rve_destroy(ct_rve);
03340 replace_str_rve(rve, v_rve);
03341 ret=1;
03342 }
03343 break;
03344 case RVE_EQ_OP:
03345 case RVE_STREQ_OP:
03346 if (rv->v.s.len==0){
03347
03348
03349 rve_destroy(ct_rve);
03350
03351 rve->op=RVE_STREMPTY_OP;
03352 rve->left.rve=v_rve;
03353 rve->right.rve=0;
03354 ret=1;
03355 if (dbg)
03356 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03357 " op%d($v, \"\") -> strempty($v)\n",
03358 rve->fpos.s_line, rve->fpos.s_col,
03359 rve->fpos.e_line, rve->fpos.e_col,
03360 op);
03361 dbg=0;
03362 }
03363 break;
03364 default:
03365 break;
03366 }
03367
03368
03369
03370
03371
03372
03373 if (ret==1 && dbg){
03374 if (right){
03375 if (rve->op==RVE_RVAL_OP){
03376 if (rve->left.rval.type==RV_STR)
03377 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03378 " op%d($v, <string>) -> \"%s\"\n",
03379 rve->fpos.s_line, rve->fpos.s_col,
03380 rve->fpos.e_line, rve->fpos.e_col,
03381 op, rve->left.rval.v.s.s);
03382 else
03383 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03384 " op%d($v, <string>) -> $v (rval)\n",
03385 rve->fpos.s_line, rve->fpos.s_col,
03386 rve->fpos.e_line, rve->fpos.e_col, op);
03387 }else if (rve->op==RVE_STR_OP){
03388 if (rve->left.rve->op==RVE_RVAL_OP &&
03389 rve->left.rve->left.rval.type==RV_STR)
03390 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03391 " op%d($v, <string>) -> (str)\"%s\"\n",
03392 rve->fpos.s_line, rve->fpos.s_col,
03393 rve->fpos.e_line, rve->fpos.e_col,
03394 op, rve->left.rve->left.rval.v.s.s);
03395 else
03396 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03397 " op%d($v, <string>) -> (str)$v\n",
03398 rve->fpos.s_line, rve->fpos.s_col,
03399 rve->fpos.e_line, rve->fpos.e_col, op);
03400 }else{
03401 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03402 " op%d($v, <string>) -> $v\n",
03403 rve->fpos.s_line, rve->fpos.s_col,
03404 rve->fpos.e_line, rve->fpos.e_col, op);
03405 }
03406 }else{
03407 if (rve->op==RVE_RVAL_OP){
03408 if (rve->left.rval.type==RV_STR)
03409 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03410 " op%d(<string>, $v) -> \"%s\"\n",
03411 rve->fpos.s_line, rve->fpos.s_col,
03412 rve->fpos.e_line, rve->fpos.e_col,
03413 op, rve->left.rval.v.s.s);
03414 else
03415 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03416 " op%d(<string>, $v) -> $v (rval)\n",
03417 rve->fpos.s_line, rve->fpos.s_col,
03418 rve->fpos.e_line, rve->fpos.e_col, op);
03419 }else if (rve->op==RVE_STR_OP){
03420 if (rve->left.rve->op==RVE_RVAL_OP &&
03421 rve->left.rve->left.rval.type==RV_STR)
03422 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03423 " op%d(<string>, $v) -> (str)\"%s\"\n",
03424 rve->fpos.s_line, rve->fpos.s_col,
03425 rve->fpos.e_line, rve->fpos.e_col,
03426 op, rve->left.rve->left.rval.v.s.s);
03427 else
03428 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03429 " op%d(<string>, $v) -> (str)$v\n",
03430 rve->fpos.s_line, rve->fpos.s_col,
03431 rve->fpos.e_line, rve->fpos.e_col, op);
03432 }else{
03433 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
03434 " op%d(<string>, $v) -> $v\n",
03435 rve->fpos.s_line, rve->fpos.s_col,
03436 rve->fpos.e_line, rve->fpos.e_col, op);
03437 }
03438 }
03439 }
03440 }
03441 if (rv) rval_destroy(rv);
03442 return ret;
03443 error:
03444 if (rv) rval_destroy(rv);
03445 return -1;
03446 }
03447
03448
03449
03451 static int rve_optimize(struct rval_expr* rve)
03452 {
03453 int ret;
03454 struct rvalue* rv;
03455 struct rvalue* trv;
03456 enum rval_expr_op op;
03457 struct rval_expr tmp_rve;
03458 enum rval_type type, l_type;
03459 struct rval_expr* bad_rve;
03460 enum rval_type bad_type, exp_type;
03461
03462 ret=0;
03463 rv=0;
03464 if (scr_opt_lev<1)
03465 return 0;
03466 if (rve->op == RVE_RVAL_OP)
03467 return 0;
03468 if (rve_is_constant(rve)){
03469 if ((rv=rval_expr_eval_new(0, 0, rve))==0){
03470 ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
03471 rve->fpos.s_line, rve->fpos.s_col,
03472 rve->fpos.e_line, rve->fpos.e_col);
03473 goto error;
03474 }
03475 op=rve->op;
03476 if (rve_replace_with_ct_rv(rve, rv)<0)
03477 goto error;
03478 rval_destroy(rv);
03479 rv=0;
03480 trv=&rve->left.rval;
03481 if (trv->type==RV_INT)
03482 DBG("FIXUP RVE (%d,%d-%d,%d): optimized constant int rve "
03483 "(old op %d) to %d\n",
03484 rve->fpos.s_line, rve->fpos.s_col,
03485 rve->fpos.e_line, rve->fpos.e_col,
03486 op, (int)trv->v.l);
03487 else if (trv->type==RV_STR)
03488 DBG("FIXUP RVE (%d,%d-%d,%d): optimized constant str rve "
03489 "(old op %d) to \"%.*s\"\n",
03490 rve->fpos.s_line, rve->fpos.s_col,
03491 rve->fpos.e_line, rve->fpos.e_col,
03492 op, trv->v.s.len, trv->v.s.s);
03493 ret=1;
03494 }else{
03495
03496
03497 if (rve_op_unary(rve->op))
03498 return rve_optimize(rve->left.rve);
03499 rve_optimize(rve->left.rve);
03500 rve_optimize(rve->right.rve);
03501 if (!rve_check_type(&type, rve, &bad_rve, &bad_type, &exp_type)){
03502 ERR("optimization failure while optimizing %d,%d-%d,%d:"
03503 " type mismatch in expression (%d,%d-%d,%d), "
03504 "type %s, but expected %s\n",
03505 rve->fpos.s_line, rve->fpos.s_col,
03506 rve->fpos.e_line, rve->fpos.e_col,
03507 bad_rve->fpos.s_line, bad_rve->fpos.s_col,
03508 bad_rve->fpos.e_line, bad_rve->fpos.e_col,
03509 rval_type_name(bad_type), rval_type_name(exp_type));
03510 return 0;
03511 }
03512
03513 if ((rve->op==RVE_MINUS_OP) && (rve_is_constant(rve->right.rve))){
03514 if ((rv=rval_expr_eval_new(0, 0, rve->right.rve))==0){
03515 ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
03516 rve->right.rve->fpos.s_line,
03517 rve->right.rve->fpos.s_col,
03518 rve->right.rve->fpos.e_line,
03519 rve->right.rve->fpos.e_col);
03520 goto error;
03521 }
03522 if (rv->type==RV_INT){
03523 rv->v.l=-rv->v.l;
03524 if (rve_replace_with_ct_rv(rve->right.rve, rv)<0)
03525 goto error;
03526 rve->op=RVE_IPLUS_OP;
03527 DBG("FIXUP RVE (%d,%d-%d,%d): optimized $v - a into "
03528 "$v + (%d)\n",
03529 rve->fpos.s_line, rve->fpos.s_col,
03530 rve->fpos.e_line, rve->fpos.e_col,
03531 (int)rve->right.rve->left.rval.v.l);
03532 }
03533 rval_destroy(rv);
03534 rv=0;
03535 }
03536
03537
03538 if (rve->op==RVE_PLUS_OP){
03539 l_type=rve_guess_type(rve->left.rve);
03540 if (l_type==RV_INT){
03541 rve->op=RVE_IPLUS_OP;
03542 DBG("FIXUP RVE (%d,%d-%d,%d): changed + into integer plus\n",
03543 rve->fpos.s_line, rve->fpos.s_col,
03544 rve->fpos.e_line, rve->fpos.e_col);
03545 }else if (l_type==RV_STR){
03546 rve->op=RVE_CONCAT_OP;
03547 DBG("FIXUP RVE (%d,%d-%d,%d): changed + into string concat\n",
03548 rve->fpos.s_line, rve->fpos.s_col,
03549 rve->fpos.e_line, rve->fpos.e_col);
03550 }
03551 }
03552
03553
03554 if (rve->op==RVE_EQ_OP || rve->op==RVE_DIFF_OP){
03555 l_type=rve_guess_type(rve->left.rve);
03556 if (l_type==RV_INT){
03557 rve->op=(rve->op==RVE_EQ_OP)?RVE_IEQ_OP:RVE_IDIFF_OP;
03558 DBG("FIXUP RVE (%d,%d-%d,%d): changed ==/!= into integer"
03559 " ==/!=\n",
03560 rve->fpos.s_line, rve->fpos.s_col,
03561 rve->fpos.e_line, rve->fpos.e_col);
03562 }else if (l_type==RV_STR){
03563 rve->op=(rve->op==RVE_EQ_OP)?RVE_STREQ_OP:RVE_STRDIFF_OP;
03564 DBG("FIXUP RVE (%d,%d-%d,%d): changed ==/!= into string"
03565 " ==/!=\n",
03566 rve->fpos.s_line, rve->fpos.s_col,
03567 rve->fpos.e_line, rve->fpos.e_col);
03568 }
03569 }
03570
03571
03572 if (rve_opt_01(rve, type)==1){
03573
03574
03575
03576 ret=1;
03577 goto end;
03578 }
03579
03580
03581 if (rve_is_constant(rve->right.rve)){
03582
03583 if ((rve->op==rve->left.rve->op) && rve_op_is_assoc(rve->op)){
03584
03585 if (rve_is_constant(rve->left.rve->right.rve)){
03586
03587
03588 tmp_rve.op=rve->op;
03589 tmp_rve.left.rve=rve->left.rve->right.rve;
03590 tmp_rve.right.rve=rve->right.rve;
03591
03592
03593 if ((rve->op==RVE_PLUS_OP) &&
03594 (rve_guess_type(tmp_rve.left.rve)!=RV_STR)){
03595 DBG("RVE optimization failed (%d,%d-%d,%d): cannot "
03596 "optimize +(+($v, a), b) when typeof(a)==INT\n",
03597 rve->fpos.s_line, rve->fpos.s_col,
03598 rve->fpos.e_line, rve->fpos.e_col);
03599 return 0;
03600 }
03601 if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
03602 ERR("optimization failure, bad expression\n");
03603 goto error;
03604 }
03605
03606 if (rve_replace_with_ct_rv(rve->right.rve, rv)<0)
03607 goto error;
03608 rval_destroy(rv);
03609 rv=0;
03610 rve_destroy(tmp_rve.left.rve);
03611 rve->left.rve=rve->left.rve->left.rve;
03612 trv=&rve->right.rve->left.rval;
03613 if (trv->type==RV_INT)
03614 DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
03615 "op(op($v, a), b) with op($v, %d); op=%d\n",
03616 rve->fpos.s_line, rve->fpos.s_col,
03617 rve->fpos.e_line, rve->fpos.e_col,
03618 (int)trv->v.l, rve->op);
03619 else if (trv->type==RV_STR)
03620 DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
03621 "op(op($v, a), b) with op($v, \"%.*s\");"
03622 " op=%d\n",
03623 rve->fpos.s_line, rve->fpos.s_col,
03624 rve->fpos.e_line, rve->fpos.e_col,
03625 trv->v.s.len, trv->v.s.s, rve->op);
03626 ret=1;
03627 }else if (rve_is_constant(rve->left.rve->left.rve) &&
03628 rve_op_is_commutative(rve->op)){
03629
03630
03631 tmp_rve.op=rve->op;
03632 tmp_rve.left.rve=rve->left.rve->left.rve;
03633 tmp_rve.right.rve=rve->right.rve;
03634
03635
03636
03637
03638 if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
03639 ERR("optimization failure, bad expression\n");
03640 goto error;
03641 }
03642
03643 rve_destroy(rve->right.rve);
03644 rve->right.rve=rve->left.rve->right.rve;
03645 rve->left.rve->right.rve=0;
03646 if (rve_replace_with_ct_rv(rve->left.rve, rv)<0)
03647 goto error;
03648 rval_destroy(rv);
03649 rv=0;
03650 trv=&rve->left.rve->left.rval;
03651 if (trv->type==RV_INT)
03652 DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
03653 "op(op(a, $v), b) with op(%d, $v); op=%d\n",
03654 rve->fpos.s_line, rve->fpos.s_col,
03655 rve->fpos.e_line, rve->fpos.e_col,
03656 (int)trv->v.l, rve->op);
03657 else if (trv->type==RV_STR)
03658 DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
03659 "op(op(a, $v), b) with op(\"%.*s\", $v);"
03660 " op=%d\n",
03661 rve->fpos.s_line, rve->fpos.s_col,
03662 rve->fpos.e_line, rve->fpos.e_col,
03663 trv->v.s.len, trv->v.s.s, rve->op);
03664 ret=1;
03665 }
03666
03667 }
03668
03669
03670 }else if (rve_is_constant(rve->left.rve)){
03671
03672 if ((rve->op==rve->right.rve->op) && rve_op_is_assoc(rve->op)){
03673
03674 if (rve_is_constant(rve->right.rve->right.rve) &&
03675 rve_op_is_commutative(rve->op)){
03676
03677
03678 tmp_rve.op=rve->op;
03679 tmp_rve.left.rve=rve->left.rve;
03680 tmp_rve.right.rve=rve->right.rve->right.rve;
03681
03682
03683
03684
03685 if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
03686 ERR("optimization failure, bad expression\n");
03687 goto error;
03688 }
03689
03690 if (rve_replace_with_ct_rv(rve->left.rve, rv)<0)
03691 goto error;
03692 rval_destroy(rv);
03693 rv=0;
03694 rve_destroy(tmp_rve.right.rve);
03695 rve->right.rve=rve->right.rve->left.rve;
03696 trv=&rve->left.rve->left.rval;
03697 if (trv->type==RV_INT)
03698 DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
03699 "op(a, op($v, b)) with op(%d, $v); op=%d\n",
03700 rve->fpos.s_line, rve->fpos.s_col,
03701 rve->fpos.e_line, rve->fpos.e_col,
03702 (int)trv->v.l, rve->op);
03703 else if (trv->type==RV_STR)
03704 DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
03705 "op(a, op($v, b)) with op(\"%.*s\", $v);"
03706 " op=%d\n",
03707 rve->fpos.s_line, rve->fpos.s_col,
03708 rve->fpos.e_line, rve->fpos.e_col,
03709 trv->v.s.len, trv->v.s.s, rve->op);
03710 ret=1;
03711 }else if (rve_is_constant(rve->right.rve->left.rve)){
03712
03713
03714 tmp_rve.op=rve->op;
03715 tmp_rve.left.rve=rve->left.rve;
03716 tmp_rve.right.rve=rve->right.rve->left.rve;
03717
03718
03719 if ((rve->op==RVE_PLUS_OP) &&
03720 (rve_guess_type(tmp_rve.left.rve) !=
03721 rve_guess_type(tmp_rve.right.rve))){
03722 DBG("RVE optimization failed (%d,%d-%d,%d): cannot "
03723 "optimize +(a, +(b, $v)) when "
03724 "typeof(a)!=typeof(b)\n",
03725 rve->fpos.s_line, rve->fpos.s_col,
03726 rve->fpos.e_line, rve->fpos.e_col);
03727 return 0;
03728 }
03729 if ((rv=rval_expr_eval_new(0, 0, &tmp_rve))==0){
03730 ERR("optimization failure, bad expression\n");
03731 goto error;
03732 }
03733
03734 if (rve_replace_with_ct_rv(rve->left.rve, rv)<0)
03735 goto error;
03736 rval_destroy(rv);
03737 rv=0;
03738 rve_destroy(tmp_rve.right.rve);
03739 rve->right.rve=rve->right.rve->right.rve;
03740 trv=&rve->left.rve->left.rval;
03741 if (trv->type==RV_INT)
03742 DBG("FIXUP RVE (%d,%d-%d,%d): optimized int rve: "
03743 "op(a, op(b, $v)) with op(%d, $v); op=%d\n",
03744 rve->fpos.s_line, rve->fpos.s_col,
03745 rve->fpos.e_line, rve->fpos.e_col,
03746 (int)trv->v.l, rve->op);
03747 else if (trv->type==RV_STR)
03748 DBG("FIXUP RVE (%d,%d-%d,%d): optimized str rve "
03749 "op(a, op(b, $v)) with op(\"%.*s\", $v);"
03750 " op=%d\n",
03751 rve->fpos.s_line, rve->fpos.s_col,
03752 rve->fpos.e_line, rve->fpos.e_col,
03753 trv->v.s.len, trv->v.s.s, rve->op);
03754 ret=1;
03755 }
03756
03757 }
03758
03759
03760 }
03761
03762 }
03763 end:
03764 return ret;
03765 error:
03766 if (rv) rval_destroy(rv);
03767 return -1;
03768 }
03769
03770
03771
03779 int fix_rval_expr(void* p)
03780 {
03781 struct rval_expr* rve;
03782 int ret;
03783
03784 rve=(struct rval_expr*)p;
03785
03786 switch(rve->op){
03787 case RVE_NONE_OP:
03788 BUG("empty rval expr\n");
03789 break;
03790 case RVE_RVAL_OP:
03791 return fix_rval(&rve->left.rval);
03792 case RVE_UMINUS_OP:
03793 case RVE_BOOL_OP:
03794 case RVE_LNOT_OP:
03795 case RVE_BNOT_OP:
03796 case RVE_STRLEN_OP:
03797 case RVE_STREMPTY_OP:
03798 case RVE_DEFINED_OP:
03799 case RVE_INT_OP:
03800 case RVE_STR_OP:
03801 ret=fix_rval_expr((void*)rve->left.rve);
03802 if (ret<0) return ret;
03803 break;
03804 case RVE_MUL_OP:
03805 case RVE_DIV_OP:
03806 case RVE_MOD_OP:
03807 case RVE_MINUS_OP:
03808 case RVE_BOR_OP:
03809 case RVE_BAND_OP:
03810 case RVE_BXOR_OP:
03811 case RVE_BLSHIFT_OP:
03812 case RVE_BRSHIFT_OP:
03813 case RVE_LAND_OP:
03814 case RVE_LOR_OP:
03815 case RVE_GT_OP:
03816 case RVE_GTE_OP:
03817 case RVE_LT_OP:
03818 case RVE_LTE_OP:
03819 case RVE_PLUS_OP:
03820 case RVE_IPLUS_OP:
03821 case RVE_EQ_OP:
03822 case RVE_DIFF_OP:
03823 case RVE_IEQ_OP:
03824 case RVE_IDIFF_OP:
03825 case RVE_STREQ_OP:
03826 case RVE_STRDIFF_OP:
03827 case RVE_CONCAT_OP:
03828 ret=fix_rval_expr((void*)rve->left.rve);
03829 if (ret<0) return ret;
03830 ret=fix_rval_expr((void*)rve->right.rve);
03831 if (ret<0) return ret;
03832 break;
03833 case RVE_MATCH_OP:
03834 ret=fix_match_rve(rve);
03835 if (ret<0) return ret;
03836 break;
03837 default:
03838 BUG("unsupported op type %d\n", rve->op);
03839 }
03840
03841 rve_optimize(rve);
03842 return 0;
03843 }