0971dc4755cf5698553b40e269830913cbddd33d
[sip-router] / rvalue.c
1 /* 
2  * Copyright (C) 2008 iptelorg GmbH
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /**
18  * @file 
19  * @brief Kamailio core :: rvalue expressions
20  * @ingroup core
21  * Module: \ref core
22  */
23
24 /** special defines:
25  *
26  *  UNDEF_EQ_* - how to behave when undef is on the right side of a generic
27  *               compare operator
28  *  UNDEF_EQ_ALWAYS_FALSE:  undef  == something  is always false
29  *  UNDEF_EQ_UNDEF_TRUE  :  undef == something false except for undef==undef
30  *                          which is true
31  *  no UNDEF_EQ* define  :  undef == expr => convert undef to typeof(expr)
32  *                          and perform normal ==. undef == undef will be
33  *                          converted to string and it will be true
34  *                          ("" == "")
35  * NOTE: expr == undef, with defined(expr) is always evaluated this way:
36          expr == (type_of(expr))undef
37  *  RV_STR2INT_VERBOSE_ERR - if a string conversion to int fails, log (L_WARN)
38  *                           the string that caused it (only the string, not
39  *                           the expression position).
40  *  RV_STR2INT_ERR         - if a string conversion to int fails, don't ignore
41  *                           the error (return error).
42  *  RVAL_GET_INT_ERR_WARN  - if a conversion to int fails, log a warning with
43  *                           the expression position.
44  *                           Depends on RV_STR2INT_ERR.
45  *  RVAL_GET_INT_ERR_IGN   - if a conversion to int fails, ignore the error
46  *                           (the result will be 0). Can be combined with
47  *                           RVAL_GET_INT_ERR_WARN.
48  *                           Depends on RV_STR2INT_ERR.
49  */
50
51
52 #include "rvalue.h"
53
54 #include <stdlib.h> /* abort() */
55
56 /* if defined warn when str2int conversions fail */
57 #define RV_STR2INT_VERBOSE_ERR
58
59 /* if defined rval_get_int will fail if str2int conversion fail
60    (else convert to 0) */
61 #define RV_STR2INT_ERR
62
63 /* if a rval_get_int fails (conversion to int), warn
64    Depends on RV_STR2INT_ERR.
65  */
66 #define RVAL_GET_INT_ERR_WARN
67
68 /* if a rval_get_int fails, ignore it (expression evaluation will not fail,
69    the int conversion will result in 0).
70    Can be combined with RVAL_GET_INT_ERR_WARN.
71    Depends on RV_STR2INT_ERR.
72  */
73 #define RVAL_GET_INT_ERR_IGN
74
75 /* minimum size alloc'ed for STR RVs (to accomodate
76  * strops without reallocs) */
77 #define RV_STR_EXTRA 80
78
79 #define rv_ref(rv) ((rv)->refcnt++)
80
81 /** unref rv and returns true if 0 */
82 #define rv_unref(rv) ((--(rv)->refcnt)==0)
83
84
85 inline static void rval_force_clean(struct rvalue* rv)
86 {
87         if (rv->flags & RV_CNT_ALLOCED_F){
88                 switch(rv->type){
89                         case RV_STR:
90                                 pkg_free(rv->v.s.s);
91                                 rv->v.s.s=0;
92                                 rv->v.s.len=0;
93                                 break;
94                         default:
95                                 BUG("RV_CNT_ALLOCED_F not supported for type %d\n", rv->type);
96                 }
97                 rv->flags&=~RV_CNT_ALLOCED_F;
98         }
99         if (rv->flags & RV_RE_ALLOCED_F){
100                 if (rv->v.re.regex){
101                         if (unlikely(rv->type!=RV_STR || !(rv->flags & RV_RE_F))){
102                                 BUG("RV_RE_ALLOCED_F not supported for type %d or "
103                                                 "bad flags %x\n", rv->type, rv->flags);
104                         }
105                         regfree(rv->v.re.regex);
106                         pkg_free(rv->v.re.regex);
107                         rv->v.re.regex=0;
108                 }
109                 rv->flags&=~(RV_RE_ALLOCED_F|RV_RE_F);
110         }
111 }
112
113
114
115 /** frees a rval returned by rval_new(), rval_convert() or rval_expr_eval().
116  *   Note: it will be freed only when refcnt reaches 0
117  */
118 void rval_destroy(struct rvalue* rv)
119 {
120         if (rv && rv_unref(rv)){
121                 rval_force_clean(rv);
122                 /* still an un-regfreed RE ? */
123                 if ((rv->flags & RV_RE_F) && rv->v.re.regex){
124                         if (unlikely(rv->type!=RV_STR))
125                                 BUG("RV_RE_F not supported for type %d\n", rv->type);
126                         regfree(rv->v.re.regex);
127                 }
128                 if (rv->flags & RV_RV_ALLOCED_F){
129                         pkg_free(rv);
130                 }
131         }
132 }
133
134
135
136 void rval_clean(struct rvalue* rv)
137 {
138         if (rv_unref(rv))
139                 rval_force_clean(rv);
140 }
141
142
143
144 void rve_destroy(struct rval_expr* rve)
145 {
146         if (rve){
147                 if (rve->op==RVE_RVAL_OP){
148                         if (rve->left.rval.refcnt){
149                                 if (rve->left.rval.refcnt==1)
150                                         rval_destroy(&rve->left.rval);
151                                 else
152                                         BUG("rval expr rval with invalid refcnt: %d (%d,%d-%d,%d)"
153                                                         "\n", rve->left.rval.refcnt,
154                                                         rve->fpos.s_line, rve->fpos.s_col,
155                                                         rve->fpos.e_line, rve->fpos.e_col);
156                         }
157                         if (rve->right.rval.refcnt){
158                                 if (rve->right.rval.refcnt==1)
159                                         rval_destroy(&rve->right.rval);
160                                 else
161                                         BUG("rval expr rval with invalid refcnt: %d (%d,%d-%d,%d)"
162                                                         "\n", rve->right.rval.refcnt,
163                                                         rve->fpos.s_line, rve->fpos.s_col,
164                                                         rve->fpos.e_line, rve->fpos.e_col);
165                         }
166                 }else{
167                         if (rve->left.rve)
168                                 rve_destroy(rve->left.rve);
169                         if (rve->right.rve)
170                                 rve_destroy(rve->right.rve);
171                 }
172                 pkg_free(rve);
173         }
174 }
175
176
177
178 void rval_cache_clean(struct rval_cache* rvc)
179 {
180         if ((rvc->cache_type==RV_CACHE_PVAR) && (rvc->val_type!=RV_NONE)){
181                 pv_value_destroy(&rvc->c.pval);
182         }
183         rvc->cache_type=RV_CACHE_EMPTY;
184         rvc->val_type=RV_NONE;
185 }
186
187
188 #define rv_chg_in_place(rv)  ((rv)->refcnt==1)
189
190
191
192 /** init a rvalue structure.
193  * Note: not needed if the structure is allocate with one of the 
194  * rval_new* functions
195  */
196 void rval_init(struct rvalue* rv, enum rval_type t, union rval_val* v, 
197                                 int flags)
198 {
199         rv->flags=flags;
200         rv->refcnt=1;
201         rv->type=t;
202         if (v){
203                 rv->v=*v;
204         }else{
205                 memset (&rv->v, 0, sizeof(rv->v));
206         }
207 }
208
209
210
211 /** create a new pk_malloc'ed empty rvalue.
212   *
213   * @param extra_size - extra space to allocate
214   *                    (e.g.: so that future string operation can reuse
215   *                     the space)
216   * @return new rv or 0 on error
217   */
218 struct rvalue* rval_new_empty(int extra_size)
219 {
220         struct rvalue* rv;
221         int size; /* extra size at the end */
222         
223         size=ROUND_LONG(sizeof(*rv)-sizeof(rv->buf)+extra_size); /* round up */
224         rv=pkg_malloc(size);
225         if (likely(rv)){
226                 rv->bsize=size-sizeof(*rv)-sizeof(rv->buf); /* remaining size->buffer*/
227                 rv->flags=RV_RV_ALLOCED_F;
228                 rv->refcnt=1;
229                 rv->type=RV_NONE;
230         }
231         return rv;
232 }
233
234
235
236 /** create a new pk_malloc'ed rv from a str.
237   *
238   * @param s - pointer to str, must be non-null
239   * @param extra_size - extra space to allocate
240   *                    (so that future string operation can reuse
241   *                     the space)
242   * @return new rv or 0 on error
243   */
244 struct rvalue* rval_new_str(str* s, int extra_size)
245 {
246         struct rvalue* rv;
247         
248         rv=rval_new_empty(extra_size+s->len+1/* 0 term */);
249         if (likely(rv)){
250                 rv->type=RV_STR;
251                 rv->v.s.s=&rv->buf[0];
252                 rv->v.s.len=s->len;
253                 memcpy(rv->v.s.s, s->s, s->len);
254                 rv->v.s.s[s->len]=0;
255         }
256         return rv;
257 }
258
259
260
261 /** create a new pk_malloc'ed RE rv from a str re.
262   * It acts as rval_new_str, but also compiles a RE from the str
263   * and sets v->re.regex.
264   * @param s - pointer to str, must be non-null, zero-term'ed and a valid RE.
265   * @return new rv or 0 on error
266   */
267 struct rvalue* rval_new_re(str* s)
268 {
269         struct rvalue* rv;
270         long offs;
271         
272         offs=(long)&((struct rvalue*)0)->buf[0]; /* offset of the buf. member */
273         /* make sure we reserve enough space so that we can satisfy any regex_t
274            alignment requirement (pointer) */
275         rv=rval_new_empty(ROUND_POINTER(offs)-offs+sizeof(*rv->v.re.regex)+
276                                                 s->len+1/* 0 */);
277         if (likely(rv)){
278                 rv->type=RV_STR;
279                 /* make sure regex points to a properly aligned address
280                    (use max./pointer alignment to be sure ) */
281                 rv->v.re.regex=(regex_t*)((char*)&rv->buf[0]+ROUND_POINTER(offs)-offs);
282                 rv->v.s.s=(char*)rv->v.re.regex+sizeof(*rv->v.re.regex);
283                 rv->v.s.len=s->len;
284                 memcpy(rv->v.s.s, s->s, s->len);
285                 rv->v.s.s[s->len]=0;
286                 /* compile the regex */
287                 /* same flags as for expr. =~ (fix_expr()) */
288                 if (unlikely(regcomp(rv->v.re.regex, s->s,
289                                                                 REG_EXTENDED|REG_NOSUB|REG_ICASE))){
290                         /* error */
291                         pkg_free(rv);
292                         rv=0;
293                 }else /* success */
294                         rv->flags|=RV_RE_F;
295         }
296         return rv;
297 }
298
299
300
301 /** get string name for a type.
302   *
303   * @return - null terminated name of the type
304   */
305 char* rval_type_name(enum rval_type type)
306 {
307         switch(type){
308                 case RV_NONE:
309                         return "none";
310                 case RV_INT:
311                         return "int";
312                 case RV_STR:
313                         return "str";
314                 case RV_BEXPR:
315                         return "bexpr_t";
316                 case RV_ACTION_ST:
317                         return "action_t";
318                 case RV_PVAR:
319                         return "pvar";
320                 case RV_AVP:
321                         return "avp";
322                         break;
323                 case RV_SEL:
324                         return "select";
325         }
326         return "error_unknown_type";
327 }
328
329
330
331 /**
332  * @brief create a new pk_malloc'ed rvalue from a rval_val union
333  * @param t rvalue type
334  * @param v rvalue value
335  * @param extra_size extra space to allocate
336  * (so that future string operation can reuse the space)
337  * @return new rv or 0 on error
338  */
339 struct rvalue* rval_new(enum rval_type t, union rval_val* v, int extra_size)
340 {
341         struct rvalue* rv;
342         
343         if (t==RV_STR && v && v->s.s)
344                 return rval_new_str(&v->s, extra_size);
345         rv=rval_new_empty(extra_size);
346         if (likely(rv)){
347                 rv->type=t;
348                 if (likely(v && t!=RV_STR)){
349                         rv->v=*v;
350                 }else if (t==RV_STR){
351                         rv->v.s.s=&rv->buf[0];
352                         rv->v.s.len=0;
353                         if (likely(extra_size)) rv->v.s.s[0]=0;
354                 }else
355                         memset (&rv->v, 0, sizeof(rv->v));
356         }
357         return rv;
358 }
359
360
361
362 /**
363  * @brief get rvalue basic type (RV_INT or RV_STR)
364  *
365  * Given a rvalue it tries to determinte its basic type.
366  * Fills val_cache if non-null and empty (can be used in other rval*
367  * function calls, to avoid re-resolving avps or pvars). It must be
368  * rval_cache_clean()'en when no longer needed.
369  *
370  * @param h run action context
371  * @param msg SIP message
372  * @param rv target rvalue
373  * @param val_cache write-only value cache, might be filled if non-null,
374  * it _must_ be rval_cache_clean()'en when done.
375  * @return basic type or RV_NONE on error
376  */
377 inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
378                                                                                         struct sip_msg* msg,
379                                                                                         struct rvalue* rv,
380                                                                                         struct rval_cache* val_cache)
381 {
382         avp_t* r_avp;
383         int_str tmp_avp_val;
384         int_str* avpv;
385         pv_value_t tmp_pval;
386         pv_value_t* pv;
387         enum rval_type tmp;
388         enum rval_type* ptype;
389         
390         switch(rv->type){
391                 case RV_INT:
392                 case RV_STR:
393                         return rv->type;
394                 case RV_BEXPR:
395                 case RV_ACTION_ST:
396                         return RV_INT;
397                 case RV_PVAR:
398                         if (likely(val_cache && val_cache->cache_type==RV_CACHE_EMPTY)){
399                                 pv=&val_cache->c.pval;
400                                 val_cache->cache_type=RV_CACHE_PVAR;
401                         }else{
402                                 val_cache=0;
403                                 pv=&tmp_pval;
404                         }
405                         memset(pv, 0, sizeof(tmp_pval));
406                         if (likely(pv_get_spec_value(msg, &rv->v.pvs, pv)==0)){
407                                 if (pv->flags & PV_TYPE_INT){
408                                         if (likely(val_cache!=0))
409                                                 val_cache->val_type=RV_INT;
410                                         else
411                                                 pv_value_destroy(pv);
412                                         return RV_INT;
413                                 }else if (pv->flags & PV_VAL_STR){
414                                         if (likely(val_cache!=0))
415                                                 val_cache->val_type=RV_STR;
416                                         else
417                                                 pv_value_destroy(pv);
418                                         return RV_STR;
419                                 }else{
420                                         pv_value_destroy(pv);
421                                         if (likely(val_cache!=0))
422                                                 val_cache->val_type=RV_NONE; /* undefined */
423                                         goto error;
424                                 }
425                         }else{
426                                 if (likely(val_cache!=0))
427                                         val_cache->val_type=RV_NONE; /* undefined */
428                                 goto error;
429                         }
430                         break;
431                 case RV_AVP:
432                         if (likely(val_cache && val_cache->cache_type==RV_CACHE_EMPTY)){
433                                 ptype=&val_cache->val_type;
434                                 avpv=&val_cache->c.avp_val;
435                                 val_cache->cache_type=RV_CACHE_AVP;
436                         }else{
437                                 ptype=&tmp;
438                                 avpv=&tmp_avp_val;
439                         }
440                         r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
441                                                                                         avpv, rv->v.avps.index);
442                         if (likely(r_avp)){
443                                 if (r_avp->flags & AVP_VAL_STR){
444                                         *ptype=RV_STR;
445                                         return RV_STR;
446                                 }else{
447                                         *ptype=RV_INT;
448                                         return RV_INT;
449                                 }
450                         }else{
451                                 *ptype=RV_NONE;
452                                 goto error;
453                         }
454                         break;
455                 case RV_SEL:
456                         return RV_STR;
457                 default:
458                         BUG("rv type %d not handled\n", rv->type);
459         }
460 error:
461         return RV_NONE;
462 }
463
464
465
466 /** guess the type of an expression.
467   * @return RV_INT, RV_STR or RV_NONE (when type could not be found,
468   * e.g. avp or pvar)
469   */
470 enum rval_type rve_guess_type( struct rval_expr* rve)
471 {
472         switch(rve->op){
473                 case RVE_RVAL_OP:
474                         switch(rve->left.rval.type){
475                                 case RV_STR:
476                                 case RV_SEL:
477                                         return RV_STR;
478                                 case RV_INT:
479                                 case RV_BEXPR:
480                                 case RV_ACTION_ST:
481                                         return RV_INT;
482                                 case RV_PVAR:
483                                 case RV_AVP:
484                                 case RV_NONE:
485                                         return RV_NONE;
486                         }
487                         break;
488                 case RVE_UMINUS_OP:
489                 case RVE_BOOL_OP:
490                 case RVE_LNOT_OP:
491                 case RVE_BNOT_OP:
492                 case RVE_MINUS_OP:
493                 case RVE_MUL_OP:
494                 case RVE_DIV_OP:
495                 case RVE_MOD_OP:
496                 case RVE_BOR_OP:
497                 case RVE_BAND_OP:
498                 case RVE_BXOR_OP:
499                 case RVE_BLSHIFT_OP:
500                 case RVE_BRSHIFT_OP:
501                 case RVE_LAND_OP:
502                 case RVE_LOR_OP:
503                 case RVE_GT_OP:
504                 case RVE_GTE_OP:
505                 case RVE_LT_OP:
506                 case RVE_LTE_OP:
507                 case RVE_EQ_OP:
508                 case RVE_DIFF_OP:
509                 case RVE_IEQ_OP:
510                 case RVE_IDIFF_OP:
511                 case RVE_STREQ_OP:
512                 case RVE_STRDIFF_OP:
513                 case RVE_MATCH_OP:
514                 case RVE_IPLUS_OP:
515                 case RVE_STRLEN_OP:
516                 case RVE_STREMPTY_OP:
517                 case RVE_DEFINED_OP:
518                 case RVE_NOTDEFINED_OP:
519                 case RVE_INT_OP:
520                         return RV_INT;
521                 case RVE_PLUS_OP:
522                         /* '+' evaluates to the type of the left operand */
523                         return rve_guess_type(rve->left.rve);
524                 case RVE_CONCAT_OP:
525                 case RVE_STR_OP:
526                         return RV_STR;
527                 case RVE_NONE_OP:
528                         break;
529         }
530         return RV_NONE;
531 }
532
533
534
535 /** returns true if expression is constant.
536   * @return 0 or 1 on
537   *  non constant type
538   */
539 int rve_is_constant(struct rval_expr* rve)
540 {
541         switch(rve->op){
542                 case RVE_RVAL_OP:
543                         switch(rve->left.rval.type){
544                                 case RV_STR:
545                                         return 1;
546                                 case RV_INT:
547                                         return 1;
548                                 case RV_SEL:
549                                 case RV_BEXPR:
550                                 case RV_ACTION_ST:
551                                 case RV_PVAR:
552                                 case RV_AVP:
553                                 case RV_NONE:
554                                         return 0;
555                         }
556                         break;
557                 case RVE_UMINUS_OP:
558                 case RVE_BOOL_OP:
559                 case RVE_LNOT_OP:
560                 case RVE_BNOT_OP:
561                 case RVE_STRLEN_OP:
562                 case RVE_STREMPTY_OP:
563                 case RVE_DEFINED_OP:
564                 case RVE_NOTDEFINED_OP:
565                 case RVE_INT_OP:
566                 case RVE_STR_OP:
567                         return rve_is_constant(rve->left.rve);
568                 case RVE_MINUS_OP:
569                 case RVE_MUL_OP:
570                 case RVE_DIV_OP:
571                 case RVE_MOD_OP:
572                 case RVE_BOR_OP:
573                 case RVE_BAND_OP:
574                 case RVE_BXOR_OP:
575                 case RVE_BLSHIFT_OP:
576                 case RVE_BRSHIFT_OP:
577                 case RVE_LAND_OP:
578                 case RVE_LOR_OP:
579                 case RVE_GT_OP:
580                 case RVE_GTE_OP:
581                 case RVE_LT_OP:
582                 case RVE_LTE_OP:
583                 case RVE_EQ_OP:
584                 case RVE_DIFF_OP:
585                 case RVE_IEQ_OP:
586                 case RVE_IDIFF_OP:
587                 case RVE_STREQ_OP:
588                 case RVE_STRDIFF_OP:
589                 case RVE_MATCH_OP:
590                 case RVE_PLUS_OP:
591                 case RVE_IPLUS_OP:
592                 case RVE_CONCAT_OP:
593                         return rve_is_constant(rve->left.rve) &&
594                                         rve_is_constant(rve->right.rve);
595                 case RVE_NONE_OP:
596                         break;
597         }
598         return 0;
599 }
600
601
602
603 /** returns true if the expression has side-effects.
604   * @return  1 for possible side-effects, 0 for no side-effects
605   * TODO: add better checks
606   */
607 int rve_has_side_effects(struct rval_expr* rve)
608 {
609         return !rve_is_constant(rve);
610 }
611
612
613
614 /** returns true if operator is unary (takes only 1 arg).
615   * @return 0 or 1 on
616   */
617 static int rve_op_unary(enum rval_expr_op op)
618 {
619         switch(op){
620                 case RVE_RVAL_OP: /* not realy an operator */
621                         return -1;
622                 case RVE_UMINUS_OP:
623                 case RVE_BOOL_OP:
624                 case RVE_LNOT_OP:
625                 case RVE_BNOT_OP:
626                 case RVE_STRLEN_OP:
627                 case RVE_STREMPTY_OP:
628                 case RVE_DEFINED_OP:
629                 case RVE_NOTDEFINED_OP:
630                 case RVE_INT_OP:
631                 case RVE_STR_OP:
632                         return 1;
633                 case RVE_MINUS_OP:
634                 case RVE_MUL_OP:
635                 case RVE_DIV_OP:
636                 case RVE_MOD_OP:
637                 case RVE_BOR_OP:
638                 case RVE_BAND_OP:
639                 case RVE_BXOR_OP:
640                 case RVE_BLSHIFT_OP:
641                 case RVE_BRSHIFT_OP:
642                 case RVE_LAND_OP:
643                 case RVE_LOR_OP:
644                 case RVE_GT_OP:
645                 case RVE_GTE_OP:
646                 case RVE_LT_OP:
647                 case RVE_LTE_OP:
648                 case RVE_EQ_OP:
649                 case RVE_DIFF_OP:
650                 case RVE_IEQ_OP:
651                 case RVE_IDIFF_OP:
652                 case RVE_STREQ_OP:
653                 case RVE_STRDIFF_OP:
654                 case RVE_MATCH_OP:
655                 case RVE_PLUS_OP:
656                 case RVE_IPLUS_OP:
657                 case RVE_CONCAT_OP:
658                         return 0;
659                 case RVE_NONE_OP:
660                         return -1;
661                         break;
662         }
663         return 0;
664 }
665
666
667
668 /**
669  * @brief Returns 1 if expression is valid (type-wise)
670  * @param type filled with the type of the expression (RV_INT, RV_STR or
671  *                RV_NONE if it's dynamic)
672  * @param rve  checked expression
673  * @param bad_rve set on failure to the subexpression for which the 
674  * type check failed
675  * @param bad_t set on failure to the type of the bad subexpression
676  * @param exp_t set on failure to the expected type for the bad
677  * subexpression
678  * @return 0 or 1 and sets *type to the resulting type
679  * (RV_INT, RV_STR or RV_NONE if it can be found only at runtime)
680  */
681 int rve_check_type(enum rval_type* type, struct rval_expr* rve,
682                                         struct rval_expr** bad_rve, 
683                                         enum rval_type* bad_t,
684                                         enum rval_type* exp_t)
685 {
686         enum rval_type type1, type2;
687         
688         switch(rve->op){
689                 case RVE_RVAL_OP:
690                         *type=rve_guess_type(rve);
691                         return 1;
692                 case RVE_UMINUS_OP:
693                 case RVE_BOOL_OP:
694                 case RVE_LNOT_OP:
695                 case RVE_BNOT_OP:
696                         *type=RV_INT;
697                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
698                                 if (type1==RV_STR){
699                                         if (bad_rve) *bad_rve=rve->left.rve;
700                                         if (bad_t) *bad_t=type1;
701                                         if (exp_t) *exp_t=RV_INT;
702                                         return 0;
703                                 }
704                                 return 1;
705                         }
706                         return 0;
707                         break;
708                 case RVE_MINUS_OP:
709                 case RVE_MUL_OP:
710                 case RVE_DIV_OP:
711                 case RVE_MOD_OP:
712                 case RVE_BOR_OP:
713                 case RVE_BAND_OP:
714                 case RVE_BXOR_OP:
715                 case RVE_BLSHIFT_OP:
716                 case RVE_BRSHIFT_OP:
717                 case RVE_LAND_OP:
718                 case RVE_LOR_OP:
719                 case RVE_GT_OP:
720                 case RVE_GTE_OP:
721                 case RVE_LT_OP:
722                 case RVE_LTE_OP:
723                 case RVE_IEQ_OP:
724                 case RVE_IDIFF_OP:
725                 case RVE_IPLUS_OP:
726                         *type=RV_INT;
727                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
728                                 if (type1==RV_STR){
729                                         if (bad_rve) *bad_rve=rve->left.rve;
730                                         if (bad_t) *bad_t=type1;
731                                         if (exp_t) *exp_t=RV_INT;
732                                         return 0;
733                                 }
734                                 if (rve_check_type(&type2, rve->right.rve, bad_rve,
735                                                                         bad_t, exp_t)){
736                                         if (type2==RV_STR){
737                                                 if (bad_rve) *bad_rve=rve->right.rve;
738                                                 if (bad_t) *bad_t=type2;
739                                                 if (exp_t) *exp_t=RV_INT;
740                                                 return 0;
741                                         }
742                                         return 1;
743                                 }
744                         }
745                         return 0;
746                 case RVE_EQ_OP:
747                 case RVE_DIFF_OP:
748                         *type=RV_INT;
749                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
750                                 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
751                                                                                 exp_t)){
752                                         if ((type2!=type1) && (type1!=RV_NONE) &&
753                                                         (type2!=RV_NONE) && 
754                                                         !(type1==RV_STR && type2==RV_INT)){
755                                                 if (bad_rve) *bad_rve=rve->right.rve;
756                                                 if (bad_t) *bad_t=type2;
757                                                 if (exp_t) *exp_t=type1;
758                                                 return 0;
759                                         }
760                                         return 1;
761                                 }
762                         }
763                         return 0;
764                 case RVE_PLUS_OP:
765                         *type=RV_NONE;
766                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
767                                 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
768                                                                         exp_t)){
769                                         if ((type2!=type1) && (type1!=RV_NONE) &&
770                                                         (type2!=RV_NONE) && 
771                                                         !(type1==RV_STR && type2==RV_INT)){
772                                                 if (bad_rve) *bad_rve=rve->right.rve;
773                                                 if (bad_t) *bad_t=type2;
774                                                 if (exp_t) *exp_t=type1;
775                                                 return 0;
776                                         }
777                                         *type=type1;
778                                         return 1;
779                                 }
780                         }
781                         break;
782                 case RVE_CONCAT_OP:
783                         *type=RV_STR;
784                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
785                                 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
786                                                                         exp_t)){
787                                         if ((type2!=type1) && (type1!=RV_NONE) &&
788                                                         (type2!=RV_NONE) && 
789                                                         !(type1==RV_STR && type2==RV_INT)){
790                                                 if (bad_rve) *bad_rve=rve->right.rve;
791                                                 if (bad_t) *bad_t=type2;
792                                                 if (exp_t) *exp_t=type1;
793                                                 return 0;
794                                         }
795                                         if (type1==RV_INT){
796                                                 if (bad_rve) *bad_rve=rve->left.rve;
797                                                 if (bad_t) *bad_t=type1;
798                                                 if (exp_t) *exp_t=RV_STR;
799                                                 return 0;
800                                         }
801                                         return 1;
802                                 }
803                         }
804                         break;
805                 case RVE_STREQ_OP:
806                 case RVE_STRDIFF_OP:
807                 case RVE_MATCH_OP:
808                         *type=RV_INT;
809                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
810                                 if (rve_check_type(&type2, rve->right.rve, bad_rve, bad_t,
811                                                                         exp_t)){
812                                         if ((type2!=type1) && (type1!=RV_NONE) &&
813                                                         (type2!=RV_NONE) &&
814                                                         !(type1==RV_STR && type2==RV_INT)){
815                                                 if (bad_rve) *bad_rve=rve->right.rve;
816                                                 if (bad_t) *bad_t=type2;
817                                                 if (exp_t) *exp_t=type1;
818                                                 return 0;
819                                         }
820                                         if (type1==RV_INT){
821                                                 if (bad_rve) *bad_rve=rve->left.rve;
822                                                 if (bad_t) *bad_t=type1;
823                                                 if (exp_t) *exp_t=RV_STR;
824                                                 return 0;
825                                         }
826                                         return 1;
827                                 }
828                         }
829                         break;
830                 case RVE_STRLEN_OP:
831                 case RVE_STREMPTY_OP:
832                 case RVE_DEFINED_OP:
833                 case RVE_NOTDEFINED_OP:
834                         *type=RV_INT;
835                         if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
836                                 if (type1==RV_INT){
837                                         if (bad_rve) *bad_rve=rve->left.rve;
838                                         if (bad_t) *bad_t=type1;
839                                         if (exp_t) *exp_t=RV_STR;
840                                         return 0;
841                                 }
842                                 return 1;
843                         }
844                         break;
845                 case RVE_INT_OP:
846                         *type=RV_INT;
847                         return 1;
848                         break;
849                 case RVE_STR_OP:
850                         *type=RV_STR;
851                         return 1;
852                         break;
853                 case RVE_NONE_OP:
854                 default:
855                         BUG("unexpected rve op %d (%d,%d-%d,%d)\n", rve->op,
856                                         rve->fpos.s_line, rve->fpos.s_col,
857                                         rve->fpos.e_line, rve->fpos.e_col);
858                         if (bad_rve) *bad_rve=rve;
859                         if (bad_t) *bad_t=RV_NONE;
860                         if (exp_t) *exp_t=RV_STR;
861                         break;
862         }
863         return 0;
864 }
865
866
867
868 /** get the integer value of an rvalue.
869   * *i=(int)rv
870   * if rv == undefined select, avp or pvar, return 0.
871   * if an error occurs while evaluating a select, avp or pvar, behave as
872   * for the undefined case (and return success).
873   * @param h - script context handle
874   * @param msg - sip msg
875   * @param i   - pointer to int, where the conversion result will be stored
876   * @param rv   - rvalue to be converted
877   * @param cache - cached rv value (read-only), can be 0
878   *
879   * @return 0 on success, \<0 on error and EXPR_DROP on drop
880  */
881 int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
882                                                                 int* i, struct rvalue* rv,
883                                                                 struct rval_cache* cache)
884 {
885         avp_t* r_avp;
886         int_str avp_val;
887         pv_value_t pval;
888         str tmp;
889         str* s;
890         int r, ret;
891         int destroy_pval;
892         
893         destroy_pval=0;
894         s=0;
895         ret=0;
896         switch(rv->type){
897                 case RV_INT:
898                         *i=rv->v.l;
899                         break;
900                 case RV_STR:
901                         s=&rv->v.s;
902                         goto rv_str;
903                 case RV_BEXPR:
904                         *i=eval_expr(h, rv->v.bexpr, msg);
905                         if (*i==EXPR_DROP){
906                                 *i=0; /* false */
907                                 return EXPR_DROP;
908                         }
909                         break;
910                 case RV_ACTION_ST:
911                         if (rv->v.action) {
912                                 *i=(run_actions_safe(h, rv->v.action, msg)>0);
913                                 h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
914                                                                                                                     break in expr*/
915                         } else
916                                 *i=0;
917                         break;
918                 case RV_SEL:
919                         r=run_select(&tmp, &rv->v.sel, msg);
920                         if (unlikely(r!=0)){
921                                 if (r<0)
922                                         goto eval_error;
923                                 else /* i>0  => undefined */
924                                         goto undef;
925                         }
926                         s=&tmp;
927                         goto rv_str;
928                 case RV_AVP:
929                         if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
930                                 if (likely(cache->val_type==RV_INT)){
931                                         *i=cache->c.avp_val.n;
932                                 }else if (cache->val_type==RV_STR){
933                                         s=&cache->c.avp_val.s;
934                                         goto rv_str;
935                                 }else if (cache->val_type==RV_NONE)
936                                         goto undef;
937                                 else goto error_cache;
938                         }else{
939                                 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
940                                                                                         &avp_val, rv->v.avps.index);
941                                 if (likely(r_avp)){
942                                         if (unlikely(r_avp->flags & AVP_VAL_STR)){
943                                                 s=&avp_val.s;
944                                                 goto rv_str;
945                                         }else{
946                                                 *i=avp_val.n;
947                                         }
948                                 }else{
949                                         goto undef;
950                                 }
951                         }
952                         break;
953                 case RV_PVAR:
954                         if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
955                                 if (likely((cache->val_type==RV_INT) ||
956                                                                 (cache->c.pval.flags & PV_VAL_INT))){
957                                         *i=cache->c.pval.ri;
958                                 }else if (cache->val_type==RV_STR){
959                                         s=&cache->c.pval.rs;
960                                         goto rv_str;
961                                 }else if (cache->val_type==RV_NONE)
962                                         goto undef;
963                                 else goto error_cache;
964                         }else{
965                                 memset(&pval, 0, sizeof(pval));
966                                 if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
967                                         if (likely(pval.flags & PV_VAL_INT)){
968                                                 *i=pval.ri;
969                                                 pv_value_destroy(&pval);
970                                         }else if (likely(pval.flags & PV_VAL_STR)){
971                                                 destroy_pval=1; /* we must pv_value_destroy() later*/
972                                                 s=&pval.rs;
973                                                 goto rv_str;
974                                         }else{
975                                                 /* no PV_VAL_STR and no PV_VAL_INT => undef
976                                                    (PV_VAL_NULL) */
977                                                 pv_value_destroy(&pval);
978                                                 goto undef;
979                                         }
980                                 }else{
981                                         goto eval_error;
982                                 }
983                         }
984                         break;
985                 default:
986                         BUG("rv type %d not handled\n", rv->type);
987                         goto error;
988         }
989         return ret;
990 undef:
991 eval_error: /* same as undefined */
992         /* handle undefined => result 0, return success */
993         *i=0;
994         return 0;
995 rv_str:
996         /* rv is of string type => try to convert it to int */
997         /* if "" => 0 (most likely case) */
998         if (likely(s->len==0)) *i=0;
999         else if (unlikely(str2sint(s, i)!=0)){
1000                 /* error converting to int => non numeric => 0 */
1001                 *i=0;
1002 #ifdef RV_STR2INT_VERBOSE_ERR
1003                 WARN("automatic string to int conversion for \"%.*s\" failed\n",
1004                                 s->len, ZSW(s->s));
1005                 /* return an error code */
1006 #endif
1007 #ifdef RV_STR2INT_ERR
1008                 ret=-1;
1009 #endif
1010         }
1011         if (destroy_pval)
1012                 pv_value_destroy(&pval);
1013         return ret;
1014 error_cache:
1015         BUG("invalid cached value:cache type %d, value type %d\n",
1016                         cache?cache->cache_type:0, cache?cache->val_type:0);
1017 error:
1018         if (destroy_pval)
1019                 pv_value_destroy(&pval);
1020         *i=0;
1021         return -1;
1022 }
1023
1024
1025
1026 /** log a message, appending rve position and a '\n'.*/
1027 #define RVE_LOG(lev, rve, txt) \
1028         LOG((lev), txt " (%d,%d-%d,%d)\n", \
1029                         (rve)->fpos.s_line, rve->fpos.s_col, \
1030                         (rve)->fpos.e_line, rve->fpos.e_col )
1031
1032
1033 /** macro for checking and handling rval_get_int() retcode.
1034  * check if the return code is an rval_get_int error and if so
1035  * handle the error (e.g. print a log message, ignore the error by
1036  * setting ret to 0 a.s.o.)
1037  * @param ret - retcode as returned by rval_get_int() (might be changed)
1038  * @param txt - warning message txt (no pointer allowed)
1039  * @param rve - rval_expr, used to access the config. pos
1040  */
1041 #if defined RVAL_GET_INT_ERR_WARN && defined RVAL_GET_INT_ERR_IGN
1042 #define rval_get_int_handle_ret(ret, txt, rve) \
1043         do { \
1044                 if (unlikely((ret)<0)) { \
1045                         RVE_LOG(L_WARN, rve, txt); \
1046                         (ret)=0; \
1047                 } \
1048         }while(0)
1049 #elif defined RVAL_GET_INT_ERR_WARN
1050 #define rval_get_int_handle_ret(ret, txt, rve) \
1051         do { \
1052                 if (unlikely((ret)<0)) \
1053                         RVE_LOG(L_WARN, rve, txt); \
1054         }while(0)
1055 #elif defined RVAL_GET_INT_ERR_IGN
1056 #define rval_get_int_handle_ret(ret, txt, rve) \
1057         do { \
1058                 if (unlikely((ret)<0)) \
1059                                 (ret)=0; \
1060         } while(0)
1061 #else
1062 #define rval_get_int_handle_ret(ret, txt, rve) /* do nothing */
1063 #endif
1064
1065
1066
1067
1068
1069
1070 /** get the string value of an rv in a tmp variable
1071   * *s=(str)rv
1072   * if rv == undefined select, avp or pvar, return "".
1073   * if an error occurs while evaluating a select, avp or pvar, behave as
1074   * for the undefined case (and return success).
1075   * The result points either inside the passed rv, inside
1076   * new_cache or inside an avp. new_cache must be non zero,
1077   * initialized previously and it _must_ be rval_cache_clean(...)'ed when
1078   * done.
1079   * WARNING: it's not intended for general use. It might return a pointer
1080   * inside rv so the result _must_ be treated as read-only. rv and new_cache
1081   * must not be released/freed until the result is no longer needed.
1082   * For general use see  rval_get_str().
1083   * @param h - script context handle
1084   * @param msg - sip msg
1085   * @param tmpv - str return value (pointer to a str struct that will be
1086   *               be filled with the conversion result)
1087   * @param rv   - rvalue to be converted
1088   * @param cache - cached rv value (read-only), can be 0
1089   * @param tmp_cache - used for temporary storage (so that tmpv will not
1090   *                 point to possible freed data), it must be non-null,
1091   *                 initialized and cleaned afterwards.
1092   * @return 0 on success, <0 on error and EXPR_DROP on drop
1093  */
1094 int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1095                                                                 str* tmpv, struct rvalue* rv,
1096                                                                 struct rval_cache* cache,
1097                                                                 struct rval_cache* tmp_cache)
1098 {
1099         avp_t* r_avp;
1100         int i;
1101         
1102         switch(rv->type){
1103                 case RV_INT:
1104                         tmpv->s=sint2strbuf(rv->v.l, tmp_cache->i2s,
1105                                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1106                         tmp_cache->cache_type = RV_CACHE_INT2STR;
1107                         break;
1108                 case RV_STR:
1109                         *tmpv=rv->v.s;
1110                         break;
1111                 case RV_ACTION_ST:
1112                         if (rv->v.action) {
1113                                 i=(run_actions_safe(h, rv->v.action, msg)>0);
1114                                 h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
1115                                                                                                                     break in expr*/
1116                         } else
1117                                 i=0;
1118                         tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1119                                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1120                         tmp_cache->cache_type = RV_CACHE_INT2STR;
1121                         break;
1122                 case RV_BEXPR:
1123                         i=eval_expr(h, rv->v.bexpr, msg);
1124                         if (i==EXPR_DROP){
1125                                 i=0; /* false */
1126                                 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1127                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1128                                 tmp_cache->cache_type = RV_CACHE_INT2STR;
1129                                 return EXPR_DROP;
1130                         }
1131                         tmpv->s=sint2strbuf(i, tmp_cache->i2s, sizeof(tmp_cache->i2s),
1132                                                                 &tmpv->len);
1133                         tmp_cache->cache_type = RV_CACHE_INT2STR;
1134                         break;
1135                 case RV_SEL:
1136                         i=run_select(tmpv, &rv->v.sel, msg);
1137                         if (unlikely(i!=0)){
1138                                 if (i<0){
1139                                         goto eval_error;
1140                                 }else { /* i>0  => undefined */
1141                                         goto undef;
1142                                 }
1143                         }
1144                         break;
1145                 case RV_AVP:
1146                         if (likely(cache && cache->cache_type==RV_CACHE_AVP)){
1147                                 if (likely(cache->val_type==RV_STR)){
1148                                         *tmpv=cache->c.avp_val.s;
1149                                 }else if (cache->val_type==RV_INT){
1150                                         i=cache->c.avp_val.n;
1151                                         tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1152                                                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1153                                         tmp_cache->cache_type = RV_CACHE_INT2STR;
1154                                 }else if (cache->val_type==RV_NONE){
1155                                         goto undef;
1156                                 }else goto error_cache;
1157                         }else{
1158                                 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1159                                                                                         &tmp_cache->c.avp_val,
1160                                                                                         rv->v.avps.index);
1161                                 if (likely(r_avp)){
1162                                         if (likely(r_avp->flags & AVP_VAL_STR)){
1163                                                 tmp_cache->cache_type=RV_CACHE_AVP;
1164                                                 tmp_cache->val_type=RV_STR;
1165                                                 *tmpv=tmp_cache->c.avp_val.s;
1166                                         }else{
1167                                                 i=tmp_cache->c.avp_val.n;
1168                                                 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1169                                                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1170                                                 tmp_cache->cache_type = RV_CACHE_INT2STR;
1171                                         }
1172                                 }else goto undef;
1173                         }
1174                         break;
1175                 case RV_PVAR:
1176                         if (likely(cache && cache->cache_type==RV_CACHE_PVAR)){
1177                                 if (likely(cache->val_type==RV_STR)){
1178                                         *tmpv=cache->c.pval.rs;
1179                                 }else if (cache->val_type==RV_INT){
1180                                         i=cache->c.pval.ri;
1181                                         tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1182                                                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1183                                         tmp_cache->cache_type = RV_CACHE_INT2STR;
1184                                 }else if (cache->val_type==RV_NONE){
1185                                         goto undef;
1186                                 }else goto error_cache;
1187                         }else{
1188                                 memset(&tmp_cache->c.pval, 0, sizeof(tmp_cache->c.pval));
1189                                 if (likely(pv_get_spec_value(msg, &rv->v.pvs,
1190                                                                                                 &tmp_cache->c.pval)==0)){
1191                                         if (likely(tmp_cache->c.pval.flags & PV_VAL_STR)){
1192                                                 /*  the value is not destroyed, but saved instead
1193                                                         in tmp_cache so that it can be destroyed later
1194                                                         when no longer needed */
1195                                                 tmp_cache->cache_type=RV_CACHE_PVAR;
1196                                                 tmp_cache->val_type=RV_STR;
1197                                                 *tmpv=tmp_cache->c.pval.rs;
1198                                         }else if (likely(tmp_cache->c.pval.flags & PV_VAL_INT)){
1199                                                 i=tmp_cache->c.pval.ri;
1200                                                 pv_value_destroy(&tmp_cache->c.pval);
1201                                                 tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1202                                                                                 sizeof(tmp_cache->i2s), &tmpv->len);
1203                                                 tmp_cache->cache_type = RV_CACHE_INT2STR;
1204                                         }else{
1205                                                 /* no PV_VAL_STR and no PV_VAL_INT => undef
1206                                                    (PV_VAL_NULL) */
1207                                                 pv_value_destroy(&tmp_cache->c.pval);
1208                                                 goto undef;
1209                                         }
1210                                 }else{
1211                                         goto eval_error;
1212                                 }
1213                         }
1214                         break;
1215                 default:
1216                         BUG("rv type %d not handled\n", rv->type);
1217                         goto error;
1218         }
1219         return 0;
1220 undef:
1221 eval_error: /* same as undefined */
1222         /* handle undefined => result "", return success */
1223         tmpv->s="";
1224         tmpv->len=0;
1225         return 0;
1226 error_cache:
1227         BUG("invalid cached value:cache type %d, value type %d\n",
1228                         cache?cache->cache_type:0, cache?cache->val_type:0);
1229 error:
1230         tmpv->s="";
1231         tmpv->len=0;
1232         return -1;
1233 }
1234
1235
1236
1237 /** get the string value of an rv.
1238   * *s=(str)rv
1239   * The result is pkg malloc'ed (so it should be pkg_free()'ed when finished.
1240   * @return 0 on success, <0 on error and EXPR_DROP on drop
1241  */
1242 int rval_get_str(struct run_act_ctx* h, struct sip_msg* msg,
1243                                                                 str* s, struct rvalue* rv,
1244                                                                 struct rval_cache* cache)
1245 {
1246         str tmp;
1247         struct rval_cache tmp_cache;
1248         
1249         rval_cache_init(&tmp_cache);
1250         if (unlikely(rval_get_tmp_str(h, msg, &tmp, rv, cache, &tmp_cache)<0))
1251                 goto error;
1252         s->s=pkg_malloc(tmp.len+1/* 0 term */);
1253         if (unlikely(s->s==0)){
1254                 ERR("memory allocation error\n");
1255                 goto error;
1256         }
1257         s->len=tmp.len;
1258         memcpy(s->s, tmp.s, tmp.len);
1259         s->s[tmp.len]=0; /* 0 term */
1260         rval_cache_clean(&tmp_cache);
1261         return 0;
1262 error:
1263         rval_cache_clean(&tmp_cache);
1264         return -1;
1265 }
1266
1267
1268
1269 /**
1270  * @brief Convert a rvalue to another rvalue, of a specific type
1271  *
1272  * Convert a rvalue to another rvalue, of a specific type.
1273  * The result is read-only in most cases (can be a reference
1274  * to another rvalue, can be checked by using rv_chg_in_place()) and
1275  * _must_ be rval_destroy()'ed.
1276  *
1277  * @param h run action context
1278  * @param msg SIP mesasge
1279  * @param type - type to convert to
1280  * @param v - rvalue to convert
1281  * @param c - rval_cache (cached v value if known/filled by another
1282  *            function), can be 0 (unknown/not needed)
1283  * @return pointer to a rvalue (reference to an existing one or a new
1284  * one, @see rv_chg_in_place() and the above comment), or 0 on error.
1285  */
1286 struct rvalue* rval_convert(struct run_act_ctx* h, struct sip_msg* msg,
1287                                                         enum rval_type type, struct rvalue* v,
1288                                                         struct rval_cache* c)
1289 {
1290         int i;
1291         struct rval_cache tmp_cache;
1292         str tmp;
1293         struct rvalue* ret;
1294         union rval_val val;
1295         
1296         if (v->type==type){
1297                 rv_ref(v);
1298                 return v;
1299         }
1300         switch(type){
1301                 case RV_INT:
1302                         if (unlikely(rval_get_int(h, msg, &i, v, c) < 0))
1303                                 return 0;
1304                         val.l=i;
1305                         return rval_new(RV_INT, &val, 0);
1306                 case RV_STR:
1307                         rval_cache_init(&tmp_cache);
1308                         if (unlikely(rval_get_tmp_str(h, msg, &tmp, v, c, &tmp_cache) < 0))
1309                         {
1310                                 rval_cache_clean(&tmp_cache);
1311                                 return 0;
1312                         }
1313                         ret=rval_new_str(&tmp, RV_STR_EXTRA);
1314                         rval_cache_clean(&tmp_cache);
1315                         return ret;
1316                 case RV_NONE:
1317                 default:
1318                         BUG("unsupported conversion to type %d\n", type);
1319                         return 0;
1320         }
1321         return 0;
1322 }
1323
1324
1325
1326 /** integer operation: *res= op v.
1327   * @return 0 on succes, \<0 on error
1328   */
1329 inline static int int_intop1(int* res, enum rval_expr_op op, int v)
1330 {
1331         switch(op){
1332                 case RVE_UMINUS_OP:
1333                         *res=-v;
1334                         break;
1335                 case RVE_BOOL_OP:
1336                         *res=!!v;
1337                         break;
1338                 case RVE_LNOT_OP:
1339                         *res=!v;
1340                         break;
1341                 case RVE_BNOT_OP:
1342                         *res=~v;
1343                         break;
1344                 default:
1345                         BUG("rv unsupported intop1 %d\n", op);
1346                         return -1;
1347         }
1348         return 0;
1349 }
1350
1351
1352
1353 /** integer operation: *res= v1 op v2
1354   * @return 0 on succes, \<0 on error
1355   */
1356 inline static int int_intop2(int* res, enum rval_expr_op op, int v1, int v2)
1357 {
1358         switch(op){
1359                 case RVE_PLUS_OP:
1360                 case RVE_IPLUS_OP:
1361                         *res=v1+v2;
1362                         break;
1363                 case RVE_MINUS_OP:
1364                         *res=v1-v2;
1365                         break;
1366                 case RVE_MUL_OP:
1367                         *res=v1*v2;
1368                         break;
1369                 case RVE_DIV_OP:
1370                         if (unlikely(v2==0)){
1371                                 ERR("rv div by 0\n");
1372                                 return -1;
1373                         }
1374                         *res=v1/v2;
1375                         break;
1376                 case RVE_MOD_OP:
1377                         if (unlikely(v2==0)){
1378                                 ERR("rv mod by 0\n");
1379                                 return -1;
1380                         }
1381                         *res=v1%v2;
1382                         break;
1383                 case RVE_BOR_OP:
1384                         *res=v1|v2;
1385                         break;
1386                 case RVE_BAND_OP:
1387                         *res=v1&v2;
1388                         break;
1389                 case RVE_BXOR_OP:
1390                         *res=v1^v2;
1391                         break;
1392                 case RVE_BLSHIFT_OP:
1393                         *res=v1<<v2;
1394                         break;
1395                 case RVE_BRSHIFT_OP:
1396                         *res=v1>>v2;
1397                         break;
1398                 case RVE_LAND_OP:
1399                         *res=v1 && v2;
1400                         break;
1401                 case RVE_LOR_OP:
1402                         *res=v1 || v2;
1403                         break;
1404                 case RVE_GT_OP:
1405                         *res=v1 > v2;
1406                         break;
1407                 case RVE_GTE_OP:
1408                         *res=v1 >= v2;
1409                         break;
1410                 case RVE_LT_OP:
1411                         *res=v1 < v2;
1412                         break;
1413                 case RVE_LTE_OP:
1414                         *res=v1 <= v2;
1415                         break;
1416                 case RVE_EQ_OP:
1417                 case RVE_IEQ_OP:
1418                         *res=v1 == v2;
1419                         break;
1420                 case RVE_DIFF_OP:
1421                 case RVE_IDIFF_OP:
1422                         *res=v1 != v2;
1423                         break;
1424                 case RVE_CONCAT_OP:
1425                         *res=0;
1426                         /* invalid operand for int */
1427                         return -1;
1428                 default:
1429                         BUG("rv unsupported intop %d\n", op);
1430                         return -1;
1431         }
1432         return 0;
1433 }
1434
1435
1436
1437 /** internal helper: compare 2 RV_STR RVs.
1438   * Warning: rv1 & rv2 must be RV_STR
1439   * @return 0 on success, -1 on error
1440   */
1441 inline static int bool_rvstrop2( enum rval_expr_op op, int* res,
1442                                                                 struct rvalue* rv1, struct rvalue* rv2)
1443 {
1444         str* s1;
1445         str* s2;
1446         regex_t tmp_re;
1447         
1448         s1=&rv1->v.s;
1449         s2=&rv2->v.s;
1450         switch(op){
1451                 case RVE_EQ_OP:
1452                 case RVE_STREQ_OP:
1453                         *res= (s1->len==s2->len) && (memcmp(s1->s, s2->s, s1->len)==0);
1454                         break;
1455                 case RVE_DIFF_OP:
1456                 case RVE_STRDIFF_OP:
1457                         *res= (s1->len!=s2->len) || (memcmp(s1->s, s2->s, s1->len)!=0);
1458                         break;
1459                 case RVE_MATCH_OP:
1460                         if (likely(rv2->flags & RV_RE_F)){
1461                                 *res=(regexec(rv2->v.re.regex, rv1->v.s.s, 0, 0, 0)==0);
1462                         }else{
1463                                 /* we need to compile the RE on the fly */
1464                                 if (unlikely(regcomp(&tmp_re, s2->s,
1465                                                                                 REG_EXTENDED|REG_NOSUB|REG_ICASE))){
1466                                         /* error */
1467                                         ERR("Bad regular expression \"%s\"\n", s2->s);
1468                                         goto error;
1469                                 }
1470                                 *res=(regexec(&tmp_re, s1->s, 0, 0, 0)==0);
1471                                 regfree(&tmp_re);
1472                         }
1473                         break;
1474                 default:
1475                         BUG("rv unsupported intop %d\n", op);
1476                         goto error;
1477         }
1478         return 0;
1479 error:
1480         *res=0; /* false */
1481         return -1;
1482 }
1483
1484
1485
1486 /** integer returning operation on string: *res= op str (returns integer)
1487   * @return 0 on succes, \<0 on error
1488   */
1489 inline static int int_strop1(int* res, enum rval_expr_op op, str* s1)
1490 {
1491         switch(op){
1492                 case RVE_STRLEN_OP:
1493                         *res=s1->len;
1494                         break;
1495                 case RVE_STREMPTY_OP:
1496                         *res=(s1->len==0);
1497                         break;
1498                 default:
1499                         BUG("rv unsupported int_strop1 %d\n", op);
1500                         *res=0;
1501                         return -1;
1502         }
1503         return 0;
1504 }
1505
1506
1507
1508 /** integer operation: ret= op v (returns a rvalue).
1509  * @return rvalue on success, 0 on error
1510  */
1511 inline static struct rvalue* rval_intop1(struct run_act_ctx* h,
1512                                                                                         struct sip_msg* msg,
1513                                                                                         enum rval_expr_op op,
1514                                                                                         struct rvalue* v)
1515 {
1516         struct rvalue* rv2;
1517         struct rvalue* ret;
1518         int i;
1519         
1520         i=0;
1521         rv2=rval_convert(h, msg, RV_INT, v, 0);
1522         if (unlikely(rv2==0)){
1523                 ERR("rval int conversion failed\n");
1524                 goto error;
1525         }
1526         if (unlikely(int_intop1(&i, op, rv2->v.l)<0))
1527                 goto error;
1528         if (rv_chg_in_place(rv2)){
1529                 ret=rv2;
1530                 rv_ref(ret);
1531         }else if (rv_chg_in_place(v)){
1532                 ret=v;
1533                 rv_ref(ret);
1534         }else{
1535                 ret=rval_new(RV_INT, &rv2->v, 0);
1536                 if (unlikely(ret==0)){
1537                         ERR("eval out of memory\n");
1538                         goto error;
1539                 }
1540         }
1541         rval_destroy(rv2);
1542         ret->v.l=i;
1543         return ret;
1544 error:
1545         rval_destroy(rv2);
1546         return 0;
1547 }
1548
1549
1550
1551 /** integer operation: ret= l op r (returns a rvalue).
1552  * @return rvalue on success, 0 on error
1553  */
1554 inline static struct rvalue* rval_intop2(struct run_act_ctx* h,
1555                                                                                         struct sip_msg* msg,
1556                                                                                         enum rval_expr_op op,
1557                                                                                         struct rvalue* l,
1558                                                                                         struct rvalue* r)
1559 {
1560         struct rvalue* rv1;
1561         struct rvalue* rv2;
1562         struct rvalue* ret;
1563         int i;
1564
1565         rv2=rv1=0;
1566         ret=0;
1567         if ((rv1=rval_convert(h, msg, RV_INT, l, 0))==0)
1568                 goto error;
1569         if ((rv2=rval_convert(h, msg, RV_INT, r, 0))==0)
1570                 goto error;
1571         if (unlikely(int_intop2(&i, op, rv1->v.l, rv2->v.l)<0))
1572                 goto error;
1573         if (rv_chg_in_place(rv1)){
1574                 /* try reusing rv1 */
1575                 ret=rv1;
1576                 rv_ref(ret);
1577         }else if (rv_chg_in_place(rv2)){
1578                 /* try reusing rv2 */
1579                 ret=rv2;
1580                 rv_ref(ret);
1581         }else if ((l->type==RV_INT) && (rv_chg_in_place(l))){
1582                 ret=l;
1583                 rv_ref(ret);
1584         } else if ((r->type==RV_INT) && (rv_chg_in_place(r))){
1585                 ret=r;
1586                 rv_ref(ret);
1587         }else{
1588                 ret=rval_new(RV_INT, &rv1->v, 0);
1589                 if (unlikely(ret==0)){
1590                         ERR("rv eval out of memory\n");
1591                         goto error;
1592                 }
1593         }
1594         rval_destroy(rv1); 
1595         rval_destroy(rv2); 
1596         ret->v.l=i;
1597         return ret;
1598 error:
1599         rval_destroy(rv1); 
1600         rval_destroy(rv2); 
1601         return 0;
1602 }
1603
1604
1605
1606 /** string add operation: ret= l . r (returns a rvalue).
1607  * Can use cached rvalues (c1 & c2).
1608  * @return rvalue on success, 0 on error
1609  */
1610 inline static struct rvalue* rval_str_add2(struct run_act_ctx* h,
1611                                                                                         struct sip_msg* msg,
1612                                                                                         struct rvalue* l,
1613                                                                                         struct rval_cache* c1,
1614                                                                                         struct rvalue* r,
1615                                                                                         struct rval_cache* c2
1616                                                                                         )
1617 {
1618         struct rvalue* rv1;
1619         struct rvalue* rv2;
1620         struct rvalue* ret;
1621         str* s1;
1622         str* s2;
1623         str tmp;
1624         short flags;
1625         int len;
1626         
1627         rv2=rv1=0;
1628         ret=0;
1629         flags=0;
1630         s1=0;
1631         s2=0;
1632         if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
1633                 goto error;
1634         if ((rv2=rval_convert(h, msg, RV_STR, r, c2))==0)
1635                 goto error;
1636         
1637         len=rv1->v.s.len + rv2->v.s.len + 1 /* 0 */;
1638         
1639         if (rv_chg_in_place(rv1) && (rv1->bsize>=len)){
1640                 /* try reusing rv1 */
1641                 ret=rv1;
1642                 rv_ref(ret);
1643                 s2=&rv2->v.s;
1644                 if (ret->v.s.s == &ret->buf[0]) s1=0;
1645                 else{
1646                         tmp=ret->v.s;
1647                         flags=ret->flags;
1648                         ret->flags &= ~RV_CNT_ALLOCED_F;
1649                         ret->v.s.s=&ret->buf[0];
1650                         ret->v.s.len=0;
1651                         s1=&tmp;
1652                 }
1653         }else if (rv_chg_in_place(rv2) && (rv2->bsize>=len)){
1654                 /* try reusing rv2 */
1655                 ret=rv2;
1656                 rv_ref(ret);
1657                 s1=&rv1->v.s;
1658                 if (ret->v.s.s == &ret->buf[0]) 
1659                         s2=&ret->v.s;
1660                 else{
1661                         tmp=ret->v.s;
1662                         flags=ret->flags;
1663                         ret->flags &= ~RV_CNT_ALLOCED_F;
1664                         ret->v.s.s=&ret->buf[0];
1665                         ret->v.s.len=0;
1666                         s2=&tmp;
1667                 }
1668         }else if ((l->type==RV_STR) && (rv_chg_in_place(l)) && (l->bsize>=len)){
1669                 ret=l;
1670                 rv_ref(ret);
1671                 s2=&rv2->v.s;
1672                 if (ret->v.s.s == &ret->buf[0]) s1=0;
1673                 else{
1674                         tmp=ret->v.s;
1675                         flags=ret->flags;
1676                         ret->flags &= ~RV_CNT_ALLOCED_F;
1677                         ret->v.s.s=&ret->buf[0];
1678                         ret->v.s.len=0;
1679                         s1=&tmp;
1680                 }
1681         } else if ((r->type==RV_STR) && (rv_chg_in_place(r) && (r->bsize>=len))){
1682                 ret=r;
1683                 rv_ref(ret);
1684                 s1=&rv1->v.s;
1685                 if (ret->v.s.s == &ret->buf[0]) 
1686                         s2=&ret->v.s;
1687                 else{
1688                         tmp=ret->v.s;
1689                         flags=ret->flags;
1690                         ret->flags &= ~RV_CNT_ALLOCED_F;
1691                         ret->v.s.s=&ret->buf[0];
1692                         ret->v.s.len=0;
1693                         s2=&tmp;
1694                 }
1695         }else{
1696                 ret=rval_new(RV_STR, &rv1->v, len + RV_STR_EXTRA);
1697                 if (unlikely(ret==0)){
1698                         ERR("rv eval out of memory\n");
1699                         goto error;
1700                 }
1701                 s1=0;
1702                 s2=&rv2->v.s;
1703         }
1704         /* do the actual copy */
1705         memmove(ret->buf+rv1->v.s.len, s2->s, s2->len);
1706         if (s1){
1707                 memcpy(ret->buf, s1->s, s1->len);
1708         }
1709         ret->v.s.len=rv1->v.s.len+s2->len;
1710         ret->v.s.s[ret->v.s.len]=0;
1711         /* cleanup if needed */
1712         if (flags & RV_CNT_ALLOCED_F)
1713                 pkg_free(tmp.s);
1714         rval_destroy(rv1); 
1715         rval_destroy(rv2); 
1716         return ret;
1717 error:
1718         rval_destroy(rv1); 
1719         rval_destroy(rv2); 
1720         return 0;
1721 }
1722
1723
1724
1725 /** bool operation on rval evaluated as strings.
1726  * Can use cached rvalues (c1 & c2).
1727  * @return 0 success, -1 on error
1728  */
1729 inline static int rval_str_lop2(struct run_act_ctx* h,
1730                                                  struct sip_msg* msg,
1731                                                  int* res,
1732                                                  enum rval_expr_op op,
1733                                                  struct rvalue* l,
1734                                                  struct rval_cache* c1,
1735                                                  struct rvalue* r,
1736                                                  struct rval_cache* c2)
1737 {
1738         struct rvalue* rv1;
1739         struct rvalue* rv2;
1740         int ret;
1741         
1742         rv2=rv1=0;
1743         ret=0;
1744         if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
1745                 goto error;
1746         if ((rv2=rval_convert(h, msg, RV_STR, r, c2))==0)
1747                 goto error;
1748         ret=bool_rvstrop2(op, res, rv1, rv2);
1749         rval_destroy(rv1); 
1750         rval_destroy(rv2); 
1751         return ret;
1752 error:
1753         rval_destroy(rv1); 
1754         rval_destroy(rv2); 
1755         return 0;
1756 }
1757
1758
1759
1760 /**
1761  * @brief Integer operation on rval evaluated as string
1762  * 
1763  * Integer operation on rval evaluated as string, can use cached
1764  * rvalues (c1 & c2).
1765  * @param h run action context
1766  * @param msg SIP message
1767  * @param res will be set to the result
1768  * @param op rvalue expression operation
1769  * @param l rvalue
1770  * @param c1 rvalue cache
1771  * @return 0 success, -1 on error
1772  */
1773 inline static int rval_int_strop1(struct run_act_ctx* h,
1774                                                  struct sip_msg* msg,
1775                                                  int* res,
1776                                                  enum rval_expr_op op,
1777                                                  struct rvalue* l,
1778                                                  struct rval_cache* c1)
1779 {
1780         struct rvalue* rv1;
1781         int ret;
1782         
1783         rv1=0;
1784         ret=0;
1785         if ((rv1=rval_convert(h, msg, RV_STR, l, c1))==0)
1786                 goto error;
1787         ret=int_strop1(res, op, &rv1->v.s);
1788         rval_destroy(rv1); 
1789         return ret;
1790 error:
1791         *res=0;
1792         rval_destroy(rv1); 
1793         return -1;
1794 }
1795
1796
1797
1798 /**
1799  * @brief Checks if rv is defined
1800  * @param h run action context
1801  * @param msg SIP message
1802  * @param res set to the result 1 is defined, 0 not defined
1803  * @param rv rvalue
1804  * @param cache rvalue cache
1805  * @return 0 on success, -1 on error
1806  * @note Can use cached rvalues (cache). A rv can be undefined if it's
1807  * an undefined avp or pvar or select or if it's NONE
1808  * @note An error in the avp, pvar or select search is equivalent to
1809  * undefined (and it's not reported)
1810  */
1811 inline static int rv_defined(struct run_act_ctx* h,
1812                                                  struct sip_msg* msg, int* res,
1813                                                  struct rvalue* rv, struct rval_cache* cache)
1814 {
1815         avp_t* r_avp;
1816         int_str avp_val;
1817         pv_value_t pval;
1818         str tmp;
1819         
1820         *res=1;
1821         switch(rv->type){
1822                 case RV_SEL:
1823                         if (unlikely(cache && cache->cache_type==RV_CACHE_SELECT)){
1824                                 *res=(cache->val_type!=RV_NONE);
1825                         }else
1826                                 /* run select returns 0 on success, -1 on error and >0 on 
1827                                    undefined. error is considered undefined */
1828                                 *res=(run_select(&tmp, &rv->v.sel, msg)==0);
1829                         break;
1830                 case RV_AVP:
1831                         if (unlikely(cache && cache->cache_type==RV_CACHE_AVP)){
1832                                 *res=(cache->val_type!=RV_NONE);
1833                         }else{
1834                                 r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
1835                                                                                         &avp_val, rv->v.avps.index);
1836                                 if (unlikely(r_avp==0)){
1837                                         *res=0;
1838                                 }
1839                         }
1840                         break;
1841                 case RV_PVAR:
1842                         /* PV_VAL_NULL or pv_get_spec_value error => undef */
1843                         if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
1844                                 *res=(cache->val_type!=RV_NONE);
1845                         }else{
1846                                 memset(&pval, 0, sizeof(pval));
1847                                 if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
1848                                         if ((pval.flags & PV_VAL_NULL) &&
1849                                                         ! (pval.flags & (PV_VAL_INT|PV_VAL_STR))){
1850                                                 *res=0;
1851                                         }
1852                                         pv_value_destroy(&pval);
1853                                 }else{
1854                                         *res=0; /* in case of error, consider it undef */
1855                                 }
1856                         }
1857                         break;
1858                 case RV_NONE:
1859                         *res=0;
1860                         break;
1861                 default:
1862                         break;
1863         }
1864         return 0;
1865 }
1866
1867
1868 /**
1869  * @brief Defined (integer) operation on rve
1870  * @param h run action context
1871  * @param msg SIP message
1872  * @param res - set to  1 defined, 0 not defined
1873  * @param rve rvalue expression
1874  * @return 0 on success, -1 on error
1875  */
1876 inline static int int_rve_defined(struct run_act_ctx* h,
1877                                                  struct sip_msg* msg, int* res,
1878                                                  struct rval_expr* rve)
1879 {
1880         /* only a rval can be undefined, any expression consisting on more
1881            then one rval => defined */
1882         if (likely(rve->op==RVE_RVAL_OP))
1883                 return rv_defined(h, msg, res, &rve->left.rval, 0);
1884         *res=1;
1885         return 0;
1886 }
1887
1888
1889
1890 /** evals an integer expr  to an int.
1891  * 
1892  *  *res=(int)eval(rve)
1893  *  @return 0 on success, \<0 on error
1894  */
1895 int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
1896                                                 int* res, struct rval_expr* rve)
1897 {
1898         int i1, i2, ret;
1899         struct rval_cache c1, c2;
1900         struct rvalue* rv1;
1901         struct rvalue* rv2;
1902         
1903         ret=-1;
1904         switch(rve->op){
1905                 case RVE_RVAL_OP:
1906                         ret=rval_get_int(h, msg, res,  &rve->left.rval, 0);
1907                         rval_get_int_handle_ret(ret, "rval expression conversion to int"
1908                                                                                 " failed", rve);
1909                         break;
1910                 case RVE_UMINUS_OP:
1911                 case RVE_BOOL_OP:
1912                 case RVE_LNOT_OP:
1913                 case RVE_BNOT_OP:
1914                         if (unlikely(
1915                                         (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
1916                                 break;
1917                         ret=int_intop1(res, rve->op, i1);
1918                         break;
1919                 case RVE_INT_OP:
1920                         ret=rval_expr_eval_int(h, msg, res, rve->left.rve);
1921                         break;
1922                 case RVE_MUL_OP:
1923                 case RVE_DIV_OP:
1924                 case RVE_MOD_OP:
1925                 case RVE_MINUS_OP:
1926                 case RVE_PLUS_OP:
1927                 case RVE_IPLUS_OP:
1928                 case RVE_BOR_OP:
1929                 case RVE_BAND_OP:
1930                 case RVE_BXOR_OP:
1931                 case RVE_BLSHIFT_OP:
1932                 case RVE_BRSHIFT_OP:
1933                 case RVE_GT_OP:
1934                 case RVE_GTE_OP:
1935                 case RVE_LT_OP:
1936                 case RVE_LTE_OP:
1937                 case RVE_IEQ_OP:
1938                 case RVE_IDIFF_OP:
1939                         if (unlikely(
1940                                         (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
1941                                 break;
1942                         if (unlikely(
1943                                         (ret=rval_expr_eval_int(h, msg, &i2, rve->right.rve)) <0) )
1944                                 break;
1945                         ret=int_intop2(res, rve->op, i1, i2);
1946                         break;
1947                 case RVE_LAND_OP:
1948                         if (unlikely(
1949                                         (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
1950                                 break;
1951                         if (i1==0){
1952                                 *res=0;
1953                         }else{
1954                                 if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
1955                                                                                 rve->right.rve)) <0) )
1956                                         break;
1957                                 *res=i1 && i2;
1958                         }
1959                         ret=0;
1960                         break;
1961                 case RVE_LOR_OP:
1962                         if (unlikely(
1963                                         (ret=rval_expr_eval_int(h, msg, &i1, rve->left.rve)) <0) )
1964                                 break;
1965                         if (i1){
1966                                 *res=1;
1967                         }else{
1968                                 if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
1969                                                                                 rve->right.rve)) <0) )
1970                                         break;
1971                                 *res=i1 || i2;
1972                         }
1973                         ret=0;
1974                         break;
1975                 case RVE_EQ_OP:
1976                 case RVE_DIFF_OP:
1977                         /* if left is string, eval left & right as string and
1978                          *   use string diff.
1979                          * if left is int eval as int using int diff
1980                          * if left is undef, look at right and convert to right type
1981                          */
1982                         rval_cache_init(&c1);
1983                         if (unlikely( (ret=rval_expr_eval_rvint(h, msg, &rv1, &i1,
1984                                                                                                         rve->left.rve, &c1))<0)){
1985                                 /* error */
1986                                 rval_cache_clean(&c1);
1987                                 break;
1988                         }
1989                         if (likely(rv1==0)){
1990                                 /* int */
1991                                 rval_cache_clean(&c1);
1992                                 if (unlikely( (ret=rval_expr_eval_int(h, msg, &i2,
1993                                                                                                                 rve->right.rve)) <0) )
1994                                         break;  /* error */
1995                                 ret=int_intop2(res, rve->op, i1, i2);
1996                         }else{
1997                                 /* not int => str or undef */
1998                                 /* check for undefined left operand */
1999                                 if (unlikely( c1.cache_type!=RV_CACHE_EMPTY &&
2000                                                                 c1.val_type==RV_NONE)){
2001 #ifdef UNDEF_EQ_ALWAYS_FALSE
2002                                         /* undef == something  always false
2003                                            undef != something  always true*/
2004                                         ret=(rve->op==RVE_DIFF_OP);
2005 #elif defined UNDEF_EQ_UNDEF_TRUE
2006                                         /* undef == something defined always false
2007                                            undef == undef true */
2008                                         if (int_rve_defined(h, msg, &i2, rve->right.rve)<0){
2009                                                 /* error */
2010                                                 rval_cache_clean(&c1);
2011                                                 rval_destroy(rv1);
2012                                                 break;
2013                                         }
2014                                         ret=(!i2) ^ (rve->op==RVE_DIFF_OP);
2015 #else  /* ! UNDEF_EQ_* */
2016                                         /*  undef == val
2017                                          *  => convert to (type_of(val)) (undef) == val */
2018                                         rval_cache_init(&c2);
2019                                         if (unlikely( (ret=rval_expr_eval_rvint(h, msg, &rv2, &i2,
2020                                                                                                         rve->right.rve, &c2))<0)){
2021                                                 /* error */
2022                                                 rval_cache_clean(&c1);
2023                                                 rval_cache_clean(&c2);
2024                                                 rval_destroy(rv1);
2025                                                 break;
2026                                         }
2027                                         if (rv2==0){
2028                                                 /* int */
2029                                                 ret=int_intop2(res, rve->op, 0 /* undef */, i2);
2030                                         }else{
2031                                                 /* str or undef */
2032                                                 ret=rval_str_lop2(h, msg, res, rve->op, rv1, &c1,
2033                                                                                         rv2, &c2);
2034                                                 rval_cache_clean(&c2);
2035                                                 rval_destroy(rv2);
2036                                         }
2037 #endif /* UNDEF_EQ_* */
2038                                         rval_cache_clean(&c1);
2039                                         rval_destroy(rv1);
2040                                 }else{
2041                                         /* left value == defined and != int => str
2042                                          * => lval == (str) val */
2043                                         if (unlikely((rv2=rval_expr_eval(h, msg,
2044                                                                                                                 rve->right.rve))==0)){
2045                                                 /* error */
2046                                                 rval_destroy(rv1);
2047                                                 rval_cache_clean(&c1);
2048                                                 break;
2049                                         }
2050                                         ret=rval_str_lop2(h, msg, res, rve->op, rv1, &c1, rv2, 0);
2051                                         rval_cache_clean(&c1);
2052                                         rval_destroy(rv1);
2053                                         rval_destroy(rv2);
2054                                 }
2055                         }
2056                         break;
2057                 case RVE_CONCAT_OP:
2058                         /* eval expression => string */
2059                         if (unlikely((rv1=rval_expr_eval(h, msg, rve))==0)){
2060                                 ret=-1;
2061                                 break;
2062                         }
2063                         /* convert to int */
2064                         ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
2065                         rval_get_int_handle_ret(ret, "rval expression conversion to int"
2066                                                                                 " failed", rve);
2067                         rval_destroy(rv1);
2068                         break;
2069                 case RVE_STR_OP:
2070                         /* (str)expr => eval expression */
2071                         rval_cache_init(&c1);
2072                         if (unlikely((ret=rval_expr_eval_rvint(h, msg, &rv1, res,
2073                                                                                                         rve->left.rve, &c1))<0)){
2074                                 /* error */
2075                                 rval_cache_clean(&c1);
2076                                 break;
2077                         }
2078                         if (unlikely(rv1)){
2079                                 /* expr evaluated to string => (int)(str)v == (int)v */
2080                                 ret=rval_get_int(h, msg, res, rv1, &c1); /* convert to int */
2081                                 rval_get_int_handle_ret(ret, "rval expression conversion"
2082                                                                                                 " to int failed", rve);
2083                                 rval_destroy(rv1);
2084                                 rval_cache_clean(&c1);
2085                         } /* else (rv1==0)
2086                                  => expr evaluated to int => 
2087                                  return (int)(str)v == (int)v => do nothing */
2088                         break;
2089
2090 #if 0
2091                         /* same thing as above, but in a not optimized, easier to
2092                            understand way */
2093                         /* 1. (str) expr => eval expr */
2094                         if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
2095                                 ret=-1;
2096                                 break;
2097                         }
2098                         /* 2. convert to str and then convert to int
2099                            but since (int)(str)v == (int)v skip over (str)v */
2100                         ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
2101                         rval_destroy(rv1);
2102                         break;
2103 #endif
2104                 case RVE_DEFINED_OP:
2105                         ret=int_rve_defined(h, msg, res, rve->left.rve);
2106                         break;
2107                 case RVE_NOTDEFINED_OP:
2108                         ret=int_rve_defined(h, msg, res, rve->left.rve);
2109                         *res = !(*res);
2110                         break;
2111                 case RVE_STREQ_OP:
2112                 case RVE_STRDIFF_OP:
2113                 case RVE_MATCH_OP:
2114                         if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
2115                                 ret=-1;
2116                                 break;
2117                         }
2118                         if (unlikely((rv2=rval_expr_eval(h, msg, rve->right.rve))==0)){
2119                                 rval_destroy(rv1);
2120                                 ret=-1;
2121                                 break;
2122                         }
2123                         ret=rval_str_lop2(h, msg, res, rve->op, rv1, 0, rv2, 0);
2124                         rval_destroy(rv1);
2125                         rval_destroy(rv2);
2126                         break;
2127                 case RVE_STRLEN_OP:
2128                 case RVE_STREMPTY_OP:
2129                         if (unlikely((rv1=rval_expr_eval(h, msg, rve->left.rve))==0)){
2130                                         ret=-1;
2131                                         break;
2132                         }
2133                         ret=rval_int_strop1(h, msg, res, rve->op, rv1, 0);
2134                         rval_destroy(rv1);
2135                         break;
2136                 case RVE_NONE_OP:
2137                 /*default:*/
2138                         BUG("invalid rval int expression operation %d (%d,%d-%d,%d)\n",
2139                                         rve->op, rve->fpos.s_line, rve->fpos.s_col,
2140                                         rve->fpos.e_line, rve->fpos.e_col);
2141                         ret=-1;
2142         };
2143         return ret;
2144 }
2145
2146
2147
2148 /**
2149  * @brief Evals a rval expression into an int or another rv(str)
2150  * @warning rv result (rv_res) must be rval_destroy()'ed if non-null
2151  * (it might be a reference to another rval). The result can be
2152  * modified only if rv_chg_in_place() returns true.
2153  * @param h run action context
2154  * @param msg SIP message
2155  * @param res_rv pointer to rvalue result, if non-null it means the 
2156  * expression evaluated to a non-int (str), which will be stored here.
2157  * @param res_i pointer to int result, if res_rv==0 and the function
2158  * returns success => the result is an int which will be stored here.
2159  * @param rve expression that will be evaluated.
2160  * @param cache write-only value cache, it might be filled if non-null and
2161  * empty (rval_cache_init()). If non-null, it _must_ be rval_cache_clean()'ed
2162  * when done. 
2163  * @return 0 on success, -1 on error, sets *res_rv or *res_i.
2164  */
2165 int rval_expr_eval_rvint(                          struct run_act_ctx* h,
2166                                                                            struct sip_msg* msg,
2167                                                                            struct rvalue** res_rv,
2168                                                                            int* res_i,
2169                                                                            struct rval_expr* rve,
2170                                                                            struct rval_cache* cache
2171                                                                            )
2172 {
2173         struct rvalue* rv1;
2174         struct rvalue* rv2;
2175         struct rval_cache c1; /* local cache */
2176         int ret;
2177         int r, i, j;
2178         enum rval_type type;
2179         
2180         rv1=0;
2181         rv2=0;
2182         ret=-1;
2183         switch(rve->op){
2184                 case RVE_RVAL_OP:
2185                         rv1=&rve->left.rval;
2186                         rv_ref(rv1);
2187                         type=rval_get_btype(h, msg, rv1, cache);
2188                         if (type==RV_INT){
2189                                         r=rval_get_int(h, msg, res_i, rv1, cache);
2190                                         rval_get_int_handle_ret(r, "rval expression conversion"
2191                                                                                                 " to int failed", rve);
2192                                         *res_rv=0;
2193                                         ret=r; /* equiv. to if (r<0) goto error */
2194                         }else{
2195                                 /* RV_STR, RV_PVAR, RV_AVP a.s.o => return rv1 and the 
2196                                    cached resolved value in cache*/
2197                                         *res_rv=rv1;
2198                                         rv_ref(rv1);
2199                                         ret=0;
2200                         }
2201                         break;
2202                 case RVE_UMINUS_OP:
2203                 case RVE_BOOL_OP:
2204                 case RVE_LNOT_OP:
2205                 case RVE_BNOT_OP:
2206                 case RVE_MINUS_OP:
2207                 case RVE_MUL_OP:
2208                 case RVE_DIV_OP:
2209                 case RVE_MOD_OP:
2210                 case RVE_BOR_OP:
2211                 case RVE_BAND_OP:
2212                 case RVE_BXOR_OP:
2213                 case RVE_BLSHIFT_OP:
2214                 case RVE_BRSHIFT_OP:
2215                 case RVE_LAND_OP:
2216                 case RVE_LOR_OP:
2217                 case RVE_GT_OP:
2218                 case RVE_GTE_OP:
2219                 case RVE_LT_OP:
2220                 case RVE_LTE_OP:
2221                 case RVE_EQ_OP:
2222                 case RVE_DIFF_OP:
2223                 case RVE_IEQ_OP:
2224                 case RVE_IDIFF_OP:
2225                 case RVE_IPLUS_OP:
2226                 case RVE_STREQ_OP:
2227                 case RVE_STRDIFF_OP:
2228                 case RVE_MATCH_OP:
2229                 case RVE_STRLEN_OP:
2230                 case RVE_STREMPTY_OP:
2231                 case RVE_DEFINED_OP:
2232                 case RVE_NOTDEFINED_OP:
2233                 case RVE_INT_OP:
2234                         /* operator forces integer type */
2235                         ret=rval_expr_eval_int(h, msg, res_i, rve);
2236                         *res_rv=0;
2237                         break;
2238                 case RVE_PLUS_OP:
2239                         rval_cache_init(&c1);
2240                         r=rval_expr_eval_rvint(h, msg, &rv1, &i, rve->left.rve, &c1);
2241                         if (unlikely(r<0)){
2242                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2243                                                 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2244                                                 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col
2245                                         );
2246                                 rval_cache_clean(&c1);
2247                                 goto error;
2248                         }
2249                         if (rv1==0){
2250                                 if (unlikely((r=rval_expr_eval_int(h, msg, &j,
2251                                                                                                                 rve->right.rve))<0)){
2252                                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)"
2253                                                                 "\n", rve->right.rve->fpos.s_line,
2254                                                                 rve->right.rve->fpos.s_col,
2255                                                                 rve->right.rve->fpos.e_line,
2256                                                                 rve->right.rve->fpos.e_col);
2257                                                 rval_cache_clean(&c1);
2258                                                 goto error;
2259                                 }
2260                                 ret=int_intop2(res_i, rve->op, i, j);
2261                                 *res_rv=0;
2262                         }else{
2263                                 rv2=rval_expr_eval(h, msg, rve->right.rve);
2264                                 if (unlikely(rv2==0)){
2265                                         ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2266                                                                 rve->right.rve->fpos.s_line,
2267                                                                 rve->right.rve->fpos.s_col,
2268                                                                 rve->right.rve->fpos.e_line,
2269                                                                 rve->right.rve->fpos.e_col);
2270                                         rval_cache_clean(&c1);
2271                                         goto error;
2272                                 }
2273                                 *res_rv=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
2274                                 ret=-(*res_rv==0);
2275                         }
2276                         rval_cache_clean(&c1);
2277                         break;
2278                 case RVE_CONCAT_OP:
2279                 case RVE_STR_OP:
2280                         *res_rv=rval_expr_eval(h, msg, rve);
2281                         ret=-(*res_rv==0);
2282                         break;
2283                 case RVE_NONE_OP:
2284                 /*default:*/
2285                         BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
2286                                         rve->op, rve->fpos.s_line, rve->fpos.s_col,
2287                                         rve->fpos.e_line, rve->fpos.e_col);
2288                         goto error;
2289         };
2290         rval_destroy(rv1);
2291         rval_destroy(rv2);
2292         return ret;
2293 error:
2294         rval_destroy(rv1);
2295         rval_destroy(rv2);
2296         return -1;
2297 }
2298
2299
2300
2301 /**
2302  * @brief Evals a rval expression
2303  * @warning result must be rval_destroy()'ed if non-null (it might be
2304  * a reference to another rval). The result can be modified only
2305  * if rv_chg_in_place() returns true.
2306  * @param h run action context
2307  * @param msg SIP message
2308  * @param rve rvalue expression
2309  * @return rvalue on success, 0 on error
2310  */
2311 struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
2312                                                                 struct rval_expr* rve)
2313 {
2314         struct rvalue* rv1;
2315         struct rvalue* rv2;
2316         struct rvalue* ret;
2317         struct rval_cache c1;
2318         union rval_val v;
2319         int r, i, j;
2320         enum rval_type type;
2321         
2322         rv1=0;
2323         rv2=0;
2324         ret=0;
2325         switch(rve->op){
2326                 case RVE_RVAL_OP:
2327                         rv_ref(&rve->left.rval);
2328                         return &rve->left.rval;
2329                         break;
2330                 case RVE_UMINUS_OP:
2331                 case RVE_BOOL_OP:
2332                 case RVE_LNOT_OP:
2333                 case RVE_BNOT_OP:
2334                 case RVE_MINUS_OP:
2335                 case RVE_MUL_OP:
2336                 case RVE_DIV_OP:
2337                 case RVE_MOD_OP:
2338                 case RVE_BOR_OP:
2339                 case RVE_BAND_OP:
2340                 case RVE_BXOR_OP:
2341                 case RVE_BLSHIFT_OP:
2342                 case RVE_BRSHIFT_OP:
2343                 case RVE_LAND_OP:
2344                 case RVE_LOR_OP:
2345                 case RVE_GT_OP:
2346                 case RVE_GTE_OP:
2347                 case RVE_LT_OP:
2348                 case RVE_LTE_OP:
2349                 case RVE_EQ_OP:
2350                 case RVE_DIFF_OP:
2351                 case RVE_IEQ_OP:
2352                 case RVE_IDIFF_OP:
2353                 case RVE_IPLUS_OP:
2354                 case RVE_STREQ_OP:
2355                 case RVE_STRDIFF_OP:
2356                 case RVE_MATCH_OP:
2357                 case RVE_STRLEN_OP:
2358                 case RVE_STREMPTY_OP:
2359                 case RVE_DEFINED_OP:
2360                 case RVE_NOTDEFINED_OP:
2361                 case RVE_INT_OP:
2362                         /* operator forces integer type */
2363                         r=rval_expr_eval_int(h, msg, &i, rve);
2364                         if (likely(r==0)){
2365                                 v.l=i;
2366                                 ret=rval_new(RV_INT, &v, 0);
2367                                 if (unlikely(ret==0)){
2368                                         ERR("rv eval int expression: out of memory\n");
2369                                         goto error;
2370                                 }
2371                                 return ret;
2372                         }else{
2373                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2374                                                 rve->fpos.s_line, rve->fpos.s_col,
2375                                                 rve->fpos.e_line, rve->fpos.e_col);
2376                                 goto error;
2377                         }
2378                         break;
2379                 case RVE_PLUS_OP:
2380                         rv1=rval_expr_eval(h, msg, rve->left.rve);
2381                         if (unlikely(rv1==0)){
2382                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2383                                                 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2384                                                 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2385                                 goto error;
2386                         }
2387                         rval_cache_init(&c1);
2388                         type=rval_get_btype(h, msg, rv1, &c1);
2389                         switch(type){
2390                                 case RV_INT:
2391                                         r=rval_get_int(h, msg, &i, rv1, &c1);
2392                                         rval_get_int_handle_ret(r, "rval expression left side "
2393                                                                                                 "conversion to int failed",
2394                                                                                         rve);
2395                                         if (unlikely(r<0)){
2396                                                 rval_cache_clean(&c1);
2397                                                 goto error;
2398                                         }
2399                                         if (unlikely((r=rval_expr_eval_int(h, msg, &j,
2400                                                                                                                 rve->right.rve))<0)){
2401                                                 rval_cache_clean(&c1);
2402                                                 ERR("rval expression evaluation failed (%d,%d-%d,%d):"
2403                                                                 " could not evaluate right side to int\n",
2404                                                                 rve->fpos.s_line, rve->fpos.s_col,
2405                                                                 rve->fpos.e_line, rve->fpos.e_col);
2406                                                 goto error;
2407                                         }
2408                                         int_intop2(&r, rve->op, i, j);
2409                                         if (rv_chg_in_place(rv1)){
2410                                                 rv1->v.l=r;
2411                                                 ret=rv1;
2412                                                 rv_ref(ret);
2413                                         }else{
2414                                                 v.l=r;
2415                                                 ret=rval_new(RV_INT, &v, 0);
2416                                                 if (unlikely(ret==0)){
2417                                                         rval_cache_clean(&c1);
2418                                                         ERR("rv eval int expression: out of memory\n");
2419                                                         goto error;
2420                                                 }
2421                                         }
2422                                         break;
2423                                 case RV_STR:
2424                                 case RV_NONE:
2425                                         rv2=rval_expr_eval(h, msg, rve->right.rve);
2426                                         if (unlikely(rv2==0)){
2427                                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)"
2428                                                                 "\n", rve->right.rve->fpos.s_line,
2429                                                                 rve->right.rve->fpos.s_col,
2430                                                                 rve->right.rve->fpos.e_line,
2431                                                                 rve->right.rve->fpos.e_col);
2432                                                 rval_cache_clean(&c1);
2433                                                 goto error;
2434                                         }
2435                                         ret=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
2436                                         break;
2437                                 default:
2438                                         BUG("rv unsupported basic type %d (%d,%d-%d,%d)\n", type,
2439                                                         rve->fpos.s_line, rve->fpos.s_col,
2440                                                         rve->fpos.e_line, rve->fpos.e_col);
2441                         }
2442                         rval_cache_clean(&c1);
2443                         break;
2444                 case RVE_CONCAT_OP:
2445                         rv1=rval_expr_eval(h, msg, rve->left.rve);
2446                         if (unlikely(rv1==0)){
2447                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2448                                                 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2449                                                 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2450                                 goto error;
2451                         }
2452                         rv2=rval_expr_eval(h, msg, rve->right.rve);
2453                         if (unlikely(rv2==0)){
2454                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2455                                                 rve->right.rve->fpos.s_line,
2456                                                 rve->right.rve->fpos.s_col,
2457                                                 rve->right.rve->fpos.e_line,
2458                                                 rve->right.rve->fpos.e_col);
2459                                 goto error;
2460                         }
2461                         ret=rval_str_add2(h, msg, rv1, 0, rv2, 0);
2462                         break;
2463                 case RVE_STR_OP:
2464                         rv1=rval_expr_eval(h, msg, rve->left.rve);
2465                         if (unlikely(rv1==0)){
2466                                 ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
2467                                                 rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
2468                                                 rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
2469                                 goto error;
2470                         }
2471                         ret=rval_convert(h, msg, RV_STR, rv1, 0);
2472                         break;
2473                 case RVE_NONE_OP:
2474                 /*default:*/
2475                         BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
2476                                         rve->op, rve->fpos.s_line, rve->fpos.s_col,
2477                                         rve->fpos.e_line, rve->fpos.e_col);
2478                         goto error;
2479         };
2480         rval_destroy(rv1);
2481         rval_destroy(rv2);
2482         return ret;
2483 error:
2484         rval_destroy(rv1);
2485         rval_destroy(rv2);
2486         return 0;
2487 }
2488
2489
2490
2491 /** evals a rval expr and always returns a new rval.
2492  * like rval_expr_eval, but always returns a new rvalue (never a reference
2493  * to an exisiting one).
2494  * WARNING: result must be rval_destroy()'ed if non-null (it might be
2495  * a reference to another rval). The result can be modified only
2496  * if rv_chg_in_place() returns true.
2497  * @result rvalue on success, 0 on error
2498  */
2499 struct rvalue* rval_expr_eval_new(struct run_act_ctx* h, struct sip_msg* msg,
2500                                                                 struct rval_expr* rve)
2501 {
2502         struct rvalue* ret;
2503         struct rvalue* rv;
2504         
2505         ret=rval_expr_eval(h, msg, rve);
2506         if (ret && !rv_chg_in_place(ret)){
2507                 rv=ret;
2508                 /* create a new rv */
2509                 ret=rval_new(rv->type, &rv->v, 0);
2510                 rval_destroy(rv);
2511         }
2512         return ret;
2513 }
2514
2515
2516
2517 /** create a RVE_RVAL_OP rval_expr, containing a single rval of the given type.
2518  *
2519  * @param rv_type - rval type
2520  * @param val     - rval value
2521  * @param pos     - config position
2522  * @return new pkg_malloc'ed rval_expr or 0 on error.
2523  */
2524 struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val, 
2525                                                                         struct cfg_pos* pos)
2526 {
2527         struct rval_expr* rve;
2528         union rval_val v;
2529         str* s;
2530         int flags;
2531         
2532         rve=pkg_malloc(sizeof(*rve));
2533         if (rve==0) 
2534                 return 0;
2535         memset(rve, 0, sizeof(*rve));
2536         flags=0;
2537         switch(rv_type){
2538                 case RV_INT:
2539                         v.l=(long)val;
2540                         break;
2541                 case RV_STR:
2542                         s=(str*)val;
2543                         v.s.s=pkg_malloc(s->len+1 /*0*/);
2544                         if (v.s.s==0){
2545                                 pkg_free(rve);
2546                                 ERR("memory allocation failure\n");
2547                                 return 0;
2548                         }
2549                         v.s.len=s->len;
2550                         memcpy(v.s.s, s->s, s->len);
2551                         v.s.s[s->len]=0;
2552                         flags=RV_CNT_ALLOCED_F;
2553                         break;
2554                 case RV_AVP:
2555                         v.avps=*(avp_spec_t*)val;
2556                         break;
2557                 case RV_PVAR:
2558                         v.pvs=*(pv_spec_t*)val;
2559                         break;
2560                 case RV_SEL:
2561                         v.sel=*(select_t*)val;
2562                         break;
2563                 case RV_BEXPR:
2564                         v.bexpr=(struct expr*)val;
2565                         break;
2566                 case RV_ACTION_ST:
2567                         v.action=(struct action*)val;
2568                         break;
2569                 default:
2570                         BUG("unsupported rv type %d\n", rv_type);
2571                         pkg_free(rve);
2572                         return 0;
2573         }
2574         rval_init(&rve->left.rval, rv_type, &v, flags);
2575         rve->op=RVE_RVAL_OP;
2576         if (pos) rve->fpos=*pos;
2577         return rve;
2578 }
2579
2580
2581
2582 /**
2583  * @brief Create a unary op. rval_expr
2584  * ret= op rve1
2585  * @param op   - rval expr. unary operator
2586  * @param rve1 - rval expr. on which the operator will act.
2587  * @param pos configuration position
2588  * @return new pkg_malloc'ed rval_expr or 0 on error.
2589  */
2590 struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
2591                                                                 struct cfg_pos* pos)
2592 {
2593         struct rval_expr* ret;
2594         
2595         switch(op){
2596                 case RVE_UMINUS_OP:
2597                 case RVE_BOOL_OP:
2598                 case RVE_LNOT_OP:
2599                 case RVE_BNOT_OP:
2600                 case RVE_STRLEN_OP:
2601                 case RVE_STREMPTY_OP:
2602                 case RVE_DEFINED_OP:
2603                 case RVE_NOTDEFINED_OP:
2604                 case RVE_INT_OP:
2605                 case RVE_STR_OP:
2606                         break;
2607                 default:
2608                         BUG("unsupported unary operator %d\n", op);
2609                         return 0;
2610         }
2611         ret=pkg_malloc(sizeof(*ret));
2612         if (ret==0) 
2613                 return 0;
2614         memset(ret, 0, sizeof(*ret));
2615         ret->op=op;
2616         ret->left.rve=rve1;
2617         if (pos) ret->fpos=*pos;
2618         return ret;
2619 }
2620
2621
2622
2623 /**
2624  * @brief Create a rval_expr. from 2 other rval exprs, using op
2625  * ret = rve1 op rve2
2626  * @param op   - rval expr. operator
2627  * @param rve1 - rval expr. on which the operator will act.
2628  * @param rve2 - rval expr. on which the operator will act.
2629  * @param pos configuration position
2630  * @return new pkg_malloc'ed rval_expr or 0 on error.
2631  */
2632 struct rval_expr* mk_rval_expr2(enum rval_expr_op op, struct rval_expr* rve1,
2633                                                                                                           struct rval_expr* rve2,
2634                                                                                                           struct cfg_pos* pos)
2635 {
2636         struct rval_expr* ret;
2637         
2638         switch(op){
2639                 case RVE_MUL_OP:
2640                 case RVE_DIV_OP:
2641                 case RVE_MOD_OP:
2642                 case RVE_MINUS_OP:
2643                 case RVE_BOR_OP:
2644                 case RVE_BAND_OP:
2645                 case RVE_BXOR_OP:
2646                 case RVE_BLSHIFT_OP:
2647                 case RVE_BRSHIFT_OP:
2648                 case RVE_LAND_OP:
2649                 case RVE_LOR_OP:
2650                 case RVE_GT_OP:
2651                 case RVE_GTE_OP:
2652                 case RVE_LT_OP:
2653                 case RVE_LTE_OP:
2654                 case RVE_PLUS_OP:
2655                 case RVE_IPLUS_OP:
2656                 case RVE_EQ_OP:
2657                 case RVE_DIFF_OP:
2658                 case RVE_IEQ_OP:
2659                 case RVE_IDIFF_OP:
2660                 case RVE_STREQ_OP:
2661                 case RVE_STRDIFF_OP:
2662                 case RVE_MATCH_OP:
2663                 case RVE_CONCAT_OP:
2664                         break;
2665                 default:
2666                         BUG("unsupported operator %d\n", op);
2667                         return 0;
2668         }
2669         ret=pkg_malloc(sizeof(*ret));
2670         if (ret==0) 
2671                 return 0;
2672         memset(ret, 0, sizeof(*ret));
2673         ret->op=op;
2674         ret->left.rve=rve1;
2675         ret->right.rve=rve2;
2676         if (pos) ret->fpos=*pos;
2677         return ret;
2678 }
2679
2680
2681
2682 /** returns true if the operator is associative. */
2683 static int rve_op_is_assoc(enum rval_expr_op op)
2684 {
2685         switch(op){
2686                 case RVE_NONE_OP:
2687                 case RVE_RVAL_OP:
2688                 case RVE_UMINUS_OP:
2689                 case RVE_BOOL_OP:
2690                 case RVE_LNOT_OP:
2691                 case RVE_BNOT_OP:
2692                 case RVE_STRLEN_OP:
2693                 case RVE_STREMPTY_OP:
2694                 case RVE_DEFINED_OP:
2695                 case RVE_NOTDEFINED_OP:
2696                 case RVE_INT_OP:
2697                 case RVE_STR_OP:
2698                         /* one operand expression => cannot be assoc. */
2699                         return 0;
2700                 case RVE_DIV_OP:
2701                 case RVE_MOD_OP:
2702                 case RVE_MINUS_OP:
2703                 case RVE_BLSHIFT_OP:
2704                 case RVE_BRSHIFT_OP:
2705                         return 0;
2706                 case RVE_PLUS_OP:
2707                         /* the generic plus is not assoc, e.g.
2708                            "a" + 1 + "2" => "a12" in one case and "a3" in the other */
2709                         return 0;
2710                 case RVE_IPLUS_OP:
2711                 case RVE_CONCAT_OP:
2712                 case RVE_MUL_OP:
2713                 case RVE_BAND_OP:
2714                 case RVE_BOR_OP:
2715                 case RVE_BXOR_OP:
2716                         return 1;
2717                 case RVE_LAND_OP:
2718                 case RVE_LOR_OP:
2719                         return 1;
2720                 case RVE_GT_OP:
2721                 case RVE_GTE_OP:
2722                 case RVE_LT_OP:
2723                 case RVE_LTE_OP:
2724                 case RVE_EQ_OP:
2725                 case RVE_DIFF_OP:
2726                 case RVE_IEQ_OP:
2727                 case RVE_IDIFF_OP:
2728                 case RVE_STREQ_OP:
2729                 case RVE_STRDIFF_OP:
2730                 case RVE_MATCH_OP:
2731                         return 0;
2732         }
2733         return 0;
2734 }
2735
2736
2737
2738 /** returns true if the operator is commutative. */
2739 static int rve_op_is_commutative(enum rval_expr_op op)
2740 {
2741         switch(op){
2742                 case RVE_NONE_OP:
2743                 case RVE_RVAL_OP:
2744                 case RVE_UMINUS_OP:
2745                 case RVE_BOOL_OP:
2746                 case RVE_LNOT_OP:
2747                 case RVE_BNOT_OP:
2748                 case RVE_STRLEN_OP:
2749                 case RVE_STREMPTY_OP:
2750                 case RVE_DEFINED_OP:
2751                 case RVE_NOTDEFINED_OP:
2752                 case RVE_INT_OP:
2753                 case RVE_STR_OP:
2754                         /* one operand expression => cannot be commut. */
2755                         return 0;
2756                 case RVE_DIV_OP:
2757                 case RVE_MOD_OP:
2758                 case RVE_MINUS_OP:
2759                 case RVE_BLSHIFT_OP:
2760                 case RVE_BRSHIFT_OP:
2761                         return 0;
2762                 case RVE_PLUS_OP:
2763                         /* non commut. when diff. type 
2764                            (e.g 1 + "2" != "2" + 1 ) => non commut. in general
2765                            (specific same type versions are covered by IPLUS & CONCAT) */
2766                         return 0;
2767                 case RVE_IPLUS_OP:
2768                 case RVE_MUL_OP:
2769                 case RVE_BAND_OP:
2770                 case RVE_BOR_OP:
2771                 case RVE_BXOR_OP:
2772                 case RVE_LAND_OP:
2773                 case RVE_LOR_OP:
2774                 case RVE_IEQ_OP:
2775                 case RVE_IDIFF_OP:
2776                 case RVE_STREQ_OP:
2777                 case RVE_STRDIFF_OP:
2778                         return 1;
2779                 case RVE_GT_OP:
2780                 case RVE_GTE_OP:
2781                 case RVE_LT_OP:
2782                 case RVE_LTE_OP:
2783                 case RVE_CONCAT_OP:
2784                 case RVE_MATCH_OP:
2785                         return 0;
2786                 case RVE_DIFF_OP:
2787                 case RVE_EQ_OP:
2788                         /* non. commut. in general, only for same type e.g.:
2789                            "" == 0  diff. 0 == "" ( "" == "0" and 0 == 0)
2790                            same type versions are covered by IEQ, IDIFF, STREQ, STRDIFF
2791                          */
2792                         return 0 /* asymmetrical undef handling */;
2793         }
2794         return 0;
2795 }
2796
2797
2798 #if 0
2799 /** returns true if the rval expr can be optimized to an int.
2800  *  (if left & right are leafs (RVE_RVAL_OP) and both of them are
2801  *   ints return true, else false)
2802  *  @return 0 or 1
2803  */
2804 static int rve_can_optimize_int(struct rval_expr* rve)
2805 {
2806         if (scr_opt_lev<1)
2807                 return 0;
2808         if (rve->op == RVE_RVAL_OP)
2809                 return 0;
2810         if (rve->left.rve->op != RVE_RVAL_OP)
2811                 return 0;
2812         if (rve->left.rve->left.rval.type!=RV_INT)
2813                 return 0;
2814         if (rve->right.rve){
2815                 if  (rve->right.rve->op != RVE_RVAL_OP)
2816                         return 0;
2817                 if (rve->right.rve->left.rval.type!=RV_INT)
2818                         return 0;
2819         }
2820         DBG("rve_can_optimize_int: left %d, right %d\n", 
2821                         rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
2822         return 1;
2823 }
2824
2825
2826
2827 /** returns true if the rval expr can be optimized to a str.
2828  *  (if left & right are leafs (RVE_RVAL_OP) and both of them are
2829  *   str or left is str and right is int return true, else false)
2830  *  @return 0 or 1
2831  */
2832 static int rve_can_optimize_str(struct rval_expr* rve)
2833 {
2834         if (scr_opt_lev<1)
2835                 return 0;
2836         if (rve->op == RVE_RVAL_OP)
2837                 return 0;
2838         DBG("rve_can_optimize_str: left %d, right %d\n", 
2839                         rve->left.rve->op, rve->right.rve?rve->right.rve->op:0);
2840         if (rve->left.rve->op != RVE_RVAL_OP)
2841                 return 0;
2842         if (rve->left.rve->left.rval.type!=RV_STR)
2843                 return 0;
2844         if (rve->right.rve){
2845                 if  (rve->right.rve->op != RVE_RVAL_OP)
2846                         return 0;
2847                 if ((rve->right.rve->left.rval.type!=RV_STR) && 
2848                                 (rve->right.rve->left.rval.type!=RV_INT))
2849                         return 0;
2850         }
2851         return 1;
2852 }
2853 #endif
2854
2855
2856
2857 static int fix_rval(struct rvalue* rv)
2858 {
2859         DBG("RV fixing type %d\n", rv->type);
2860         switch(rv->type){
2861                 case RV_INT:
2862                         /*nothing to do*/
2863                         DBG("RV is int: %d\n", (int)rv->v.l);
2864                         return 0;
2865                 case RV_STR:
2866                         /*nothing to do*/
2867                         DBG("RV is str: \"%s\"\n", rv->v.s.s);
2868                         return 0;
2869                 case RV_BEXPR:
2870                         return fix_expr(rv->v.bexpr);
2871                 case RV_ACTION_ST:
2872                         return fix_actions(rv->v.action);
2873                 case RV_SEL:
2874                         if (resolve_select(&rv->v.sel)<0){
2875                                 ERR("Unable to resolve select\n");
2876                                 print_select(&rv->v.sel);
2877                         }
2878                         return 0;
2879                 case RV_AVP:
2880                         /* nothing to do, resolved at runtime */
2881                         return 0;
2882                 case RV_PVAR:
2883                         /* nothing to do, resolved at parsing time */
2884                         return 0;
2885                 case RV_NONE:
2886                         BUG("uninitialized rvalue\n");
2887                         return -1;
2888         }
2889         BUG("unknown rvalue type %d\n", rv->type);
2890         return -1;
2891 }
2892
2893
2894
2895 /**
2896  * @brief Helper function: replace a rve (in-place) with a constant rval_val
2897  * @warning since it replaces in-place, one should make sure that if
2898  * rve is in fact a rval (rve->op==RVE_RVAL_OP), no reference is kept
2899  * to the rval!
2900  * @param rve expression to be replaced (in-place)
2901  * @param type rvalue type
2902  * @param v pointer to a rval_val union containing the replacement value.
2903  * @param flags value flags (how it was alloc'ed, e.g.: RV_CNT_ALLOCED_F)
2904  * @return 0 on success, -1 on error
2905  */
2906 static int rve_replace_with_val(struct rval_expr* rve, enum rval_type type,
2907                                                                 union rval_val* v, int flags)
2908 {
2909         int refcnt;
2910         
2911         refcnt=1; /* replaced-in-place rval refcnt */
2912         if (rve->op!=RVE_RVAL_OP){
2913                 rve_destroy(rve->left.rve);
2914                 if (rve_op_unary(rve->op)==0)
2915                         rve_destroy(rve->right.rve);
2916         }else{
2917                 if (rve->left.rval.refcnt!=1){
2918                         BUG("trying to replace a referenced rval! (refcnt=%d)\n",
2919                                         rve->left.rval.refcnt);
2920                         /* try to recover */
2921                         refcnt=rve->left.rval.refcnt;
2922                         abort(); /* find bugs quicker -- andrei */
2923                 }
2924                 rval_destroy(&rve->left.rval);
2925         }
2926         rval_init(&rve->left.rval, type, v, flags);
2927         rve->left.rval.refcnt=refcnt;
2928         rval_init(&rve->right.rval, RV_NONE, 0, 0);
2929         rve->op=RVE_RVAL_OP;
2930         return 0;
2931 }
2932
2933
2934
2935 /** helper function: replace a rve (in-place) with a constant rvalue.
2936  * @param rve - expression to be replaced (in-place)
2937  * @param rv   - pointer to the replacement _constant_ rvalue structure
2938  * @return 0 on success, -1 on error */
2939 static int rve_replace_with_ct_rv(struct rval_expr* rve, struct rvalue* rv)
2940 {
2941         enum rval_type type;
2942         int flags;
2943         int i;
2944         union rval_val v;
2945         
2946         type=rv->type;
2947         flags=0;
2948         if (rv->type==RV_INT){
2949                 if (rval_get_int(0, 0, &i, rv, 0)!=0){
2950                         BUG("unexpected int evaluation failure (%d,%d-%d,%d)\n",
2951                                         rve->fpos.s_line, rve->fpos.s_col,
2952                                         rve->fpos.e_line, rve->fpos.e_col);
2953                         return -1;
2954                 }
2955                 v.l=i;
2956         }else if(rv->type==RV_STR){
2957                 if (rval_get_str(0, 0, &v.s, rv, 0)<0){
2958                         BUG("unexpected str evaluation failure(%d,%d-%d,%d)\n",
2959                                         rve->fpos.s_line, rve->fpos.s_col,
2960                                         rve->fpos.e_line, rve->fpos.e_col);
2961                         return -1;
2962                 }
2963                 flags|=RV_CNT_ALLOCED_F;
2964         }else{
2965                 BUG("unknown constant expression type %d (%d,%d-%d,%d)\n", rv->type,
2966                                 rve->fpos.s_line, rve->fpos.s_col,
2967                                 rve->fpos.e_line, rve->fpos.e_col);
2968                 return -1;
2969         }
2970         return rve_replace_with_val(rve, type, &v, flags);
2971 }
2972
2973
2974
2975 /** try to replace the right side of the rve with a compiled regex.
2976   * @return 0 on success and -1 on error.
2977  */
2978 static int fix_match_rve(struct rval_expr* rve)
2979 {
2980         struct rvalue* rv;
2981         regex_t* re;
2982         union rval_val v;
2983         int flags;
2984         int ret;
2985
2986         rv=0;
2987         v.s.s=0;
2988         v.re.regex=0;
2989         /* normal fix-up for the  left side */
2990         ret=fix_rval_expr((void*)rve->left.rve);
2991         if (ret<0) return ret;
2992         
2993         /* fixup the right side (RE) */
2994         if (rve_is_constant(rve->right.rve)){
2995                 if ((rve_guess_type(rve->right.rve)!=RV_STR)){
2996                         ERR("fixup failure(%d,%d-%d,%d): left side of  =~ is not string"
2997                                         " (%d,%d)\n",   rve->fpos.s_line, rve->fpos.s_col,
2998                                                                         rve->fpos.e_line, rve->fpos.e_col,
2999                                                                         rve->right.rve->fpos.s_line,
3000                                                                         rve->right.rve->fpos.s_col);
3001                         goto error;
3002                 }
3003                 if ((rv=rval_expr_eval(0, 0, rve->right.rve))==0){
3004                         ERR("fixup failure(%d,%d-%d,%d):  bad RE expression\n",
3005                                         rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
3006                                         rve->right.rve->fpos.e_line, rve->right.rve->fpos.e_col);
3007                         goto error;
3008                 }
3009                 if (rval_get_str(0, 0, &v.s, rv, 0)<0){
3010                         BUG("fixup unexpected failure (%d,%d-%d,%d)\n",
3011                                         rve->fpos.s_line, rve->fpos.s_col,
3012                                         rve->fpos.e_line, rve->fpos.e_col);
3013                         goto error;
3014                 }
3015                 /* we have the str, we don't need the rv anymore */
3016                 rval_destroy(rv);
3017                 rv=0;
3018                 re=pkg_malloc(sizeof(*re));
3019                 if (re==0){
3020                         ERR("out of memory\n");
3021                         goto error;
3022                 }
3023                 /* same flags as for expr. =~ (fix_expr()) */
3024                 if (regcomp(re, v.s.s, REG_EXTENDED|REG_NOSUB|REG_ICASE)){
3025                         pkg_free(re);
3026                         ERR("Bad regular expression \"%s\"(%d,%d-%d,%d)\n", v.s.s,
3027                                         rve->right.rve->fpos.s_line, rve->right.rve->fpos.s_col,
3028                                         rve->right.rve->fpos.e_line, rve->right.rve->fpos.e_col);
3029                         goto error;
3030                 }
3031                 v.re.regex=re;
3032                 flags=RV_RE_F|RV_RE_ALLOCED_F|RV_CNT_ALLOCED_F;
3033                 if (rve_replace_with_val(rve->right.rve, RV_STR, &v, flags)<0)
3034                         goto error;
3035         }else{
3036                 /* right side is not constant => normal fixup */
3037                 return fix_rval_expr((void*)rve->right.rve);
3038         }
3039         return 0;
3040 error:
3041         if (rv) rval_destroy(rv);
3042         if (v.s.s) pkg_free(v.s.s);
3043         if (v.re.regex){
3044                 regfree(v.re.regex);
3045                 pkg_free(v.re.regex);
3046         }
3047         return -1;
3048 }
3049
3050
3051
3052 /** optimize op($v, 0) or op($v, 1).
3053  * Note: internal use only from rve_optimize
3054  * It should be called after ct optimization, for non-contant
3055  *  expressions (the left or right side is not constant).
3056  * @return 1 on success (rve was changed), 0 on failure and -1 on error
3057  */
3058 static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
3059 {
3060         struct rvalue* rv;
3061         struct rval_expr* ct_rve;
3062         struct rval_expr* v_rve;
3063         int i;
3064         int ret;
3065         enum rval_expr_op op;
3066         struct cfg_pos pos;
3067         int right; /* debugging msg */
3068         int dbg; /* debugging msg on/off */
3069
3070 /* helper macro: replace in-place a <ctype> type rve with v (another rve).
3071  * if type_of(v)== <ctype> => rve:=*v (copy v contents into rve and free v)
3072  * else if type_of(v)!=<ctype> => rve:= (ctype) v (casts v to <ctype>)
3073  * Uses pos.
3074  * ctype can be INT or STR
3075  * WARNING: - v might be pkg_free()'d
3076  *          - rve members _are_ _not_ freed or destroyed
3077  */
3078 #define replace_rve_type_cast(e, v, ctype) \
3079         do{\
3080                 if ( rve_guess_type((v)) == RV_##ctype ){\
3081                         /* if type_of($v)==int we don't need to add an \
3082                            int cast operator => replace with v */\
3083                         pos=(e)->fpos; \
3084                         *(e)=*(v); /* replace e with v (in-place) */ \
3085                         (e)->fpos=pos; \
3086                         pkg_free((v)); /* rve_destroy(v_rve) would free everything*/ \
3087                 }else{\
3088                         /* unknown type or str => (int) $v */ \
3089                         (e)->op=RVE_##ctype##_OP; \
3090                         (e)->left.rve=(v); \
3091                         (e)->right.rve=0; \
3092                 }\
3093         }while(0)
3094         
3095 /* helper macro: replace in-place an int type rve with v (another rve).*/
3096 #define replace_int_rve(e, v) replace_rve_type_cast(e, v, INT)
3097 /* helper macro: replace in-place a str type rve with v (another rve).*/
3098 #define replace_str_rve(e, v) replace_rve_type_cast(e, v, STR)
3099         
3100         
3101         rv=0;
3102         ret=0;
3103         right=0;
3104         dbg=1;
3105         
3106         if (rve_is_constant(rve->right.rve)){
3107                 ct_rve=rve->right.rve;
3108                 v_rve=rve->left.rve;
3109                 right=1;
3110         }else if (rve_is_constant(rve->left.rve)){
3111                 ct_rve=rve->left.rve;
3112                 v_rve=rve->right.rve;
3113                 right=0;
3114         }else
3115                 return 0; /* op($v, $w) */
3116         
3117         /* rval_expr_eval_new() instead of rval_expr_eval() to avoid
3118            referencing a ct_rve->left.rval if ct_rve is a rval, which
3119            would prevent rve_destroy(ct_rve) from working */
3120         if ((rv=rval_expr_eval_new(0, 0, ct_rve))==0){
3121                 ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
3122                                 ct_rve->fpos.s_line, ct_rve->fpos.s_col,
3123                                 ct_rve->fpos.e_line, ct_rve->fpos.e_col);
3124                 goto error;
3125         }
3126         op=rve->op;
3127         if (rv->type==RV_INT){
3128                 i=rv->v.l;
3129                 switch(op){
3130                         case RVE_MUL_OP:
3131                                 if (i==0){
3132                                         /* $v *  0 -> 0
3133                                          *  0 * $v -> 0 */
3134                                         if (rve_replace_with_ct_rv(rve, rv)<0)
3135                                                 goto error;
3136                                         ret=1;
3137                                 }else if (i==1){
3138                                         /* $v *  1 -> (int)$v
3139                                          *  1 * $v -> (int)$v */
3140                                         rve_destroy(ct_rve);
3141                                         replace_int_rve(rve, v_rve);
3142                                         ret=1;
3143                                 }
3144                                 break;
3145                         case RVE_DIV_OP:
3146                                 if (i==0){
3147                                         if (ct_rve==rve->left.rve){
3148                                                 /* 0 / $v -> 0 */
3149                                                 if (rve_replace_with_ct_rv(rve, rv)<0)
3150                                                         goto error;
3151                                                 ret=1;
3152                                         }else{
3153                                                 /* $v / 0 */
3154                                                 ERR("RVE divide by 0 at %d,%d\n",
3155                                                                 ct_rve->fpos.s_line, ct_rve->fpos.s_col);
3156                                         }
3157                                 }else if (i==1){
3158                                         if (ct_rve==rve->right.rve){
3159                                                 /* $v / 1 -> (int)$v */
3160                                                 rve_destroy(ct_rve);
3161                                                 replace_int_rve(rve, v_rve);
3162                                                 ret=1;
3163                                         }
3164                                 }
3165                                 break;
3166                         case RVE_MOD_OP:
3167                                 if (i==0){
3168                                         if (ct_rve==rve->left.rve){
3169                                                 /* 0 % $v -> 0 */
3170                                                 if (rve_replace_with_ct_rv(rve, rv)<0)
3171                                                         goto error;
3172                                                 ret=1;
3173                                         }else{
3174                                                 /* $v % 0 */
3175                                                 ERR("RVE modulo by 0 at %d,%d\n",
3176                                                                 ct_rve->fpos.s_line, ct_rve->fpos.s_col);
3177                                         }
3178                                 }
3179                                 /* $v % 1 -> 0 ? */
3180                                 break;
3181                         case RVE_MINUS_OP:
3182                                 if (i==0){
3183                                         if (ct_rve==rve->right.rve){
3184                                                 /* $v - 0 -> $v */
3185                                                 rve_destroy(ct_rve);
3186                                                 replace_int_rve(rve, v_rve);
3187                                                 ret=1;
3188                                         }
3189                                         /* ? 0 - $v -> -($v)  ? */
3190                                 }
3191                                 break;
3192                         case RVE_BAND_OP:
3193                                 if (i==0){
3194                                         /* $v &  0 -> 0
3195                                          *  0 & $v -> 0 */
3196                                         if (rve_replace_with_ct_rv(rve, rv)<0)
3197                                                 goto error;
3198                                         ret=1;
3199                                 }
3200                                 /* no 0xffffff optimization for now (haven't decided on
3201                                    the number of bits ) */
3202                                 break;
3203                         case RVE_BOR_OP:
3204                                 if (i==0){
3205                                         /* $v |  0 -> (int)$v
3206                                          *  0 | $v -> (int)$v */
3207                                         rve_destroy(ct_rve);
3208                                         replace_int_rve(rve, v_rve);
3209                                         ret=1;
3210                                 }
3211                                 break;
3212                         case RVE_LAND_OP:
3213                                 if (i==0){
3214                                         /* $v &&  0 -> 0
3215                                          *  0 && $v -> 0 */
3216                                         if (rve_replace_with_ct_rv(rve, rv)<0)
3217                                                 goto error;
3218                                         ret=1;
3219                                 }else if (i==1){
3220                                         /* $v &&  1 -> (int)$v
3221                                          *  1 && $v -> (int)$v */
3222                                         rve_destroy(ct_rve);
3223                                         replace_int_rve(rve, v_rve);
3224                                         ret=1;
3225                                 }
3226                                 break;
3227                         case RVE_LOR_OP:
3228                                 if (i==1){
3229                                         /* $v ||  1 -> 1
3230                                          *  1 || $v -> 1 */
3231                                         if (rve_replace_with_ct_rv(rve, rv)<0)
3232                                                 goto error;
3233                                         ret=1;
3234                                 }else if (i==0){
3235                                         /* $v ||  0 -> (int)$v
3236                                          *  0 && $v -> (int)$v */
3237                                         rve_destroy(ct_rve);
3238                                         replace_int_rve(rve, v_rve);
3239                                         ret=1;
3240                                 }
3241                                 break;
3242                         case RVE_PLUS_OP:
3243                         case RVE_IPLUS_OP:
3244                                 /* we must make sure that this is an int PLUS
3245                                    (because "foo"+0 is valid => "foo0") =>
3246                                    check if it's an IPLUS or the result is an integer
3247                                    (which generally means unoptimized <int> + <something>).
3248                                  */
3249                                 if ((i==0) && ((op==RVE_IPLUS_OP) || (rve_type==RV_INT))){
3250                                         /* $v +  0 -> (int)$v
3251                                          *  0 + $v -> (int)$v */
3252                                         rve_destroy(ct_rve);
3253                                         replace_int_rve(rve, v_rve);
3254                                         ret=1;
3255                                 }
3256                                 break;
3257                         default:
3258                                 /* do nothing */
3259                                 break;
3260                 }
3261                 /* debugging messages */
3262                 if (ret==1 && dbg){
3263                         if (right){
3264                                 if (rve->op==RVE_RVAL_OP){
3265                                         if (rve->left.rval.type==RV_INT)
3266                                                 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3267                                                                 " op%d($v, %d) -> %d\n", 
3268                                                                 rve->fpos.s_line, rve->fpos.s_col,
3269                                                                 rve->fpos.e_line, rve->fpos.e_col,
3270                                                                 op, i, (int)rve->left.rval.v.l);
3271                                         else
3272                                                 DBG("FIXUP RVE: (%d,%d-%d,%d) optimized"
3273  &n