0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 
0017 
0018 
0019 
0020 
0021 
0022 
0023 
0024 
0025 
0026 
0027 
0028 
0029 
0030 
0031 
0032 
0033 
0034 
0035 
0036 
0037 
0038 #ifndef _GNU_SOURCE
0039 #define _GNU_SOURCE
0040 #endif
0041 
0042 #include <stdio.h>
0043 #include <stdlib.h>
0044 #include <stdarg.h>
0045 #include <string.h>
0046 #include <math.h>
0047 #include "expr.h"
0048 #include "ndebug.h"
0049 #include "ferror.h"
0050 #include <ubf.h>
0051 #include <ubf_int.h>
0052 #include <errno.h>
0053 #include <sys/types.h>
0054 #include <regex.h>
0055 #include <expr.tab.h>
0056 #include <exhash.h>
0057 
0058 
0059 extern void yy_scan_string (char *yy_str  );
0060 extern void _free_parser(void);
0061 extern int yyparse (void);
0062 
0063 #define FREE_UP_UB_BUF(v) \
0064 if (v->dyn_alloc && NULL!=v->strval)\
0065 {\
0066 free(v->strval);\
0067 v->strval=NULL;\
0068 v->dyn_alloc=0;\
0069 }
0070 
0071 #ifdef UBF_DEBUG
0072 #define DUMP_VALUE_BLOCK(TEXT, V) if (EXSUCCEED==ret) dump_val(TEXT, V)
0073 #else
0074 #define DUMP_VALUE_BLOCK(TEXT, V) {}
0075 #endif
0076 
0077 
0078 #define IS_FLOAT_0(X) (X < 0.000000001 && X > -0.000000001)
0079 
0080 
0081 
0082 
0083 
0084 
0085 __thread struct ast *G_p_root_node=NULL;
0086 __thread int G_node_count=0;
0087 __thread int G_error;
0088 static __thread struct list_node *M_cur_mem;
0089 static __thread struct list_node *M_first_mem;
0090 
0091 
0092 func_hash_t *M_func_hash = NULL;    
0093 
0094 
0095 
0096 
0097 
0098 char *M_nodetypes[] =
0099 {
0100     "[OR    (0) ]",
0101     "[AND   (1) ]",
0102     "[XOR   (2) ]",
0103     "[EQOP  (3) ]",
0104     "[RELOP (4) ]",
0105     "[ADDOP (5) ]",
0106     "[MULTOP(6) ]",
0107     "[UNARY (7) ]",
0108     "[FLD   (8) ]",
0109     "[STR   (9) ]",
0110     "[FLOAT (10)]",
0111     "[LONG  (11)]",
0112     "[FUNC  (12)]"
0113 };
0114 
0115 
0116 
0117 
0118 char *M_subtypes[] =
0119 {
0120     "[DF(0) ]",
0121     "[==(1) ]",
0122     "[!=(2) ]",
0123     "[%%(3) ]",
0124     "[!%(4) ]",
0125     "[< (5) ]",
0126     "[<=(6) ]",
0127     "[> (7) ]",
0128     "[>=(8) ]",
0129     "[+ (9) ]",
0130     "[- (10)]",
0131     "[~ (11)]",
0132     "[! (12)]",
0133     "[* (13)]",
0134     "[/ (14)]",
0135     "[% (15)]",
0136     "[||(16)]",
0137     "[&&(17)]",
0138     "[^ (18)]"
0139 };
0140 
0141 
0142 
0143 
0144 char *M_subtypes_sign_only[] =
0145 {
0146     " ",
0147     " == ",
0148     " != ",
0149     " %% ",
0150     " !% ",
0151     " < ",
0152     " <= ",
0153     " > ",
0154     " >= ",
0155     "+",
0156     "-",
0157     "~",
0158     "!",
0159     "*",
0160     "/",
0161     "%",
0162     " || ",
0163     " && ",
0164     " ^ "
0165 };
0166 
0167 
0168 expublic void _Btreefree_no_recurse (char *tree);
0169 int is_float_val(value_block_t *v);
0170 
0171 
0172 
0173 
0174 
0175 
0176 
0177 
0178 
0179 
0180 
0181 
0182 
0183 
0184 void yyerror(char *s, ...)
0185 {
0186     
0187     if (EXFAIL!=G_error)
0188     {
0189         va_list ap;
0190         char errbuf[2048];
0191         int len;
0192 
0193         va_start(ap, s);
0194         snprintf(errbuf, sizeof(errbuf), ". Near of %d-%d: ", 
0195                 yylloc.first_column, yylloc.last_column);
0196         len=strlen(errbuf);
0197         vsnprintf(errbuf+len, sizeof(errbuf)-len, s, ap);
0198         va_end(ap);
0199 
0200         if (ndrx_Bis_error())
0201         {
0202           
0203           ndrx_Bappend_error_msg(errbuf);
0204         }
0205         else
0206         {
0207           
0208           ndrx_Bset_error_msg(BSYNTAX, errbuf+2);
0209         }
0210 
0211         G_error = EXFAIL;
0212     }
0213 }
0214 
0215 
0216 
0217 
0218 
0219 
0220 
0221 int add_resource(char *p)
0222 {
0223 
0224     struct list_node *tmp = M_cur_mem;
0225     M_cur_mem = malloc (sizeof(struct list_node));
0226 
0227     if (NULL==M_cur_mem)
0228             return EXFAIL; 
0229 
0230     if (NULL!=tmp)
0231         tmp->next = M_cur_mem;
0232     
0233     M_cur_mem->mem = p;
0234     M_cur_mem->next = NULL;
0235 
0236     if (NULL==M_first_mem)
0237     {
0238         M_first_mem=M_cur_mem;
0239     }
0240 
0241     return EXSUCCEED;
0242 }
0243 
0244 
0245 
0246 
0247 
0248 void remove_resouce_list(void)
0249 {
0250     struct list_node *p = M_first_mem;
0251     while (p)
0252     {
0253         struct list_node *tmp = p;
0254         p = p->next;
0255         NDRX_FREE(tmp); 
0256         UBF_LOG(6, "List node free-up!");
0257     }
0258 }
0259 
0260 
0261 
0262 
0263 
0264 void remove_resouces(void)
0265 {
0266     struct list_node *p = M_first_mem;
0267     while (p)
0268     {
0269         
0270         _Btreefree_no_recurse(p->mem);
0271         p = p->next;
0272     }
0273     
0274     remove_resouce_list();
0275 }
0276 
0277 
0278 
0279 
0280 
0281 
0282 
0283 expublic void _Btreefree_no_recurse (char *tree)
0284 {
0285     struct ast *a = (struct ast *)tree;
0286     struct ast_string *a_string = (struct ast_string *)tree;
0287     struct ast_fld *a_fld;
0288     struct ast_func *a_func;
0289     
0290     if (NULL==tree)
0291         return; 
0292 
0293     UBF_LOG(6, "Free up nodeid=%d nodetype=%d", a->nodeid, a->nodetype);
0294     switch (a->nodetype)
0295     {
0296         case NODE_TYPE_FLD:
0297             a_fld = (struct ast_fld *)tree;
0298             ndrx_ubf_rfldid_free(&(a_fld->fld));
0299             break;
0300         case NODE_TYPE_STR:
0301             
0302             if (NULL!=a_string->str)
0303             {
0304                 NDRX_FREE(a_string->str);
0305                 a_string->str_bufsz=0;
0306             }
0307 
0308             
0309             if (a_string->regex.compiled)
0310                 regfree(&(a_string->regex.re));
0311             break;
0312         case NODE_TYPE_FLOAT:
0313             
0314             break;
0315         case NODE_TYPE_LONG:
0316             
0317             break;
0318         case NODE_TYPE_FUNC:
0319             a_func = (struct ast_func *)tree;
0320             
0321             if (NULL!=a_func->funcall)
0322             {
0323                 NDRX_FPFREE(a_func->funcall);
0324                 
0325             }
0326             break;
0327         default:
0328             
0329             break;
0330     }
0331     
0332     NDRX_FREE(tree);
0333 }
0334 
0335 
0336 
0337 
0338 
0339 
0340 
0341 
0342 
0343 struct ast * newast(int nodetype, int sub_type, struct ast *l, struct ast *r)
0344 {
0345     struct ast *a = NDRX_MALLOC(sizeof(struct ast));
0346     memset(a, 0, sizeof(struct ast));
0347 
0348     if(!a)
0349     {
0350         yyerror("out of space");
0351         ndrx_Bset_error_msg(BMALLOC, "out of memory for new ast");
0352         return NULL;
0353     }
0354     else
0355     {
0356         if (EXSUCCEED!=add_resource((char *)a))
0357         {
0358             yyerror("out of space");
0359             ndrx_Bset_error_msg(BMALLOC, "out of memory for resource list");
0360             return NULL;
0361         }
0362     }
0363 
0364     a->nodetype = nodetype;
0365     a->sub_type = sub_type;
0366     a->nodeid = G_node_count;
0367     a->l = l;
0368     a->r = r;
0369 
0370     G_node_count++;
0371 
0372     UBF_LOG(log_debug, "adding newast: nodeid: %d, nodetype: %d, type: %s, sub-type:%s "
0373                               "value: [N/A] l=%p r=%p",
0374                           a->nodeid, a->nodetype,
0375                           M_nodetypes[a->nodetype],
0376                           M_subtypes[a->sub_type],
0377                           l, r);
0378 
0379     return a;
0380 }
0381 
0382 struct ast * newfld(ndrx_ubf_rfldid_t f)
0383 {
0384     struct ast_fld *a;
0385     int typ = Bfldtype(f.bfldid);
0386     
0387     if ((BFLD_UBF==typ) || (BFLD_VIEW==typ && NULL==f.cname))
0388     {
0389         
0390         ndrx_Bset_error_msg(BEBADOP, "Field types: BFLD_UBF and BFLD_VIEW "
0391                 "not supported in expression");
0392         
0393         yyerror("Field types: BFLD_UBF and BFLD_VIEW not supported in expression");
0394         
0395         
0396         ndrx_ubf_rfldid_free(&f);
0397         
0398         return NULL;
0399     }
0400     
0401     a = NDRX_MALLOC(sizeof(struct ast_fld));
0402     if(!a) 
0403     {
0404         yyerror("out of space");
0405         ndrx_Bset_error_msg(BMALLOC, "out of memory for new ast_fld");
0406         return NULL;
0407     }
0408     else
0409     {
0410         if (EXSUCCEED!=add_resource((char *)a))
0411         {
0412             yyerror("out of space");
0413             ndrx_Bset_error_msg(BMALLOC, "out of memory for resource list");
0414             return NULL;
0415         }
0416     }
0417     
0418     memset(a, 0, sizeof(struct ast_fld));
0419 
0420     a->nodetype = NODE_TYPE_FLD;
0421     a->sub_type = NODE_SUB_TYPE_DEF;
0422     a->nodeid = G_node_count;
0423     
0424 
0425 
0426 
0427     G_node_count++;
0428 
0429     
0430     memcpy(&(a->fld), &f, sizeof(ndrx_ubf_rfldid_t));
0431     
0432     UBF_LOG(log_debug, "adding newfld: id: %02d, type: %s, sub-type:%s "
0433                               "value: [fld: [%s] occ: [%d] bfldid: [%d]]",
0434                           a->nodeid,
0435                           M_nodetypes[a->nodetype],
0436                           M_subtypes[a->sub_type],
0437                           a->fld.fldnm, a->fld.occ,
0438                           a->fld.bfldid);
0439 out:
0440     return (struct ast *)a;
0441 
0442 }
0443 
0444 
0445 
0446 
0447 func_hash_t * get_func(char *funcname)
0448 {
0449     func_hash_t *r = NULL;
0450     EXHASH_FIND_STR( M_func_hash, funcname, r);
0451     if (NULL!=r)
0452         return r;
0453     else
0454         return NULL;
0455 }
0456 
0457 
0458 
0459 
0460 
0461 int set_func(char *funcname, void* functionPtr, int functype)
0462 {
0463     int ret=EXSUCCEED;
0464     func_hash_t *tmp;
0465     
0466     UBF_LOG(log_warn, "registering callback: [%s]:%p", 
0467                         funcname, functionPtr);
0468     
0469     if (NULL==functionPtr)
0470     {
0471         func_hash_t *r = NULL;
0472         EXHASH_FIND_STR( M_func_hash, funcname, r);
0473         if (NULL!=r)
0474         {
0475             EXHASH_DEL(M_func_hash, r);
0476             NDRX_FREE(r);
0477         }
0478     }
0479     else
0480     {
0481         tmp = NDRX_MALLOC(sizeof(func_hash_t));
0482 
0483         if (NULL==tmp)
0484         {
0485             yyerror("out of space");
0486             ndrx_Bset_error_msg(BMALLOC, "out of memory for new func_hash_t");
0487             ret=EXFAIL;
0488             goto out;
0489         }
0490 
0491         NDRX_STRCPY_SAFE(tmp->name, funcname);
0492         tmp->fptr = functionPtr;
0493         tmp->functype = functype;
0494         EXHASH_ADD_STR( M_func_hash, name, tmp );
0495     }
0496     
0497 out:
0498     return ret;
0499 }
0500 
0501 
0502 struct ast *newfunc(ndrx_symbfunc_t *funccall)
0503 {
0504     int len;
0505     int ret = EXSUCCEED;
0506     struct ast_func *a = NDRX_MALLOC(sizeof(struct ast_func));
0507     memset(a, 0, sizeof(struct ast_func));
0508 
0509     if(!a)
0510     {
0511         yyerror("out of space");
0512         ndrx_Bset_error_msg(BMALLOC, "out of memory for new ast_func");
0513         return NULL;
0514     }
0515     else
0516     {
0517         if (EXSUCCEED!=add_resource((char *)a))
0518         {
0519             yyerror("out of space");
0520             ndrx_Bset_error_msg(BMALLOC, "out of memory for resource list");
0521             return NULL;
0522         }
0523     }
0524 
0525     a->nodetype = NODE_TYPE_FUNC;
0526     a->sub_type = NODE_SUB_TYPE_DEF;
0527     a->nodeid = G_node_count;
0528 
0529     len = strlen(funccall->funcname);
0530 
0531     
0532     if (len<1)
0533     {
0534         yyerror("Function name too short!");
0535         ndrx_Bset_error_fmt(BBADNAME, "Full function name too short [%s]", funccall->funcname);
0536         
0537         EXFAIL_OUT(ret);
0538     }
0539 
0540     a->funcall = funccall;
0541 
0542     
0543     if (NULL==(a->f=get_func(a->funcall->funcname)))
0544     {
0545         yyerror("Bad function name");
0546         
0547         ndrx_Bset_error_fmt(BBADNAME, "Bad function name for [%s]", a->funcall);
0548         
0549         EXFAIL_OUT(ret);
0550     }
0551 
0552     UBF_LOG(log_debug, "ast_func id: %02d, type: %s, sub-type:%s "
0553                               "value: [func: [%s]]",
0554                           a->nodeid,
0555                           M_nodetypes[a->nodetype],
0556                           M_subtypes[a->sub_type],
0557                           a->funcall);
0558     G_node_count++;
0559 out:
0560             
0561     if (EXSUCCEED!=ret)
0562     {
0563         a->funcall=NULL;
0564         NDRX_FPFREE(funccall);
0565     }
0566     
0567     return (struct ast *)a;
0568 }
0569 
0570 struct ast * newstring(char *str)
0571 {
0572     struct ast_string *a = NDRX_MALLOC(sizeof(struct ast_string));
0573     memset(a, 0, sizeof(struct ast_string));
0574 
0575     a->str_bufsz = strlen(str)+1;
0576 
0577     a->str = NDRX_MALLOC (a->str_bufsz);
0578 
0579     if(!a || !a->str) {
0580         yyerror("out of space");
0581         ndrx_Bset_error_msg(BMALLOC, "out of memory for new ast_string or a->str");
0582         return NULL;
0583     }
0584     else
0585     {
0586       if (EXSUCCEED!=add_resource((char *)a))
0587       {
0588           yyerror("out of space");
0589           ndrx_Bset_error_msg(BMALLOC, "out of memory for resource list");
0590           return NULL;
0591       }
0592     }
0593 
0594     a->nodetype = NODE_TYPE_STR;
0595     a->sub_type = NODE_SUB_TYPE_DEF;
0596     a->nodeid = G_node_count;
0597     strcpy(a->str, str);
0598     G_node_count++;
0599 
0600     UBF_LOG(log_debug, "adding newstr: id: %02d, type: %s, sub-type:%s "
0601                     "value: [%s]",
0602                     a->nodeid,
0603                     M_nodetypes[a->nodetype],
0604                     M_subtypes[a->sub_type],
0605                     a->str);
0606 
0607     return (struct ast *)a;
0608 }
0609 
0610 struct ast * newfloat(double d)
0611 {
0612     struct ast_float *a = NDRX_MALLOC(sizeof(struct ast_float));
0613     memset(a, 0, sizeof(struct ast_float));
0614     
0615     if(!a) 
0616     {
0617         yyerror("out of space");
0618         ndrx_Bset_error_msg(BMALLOC, "out of memory for new newfloat");
0619         return NULL;
0620     }
0621     else
0622     {
0623         if (EXSUCCEED!=add_resource((char *)a))
0624         {
0625             yyerror("out of space");
0626             ndrx_Bset_error_msg(BMALLOC, "out of memory for resource list");
0627             return NULL;
0628         }
0629     }
0630     
0631     a->nodetype = NODE_TYPE_FLOAT;
0632     a->sub_type = NODE_SUB_TYPE_DEF;
0633     a->nodeid = G_node_count;
0634     a->d = d;
0635     G_node_count++;
0636     
0637     UBF_LOG(log_debug, "adding newflt: id: %02d, type: %s, sub-type:%s "
0638             "value: [%0.13lf]",
0639             a->nodeid,
0640             M_nodetypes[a->nodetype],
0641             M_subtypes[a->sub_type],
0642             a->d);
0643 
0644     return (struct ast *)a;
0645 }
0646 
0647 struct ast * newlong(long l)
0648 {
0649     struct ast_long *a = NDRX_MALLOC(sizeof(struct ast_long));
0650     memset(a, 0, sizeof(struct ast_long));
0651 
0652     if(!a) {
0653         yyerror("out of space");
0654         ndrx_Bset_error_msg(BMALLOC, "out of memory for new newfloat");
0655         return NULL;
0656     }
0657     else
0658     {
0659         if (EXSUCCEED!=add_resource((char *)a))
0660         {
0661             yyerror("out of space");
0662             ndrx_Bset_error_msg(BMALLOC, "out of memory for resource list");
0663             return NULL;
0664         }
0665     }
0666     
0667     a->nodetype = NODE_TYPE_LONG;
0668     a->sub_type = NODE_SUB_TYPE_DEF;
0669     a->nodeid = G_node_count;
0670     a->l = l;
0671     G_node_count++;
0672 
0673     UBF_LOG(log_debug, "adding newlng: id: %02d, type: %s, sub-type:%s "
0674                 "value: [%ld]",
0675                 a->nodeid,
0676                 M_nodetypes[a->nodetype],
0677                 M_subtypes[a->sub_type],
0678                 a->l);
0679 
0680     return (struct ast *)a;
0681 }
0682 
0683 
0684 
0685 
0686 
0687 int get_float(value_block_t *v)
0688 {
0689     int ret=EXSUCCEED;
0690     if (VALUE_TYPE_FLOAT==v->value_type)
0691     {
0692         
0693     }
0694     else if (VALUE_TYPE_LONG==v->value_type)
0695     {
0696         v->value_type = VALUE_TYPE_FLOAT;
0697         v->floatval= (double) v->longval;
0698     }
0699     else if (VALUE_TYPE_STRING==v->value_type || VALUE_TYPE_FLD_STR==v->value_type)
0700     {
0701         v->value_type = VALUE_TYPE_FLOAT;
0702         v->floatval = atof(v->strval);
0703     }
0704     else
0705     {
0706         UBF_LOG(log_error, "get_float: Unknown value type %d\n",
0707                                     v->value_type);
0708         ndrx_Bset_error_fmt(BSYNTAX, "get_float: Unknown value type %d\n",
0709                                     v->value_type);
0710         ret=EXFAIL;
0711     }
0712     
0713     return ret;
0714 }
0715 
0716 
0717 
0718 
0719 void dump_val(char *text, value_block_t *v)
0720 {
0721     switch(v->value_type)
0722     {
0723         case VALUE_TYPE_LONG:
0724             UBF_LOG(log_info, "%s:ret long          : %ld", text, v->longval);
0725             break;
0726         case VALUE_TYPE_FLOAT:
0727             UBF_LOG(log_info, "%s:ret float         : %.13lf", text, v->floatval);
0728             break;
0729         case VALUE_TYPE_STRING:
0730             UBF_LOG(log_info, "%s:ret const string  : [%s]", text, v->strval);
0731             break;
0732         case VALUE_TYPE_FLD_STR:
0733             UBF_LOG(log_info, "%s:ret fld string    : [%s]", text, v->strval);
0734             break;
0735         default:
0736             UBF_LOG(log_error,   "%s:Error: unknown type value block", text, v->strval);
0737             break;
0738     }
0739     UBF_LOG(log_debug,       "%s:ret bool          : %d", text, v->boolval);
0740 }
0741 
0742 
0743 
0744 
0745 
0746 
0747 
0748 exprivate int conv_to_string(char *buf, size_t bufsz, value_block_t *v)
0749 {
0750     int ret=EXSUCCEED;
0751 
0752     v->strval = buf;
0753     
0754     if (VALUE_TYPE_LONG==v->value_type)
0755     {
0756         v->value_type = VALUE_TYPE_STRING;
0757         snprintf(v->strval, bufsz, "%ld", v->longval);
0758     }
0759     else if (VALUE_TYPE_FLOAT==v->value_type)
0760     {
0761         v->value_type = VALUE_TYPE_STRING;
0762         snprintf(v->strval, bufsz, "%.13lf", v->floatval);
0763     }
0764     else
0765     {
0766         UBF_LOG(log_error, "conv_to_string: Unknown value type %d\n",
0767                                 v->value_type);
0768         ndrx_Bset_error_fmt(BSYNTAX, "conv_to_string: Unknown value type %d\n",
0769                                 v->value_type);
0770         ret=EXFAIL;
0771     }
0772 
0773     return ret;
0774 }
0775 
0776 
0777 
0778 
0779 
0780 
0781 int conv_to_long(value_block_t *v)
0782 {
0783     int ret=EXSUCCEED;
0784 
0785     if (VALUE_TYPE_STRING==v->value_type || VALUE_TYPE_FLD_STR==v->value_type)
0786     {
0787         v->longval=atof(v->strval);
0788     }
0789     else if (VALUE_TYPE_FLOAT==v->value_type)
0790     {
0791         v->longval=(long)v->floatval;
0792     }
0793     else
0794     {
0795         UBF_LOG(log_error,"conv_to_long: Unknown value type %d\n",
0796                                 v->value_type);
0797         ndrx_Bset_error_fmt(BSYNTAX, "conv_to_long: Unknown value type %d\n",
0798                                 v->value_type);
0799         ret=EXFAIL;
0800     }
0801 
0802     return ret;
0803 }
0804 
0805 
0806 
0807 
0808 
0809 
0810 
0811 
0812 
0813 
0814 int op_equal_float_cmp(int type, int sub_type, value_block_t *lval, 
0815         value_block_t *rval, value_block_t *v)
0816 {
0817     int ret=EXSUCCEED;
0818 
0819     v->value_type = VALUE_TYPE_LONG;
0820 
0821     if (VALUE_TYPE_FLOAT!=lval->value_type && EXSUCCEED!=get_float(lval))
0822     {
0823         ret=EXFAIL;
0824     }
0825 
0826     if (EXSUCCEED==ret && VALUE_TYPE_FLOAT!=rval->value_type &&
0827                             EXSUCCEED!=get_float(rval))
0828     {
0829         ret=EXFAIL;
0830     }
0831 
0832     if (EXSUCCEED==ret)
0833     {
0834         UBF_LOG(log_debug, "flt CMP (%s/%s): [%lf] vs [%lf]",
0835                         M_nodetypes[type], M_subtypes[sub_type], lval->floatval, rval->floatval);
0836 
0837         if (NODE_TYPE_EQOP==type)
0838         {
0839             v->longval = v->boolval = (fabs(lval->floatval-rval->floatval)<DOUBLE_EQUAL);
0840         }
0841         else if (NODE_TYPE_RELOP==type && RELOP_LESS==sub_type) 
0842         {
0843             v->longval = v->boolval = (lval->floatval<rval->floatval?EXTRUE:EXFALSE);
0844         }
0845         else if (NODE_TYPE_RELOP==type && RELOP_LESS_EQUAL==sub_type) 
0846         {
0847             v->longval = v->boolval = (lval->floatval<=rval->floatval?EXTRUE:EXFALSE);
0848         }
0849         else if (NODE_TYPE_RELOP==type && RELOP_GREATER==sub_type) 
0850         {
0851             v->longval = v->boolval = (lval->floatval>rval->floatval?EXTRUE:EXFALSE);
0852         }
0853         else if (NODE_TYPE_RELOP==type && RELOP_GREATER_EQUAL==sub_type) 
0854         {
0855             v->longval = v->boolval = (lval->floatval>=rval->floatval?EXTRUE:EXFALSE);
0856         }
0857         else if (NODE_TYPE_ADDOP==type || NODE_TYPE_MULTOP==type)
0858         {
0859             v->value_type = VALUE_TYPE_FLOAT;
0860 
0861             if (NODE_TYPE_ADDOP==type && ADDOP_PLUS==sub_type)
0862             {
0863                 v->floatval=lval->floatval+rval->floatval;
0864             }
0865             else if (NODE_TYPE_ADDOP==type && ADDOP_MINUS==sub_type)
0866             {
0867                 v->floatval=lval->floatval-rval->floatval;
0868             }
0869             else if (NODE_TYPE_MULTOP==type && MULOP_DOT==sub_type)
0870             {
0871                 v->floatval=lval->floatval*rval->floatval;
0872             }
0873             else if (NODE_TYPE_MULTOP==type && MULOP_DIV==sub_type)
0874             {
0875                 if (IS_FLOAT_0(rval->floatval)) 
0876                     rval->floatval = 0;
0877                 else
0878                     v->floatval=lval->floatval/rval->floatval;
0879             }
0880             else if (NODE_TYPE_MULTOP==type && MULOP_MOD==sub_type)
0881             {
0882                 
0883                 v->value_type = VALUE_TYPE_LONG;
0884                 UBF_LOG(log_warn, "ERROR! No mod support for floats!");
0885                 v->longval = v->boolval = EXFALSE;
0886             }
0887             
0888             
0889             if (!IS_FLOAT_0(v->floatval))
0890                 v->boolval=EXTRUE;
0891             else
0892                 v->boolval=EXFALSE;
0893         }
0894     } 
0895     
0896     
0897     DUMP_VALUE_BLOCK("op_equal_float_cmp", v);
0898 
0899     return ret;
0900 }
0901 
0902 
0903 
0904 
0905 
0906 
0907 
0908 
0909 
0910 
0911 int op_equal_long_cmp(int type, int sub_type, value_block_t *lval, 
0912         value_block_t *rval, value_block_t *v)
0913 {
0914     int ret=EXSUCCEED;
0915     v->value_type = VALUE_TYPE_LONG;
0916 
0917     if ((VALUE_TYPE_LONG!=lval->value_type) && EXSUCCEED!=conv_to_long(lval))
0918     {
0919         ret=EXFAIL;
0920     }
0921 
0922     if (EXSUCCEED==ret && (VALUE_TYPE_LONG!=rval->value_type) &&
0923             EXSUCCEED!=conv_to_long(rval))
0924     {
0925         ret=EXFAIL;
0926     }
0927 
0928     if (EXSUCCEED==ret)
0929     {
0930         UBF_LOG(log_debug, "lng CMP (%s/%s): [%ld] vs [%ld]",
0931                         M_nodetypes[type], M_subtypes[sub_type], lval->longval, rval->longval);
0932 
0933         if (NODE_TYPE_EQOP==type)
0934         {
0935             v->longval = v->boolval = (lval->longval==rval->longval);
0936         }
0937         else if (NODE_TYPE_RELOP==type && RELOP_LESS==sub_type) 
0938         {
0939             v->longval = v->boolval = (lval->longval<rval->longval?EXTRUE:EXFALSE);
0940         }
0941         else if (NODE_TYPE_RELOP==type && RELOP_LESS_EQUAL==sub_type) 
0942         {
0943             v->longval = v->boolval = (lval->longval<=rval->longval?EXTRUE:EXFALSE);
0944         }
0945         else if (NODE_TYPE_RELOP==type && RELOP_GREATER==sub_type) 
0946         {
0947             v->longval = v->boolval = (lval->longval>rval->longval?EXTRUE:EXFALSE);
0948         }
0949         else if (NODE_TYPE_RELOP==type && RELOP_GREATER_EQUAL==sub_type) 
0950         {
0951             v->longval = v->boolval = (lval->longval>=rval->longval?EXTRUE:EXFALSE);
0952         }
0953         else if (NODE_TYPE_ADDOP==type || NODE_TYPE_MULTOP==type)
0954         {
0955             v->value_type = VALUE_TYPE_LONG;
0956 
0957             if (NODE_TYPE_ADDOP==type && ADDOP_PLUS==sub_type)
0958             {
0959                 v->longval=lval->longval+rval->longval;
0960             }
0961             if (NODE_TYPE_ADDOP==type && ADDOP_MINUS==sub_type)
0962             {
0963                 v->longval=lval->longval-rval->longval;
0964             }
0965             else if (NODE_TYPE_MULTOP==type && MULOP_DOT==sub_type)
0966             {
0967                 v->longval=lval->longval*rval->longval;
0968             }
0969             else if (NODE_TYPE_MULTOP==type && MULOP_DIV==sub_type)
0970             {
0971                 
0972                 if (0==rval->longval)
0973                     v->longval=0;
0974                 else
0975                     v->longval=lval->longval/rval->longval;
0976             }
0977             else if (NODE_TYPE_MULTOP==type && MULOP_MOD==sub_type)
0978             {
0979                 if (0==rval->longval)
0980                     v->longval=lval->longval;
0981                 else
0982                     v->longval=lval->longval%rval->longval;
0983             }
0984             
0985             if (v->longval)
0986                 v->boolval=EXTRUE;
0987             else
0988                 v->boolval=EXFALSE;
0989         }
0990     }
0991 
0992     
0993     DUMP_VALUE_BLOCK("op_equal_long_cmp", v);
0994 
0995     return ret;
0996 }
0997 
0998 int op_equal_str_cmp(int type, int sub_type, value_block_t *lval, 
0999         value_block_t *rval, value_block_t *v)
1000 {
1001     int ret=EXSUCCEED;
1002     int result;
1003     char lval_buf[CF_TEMP_BUF_MAX]; 
1004     char rval_buf[CF_TEMP_BUF_MAX]; 
1005     v->value_type = VALUE_TYPE_LONG;
1006 
1007     if (VALUE_TYPE_FLD_STR!=lval->value_type &&
1008             VALUE_TYPE_STRING!=lval->value_type &&
1009             EXSUCCEED!=conv_to_string(lval_buf, CF_TEMP_BUF_MAX, lval))
1010     {
1011         ret=EXFAIL;
1012     }
1013 
1014     if (EXSUCCEED==ret && VALUE_TYPE_FLD_STR!=rval->value_type &&
1015             VALUE_TYPE_STRING!=rval->value_type &&
1016             EXSUCCEED!=conv_to_string(rval_buf, CF_TEMP_BUF_MAX, rval))
1017     {
1018         ret=EXFAIL;
1019     }
1020 
1021     if (EXSUCCEED==ret)
1022     {
1023         result=strcmp(lval->strval, rval->strval);
1024 
1025         UBF_LOG(log_debug, "str CMP (%s/%s): [%s] vs [%s]",
1026                 M_nodetypes[type], M_subtypes[sub_type], 
1027                 lval->strval, rval->strval);
1028 
1029         if (NODE_TYPE_EQOP==type)
1030         {
1031             v->longval = v->boolval = result==0?EXTRUE:EXFALSE;
1032         }
1033         else if (NODE_TYPE_RELOP==type && RELOP_LESS==sub_type) 
1034         {
1035             v->longval = v->boolval = (result<0?EXTRUE:EXFALSE);
1036         }
1037         else if (NODE_TYPE_RELOP==type && RELOP_LESS_EQUAL==sub_type) 
1038         {
1039             v->longval = v->boolval = (result<=0?EXTRUE:EXFALSE);
1040         }
1041         else if (NODE_TYPE_RELOP==type && RELOP_GREATER==sub_type) 
1042         {
1043             v->longval = v->boolval = (result>0?EXTRUE:EXFALSE);
1044         }
1045         else if (NODE_TYPE_RELOP==type && RELOP_GREATER_EQUAL==sub_type) 
1046         {
1047             v->longval = v->boolval = (result>=0?EXTRUE:EXFALSE);
1048         }
1049         else if (NODE_TYPE_ADDOP==type || NODE_TYPE_MULTOP==type)
1050         {
1051             
1052             UBF_LOG(log_warn, "ERROR! No math support for strings!");
1053             v->longval = v->boolval = EXFALSE;
1054         }
1055 
1056         UBF_LOG(log_debug, "Result bool: %d long:%ld", v->boolval, rval->longval);
1057     }
1058 
1059     
1060     DUMP_VALUE_BLOCK("op_equal_str_cmp", v);
1061     
1062     return ret;
1063 }
1064 
1065 
1066 
1067 
1068 
1069 int op_equal(UBFH *p_ub, int type, int sub_type, struct ast *l, struct ast *r, value_block_t *v)
1070 {
1071     int ret=EXSUCCEED;
1072     value_block_t lval, rval;
1073     memset(&lval, 0, sizeof(lval));
1074     memset(&rval, 0, sizeof(rval));
1075     
1076     if (EXSUCCEED!=eval(p_ub, l, &lval))
1077     {
1078         ret=EXFAIL;
1079     }
1080 
1081     if (EXSUCCEED==ret && EXSUCCEED!=eval(p_ub, r, &rval))
1082     {
1083         ret=EXFAIL;
1084     }
1085 
1086     if (EXSUCCEED==ret)
1087     {
1088         if (lval.is_null || rval.is_null)
1089         {
1090             
1091             UBF_LOG(log_debug, "LVAR or LVAL is NULL => False");
1092             v->longval = v->boolval = EXFALSE;
1093             goto out;
1094         }
1095     
1096         if (( (VALUE_TYPE_STRING==lval.value_type &&
1097             VALUE_TYPE_STRING==rval.value_type)
1098             ||
1099             (VALUE_TYPE_FLD_STR==lval.value_type &&
1100             VALUE_TYPE_FLD_STR==rval.value_type)
1101             ||
1102             (VALUE_TYPE_STRING==lval.value_type &&
1103             VALUE_TYPE_FLD_STR==rval.value_type)
1104             ||
1105             (VALUE_TYPE_FLD_STR==lval.value_type &&
1106             VALUE_TYPE_STRING==rval.value_type)) &&
1107                 !(type==NODE_TYPE_ADDOP || type==NODE_TYPE_MULTOP) 
1108                 )
1109         {
1110             ret=op_equal_str_cmp(type, sub_type, &lval, &rval, v);
1111 
1112         }
1113         else if ((VALUE_TYPE_STRING==lval.value_type ||
1114             VALUE_TYPE_STRING==rval.value_type) && !(type==NODE_TYPE_ADDOP || 
1115                 type==NODE_TYPE_MULTOP))
1116         {
1117             ret=op_equal_str_cmp(type, sub_type, &lval, &rval, v);
1118         }
1119         
1120         else if (VALUE_TYPE_LONG==lval.value_type && VALUE_TYPE_LONG==rval.value_type)
1121         {
1122             ret=op_equal_long_cmp(type, sub_type, &lval, &rval, v);
1123         }
1124         else 
1125         {
1126             int is_lval_float = is_float_val(&lval);
1127             int is_rval_float = is_float_val(&rval);
1128 #if 0
1129             
1130             if (VALUE_TYPE_LONG==lval.value_type && !is_rval_float ||
1131                      VALUE_TYPE_LONG==rval.value_type && !is_lval_float)
1132             {
1133                 ret=op_equal_long_cmp(type, sub_type, &lval, &rval, v);
1134             }
1135             
1136             else
1137 #endif      
1138             if ((!is_lval_float && !is_rval_float) || 
1139                     (NODE_TYPE_MULTOP==type && MULOP_MOD==sub_type))
1140             {
1141                 ret=op_equal_long_cmp(type, sub_type, &lval, &rval, v);
1142             }
1143             else 
1144             {
1145                 ret=op_equal_float_cmp(type, sub_type, &lval, &rval, v);
1146             } 
1147         }
1148 
1149     } 
1150 
1151 out:
1152     
1153     FREE_UP_UB_BUF((&lval));
1154     FREE_UP_UB_BUF((&rval));
1155 
1156     return ret;
1157 }
1158 
1159 
1160 
1161 
1162 
1163 
1164 
1165 
1166 
1167 
1168 
1169 
1170 
1171 exprivate int CBget_unified(UBFH *p_ub, ndrx_ubf_rfldid_t *rbfldid, 
1172         char *buf, BFLDLEN *len, int usrtype)
1173 {
1174     int ret = EXSUCCEED;
1175     char **dptr = (char **)buf;
1176     if (rbfldid->nrflds==1)
1177     {
1178         if (BFLD_STRING==usrtype)
1179         {
1180             *dptr=CBgetalloc(p_ub, rbfldid->bfldid, rbfldid->occ, usrtype, NULL);
1181             if (NULL==*dptr)
1182             {
1183                 ret=EXFAIL;
1184             }
1185             
1186         }
1187         else
1188         {
1189             ret=CBget(p_ub, rbfldid->bfldid, rbfldid->occ, buf, len, usrtype);
1190         }
1191     }
1192     else if (NULL!=rbfldid->cname)
1193     {
1194         
1195 
1196 
1197 
1198         if (BFLD_STRING==usrtype)
1199         {
1200             *dptr = CBvgetallocr(p_ub, (BFLDID *)rbfldid->fldidocc.mem, rbfldid->cname, 
1201                     rbfldid->cname_occ, usrtype, BVACCESS_NOTNULL, NULL);
1202             if (NULL==*dptr)
1203             {
1204                 ret=EXFAIL;
1205             }
1206         }
1207         else
1208         {
1209             ret = CBvgetr(p_ub, (BFLDID *)rbfldid->fldidocc.mem, rbfldid->cname, 
1210                     rbfldid->cname_occ, buf, len, usrtype, BVACCESS_NOTNULL);
1211         }
1212     }
1213     else
1214     {
1215         if (BFLD_STRING==usrtype)
1216         {
1217             *dptr = CBgetallocr (p_ub, (BFLDID *)rbfldid->fldidocc.mem, usrtype, NULL);
1218             
1219             if (NULL==*dptr)
1220             {
1221                 ret=EXFAIL;
1222             }
1223         }
1224         else
1225         {
1226             ret = CBgetr (p_ub, (BFLDID *)rbfldid->fldidocc.mem,
1227                                 buf, len, usrtype);
1228         }
1229     }
1230     
1231     return ret;
1232 }
1233 
1234 
1235 
1236 
1237 
1238 
1239 
1240 exprivate int Bpres_unified(UBFH *p_ub, ndrx_ubf_rfldid_t *rbfldid)
1241 {
1242     int ret = EXSUCCEED;
1243     
1244     if (rbfldid->nrflds==1)
1245     {
1246         ret=Bpres(p_ub, rbfldid->bfldid, rbfldid->occ);
1247     }
1248     else if (NULL!=rbfldid->cname)
1249     {
1250         
1251         ret=Bvnullr(p_ub, (BFLDID *)rbfldid->fldidocc.mem, rbfldid->cname, 
1252                 rbfldid->cname_occ);
1253         
1254         if (EXFALSE==ret)
1255         {
1256             ret=EXTRUE;
1257         }
1258         else if (EXTRUE==ret)
1259         {
1260             ret=EXFALSE;
1261         }
1262         
1263     }
1264     else
1265     {
1266         
1267         ret=Bpresr (p_ub, (BFLDID *)rbfldid->fldidocc.mem);
1268     }
1269     
1270     return ret;
1271 }
1272 
1273 
1274 int regexp_eval(UBFH *p_ub, struct ast *l, struct ast *r, value_block_t *v)
1275 {
1276     int ret=EXSUCCEED;
1277     char *l_buf=NULL;
1278     char *p_l=NULL;
1279     char *p_r=NULL;
1280     regex_t *re;
1281     int err;
1282     struct ast_string *ls = (struct ast_string *)l;
1283     struct ast_fld *lf = (struct ast_fld *)l;
1284     struct ast_string *rs = (struct ast_string *)r;
1285 
1286     if (NODE_TYPE_FLD==l->nodetype)
1287     {
1288         
1289         if (EXSUCCEED!=(ret=CBget_unified(p_ub, &(lf->fld),
1290                                     (char *)&l_buf, NULL, BFLD_STRING)))
1291         {
1292             if (BNOTPRES==Berror)
1293             {
1294                 ndrx_Bunset_error(); 
1295                 
1296                 UBF_LOG(log_warn, "Field not present [%s]", lf->fld.fldnm);
1297                 v->value_type=VALUE_TYPE_LONG;
1298                 v->longval=v->boolval=EXFALSE;
1299                 v->is_null=EXTRUE; 
1300 
1301                 return EXSUCCEED; 
1302             }
1303             else
1304             {
1305                 UBF_LOG(log_warn, "Failed to get [%s] - %s",
1306                                         lf->fld.fldnm, Bstrerror(Berror));
1307                 EXFAIL_OUT(ret);
1308             }
1309 
1310         }
1311         else
1312         {
1313             p_l = l_buf;
1314         }
1315     }
1316     else if (NODE_TYPE_STR==l->nodetype)
1317     {
1318         
1319         p_l = ls->str;
1320     }
1321     else
1322     {
1323         
1324         ndrx_Bset_error_msg(BSYNTAX, "Left side of regex must be const string or FB field");
1325         ret=EXFAIL;
1326     }
1327 
1328     
1329     if (NODE_TYPE_STR==r->nodetype)
1330     {
1331         p_r = rs->str;
1332     } 
1333     else
1334     {
1335     
1336         UBF_LOG(log_error, "Right side of regexp must be const string! "
1337                                 "But got node type [%d]\n", r->nodetype);
1338          ndrx_Bset_error_msg(BSYNTAX, "Right side of regex must be const string");
1339          EXFAIL_OUT(ret);
1340     }
1341 
1342 
1343     re = &(rs->regex.re);
1344     UBF_LOG(log_debug, "Regex left  [%s]", p_l);
1345     UBF_LOG(log_debug, "Regex right [%s]", p_r);
1346 
1347     
1348     if (!rs->regex.compiled)
1349     {
1350         UBF_LOG(log_debug, "Compiling regex");
1351         if (EXSUCCEED!=(err=regcomp(re, p_r, REG_EXTENDED | REG_NOSUB)))
1352         {
1353             ndrx_report_regexp_error("regcomp", err, re);
1354             EXFAIL_OUT(ret);
1355         }
1356         else
1357         {
1358             UBF_LOG(log_debug, "REGEX: Compiled OK");
1359             rs->regex.compiled = 1;
1360         }
1361     }
1362 
1363     if (EXSUCCEED==regexec(re, p_l, (size_t) 0, NULL, 0))
1364     {
1365         v->value_type=VALUE_TYPE_LONG;
1366         v->longval=v->boolval=EXTRUE;
1367         UBF_LOG(log_debug, "REGEX: matched!");
1368     }
1369     else if (EXSUCCEED==ret)
1370     {
1371         v->value_type=VALUE_TYPE_LONG;
1372         v->longval=v->boolval=EXFALSE;
1373         UBF_LOG(log_debug, "REGEX: NOT matched!");
1374     }
1375 
1376 out:
1377     
1378     DUMP_VALUE_BLOCK("regexp_eval", v);
1379 
1380     if (NULL!=l_buf)
1381     {
1382         NDRX_FREE(l_buf);
1383     }
1384 
1385     return ret;
1386 }
1387 
1388 
1389 
1390 
1391 int read_unary_func(UBFH *p_ub, struct ast *a, value_block_t * v)
1392 {
1393     int ret=EXSUCCEED;
1394     struct ast_func *func = (struct ast_func *)a;
1395     char *fn = "read_unary_func";
1396 
1397     UBF_LOG(log_debug, "Entering %s func: [%s]",
1398                                     fn, func->funcall);
1399     
1400     
1401     v->value_type=VALUE_TYPE_LONG;
1402     
1403     if (NDRX_CBFUNTYPE_ARG1==func->f->functype)
1404     {
1405         functionPtr2_t fcall = (functionPtr2_t)func->f->fptr;
1406         UBF_LOG(log_debug, "Arg1 func call");
1407         
1408         v->longval = fcall(p_ub, func->funcall->funcname, func->funcall->arg1);
1409         
1410     }
1411     else
1412     {
1413         functionPtr_t fcall = (functionPtr_t)func->f->fptr;
1414         UBF_LOG(log_debug, "No args call %d", func->f->functype);
1415         
1416         v->longval = fcall(p_ub, func->funcall->funcname);
1417     }
1418 
1419     if (v->longval)
1420         v->boolval=EXTRUE;
1421     else
1422         v->boolval=EXFALSE;
1423     
1424     
1425     DUMP_VALUE_BLOCK("read_unary_fb", v);
1426 
1427     UBF_LOG(log_debug, "return %s %d", fn, ret);
1428     
1429     return ret;
1430 }
1431 
1432 
1433 
1434 
1435 
1436 
1437 
1438 
1439 
1440 
1441 int read_unary_fb(UBFH *p_ub, struct ast *a, value_block_t * v)
1442 {
1443     int ret=EXSUCCEED;
1444     struct ast_fld *fld = (struct ast_fld *)a;
1445     BFLDID bfldid;
1446     BFLDOCC occ;
1447     int fld_type;
1448     char fn[] = "read_unary_fb()";
1449     
1450     bfldid = fld->fld.bfldid;
1451     occ = fld->fld.occ;
1452 
1453     UBF_LOG(log_debug, "Entering %s fldnm [%s] bfldid=%d occ=%d",
1454                                     fn, fld->fld.fldnm, bfldid, occ);
1455     
1456 
1457 
1458 
1459 
1460 
1461 
1462 
1463     fld_type=Bfldtype(bfldid);
1464 
1465     if (!Bpres_unified(p_ub, &(fld->fld)))
1466     {
1467         UBF_LOG(log_debug, "Field [%s] not present in fb",
1468                                             fld->fld.fldnm);
1469         v->value_type = VALUE_TYPE_LONG;
1470         v->longval=v->boolval=EXFALSE;
1471         v->is_null=EXTRUE;
1472     }
1473     
1474     else if (BFLD_STRING==fld_type || BFLD_CARRAY==fld_type || BFLD_CHAR==fld_type ||
1475             NULL!=fld->fld.cname)
1476     {
1477         if (EXSUCCEED!=CBget_unified(p_ub, &(fld->fld),
1478                         (char *)&v->strval, NULL, BFLD_STRING))
1479         {
1480             if (BNOTPRES==Berror)
1481             {
1482                 ndrx_Bunset_error(); 
1483                 UBF_LOG(log_warn, "Failed to get [%s] as str"
1484                                              " - downgrade to FALSE!",
1485                                              fld->fld.fldnm);
1486                 v->value_type = VALUE_TYPE_FLD_STR;
1487                 v->longval=v->boolval=EXFALSE;
1488                 v->is_null=EXTRUE;
1489             }
1490             else 
1491             {
1492                 UBF_LOG(log_warn, "Failed to get [%s] - %s",
1493                     fld->fld.fldnm, Bstrerror(Berror));
1494                 ret=EXFAIL;
1495             }
1496             
1497 
1498             NDRX_FREE(v->strval);
1499             v->dyn_alloc = EXFALSE;
1500             v->strval = NULL;
1501         }
1502         else
1503         {
1504             v->value_type = VALUE_TYPE_FLD_STR;
1505             v->boolval=EXTRUE;
1506             v->dyn_alloc = EXTRUE;
1507         }
1508 
1509     }
1510     else if (BFLD_SHORT==fld_type || BFLD_LONG==fld_type)
1511     {
1512         if (EXSUCCEED!=CBget_unified(p_ub, &(fld->fld), 
1513                         (char *)&v->longval, NULL, BFLD_LONG))
1514         {
1515             if (BNOTPRES==Berror)
1516             {
1517                 ndrx_Bunset_error(); 
1518                 UBF_LOG(log_warn, "Failed to get [%s] as long"
1519                         " - downgrade to FALSE!",
1520                         fld->fld.fldnm);
1521                 v->value_type = VALUE_TYPE_LONG;
1522                 v->longval=v->boolval=EXFALSE;
1523                 v->is_null=EXTRUE;
1524             }
1525             else 
1526             {
1527                 UBF_LOG(log_warn, "Failed to get [%s] - %s",
1528                     fld->fld.fldnm, Bstrerror(Berror));
1529                 ret=EXFAIL;
1530             }
1531         }
1532         else
1533         {
1534                 v->value_type = VALUE_TYPE_LONG;
1535                 v->boolval=EXTRUE;
1536         }
1537     }
1538     else if (BFLD_FLOAT==fld_type || BFLD_DOUBLE==fld_type)
1539     {
1540         if (EXSUCCEED!=CBget_unified(p_ub, &(fld->fld), 
1541                         (char *)&v->floatval, NULL, BFLD_DOUBLE))
1542         {
1543             if (BNOTPRES==Berror)
1544             {
1545                 ndrx_Bunset_error(); 
1546                 UBF_LOG(log_warn, "Failed to get [%s] as double"
1547                         " - downgrade to FALSE!",
1548                         fld->fld.fldnm);
1549                 v->value_type = VALUE_TYPE_LONG;
1550                 v->longval=v->boolval=EXFALSE;
1551                 v->is_null=EXTRUE;
1552             }
1553             else 
1554             {
1555                 UBF_LOG(log_warn, "Failed to get [%s] - %s",
1556                     fld->fld.fldnm, Bstrerror(Berror));
1557                 ret=EXFAIL;
1558             }
1559         }
1560         else
1561         {
1562             v->value_type = VALUE_TYPE_FLOAT;
1563             v->boolval=EXTRUE;
1564         }
1565     }
1566 
1567     
1568     DUMP_VALUE_BLOCK("read_unary_fb", v);
1569 
1570     UBF_LOG(log_debug, "return %s %d", fn, ret);
1571 
1572     return ret;
1573 }
1574 
1575 
1576 
1577 
1578 
1579 
1580 int is_float(char *s)
1581 {
1582     if (strpbrk(s, ".,eE")) 
1583     {
1584         return EXTRUE;
1585     }
1586     return EXFALSE;
1587 }
1588 
1589 
1590 
1591 
1592 
1593 int is_float_val(value_block_t *v)
1594 {
1595     if ( VALUE_TYPE_FLOAT==v->value_type )
1596         return EXTRUE;
1597 
1598     if ( VALUE_TYPE_FLD_STR==v->value_type || VALUE_TYPE_STRING==v->value_type)
1599         return is_float(v->strval);
1600     
1601     return EXFALSE;
1602 }
1603 
1604 
1605 
1606 
1607 
1608 
1609 
1610 
1611 
1612 
1613 
1614 int process_unary(UBFH *p_ub, int op, struct ast *a, value_block_t *v)
1615 {
1616     int ret=EXSUCCEED;
1617     value_block_t pri;
1618     
1619     double f;
1620     long  l;
1621     int is_long=EXTRUE;
1622     char fn[] = "process_unary()";
1623 
1624     memset(&pri, 0, sizeof(pri));
1625     
1626     UBF_LOG(log_debug, "Entering %s", fn);
1627 
1628     if (EXSUCCEED==eval(p_ub, a->r, &pri))
1629     {
1630 
1631         if (VALUE_TYPE_FLD_STR==pri.value_type || 
1632                 VALUE_TYPE_STRING==pri.value_type)
1633         {
1634             if (is_float(pri.strval))
1635             {
1636                 f = atof(pri.strval);
1637                 is_long = EXFALSE;
1638                 UBF_LOG(log_warn, "Treating unary field as "
1639                                     "float [%f]!", f);
1640             }
1641             else
1642             {
1643                 l = atol(pri.strval);
1644                 is_long = EXTRUE;
1645                 UBF_LOG(log_warn, "Treating unary "
1646                         "field as long [%ld]", l);
1647             }
1648         }
1649         else if (VALUE_TYPE_FLOAT==pri.value_type)
1650         {
1651             is_long=EXFALSE;
1652             f = pri.floatval;
1653         }
1654         else if (VALUE_TYPE_LONG==pri.value_type)
1655         {
1656             
1657             is_long=EXTRUE;
1658             l = pri.longval;
1659         } 
1660         else if (VALUE_TYPE_BOOL!=pri.value_type)
1661         {
1662             UBF_LOG(log_warn, "Unknown value type %d op: %d", 
1663                                 pri.value_type, op);
1664             return EXFAIL;
1665         }
1666         
1667 #if 0
1668         - Bug #325
1669         if (((op==UNARY_CMPL || op==UNARY_INV) && !is_long) 
1670                 && VALUE_TYPE_BOOL!=pri.value_type)
1671         {
1672             
1673             UBF_LOG(log_warn, "! or ~ converting double to long!");
1674             l = (long) f;
1675         }
1676 #endif
1677         
1678         v->boolval = pri.boolval;
1679 
1680         switch (op)
1681         {
1682             case ADDOP_PLUS:
1683                 
1684                 if (is_long)
1685                 {
1686                     v->value_type=VALUE_TYPE_LONG;
1687                     v->longval = l;
1688                     
1689                     if (v->longval)
1690                         v->boolval=EXTRUE;
1691                     else
1692                         v->boolval=EXFALSE;
1693                     
1694                 }
1695                 else 
1696                 {
1697                     v->value_type=VALUE_TYPE_FLOAT;
1698                     v->floatval = f;
1699                     if (!IS_FLOAT_0(v->floatval))
1700                         v->boolval=EXTRUE;
1701                     else
1702                         v->boolval=EXFALSE;
1703                 }
1704                 break;
1705             case ADDOP_MINUS:
1706                 
1707                 if (is_long)
1708                 {
1709                     v->value_type=VALUE_TYPE_LONG;
1710                     v->longval = -l;
1711                     
1712                     if (v->longval)
1713                         v->boolval=EXTRUE;
1714                     else
1715                         v->boolval=EXFALSE;
1716                     
1717                 }
1718                 else 
1719                 {
1720                     v->value_type=VALUE_TYPE_FLOAT;
1721                     v->floatval = -f;
1722                     
1723                     if (!IS_FLOAT_0(v->floatval))
1724                         v->boolval=EXTRUE;
1725                     else
1726                         v->boolval=EXFALSE;
1727                 }
1728                 break;
1729             case UNARY_CMPL:
1730                 
1731                 v->value_type=VALUE_TYPE_LONG;
1732                 v->boolval = ~pri.boolval;
1733                 
1734                 v->longval = v->boolval;
1735                 break;
1736             case UNARY_INV:
1737                 v->value_type=VALUE_TYPE_LONG;
1738                 v->boolval = !pri.boolval;
1739                 v->longval = v->boolval;
1740                 break;
1741         }
1742     }
1743     else
1744     {
1745         ret=EXFAIL;
1746     }
1747     
1748     FREE_UP_UB_BUF((&pri));
1749     
1750     DUMP_VALUE_BLOCK("process_unary", v);
1751     UBF_LOG(log_debug, "Return %s %d", fn, ret);
1752     return ret;
1753 }
1754 
1755 
1756 
1757 
1758 
1759 
1760 
1761 
1762 
1763 
1764 
1765 
1766 int eval(UBFH *p_ub, struct ast *a, value_block_t *v)
1767 {
1768     int ret=EXSUCCEED;
1769     value_block_t l, r;
1770     char fn[] = "eval";
1771     memset(v, 0, sizeof(*v));
1772     memset(&l, 0, sizeof(l));
1773     memset(&r, 0, sizeof(r));
1774 
1775     if (!v)
1776     {
1777         ndrx_Bset_error_msg(BNOTFLD, "internal error, null ret value");
1778             return EXFAIL; 
1779     }
1780 
1781     if(!a)
1782     {
1783         ndrx_Bset_error_msg(BNOTFLD, "internal error, null eval");
1784         return EXFAIL; 
1785     }
1786     
1787     UBF_LOG(log_debug, "%s: id: %02d type: %s sub-type %s", fn,
1788                     a->nodeid, M_nodetypes[a->nodetype], M_subtypes[a->sub_type]);
1789     
1790     
1791     switch (a->nodetype)
1792     {
1793         case NODE_TYPE_OR:
1794             ret=eval(p_ub, a->l, &l);
1795             
1796 
1797 
1798             if (EXSUCCEED==ret && !l.boolval)
1799                     ret=eval(p_ub, a->r, &r);
1800 
1801             if (EXSUCCEED==ret)
1802             {
1803                 v->value_type=VALUE_TYPE_LONG;
1804                 v->longval = v->boolval = (l.boolval || r.boolval)?EXTRUE:EXFALSE;
1805             }
1806             DUMP_VALUE_BLOCK("NODE_TYPE_OR", v);
1807             break;
1808         case NODE_TYPE_AND:
1809             ret=eval(p_ub, a->l, &l);
1810             
1811 
1812 
1813             if (EXSUCCEED==ret && l.boolval)
1814             {
1815                 ret=eval( p_ub, a->r, &r);
1816             }
1817 
1818             if (EXSUCCEED==ret)
1819             {
1820                 v->value_type=VALUE_TYPE_LONG;
1821 
1822                 v->longval = v->boolval = (l.boolval && r.boolval)?EXTRUE:EXFALSE;
1823             }
1824             DUMP_VALUE_BLOCK("NODE_TYPE_AND", v);
1825             break;
1826         case NODE_TYPE_XOR:
1827             ret = eval( p_ub, a->l, &l);
1828 
1829             if (EXSUCCEED==ret)
1830             {
1831                 ret = eval( p_ub, a->r, &r);
1832             }
1833 
1834             if (EXSUCCEED==ret)
1835             {
1836                 v->value_type=VALUE_TYPE_LONG;
1837 
1838                 if ((l.boolval && !r.boolval) || (!l.boolval && r.boolval))
1839                     v->boolval=EXTRUE;
1840                 else
1841                     v->boolval=EXFALSE;
1842             }
1843             DUMP_VALUE_BLOCK("NODE_TYPE_XOR", v);
1844             break;
1845         case NODE_TYPE_EQOP:
1846             switch (a->sub_type)
1847             {
1848                 case EQOP_EQUAL:
1849                     ret = op_equal(p_ub, NODE_TYPE_EQOP, NODE_SUB_TYPE_DEF, a->l, a->r, v);
1850                     break;
1851                 case EQOP_NOT_EQUAL:
1852                     ret = op_equal(p_ub, NODE_TYPE_EQOP, NODE_SUB_TYPE_DEF, a->l, a->r, v);
1853                     if (EXSUCCEED==ret)
1854                     {
1855                         
1856                         v->boolval = !v->boolval;
1857                         v->longval = !v->longval;
1858                     }
1859                     DUMP_VALUE_BLOCK("EQOP_NOT_EQUAL", v);
1860                     break;
1861                 case EQOP_REGEX_EQUAL:
1862                     ret=regexp_eval(p_ub, a->l, a->r, v);
1863                     break;
1864                 case EQOP_REGEX_NOT_EQUAL:
1865                     ret=regexp_eval(p_ub, a->l, a->r, v);
1866                     if (EXSUCCEED==ret)
1867                     {
1868                         
1869                         v->boolval = !v->boolval;
1870                         v->longval = !v->longval;
1871                     }
1872                     DUMP_VALUE_BLOCK("EQOP_REGEX_NOT_EQUAL", v);
1873                     break;
1874             }
1875             break;
1876         case NODE_TYPE_RELOP:
1877             ret = op_equal(p_ub, NODE_TYPE_RELOP, a->sub_type, a->l, a->r, v);
1878             break;
1879         case NODE_TYPE_ADDOP:
1880             ret = op_equal(p_ub, NODE_TYPE_ADDOP, a->sub_type, a->l, a->r, v);
1881             break;
1882         case NODE_TYPE_MULTOP:
1883             ret = op_equal(p_ub, NODE_TYPE_MULTOP, a->sub_type, a->l, a->r, v);
1884             break;
1885         case NODE_TYPE_UNARY:
1886             ret = process_unary(p_ub, a->sub_type, a, v);
1887             break;
1888         case NODE_TYPE_FLD:
1889             
1890             ret=read_unary_fb(p_ub, a, v);
1891             break;
1892         case NODE_TYPE_FUNC:
1893             
1894             ret=read_unary_func(p_ub, a, v);
1895             break;
1896         case NODE_TYPE_STR:
1897             
1898 
1899 
1900 
1901             v->value_type = VALUE_TYPE_STRING;
1902             v->boolval = EXTRUE; 
1903             {
1904                 struct ast_string *s = (struct ast_string *)a;
1905                 
1906                 
1907                 v->strval = s->str;
1908             }
1909             
1910             DUMP_VALUE_BLOCK("NODE_TYPE_STR", v);
1911             break;
1912         case NODE_TYPE_FLOAT:
1913             v->value_type = VALUE_TYPE_FLOAT;
1914             
1915             {
1916                 struct ast_float * a_f = (struct ast_float*)a;
1917                 v->floatval = a_f->d;
1918                 
1919                 if (!IS_FLOAT_0(v->floatval))
1920                     v->boolval = EXTRUE;
1921                 else
1922                     v->boolval = EXFALSE;
1923             }
1924             
1925              DUMP_VALUE_BLOCK("VALUE_TYPE_FLOAT", v);
1926             break;
1927         case NODE_TYPE_LONG:
1928             v->value_type = VALUE_TYPE_LONG;
1929             
1930             {
1931                 struct ast_long * a_long = (struct ast_long*)a;
1932                 v->longval = a_long->l;
1933                 
1934                 if (v->longval)
1935                     v->boolval = EXTRUE;
1936                 else
1937                     v->boolval = EXFALSE;
1938             }
1939             
1940             DUMP_VALUE_BLOCK("VALUE_TYPE_LONG", v);
1941             break;
1942     }
1943     
1944     FREE_UP_UB_BUF((&l));
1945     FREE_UP_UB_BUF((&r));
1946     return ret;
1947 }
1948 
1949 
1950 
1951 
1952 expublic char * ndrx_Bboolco (char * expr)
1953 {
1954 
1955     char *ret=NULL;
1956     char *fn = "Bboolco";
1957     extern  int yycolumn;
1958     char *expr_int;
1959     int buf_len = strlen(expr)+2;
1960     UBF_LOG(log_debug, "%s: Compiling expression [%s]", fn, expr);
1961 
1962     
1963 
1964     expr_int = NDRX_MALLOC(buf_len);
1965 
1966     if (NULL==expr_int)
1967     {
1968         ndrx_Bset_error_fmt(BMALLOC, "cannot allocate %d bytes for expression copy",
1969                                     buf_len);
1970     }
1971     else
1972     {
1973         
1974         NDRX_STRCPY_SAFE_DST(expr_int, expr, buf_len);
1975         strcat(expr_int, "\n");
1976 
1977         yy_scan_string(expr_int);
1978         G_p_root_node = NULL;
1979         G_node_count = 0;
1980         G_error = 0;
1981         yycolumn = 1;
1982 
1983         M_first_mem=NULL;
1984         M_cur_mem=NULL;
1985 
1986         if (EXSUCCEED==yyparse() && NULL!=G_p_root_node && EXFAIL!=G_error)
1987         {
1988             ret=(char *)G_p_root_node;
1989             remove_resouce_list();
1990         }
1991         else
1992         {
1993             remove_resouces();
1994         }
1995 
1996     
1997         _free_parser();
1998 
1999         NDRX_FREE(expr_int);
2000     }
2001     UBF_LOG(log_debug, "%s: return %p", fn, ret);
2002     return ret;
2003 }
2004 
2005 expublic int ndrx_Bboolev (UBFH * p_ub, char *tree)
2006 {
2007     int ret=EXSUCCEED;
2008     value_block_t v;
2009     struct ast *a = (struct ast *)tree;
2010     memset(&v, 0, sizeof(v));
2011 
2012     if (NULL==tree)
2013     {
2014         ndrx_Bset_error_msg(BEINVAL, "NULL tree passed for eval!");
2015         return EXFAIL; 
2016     }
2017     
2018 
2019 
2020     if (EXSUCCEED==eval(p_ub, a, &v))
2021     {
2022         if (v.boolval)
2023         {
2024             ret=EXTRUE;
2025         }
2026         else
2027         {
2028             ret=EXFALSE;
2029         }
2030     }
2031     else
2032     {
2033         ret=EXFAIL;
2034     }
2035 
2036     FREE_UP_UB_BUF((&v));
2037 
2038     return ret;
2039 }
2040 
2041 
2042 
2043 
2044 
2045 
2046 
2047 expublic double ndrx_Bfloatev (UBFH * p_ub, char *tree)
2048 {
2049     double ret=0.0;
2050     value_block_t v;
2051     struct ast *a = (struct ast *)tree;
2052     memset(&v, 0, sizeof(v));
2053 
2054     if (NULL==tree)
2055     {
2056         ndrx_Bset_error_msg(BEINVAL, "NULL tree passed for eval!");
2057         return EXFAIL; 
2058     }
2059     
2060 
2061 
2062     if (EXSUCCEED==eval(p_ub, a, &v))
2063     {
2064         if (VALUE_TYPE_FLOAT!=v.value_type)
2065             get_float(&v);
2066         ret=v.floatval;
2067     }
2068     else
2069     {
2070         ret=EXFAIL;
2071     }
2072 
2073     FREE_UP_UB_BUF((&v));
2074 
2075     return ret;
2076 }
2077 
2078 
2079 
2080 
2081 
2082 
2083 expublic void ndrx_Btreefree (char *tree)
2084 {
2085     struct ast *a = (struct ast *)tree;
2086     struct ast_string *a_string = (struct ast_string *)tree;
2087     struct ast_fld *a_fld;
2088     struct ast_func *a_func;    
2089 
2090     if (NULL==tree)
2091         return; 
2092 
2093     UBF_LOG(6, "Free up buffer %p nodeid=%d nodetype=%d", tree, a->nodeid, a->nodetype);
2094     switch (a->nodetype)
2095     {
2096         case NODE_TYPE_FLD:
2097             a_fld = (struct ast_fld *)tree;
2098             ndrx_ubf_rfldid_free(&(a_fld->fld));
2099             break;
2100         case NODE_TYPE_STR:
2101             
2102             if (NULL!=a_string->str)
2103             {
2104                 NDRX_FREE(a_string->str);
2105                 a_string->str_bufsz=0;
2106             }
2107 
2108             
2109             if (a_string->regex.compiled)
2110                 regfree(&(a_string->regex.re));
2111             break;
2112         case NODE_TYPE_FLOAT:
2113             
2114             break;
2115         case NODE_TYPE_FUNC:
2116             a_func = (struct ast_func *)tree;
2117             if (NULL!=a_func->funcall)
2118             {
2119                 NDRX_FPFREE(a_func->funcall);
2120             }
2121             break;
2122         case NODE_TYPE_LONG:
2123             
2124             break;
2125         default:
2126             if (a->l)
2127             {
2128                 ndrx_Btreefree ((char *)a->l);
2129             }
2130             if (a->r)
2131             {
2132                 ndrx_Btreefree ((char *)a->r);
2133             }
2134             break;
2135     }
2136     
2137     NDRX_FREE(tree);
2138 
2139 }
2140 
2141 
2142 
2143 
2144 
2145 
2146 
2147 
2148 
2149 expublic void ndrx_Bboolpr (char * tree, FILE *outf, 
2150         int (*p_writef)(char *buffer, long datalen, void *dataptr1), void *dataptr1)
2151 {
2152     struct ast *a = (struct ast *)tree;
2153     struct ast_string *a_string = (struct ast_string *)tree;
2154     char *tmp;
2155     long tmp_len;
2156 
2157     if (NULL==tree)
2158         return; 
2159 
2160     if (NULL!=outf && ferror(outf))
2161     {
2162         return;
2163     }
2164     
2165 #define NDRX_BBOOLPR_FMT(...) \
2166     if (NULL!=p_writef)\
2167     {\
2168         NDRX_ASPRINTF(&tmp, &tmp_len, ##__VA_ARGS__);\
2169         if (NULL==tmp)\
2170         {\
2171             int err = errno;\
2172             UBF_LOG(log_error, "Failed to asprintf: %s", strerror(err));\
2173             userlog("Failed to asprintf: %s", strerror(err));\
2174         }\
2175         tmp_len++;\
2176         if (EXSUCCEED!=p_writef(tmp, tmp_len, dataptr1))\
2177         {\
2178             return;\
2179         }\
2180     }\
2181     else\
2182     {\
2183         fprintf(outf, ##__VA_ARGS__);\
2184     }
2185 
2186     switch (a->nodetype)
2187     {
2188         case NODE_TYPE_FUNC:
2189             {
2190                 
2191                 struct ast_func *a_func = (struct ast_func *)tree;
2192                 
2193                 NDRX_BBOOLPR_FMT("%s(%s)", a_func->funcall->funcname, a_func->funcall->arg1);
2194                 
2195             }
2196             break;
2197         case NODE_TYPE_FLD:
2198             {
2199                 
2200                 struct ast_fld *a_fld = (struct ast_fld *)tree;
2201                 NDRX_BBOOLPR_FMT("%s", a_fld->fld.fldnm);
2202             }
2203             break;
2204         case NODE_TYPE_STR:
2205             
2206             
2207             if (NULL!=a_string->str)
2208             {
2209                 NDRX_BBOOLPR_FMT("'%s'", a_string->str);
2210             }
2211             else
2212             {
2213                 NDRX_BBOOLPR_FMT("<null>");
2214             }
2215             
2216             break;
2217         case NODE_TYPE_FLOAT:
2218             {
2219                 
2220                 struct ast_float *a_float = (struct ast_float *)tree;
2221                 
2222                 NDRX_BBOOLPR_FMT("%.*lf", DOUBLE_RESOLUTION, a_float->d);
2223             }
2224             break;
2225         case NODE_TYPE_LONG:
2226             {
2227                 
2228                 struct ast_long *a_long = (struct ast_long *)tree;
2229                 NDRX_BBOOLPR_FMT("%ld", a_long->l);
2230             }
2231             break;
2232         default:
2233             NDRX_BBOOLPR_FMT("(");
2234             if (a->l)
2235             {
2236                 ndrx_Bboolpr ((char *)a->l, outf, p_writef, dataptr1);
2237             }
2238             NDRX_BBOOLPR_FMT("%s", M_subtypes_sign_only[a->sub_type]);
2239             if (a->r)
2240             {
2241                 ndrx_Bboolpr ((char *)a->r, outf, p_writef, dataptr1);
2242             }
2243             NDRX_BBOOLPR_FMT(")");
2244             break;
2245     }
2246 }
2247 
2248 
2249 
2250 
2251 
2252 
2253 
2254 
2255 expublic int ndrx_Bboolsetcbf2 (char *funcname, void *funcptr, int functype)
2256 {
2257 
2258     int ret=EXSUCCEED;
2259     char *fn = "_Bsetcbfunc";
2260     int len;
2261     
2262     UBF_LOG(log_debug, "%s: setting callback function [%s]:%p", fn, 
2263             funcname, funcptr);
2264 
2265     if (NULL==funcname || (len=strlen(funcname)) < 1 || len > MAX_FUNC_NAME-1)
2266     {
2267         ndrx_Bset_error_fmt(BBADNAME, "Bad function name passed [%s]", funcname);
2268         ret=EXFAIL;
2269         goto out;
2270     }
2271     
2272     ret = set_func(funcname, funcptr, functype);
2273     
2274 out:
2275     UBF_LOG(log_debug, "%s: return %p", fn, ret);
2276     return ret;
2277 }
2278 
2279