Browse code

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 authored on 20/09/2022 15:41:36
Showing 3 changed files
... ...
@@ -575,6 +575,7 @@ IFEXP        ifexp
575 575
 ENDIF        endif
576 576
 TRYDEF       "trydefine"|"trydef"
577 577
 REDEF        "redefine"|"redef"
578
+DEFEXP       defexp
578 579
 DEFENV       defenv
579 580
 DEFENVS      defenvs
580 581
 TRYDEFENV    trydefenv
... ...
@@ -1339,6 +1340,10 @@ IMPORTFILE      "import_file"
1339 1340
 											ksr_cfg_print_part(yytext);
1340 1341
 											pp_define_set_type(KSR_PPDEF_REDEF);
1341 1342
 											state = DEFINE_S; BEGIN(DEFINE_ID); }
1343
+<INITIAL,CFGPRINTMODE>{PREP_START}{DEFEXP}{EAT_ABLE}+	{	count();
1344
+											ksr_cfg_print_part(yytext);
1345
+											pp_define_set_type(KSR_PPDEF_DEFEXP);
1346
+											state = DEFINE_S; BEGIN(DEFINE_ID); }
1342 1347
 <DEFINE_ID>{ID}{MINUS}          {	count();
1343 1348
 									ksr_cfg_print_part(yytext);
1344 1349
 									LM_CRIT(
... ...
@@ -2107,6 +2112,7 @@ int pp_define(int len, const char *text)
2107 2112
 int pp_define_set(int len, char *text, int mode)
2108 2113
 {
2109 2114
 	int ppos;
2115
+	char *sval = NULL;
2110 2116
 
2111 2117
 	if(pp_define_index == -2) {
2112 2118
 		/* #!trydef that should be ignored */
... ...
@@ -2144,17 +2150,28 @@ int pp_define_set(int len, char *text, int mode)
2144 2150
 		return -1;
2145 2151
 	}
2146 2152
 
2147
-	pp_defines[ppos].value.s = (char*)pkg_malloc(len+1);
2148
-	if (pp_defines[ppos].value.s == NULL) {
2149
-		LM_ERR("no more memory to define %.*s [%d]\n",
2150
-			pp_defines[ppos].name.len,
2151
-			pp_defines[ppos].name.s, ppos);
2152
-		return -1;
2153
-	}
2153
+	if(pp_defines[ppos].dtype == KSR_PPDEF_DEFEXP) {
2154
+		sval = pp_defexp_eval(text, len);
2155
+		if(sval==NULL) {
2156
+			LM_NOTICE("no value returned to set the defexp [%.*s]\n",
2157
+				pp_defines[ppos].name.len, pp_defines[ppos].name.s);
2158
+			return 0;
2159
+		}
2160
+		pp_defines[ppos].value.s = sval;
2161
+		pp_defines[ppos].value.len = strlen(sval);
2162
+	} else {
2163
+		pp_defines[ppos].value.s = (char*)pkg_malloc(len+1);
2164
+		if (pp_defines[ppos].value.s == NULL) {
2165
+			LM_ERR("no more memory to define %.*s [%d]\n",
2166
+				pp_defines[ppos].name.len,
2167
+				pp_defines[ppos].name.s, ppos);
2168
+			return -1;
2169
+		}
2154 2170
 
2155
-	memcpy(pp_defines[ppos].value.s, text, len);
2156
-	pp_defines[ppos].value.s[len] = '\0';
2157
-	pp_defines[ppos].value.len = len;
2171
+		memcpy(pp_defines[ppos].value.s, text, len);
2172
+		pp_defines[ppos].value.s[len] = '\0';
2173
+		pp_defines[ppos].value.len = len;
2174
+	}
2158 2175
 	LM_DBG("### setting define ID [%.*s] value [%.*s] (mode: %d)\n",
2159 2176
 			pp_defines[ppos].name.len,
2160 2177
 			pp_defines[ppos].name.s,
... ...
@@ -461,4 +461,63 @@ end:
461 461
 	snexpr_destroy(e, &vars);
462 462
 }
463 463
 
464
+char *pp_defexp_eval(char *exval, int exlen)
465
+{
466
+	str exstr;
467
+	struct snexpr_var_list vars = {0};
468
+	struct snexpr *e = NULL;
469
+	struct snexpr *result = NULL;
470
+	str sval = STR_NULL;
471
+	char *res = NULL;
472
+
473
+	exstr.s = exval;
474
+	exstr.len = exlen;
475
+	trim(&exstr);
476
+
477
+	LM_DBG("evaluating [%.*s]\n", exstr.len, exstr.s);
478
+
479
+	e = snexpr_create(exstr.s, exstr.len, &vars, NULL, pp_snexpr_defval);
480
+	if(e == NULL) {
481
+		LM_ERR("failed to create expression [%.*s]\n", exstr.len, exstr.s);
482
+		return NULL;
483
+	}
484
+
485
+	result = snexpr_eval(e);
486
+
487
+	if(result==NULL) {
488
+		LM_ERR("expression evaluation [%.*s] is null\n", exstr.len, exstr.s);
489
+		goto end;
490
+	}
491
+
492
+	if(result->type == SNE_OP_CONSTNUM) {
493
+		LM_DBG("expression number result: %g\n", result->param.num.nval);
494
+		sval.s = int2str((long)result->param.num.nval, &sval.len);
495
+		if(sval.s==NULL) {
496
+			goto done;
497
+		}
498
+	} else if(result->type == SNE_OP_CONSTSTZ) {
499
+		if(result->param.stz.sval==NULL) {
500
+			LM_DBG("expression string result is null\n");
501
+			goto done;
502
+		}
503
+		LM_DBG("expression string result: [%s]\n", result->param.stz.sval);
504
+		sval.s = result->param.stz.sval;
505
+		sval.len = strlen(result->param.stz.sval);
506
+	}
507
+
508
+	res = (char*)pkg_malloc(sval.len + 1);
509
+	if(res==NULL) {
510
+		PKG_MEM_ERROR;
511
+		goto done;
512
+	}
513
+	memcpy(res, sval.s, sval.len);
514
+	res[sval.len] = '\0';
515
+
516
+done:
517
+	snexpr_result_free(result);
518
+end:
519
+	snexpr_destroy(e, &vars);
520
+	return res;
521
+}
522
+
464 523
 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */
... ...
@@ -34,6 +34,7 @@
34 34
 #define KSR_PPDEF_DEFINE  0
35 35
 #define KSR_PPDEF_TRYDEF  1
36 36
 #define KSR_PPDEF_REDEF   2
37
+#define KSR_PPDEF_DEFEXP  3
37 38
 
38 39
 typedef struct ksr_ppdefine {
39 40
 	str name;
... ...
@@ -67,6 +68,7 @@ void ksr_cfg_print_initial_state(void);
67 68
 
68 69
 void pp_ifexp_eval(char *exval, int exlen);
69 70
 void pp_ifexp_state(int state);
71
+char *pp_defexp_eval(char *exval, int exlen);
70 72
 
71 73
 #endif /*_PPCFG_H_*/
72 74