Преглед изворни кода

core: added new preprocessor directive: substdef

- prototype
  !!substdef '/regexp/replacement/flags'
- separator char '/' can be replaced with any other character to avoid
  conflicts
- it adds a preprocessor substitution like '!!subst' and in addition
  defines the regexp to replacement, like
  !!define regexp replacement
- useful when you need to replace tokens present as ID and inside string
  values
Daniel-Constantin Mierla пре 14 година
родитељ
комит
78d26523c9
4 измењених фајлова са 81 додато и 5 уклоњено
  1. 4 2
      cfg.lex
  2. 3 0
      cfg.y
  3. 71 1
      ppcfg.c
  4. 3 2
      ppcfg.h

+ 4 - 2
cfg.lex

@@ -561,6 +561,7 @@ EAT_ABLE	[\ \t\b\r]
 
 /* pre-processing blocks */
 SUBST       subst
+SUBSTDEF    substdef
 
 %%
 
@@ -1230,6 +1231,7 @@ SUBST       subst
 							addstr(&s_buf, yytext, yyleng); }
 
 <INITIAL>{PREP_START}{SUBST}	{ count();  return SUBST;}
+<INITIAL>{PREP_START}{SUBSTDEF}	{ count();  return SUBSTDEF;}
 
 <INITIAL,IFDEF_SKIP>{PREP_START}{IFDEF}{EAT_ABLE}+    { count();
 								if (pp_ifdef_type(1)) return 1;
@@ -1663,7 +1665,7 @@ int pp_define(int len, const char * text)
 	return 0;
 }
 
-int  pp_define_set(int len, char *text)
+int pp_define_set(int len, char *text)
 {
 	if(len<=0) {
 		LOG(L_DBG, "no define value - ignoring\n");
@@ -1700,7 +1702,7 @@ int  pp_define_set(int len, char *text)
 	return 0;
 }
 
-static str  *pp_define_get(int len, const char * text)
+static str *pp_define_get(int len, const char * text)
 {
 	str var = {(char *)text, len};
 	int i;

+ 3 - 0
cfg.y

@@ -562,6 +562,7 @@ extern char *finame;
 
 /*pre-processor*/
 %token SUBST
+%token SUBSTDEF
 
 /* operators, C like precedence */
 %right EQUAL
@@ -1968,6 +1969,8 @@ event_route_stm: ROUTE_EVENT LBRACK EVENT_RT_NAME RBRACK LBRACE actions RBRACE {
 preprocess_stm:
 	SUBST STRING { if(pp_subst_add($2)<0) YYERROR; }
 	| SUBST error { yyerror("invalid subst preprocess statement"); }
+	| SUBSTDEF STRING { if(pp_substdef_add($2)<0) YYERROR; }
+	| SUBSTDEF error { yyerror("invalid substdef preprocess statement"); }
 	;
 
 /*exp:	rval_expr

+ 71 - 1
ppcfg.c

@@ -62,7 +62,7 @@ int pp_subst_add(char *data)
 	se=subst_parser(&subst);
 	if (se==0)
 	{
-		LM_ERR("bad subst expression:: %s\n", data);
+		LM_ERR("bad subst expression: %s\n", data);
 		pkg_free(pr);
 		return -2;
 	}
@@ -76,9 +76,79 @@ int pp_subst_add(char *data)
 	}
 	pp_subst_rules_tail = pr;
 
+	LM_ERR("### added subst expression: %s\n", data);
+
 	return 0;
 }
 
+int pp_substdef_add(char *data)
+{
+	char c;
+	char *p;
+	str defname;
+	str defvalue;
+
+	if(pp_subst_add(data)<0) {
+		LM_ERR("subst rule cannot be added\n");
+		goto error;
+	}
+
+	p=data;
+	c=*p;
+	if (c=='\\') {
+		LM_ERR("invalid separator char [%c] in [%s]\n", c, data);
+		goto error;
+	}
+	p++;
+	/* find regexp */
+	defname.s=p;
+	for ( ; *p; p++) {
+		/* if unescaped sep. char */
+		if ((*p==c) && (*(p-1)!='\\'))
+			goto found_regexp;
+	}
+	LM_ERR("separator [%c] not found after regexp: [%s]\n", c, data);
+	goto error;
+
+found_regexp:
+	defname.len = p - defname.s;
+	if(defname.len==0) {
+		LM_ERR("define name too short\n");
+		goto error;
+	}
+
+	p++;
+	defvalue.s = p;
+	/* find replacement */
+	for ( ; *p; p++) {
+		/* if unescaped sep. char */
+		if ((*p==c) && (*(p-1)!='\\'))
+			goto found_repl;
+	}
+	LM_ERR("separator [%c] not found after replacement: [%s]\n", c, data);
+	goto error;
+
+found_repl:
+	defvalue.len = p - defvalue.s;
+
+	if(pp_define(defname.len, defname.s)<0) {
+		LM_ERR("cannot set define name\n");
+		goto error;
+	}
+	if(pp_define_set(defvalue.len, defvalue.s)<0) {
+		LM_ERR("cannot set define value\n");
+		goto error;
+	}
+
+	LM_DBG("### added substdef: [%.*s]=[%.*s]\n", defname.len, defname.s,
+			defvalue.len, defvalue.s);
+
+	return 0;
+
+error:
+	return 1;
+}
+
 int pp_subst_run(char **data)
 {
 	str* result;

+ 3 - 2
ppcfg.h

@@ -23,10 +23,11 @@
 #define _PPCFG_H_
 
 int pp_subst_add(char *data);
+int pp_substdef_add(char *data);
 int pp_subst_run(char **data);
 
-int  pp_define(int len, const char * text);
-int  pp_define_set(int len, char * text);
+int  pp_define(int len, const char *text);
+int  pp_define_set(int len, char *text);
 
 #endif /*_PPCFG_H_*/