pkg: fix wrong package name, closes FS#148, reported from Andrew Pogrebennyk
[sip-router] / rvalue.c
index d02b194..00dc19d 100644 (file)
--- a/rvalue.c
+++ b/rvalue.c
@@ -1,6 +1,4 @@
 /* 
- * $Id$
- * 
  * Copyright (C) 2008 iptelorg GmbH
  *
  * Permission to use, copy, modify, and distribute this software for any
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
 /**
  * @file 
- * @brief rvalue expressions
+ * @brief SIP-router core :: rvalue expressions
+ * @ingroup core
+ * Module: \ref core
  */
+
 /* 
  * History:
  * --------
  *                           Depends on RV_STR2INT_ERR.
  */
 
-/*!
- * \file
- * \brief SIP-router core :: 
- * \ingroup core
- * Module: \ref core
- */
 
 #include "rvalue.h"
 
@@ -344,14 +340,14 @@ char* rval_type_name(enum rval_type type)
 
 
 
-/** create a new pk_malloc'ed rvalue from a rval_val union.
-  *
-  * @param s - pointer to str, must be non-null
 * @param extra_size - extra space to allocate
 *                    (so that future string operation can reuse
 *                     the space)
 * @return new rv or 0 on error
 */
+/**
+ * @brief create a new pk_malloc'ed rvalue from a rval_val union
+ * @param t rvalue type
* @param v rvalue value
* @param extra_size extra space to allocate
* (so that future string operation can reuse the space)
+ * @return new rv or 0 on error
+ */
 struct rvalue* rval_new(enum rval_type t, union rval_val* v, int extra_size)
 {
        struct rvalue* rv;
@@ -375,18 +371,21 @@ struct rvalue* rval_new(enum rval_type t, union rval_val* v, int extra_size)
 
 
 
-/** get rvalue basic type (RV_INT or RV_STR).
-  *
-  * Given a rvalue it tries to determinte its basic type.
-  * Fills val_cache if non-null and empty (can be used in other rval*
-  * function calls, to avoid re-resolving avps or pvars). It must be
-  * rval_cache_clean()'en when no longer needed.
-  *
-  * @param rv - target rvalue
-  * @param val_cache - write-only: value cache, might be filled if non-null,
-  *                    it _must_ be rval_cache_clean()'en when done.
-  * @return - basic type or RV_NONE on error
-  */
+/**
+ * @brief get rvalue basic type (RV_INT or RV_STR)
+ *
+ * Given a rvalue it tries to determinte its basic type.
+ * Fills val_cache if non-null and empty (can be used in other rval*
+ * function calls, to avoid re-resolving avps or pvars). It must be
+ * rval_cache_clean()'en when no longer needed.
+ *
+ * @param h run action context
+ * @param msg SIP message
+ * @param rv target rvalue
+ * @param val_cache write-only value cache, might be filled if non-null,
+ * it _must_ be rval_cache_clean()'en when done.
+ * @return basic type or RV_NONE on error
+ */
 inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
                                                                                        struct sip_msg* msg,
                                                                                        struct rvalue* rv,
@@ -501,12 +500,16 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_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_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -565,6 +568,7 @@ int rve_is_constant(struct rval_expr* rve)
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                case RVE_STRLEN_OP:
                case RVE_STREMPTY_OP:
                case RVE_DEFINED_OP:
@@ -577,6 +581,9 @@ int rve_is_constant(struct rval_expr* rve)
                case RVE_MOD_OP:
                case RVE_BOR_OP:
                case RVE_BAND_OP:
+               case RVE_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -625,6 +632,7 @@ static int rve_op_unary(enum rval_expr_op op)
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                case RVE_STRLEN_OP:
                case RVE_STREMPTY_OP:
                case RVE_DEFINED_OP:
@@ -637,6 +645,9 @@ static int rve_op_unary(enum rval_expr_op op)
                case RVE_MOD_OP:
                case RVE_BOR_OP:
                case RVE_BAND_OP:
+               case RVE_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -663,18 +674,19 @@ static int rve_op_unary(enum rval_expr_op op)
 
 
 
-/** returns 1 if expression is valid (type-wise).
-  * @param type - filled with the type of the expression (RV_INT, RV_STR or
-  *                RV_NONE if it's dynamic)
-  * @param rve  - checked expression
-  * @param bad_rve - set on failure to the subexpression for which the 
-  *                    type check failed
-  * @param bad_type - set on failure to the type of the bad subexpression
-  * @param exp_type - set on failure to the expected type for the bad
-  *                   subexpression
-  * @return 0 or 1  and sets *type to the resulting type
-  * (RV_INT, RV_STR or RV_NONE if it can be found only at runtime)
-  */
+/**
+ * @brief Returns 1 if expression is valid (type-wise)
+ * @param type filled with the type of the expression (RV_INT, RV_STR or
+ *                RV_NONE if it's dynamic)
+ * @param rve  checked expression
+ * @param bad_rve set on failure to the subexpression for which the 
+ * type check failed
+ * @param bad_t set on failure to the type of the bad subexpression
+ * @param exp_t set on failure to the expected type for the bad
+ * subexpression
+ * @return 0 or 1 and sets *type to the resulting type
+ * (RV_INT, RV_STR or RV_NONE if it can be found only at runtime)
+ */
 int rve_check_type(enum rval_type* type, struct rval_expr* rve,
                                        struct rval_expr** bad_rve, 
                                        enum rval_type* bad_t,
@@ -689,6 +701,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                        *type=RV_INT;
                        if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
                                if (type1==RV_STR){
@@ -707,6 +720,9 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
                case RVE_MOD_OP:
                case RVE_BOR_OP:
                case RVE_BAND_OP:
+               case RVE_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -900,9 +916,11 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
                        }
                        break;
                case RV_ACTION_ST:
-                       if (rv->v.action)
-                               *i=(run_actions(h, rv->v.action, msg)>0);
-                       else
+                       if (rv->v.action) {
+                               *i=(run_actions_safe(h, rv->v.action, msg)>0);
+                               h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
+                                                                                                                   break in expr*/
+                       } else
                                *i=0;
                        break;
                case RV_SEL:
@@ -1062,12 +1080,14 @@ error:
   * if rv == undefined select, avp or pvar, return "".
   * if an error occurs while evaluating a select, avp or pvar, behave as
   * for the undefined case (and return success).
-  * The result points either to a temporary string or inside
-  * new_cache. new_cache must be non zero, initialized previously,
-  * and it _must_ be rval_cache_clean(...)'ed when done.
-  * WARNING: it's not intended for general use, it might return a pointer
-  * to a static buffer (int2str) so use the result a.s.a.p, make a copy.
-  * or use rval_get_str() instead.
+  * The result points either inside the passed rv, inside
+  * new_cache or inside an avp. new_cache must be non zero,
+  * initialized previously and it _must_ be rval_cache_clean(...)'ed when
+  * done.
+  * WARNING: it's not intended for general use. It might return a pointer
+  * inside rv so the result _must_ be treated as read-only. rv and new_cache
+  * must not be released/freed until the result is no longer needed.
+  * For general use see  rval_get_str().
   * @param h - script context handle
   * @param msg - sip msg
   * @param tmpv - str return value (pointer to a str struct that will be
@@ -1089,26 +1109,36 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
        
        switch(rv->type){
                case RV_INT:
-                       tmpv->s=int2str(rv->v.l, &tmpv->len);
+                       tmpv->s=sint2strbuf(rv->v.l, tmp_cache->i2s,
+                                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                       tmp_cache->cache_type = RV_CACHE_INT2STR;
                        break;
                case RV_STR:
                        *tmpv=rv->v.s;
                        break;
                case RV_ACTION_ST:
-                       if (rv->v.action)
-                               i=(run_actions(h, rv->v.action, msg)>0);
-                       else
+                       if (rv->v.action) {
+                               i=(run_actions_safe(h, rv->v.action, msg)>0);
+                               h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
+                                                                                                                   break in expr*/
+                       } else
                                i=0;
-                       tmpv->s=int2str(i, &tmpv->len);
+                       tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+                                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                       tmp_cache->cache_type = RV_CACHE_INT2STR;
                        break;
                case RV_BEXPR:
                        i=eval_expr(h, rv->v.bexpr, msg);
                        if (i==EXPR_DROP){
                                i=0; /* false */
-                               tmpv->s=int2str(i, &tmpv->len);
+                               tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                               tmp_cache->cache_type = RV_CACHE_INT2STR;
                                return EXPR_DROP;
                        }
-                       tmpv->s=int2str(i, &tmpv->len);
+                       tmpv->s=sint2strbuf(i, tmp_cache->i2s, sizeof(tmp_cache->i2s),
+                                                               &tmpv->len);
+                       tmp_cache->cache_type = RV_CACHE_INT2STR;
                        break;
                case RV_SEL:
                        i=run_select(tmpv, &rv->v.sel, msg);
@@ -1126,7 +1156,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
                                        *tmpv=cache->c.avp_val.s;
                                }else if (cache->val_type==RV_INT){
                                        i=cache->c.avp_val.n;
-                                       tmpv->s=int2str(i, &tmpv->len);
+                                       tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+                                                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                                       tmp_cache->cache_type = RV_CACHE_INT2STR;
                                }else if (cache->val_type==RV_NONE){
                                        goto undef;
                                }else goto error_cache;
@@ -1141,7 +1173,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
                                                *tmpv=tmp_cache->c.avp_val.s;
                                        }else{
                                                i=tmp_cache->c.avp_val.n;
-                                               tmpv->s=int2str(i, &tmpv->len);
+                                               tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+                                                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                                               tmp_cache->cache_type = RV_CACHE_INT2STR;
                                        }
                                }else goto undef;
                        }
@@ -1152,7 +1186,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
                                        *tmpv=cache->c.pval.rs;
                                }else if (cache->val_type==RV_INT){
                                        i=cache->c.pval.ri;
-                                       tmpv->s=int2str(i, &tmpv->len);
+                                       tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+                                                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                                       tmp_cache->cache_type = RV_CACHE_INT2STR;
                                }else if (cache->val_type==RV_NONE){
                                        goto undef;
                                }else goto error_cache;
