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