diff --git a/src/core/cfg.lex b/src/core/cfg.lex index 97ce62f1eb2..e508d420e39 100644 --- a/src/core/cfg.lex +++ b/src/core/cfg.lex @@ -575,6 +575,7 @@ IFEXP ifexp ENDIF endif TRYDEF "trydefine"|"trydef" REDEF "redefine"|"redef" +DEFEXP defexp DEFENV defenv DEFENVS defenvs TRYDEFENV trydefenv @@ -1339,6 +1340,10 @@ IMPORTFILE "import_file" ksr_cfg_print_part(yytext); pp_define_set_type(KSR_PPDEF_REDEF); state = DEFINE_S; BEGIN(DEFINE_ID); } +{PREP_START}{DEFEXP}{EAT_ABLE}+ { count(); + ksr_cfg_print_part(yytext); + pp_define_set_type(KSR_PPDEF_DEFEXP); + state = DEFINE_S; BEGIN(DEFINE_ID); } {ID}{MINUS} { count(); ksr_cfg_print_part(yytext); LM_CRIT( @@ -2107,6 +2112,7 @@ int pp_define(int len, const char *text) int pp_define_set(int len, char *text, int mode) { int ppos; + char *sval = NULL; if(pp_define_index == -2) { /* #!trydef that should be ignored */ @@ -2144,17 +2150,28 @@ int pp_define_set(int len, char *text, int mode) return -1; } - pp_defines[ppos].value.s = (char*)pkg_malloc(len+1); - if (pp_defines[ppos].value.s == NULL) { - LM_ERR("no more memory to define %.*s [%d]\n", - pp_defines[ppos].name.len, - pp_defines[ppos].name.s, ppos); - return -1; - } + if(pp_defines[ppos].dtype == KSR_PPDEF_DEFEXP) { + sval = pp_defexp_eval(text, len); + if(sval==NULL) { + LM_NOTICE("no value returned to set the defexp [%.*s]\n", + pp_defines[ppos].name.len, pp_defines[ppos].name.s); + return 0; + } + pp_defines[ppos].value.s = sval; + pp_defines[ppos].value.len = strlen(sval); + } else { + pp_defines[ppos].value.s = (char*)pkg_malloc(len+1); + if (pp_defines[ppos].value.s == NULL) { + LM_ERR("no more memory to define %.*s [%d]\n", + pp_defines[ppos].name.len, + pp_defines[ppos].name.s, ppos); + return -1; + } - memcpy(pp_defines[ppos].value.s, text, len); - pp_defines[ppos].value.s[len] = '\0'; - pp_defines[ppos].value.len = len; + memcpy(pp_defines[ppos].value.s, text, len); + pp_defines[ppos].value.s[len] = '\0'; + pp_defines[ppos].value.len = len; + } LM_DBG("### setting define ID [%.*s] value [%.*s] (mode: %d)\n", pp_defines[ppos].name.len, pp_defines[ppos].name.s, diff --git a/src/core/ppcfg.c b/src/core/ppcfg.c index ba9c2ceb2d4..8e43e9722d6 100644 --- a/src/core/ppcfg.c +++ b/src/core/ppcfg.c @@ -461,4 +461,63 @@ void pp_ifexp_eval(char *exval, int exlen) snexpr_destroy(e, &vars); } +char *pp_defexp_eval(char *exval, int exlen) +{ + str exstr; + struct snexpr_var_list vars = {0}; + struct snexpr *e = NULL; + struct snexpr *result = NULL; + str sval = STR_NULL; + char *res = NULL; + + exstr.s = exval; + exstr.len = exlen; + trim(&exstr); + + LM_DBG("evaluating [%.*s]\n", exstr.len, exstr.s); + + e = snexpr_create(exstr.s, exstr.len, &vars, NULL, pp_snexpr_defval); + if(e == NULL) { + LM_ERR("failed to create expression [%.*s]\n", exstr.len, exstr.s); + return NULL; + } + + result = snexpr_eval(e); + + if(result==NULL) { + LM_ERR("expression evaluation [%.*s] is null\n", exstr.len, exstr.s); + goto end; + } + + if(result->type == SNE_OP_CONSTNUM) { + LM_DBG("expression number result: %g\n", result->param.num.nval); + sval.s = int2str((long)result->param.num.nval, &sval.len); + if(sval.s==NULL) { + goto done; + } + } else if(result->type == SNE_OP_CONSTSTZ) { + if(result->param.stz.sval==NULL) { + LM_DBG("expression string result is null\n"); + goto done; + } + LM_DBG("expression string result: [%s]\n", result->param.stz.sval); + sval.s = result->param.stz.sval; + sval.len = strlen(result->param.stz.sval); + } + + res = (char*)pkg_malloc(sval.len + 1); + if(res==NULL) { + PKG_MEM_ERROR; + goto done; + } + memcpy(res, sval.s, sval.len); + res[sval.len] = '\0'; + +done: + snexpr_result_free(result); +end: + snexpr_destroy(e, &vars); + return res; +} + /* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/core/ppcfg.h b/src/core/ppcfg.h index 0f9b09a1aeb..7b5b016c082 100644 --- a/src/core/ppcfg.h +++ b/src/core/ppcfg.h @@ -34,6 +34,7 @@ #define KSR_PPDEF_DEFINE 0 #define KSR_PPDEF_TRYDEF 1 #define KSR_PPDEF_REDEF 2 +#define KSR_PPDEF_DEFEXP 3 typedef struct ksr_ppdefine { str name; @@ -67,6 +68,7 @@ void ksr_cfg_print_initial_state(void); void pp_ifexp_eval(char *exval, int exlen); void pp_ifexp_state(int state); +char *pp_defexp_eval(char *exval, int exlen); #endif /*_PPCFG_H_*/