@@ -1170,7 +1206,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
                                        }else if (likely(tmp_cache->c.pval.flags & PV_VAL_INT)){
                                                i=tmp_cache->c.pval.ri;
                                                pv_value_destroy(&tmp_cache->c.pval);
-                                               tmpv->s=int2str(i, &tmpv->len);
+                                               tmpv->s=sint2strbuf(i, tmp_cache->i2s,
+                                                                               sizeof(tmp_cache->i2s), &tmpv->len);
+                                               tmp_cache->cache_type = RV_CACHE_INT2STR;
                                        }else{
                                                /* no PV_VAL_STR and no PV_VAL_INT => undef
                                                   (PV_VAL_NULL) */
@@ -1236,18 +1274,22 @@ error:
 
 
 
-/** convert a rvalue to another rvalue, of a specific type.
+/**
+ * @brief Convert a rvalue to another rvalue, of a specific type
  *
+ * Convert a rvalue to another rvalue, of a specific type.
  * The result is read-only in most cases (can be a reference
  * to another rvalue, can be checked by using rv_chg_in_place()) and
  * _must_ be rval_destroy()'ed.
  *
+ * @param h run action context
+ * @param msg SIP mesasge
  * @param type - type to convert to
  * @param v - rvalue to convert
  * @param c - rval_cache (cached v value if known/filled by another
  *            function), can be 0 (unknown/not needed)
  * @return pointer to a rvalue (reference to an existing one or a new
- *   one, @see rv_chg_in_place() and the above comment) or 0 on error.
+ * one, @see rv_chg_in_place() and the above comment), or 0 on error.
  */
 struct rvalue* rval_convert(struct run_act_ctx* h, struct sip_msg* msg,
                                                        enum rval_type type, struct rvalue* v,
@@ -1304,6 +1346,9 @@ inline static int int_intop1(int* res, enum rval_expr_op op, int v)
                case RVE_LNOT_OP:
                        *res=!v;
                        break;
+               case RVE_BNOT_OP:
+                       *res=~v;
+                       break;
                default:
                        BUG("rv unsupported intop1 %d\n", op);
                        return -1;
@@ -1349,6 +1394,15 @@ inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
                case RVE_BAND_OP:
                        *res=v1&v2;
                        break;
+               case RVE_BXOR_OP:
+                       *res=v1^v2;
+                       break;
+               case RVE_BLSHIFT_OP:
+                       *res=v1<<v2;
+                       break;
+               case RVE_BRSHIFT_OP:
+                       *res=v1>>v2;
+                       break;
                case RVE_LAND_OP:
                        *res=v1 && v2;
                        break;
@@ -1711,9 +1765,17 @@ error:
 
 
 
-/** integer operation on rval evaluated as string.
- * Can use cached rvalues (c1 & c2).
- * @param res - will be set to the result
+/**
+ * @brief Integer operation on rval evaluated as string
+ * 
+ * Integer operation on rval evaluated as string, can use cached
+ * rvalues (c1 & c2).
+ * @param h run action context
+ * @param msg SIP message
+ * @param res will be set to the result
+ * @param op rvalue expression operation
+ * @param l rvalue
+ * @param c1 rvalue cache
  * @return 0 success, -1 on error
  */
 inline static int rval_int_strop1(struct run_act_ctx* h,
@@ -1741,14 +1803,18 @@ error:
 
 
 
-/** checks if rv is defined.
- * @param res - set to the result 1 - defined, 0 not defined
+/**
+ * @brief Checks if rv is defined
+ * @param h run action context
+ * @param msg SIP message
+ * @param res set to the result 1 is defined, 0 not defined
+ * @param rv rvalue
+ * @param cache rvalue cache
  * @return 0 on success, -1 on error
- * Can use cached rvalues (cache).
- * Note: a rv can be undefined if it's an undefined avp or pvar or select or
- * if it's NONE
- * Note2: an error in the avp, pvar or select search is equivalent to 
- *  undefined (and it's not reported)
+ * @note Can use cached rvalues (cache). A rv can be undefined if it's
+ * an undefined avp or pvar or select or if it's NONE
+ * @note An error in the avp, pvar or select search is equivalent to
+ * undefined (and it's not reported)
  */
 inline static int rv_defined(struct run_act_ctx* h,
                                                 struct sip_msg* msg, int* res,
@@ -1807,9 +1873,13 @@ inline static int rv_defined(struct run_act_ctx* h,
 }
 
 
-/** defined (integer) operation on rve.
+/**
+ * @brief Defined (integer) operation on rve
+ * @param h run action context
+ * @param msg SIP message
  * @param res - set to  1 defined, 0 not defined
- * @return - 0 on success, -1 on error
+ * @param rve rvalue expression
+ * @return 0 on success, -1 on error
  */
 inline static int int_rve_defined(struct run_act_ctx* h,
                                                 struct sip_msg* msg, int* res,
@@ -1848,6 +1918,7 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                        if (unlikely(
                                        (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
                                break;
@@ -1864,6 +1935,9 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
                case RVE_IPLUS_OP:
                case RVE_BOR_OP:
                case RVE_BAND_OP:
+               case RVE_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_GT_OP:
                case RVE_GTE_OP:
                case RVE_LT_OP:
@@ -2075,22 +2149,22 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
 
 
 
-/** evals a rval expr. into an int or another rv(str).
- * WARNING: rv result (rv_res) must be rval_destroy()'ed if non-null
+/**
+ * @brief Evals a rval expression into an int or another rv(str)
+ * @warning rv result (rv_res) must be rval_destroy()'ed if non-null
  * (it might be a reference to another rval). The result can be
  * modified only if rv_chg_in_place() returns true.
- * @param res_rv - pointer to rvalue result, if non-null it means the 
- *                 expression evaluated to a non-int (str), which will be
- *                 stored here.
- * @param res_i  - pointer to int result, if res_rv==0 and the function
- *                 returns success => the result is an int which will be 
- *                 stored here.
- * @param rve    - expression that will be evaluated.
- * @param cache  - write-only value cache, it might be filled if non-null and
- *                 empty (rval_cache_init()). If non-null, it _must_ be 
- *                 rval_cache_clean()'ed when done. 
- *
- * @result  0 on success, -1 on error,  sets *res_rv or *res_i.
+ * @param h run action context
+ * @param msg SIP message
+ * @param res_rv pointer to rvalue result, if non-null it means the 
+ * expression evaluated to a non-int (str), which will be stored here.
+ * @param res_i pointer to int result, if res_rv==0 and the function
+ * returns success => the result is an int which will be stored here.
+ * @param rve expression that will be evaluated.
+ * @param cache write-only value cache, it might be filled if non-null and
+ * empty (rval_cache_init()). If non-null, it _must_ be rval_cache_clean()'ed
+ * when done. 
+ * @return 0 on success, -1 on error, sets *res_rv or *res_i.
  */
 int rval_expr_eval_rvint(                         struct run_act_ctx* h,
                                                                           struct sip_msg* msg,
@@ -2132,12 +2206,16 @@ int rval_expr_eval_rvint(                          struct run_act_ctx* h,
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_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_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -2223,10 +2301,14 @@ error:
 
 
 
-/** evals a rval expr..
- * WARNING: result must be rval_destroy()'ed if non-null (it might be
+/**
+ * @brief Evals a rval expression
+ * @warning result must be rval_destroy()'ed if non-null (it might be
  * a reference to another rval). The result can be modified only
  * if rv_chg_in_place() returns true.
+ * @param h run action context
+ * @param msg SIP message
+ * @param rve rvalue expression
  * @return rvalue on success, 0 on error
  */
 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
@@ -2251,12 +2333,16 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_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_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -2448,7 +2534,7 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
        rve=pkg_malloc(sizeof(*rve));
        if (rve==0) 
                return 0;
-       memset(rve, sizeof(*rve), 0);
+       memset(rve, 0, sizeof(*rve));
        flags=0;
        switch(rv_type){
                case RV_INT:
@@ -2494,10 +2580,12 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
 
 
 
-/** create a unary op. rval_expr..
+/**
+ * @brief Create a unary op. rval_expr
  * ret= op rve1
  * @param op   - rval expr. unary operator
  * @param rve1 - rval expr. on which the operator will act.
+ * @param pos configuration position
  * @return new pkg_malloc'ed rval_expr or 0 on error.
  */
 struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
@@ -2509,6 +2597,7 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                case RVE_STRLEN_OP:
                case RVE_STREMPTY_OP:
                case RVE_DEFINED_OP:
@@ -2522,7 +2611,7 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
        ret=pkg_malloc(sizeof(*ret));
        if (ret==0) 
                return 0;
-       memset(ret, sizeof(*ret), 0);
+       memset(ret, 0, sizeof(*ret));
        ret->op=op;
        ret->left.rve=rve1;
        if (pos) ret->fpos=*pos;
@@ -2531,11 +2620,13 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
 
 
 
-/** create a rval_expr. from 2 other rval exprs, using op.
+/**
+ * @brief Create a rval_expr. from 2 other rval exprs, using op
  * ret = rve1 op rve2
  * @param op   - rval expr. operator
  * @param rve1 - rval expr. on which the operator will act.
  * @param rve2 - rval expr. on which the operator will act.
+ * @param pos configuration position
  * @return new pkg_malloc'ed rval_expr or 0 on error.
  */
 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
@@ -2551,6 +2642,9 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
                case RVE_MINUS_OP:
                case RVE_BOR_OP:
                case RVE_BAND_OP:
+               case RVE_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -2575,7 +2669,7 @@ struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
        ret=pkg_malloc(sizeof(*ret));
        if (ret==0) 
                return 0;
-       memset(ret, sizeof(*ret), 0);
+       memset(ret, 0, sizeof(*ret));
        ret->op=op;
        ret->left.rve=rve1;
        ret->right.rve=rve2;
@@ -2594,6 +2688,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                case RVE_STRLEN_OP:
                case RVE_STREMPTY_OP:
                case RVE_DEFINED_OP:
@@ -2604,6 +2699,8 @@ static int rve_op_is_assoc(enum rval_expr_op op)
                case RVE_DIV_OP:
                case RVE_MOD_OP:
                case RVE_MINUS_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                        return 0;
                case RVE_PLUS_OP:
                        /* the generic plus is not assoc, e.g.
@@ -2614,6 +2711,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
                case RVE_MUL_OP:
                case RVE_BAND_OP:
                case RVE_BOR_OP:
+               case RVE_BXOR_OP:
                        return 1;
                case RVE_LAND_OP:
                case RVE_LOR_OP:
@@ -2645,6 +2743,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
                case RVE_UMINUS_OP:
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                case RVE_STRLEN_OP:
                case RVE_STREMPTY_OP:
                case RVE_DEFINED_OP:
@@ -2655,6 +2754,8 @@ static int rve_op_is_commutative(enum rval_expr_op op)
                case RVE_DIV_OP:
                case RVE_MOD_OP:
                case RVE_MINUS_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                        return 0;
                case RVE_PLUS_OP:
                        /* non commut. when diff. type 
@@ -2665,6 +2766,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
                case RVE_MUL_OP:
                case RVE_BAND_OP:
                case RVE_BOR_OP:
+               case RVE_BXOR_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_IEQ_OP:
@@ -2768,7 +2870,7 @@ static int fix_rval(struct rvalue* rv)
                        return fix_actions(rv->v.action);
                case RV_SEL:
                        if (resolve_select(&rv->v.sel)<0){
-                               BUG("Unable to resolve select\n");
+                               ERR("Unable to resolve select\n");
                                print_select(&rv->v.sel);
                        }
                        return 0;
@@ -2788,15 +2890,17 @@ static int fix_rval(struct rvalue* rv)
 
 
 
-/** helper function: replace a rve (in-place) with a constant rval_val.
- * WARNING: since it replaces in-place, one should make sure that if
+/**
+ * @brief Helper function: replace a rve (in-place) with a constant rval_val
+ * @warning since it replaces in-place, one should make sure that if
  * rve is in fact a rval (rve->op==RVE_RVAL_OP), no reference is kept
  * to the rval!
- * @param rve - expression to be replaced (in-place)
- * @param v   - pointer to a rval_val union containing the replacement
- *              value.
- * @param flags - value flags (how it was alloc'ed, e.g.: RV_CNT_ALLOCED_F)
- * @return 0 on success, -1 on error */
+ * @param rve expression to be replaced (in-place)
+ * @param type rvalue type
+ * @param v pointer to a rval_val union containing the replacement value.
+ * @param flags value flags (how it was alloc'ed, e.g.: RV_CNT_ALLOCED_F)
+ * @return 0 on success, -1 on error
+ */
 static int rve_replace_with_val(struct rval_expr* rve, enum rval_type type,
                                                                union rval_val* v, int flags)
 {
@@ -2881,7 +2985,7 @@ static int fix_match_rve(struct rval_expr* rve)
        v.s.s=0;
        v.re.regex=0;
        /* normal fix-up for the  left side */
-       ret=fix_rval_expr((void**)&rve->left.rve);
+       ret=fix_rval_expr((void*)rve->left.rve);
        if (ret<0) return ret;
        
        /* fixup the right side (RE) */
@@ -2928,7 +3032,7 @@ static int fix_match_rve(struct rval_expr* rve)
                        goto error;
        }else{
                /* right side is not constant => normal fixup */
-               return fix_rval_expr((void**)&rve->right.rve);
+               return fix_rval_expr((void*)rve->right.rve);
        }
        return 0;
 error:
@@ -3350,14 +3454,12 @@ static int rve_optimize(struct rval_expr* rve)
        struct rvalue* rv;
        struct rvalue* trv; /* used only for DBG() */
        enum rval_expr_op op;
-       int flags;
        struct rval_expr tmp_rve;
        enum rval_type type, l_type;
        struct rval_expr* bad_rve;
        enum rval_type bad_type, exp_type;
        
        ret=0;
-       flags=0;
        rv=0;
        if (scr_opt_lev<1)
                return 0;
@@ -3670,19 +3772,16 @@ error:
 /** fix a rval_expr.
  * fixes action, bexprs, resolves selects, pvars and
  * optimizes simple sub expressions (e.g. 1+2).
- * It might modify *p.
  *
- * @param p - double pointer to a rval_expr (might be changed to a new one)
- * @return 0 on success, <0 on error (modifies also *p)
+ * @param p - pointer to a rval_expr
+ * @return 0 on success, <0 on error (modifies also *(struct rval_expr*)p)
  */
-int fix_rval_expr(void** p)
+int fix_rval_expr(void* p)
 {
-       struct rval_expr** prve;
        struct rval_expr* rve;
        int ret;
        
-       prve=(struct rval_expr**)p;
-       rve=*prve;
+       rve=(struct rval_expr*)p;
        
        switch(rve->op){
                case RVE_NONE_OP:
@@ -3693,12 +3792,13 @@ int fix_rval_expr(void** p)
                case RVE_UMINUS_OP: /* unary operators */
                case RVE_BOOL_OP:
                case RVE_LNOT_OP:
+               case RVE_BNOT_OP:
                case RVE_STRLEN_OP:
                case RVE_STREMPTY_OP:
                case RVE_DEFINED_OP:
                case RVE_INT_OP:
                case RVE_STR_OP:
-                       ret=fix_rval_expr((void**)&rve->left.rve);
+                       ret=fix_rval_expr((void*)rve->left.rve);
                        if (ret<0) return ret;
                        break;
                case RVE_MUL_OP:
@@ -3707,6 +3807,9 @@ int fix_rval_expr(void** p)
                case RVE_MINUS_OP:
                case RVE_BOR_OP:
                case RVE_BAND_OP:
+               case RVE_BXOR_OP:
+               case RVE_BLSHIFT_OP:
+               case RVE_BRSHIFT_OP:
                case RVE_LAND_OP:
                case RVE_LOR_OP:
                case RVE_GT_OP:
@@ -3722,9 +3825,9 @@ int fix_rval_expr(void** p)
                case RVE_STREQ_OP:
                case RVE_STRDIFF_OP:
                case RVE_CONCAT_OP:
-                       ret=fix_rval_expr((void**)&rve->left.rve);
+                       ret=fix_rval_expr((void*)rve->left.rve);
                        if (ret<0) return ret;
-                       ret=fix_rval_expr((void**)&rve->right.rve);
+                       ret=fix_rval_expr((void*)rve->right.rve);
                        if (ret<0) return ret;
                        break;
                case RVE_MATCH_OP: