Browse Source

core: added #!defexp ID STM preprocessor directive

- abity to set a defined it to the result of snexpr statement
- example:

  #!define ADDR 127.0.0.1
  #!defexp SIPURI "sip:" + ADDR + ":5060"
Daniel-Constantin Mierla 3 years ago
parent
commit
411fb392fc
3 changed files with 88 additions and 10 deletions
  1. 27 10
      src/core/cfg.lex
  2. 59 0
      src/core/ppcfg.c
  3. 2 0
      src/core/ppcfg.h

+ 27 - 10
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); }
+<INITIAL,CFGPRINTMODE>{PREP_START}{DEFEXP}{EAT_ABLE}+	{	count();
+											ksr_cfg_print_part(yytext);
+											pp_define_set_type(KSR_PPDEF_DEFEXP);
+											state = DEFINE_S; BEGIN(DEFINE_ID); }
 <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,

+ 59 - 0
src/core/ppcfg.c

@@ -461,4 +461,63 @@ end:
 	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: */

+ 2 - 0
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_*/