core expr eval: defined @select
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 28 Apr 2009 07:50:07 +0000 (09:50 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 28 Apr 2009 10:44:38 +0000 (12:44 +0200)
- a select can now be undefined (defined @select when run_select
 returns >0 or error => true)
- RV_CACHE_SELECT introduced

rvalue.c
rvalue.h

index 897fb4d..aa99131 100644 (file)
--- a/rvalue.c
+++ b/rvalue.c
@@ -1386,9 +1386,11 @@ error:
 /** checks if rv is defined.
  * @param res - set to the result 1 - defined, 0 not defined
  * @return 0 on success, -1 on error
- * Can use cached rvalues (c1).
- * Note: a rv can be undefined if it's an undefined avp or pvar or
+ * 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)
  */
 inline static int rv_defined(struct run_act_ctx* h,
                                                 struct sip_msg* msg, int* res,
@@ -1397,13 +1399,21 @@ inline static int rv_defined(struct run_act_ctx* h,
        avp_t* r_avp;
        int_str avp_val;
        pv_value_t pval;
+       str tmp;
        
        *res=1;
        switch(rv->type){
+               case RV_SEL:
+                       if (unlikely(cache && cache->cache_type==RV_CACHE_SELECT)){
+                               *res=(cache->val_type!=RV_NONE);
+                       }else
+                               /* run select returns 0 on success, -1 on error and >0 on 
+                                  undefined. error is considered undefined */
+                               *res=(run_select(&tmp, &rv->v.sel, msg)==0);
+                       break;
                case RV_AVP:
                        if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
-                               if (cache->val_type==RV_NONE)
-                                       *res=0;
+                               *res=(cache->val_type!=RV_NONE);
                        }else{
                                r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
                                                                                        &avp_val, rv->v.avps.index);
@@ -1415,8 +1425,7 @@ inline static int rv_defined(struct run_act_ctx* h,
                case RV_PVAR:
                        /* PV_VAL_NULL or pv_get_spec_value error => undef */
                        if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
-                               if (cache->val_type==RV_NONE)
-                                       *res=0;
+                               *res=(cache->val_type==RV_NONE);
                        }else{
                                memset(&pval, 0, sizeof(pval));
                                if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
index a9dbe0d..e99d1f8 100644 (file)
--- a/rvalue.h
+++ b/rvalue.h
@@ -118,7 +118,8 @@ struct rval_expr{
 enum rval_cache_type{
        RV_CACHE_EMPTY,
        RV_CACHE_PVAR,
-       RV_CACHE_AVP
+       RV_CACHE_AVP,
+       RV_CACHE_SELECT
 };
 
 /** value cache for a rvalue struct.