[sr-dev] git:master: core: support for include file in cfg

Daniel-Constantin Mierla miconda at gmail.com
Tue Aug 25 18:41:52 CEST 2009


Module: sip-router
Branch: master
Commit: d20565193c1176312a29d75710d494707abdf6a5
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d20565193c1176312a29d75710d494707abdf6a5

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Tue Aug 25 19:27:01 2009 +0300

core: support for include file in cfg

- syntax:
include path/to/file
- example:
include checks.cfg
- path can be absolute or relative
- if path is relative:
	- first attempt is to open the file relative to current directory
	- second attempt is to open the file relative to the directory
	of the file including it
- if include file fails, then print error and exit
- cfg syntax error messages print file name
- there is no restriction where 'include' can be used, can have
global parameters, module configs or entire/parts of route blocks

---

 cfg.lex        |  159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 cfg.y          |   29 ++++++-----
 route_struct.h |    1 +
 3 files changed, 174 insertions(+), 15 deletions(-)

diff --git a/cfg.lex b/cfg.lex
index ebe2b6d..079613d 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -122,6 +122,7 @@
 	int column=1;
 	int startcolumn=1;
 	int startline=1;
+	char *finame = 0;
 	static int ign_lines=0;
 	static int ign_columns=0;
 	char* yy_number_str=0; /* str correspondent for the current NUMBER token */
@@ -132,12 +133,30 @@
 	static void count_more();
 	static void count_ignore();
 
+	#define MAX_INCLUDE_DEPTH 10
+	static struct sr_yy_state {
+		YY_BUFFER_STATE state;
+		int line;
+		int column;
+		int startcolumn;
+		int startline;
+		char *finame;
+	} include_stack[MAX_INCLUDE_DEPTH];
+	static int include_stack_ptr = 0;
+
+	static int sr_push_yy_state(char *fin);
+	static int sr_pop_yy_state();
+
+	static struct sr_yy_fname {
+		char *fname;
+		struct sr_yy_fname *next;
+	} *sr_yy_fname_list = 0;
 
 %}
 
 /* start conditions */
 %x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P 
-%x PVARID
+%x PVARID INCL
 
 /* config script types : #!SER  or #!KAMAILIO or #!MAX_COMPAT */
 SER_CFG			SER
@@ -201,6 +220,8 @@ CASE			"case"
 DEFAULT			"default"
 WHILE			"while"
 
+INCLUDE         "include"
+
 /*ACTION LVALUES*/
 URIHOST			"uri:host"
 URIPORT			"uri:port"
@@ -556,6 +577,8 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{DEFAULT}	{ count(); yylval.strval=yytext; return DEFAULT; }
 <INITIAL>{WHILE}	{ count(); yylval.strval=yytext; return WHILE; }
 
+<INITIAL>{INCLUDE}  { BEGIN(INCL); }
+
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
 
@@ -1097,6 +1120,13 @@ EAT_ABLE	[\ \t\b\r]
 
 <SELECT>.               { unput(yytext[0]); state = INITIAL_S; BEGIN(INITIAL); } /* Rescan the token in INITIAL state */
 
+<INCL>[ \t]*      /* eat the whitespace */
+<INCL>[^ \t\n]+   { /* get the include file name */
+				if(sr_push_yy_state(yytext)<0)
+					exit(-1);
+				BEGIN(INITIAL);
+}
+
 
 <<EOF>>							{
 									switch(state){
@@ -1141,7 +1171,8 @@ EAT_ABLE	[\ \t\b\r]
 													" while parsing"
 													" avp or pvar name\n");
 									}
-									return 0;
+									if(sr_pop_yy_state()<0)
+										return 0;
 								}
 
 %%
@@ -1253,3 +1284,127 @@ int yywrap()
 {
 	return 1;
 }
+
+static int sr_push_yy_state(char *fin)
+{
+	struct sr_yy_fname *fn = NULL;
+	char *x = NULL;
+	char *newf = NULL;
+
+	if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
+	{
+		LOG(L_CRIT, "too many includes\n");
+		return -1;
+	}
+
+	include_stack[include_stack_ptr].state = YY_CURRENT_BUFFER;
+	include_stack[include_stack_ptr].line = line;
+	include_stack[include_stack_ptr].column = column;
+	include_stack[include_stack_ptr].startline = startline;
+	include_stack[include_stack_ptr].startcolumn = startcolumn;
+	include_stack[include_stack_ptr].finame = finame;
+	include_stack_ptr++;
+
+	line=1;
+	column=1;
+	startline=1;
+	startcolumn=1;
+
+	yyin = fopen(fin, "r" );
+
+	if ( ! yyin )
+	{
+		finame = (finame==0)?cfg_file:finame;
+		if(finame==0 || fin[0]=='/')
+		{
+			LOG(L_CRIT, "cannot open included file: %s\n", fin);
+			return -1;
+		}
+		x = strrchr(finame, '/');
+		if(x)
+		{
+			newf = (char*)pkg_malloc(x-finame+strlen(fin)+2);
+			if(newf==0)
+			{
+				LOG(L_CRIT, "no more pkg\n");
+				return -1;
+			}
+			newf[0] = '\0';
+			strncat(newf, finame, x-finame);
+			strcat(newf, "/");
+			strcat(newf, fin);
+		}
+		yyin = fopen(newf, "r" );
+		if ( ! yyin )
+		{
+			LOG(L_CRIT, "cannot open included file: %s (%s)\n", fin, newf);
+			return -1;
+		}
+		LOG(L_DBG, "including file: %s (%s)\n", fin, newf);
+	} else {
+		newf = fin;
+	}
+
+	fn = sr_yy_fname_list;
+	while(fn!=0)
+	{
+		if(strcmp(fn->fname, newf)==0)
+		{
+			if(newf!=fin)
+				pkg_free(newf);
+			newf = fin;
+			break;
+		}
+		fn = fn->next;
+	}
+	if(fn==0)
+	{
+		fn = (struct sr_yy_fname*)pkg_malloc(sizeof(struct sr_yy_fname));
+		if(fn==0)
+		{
+			if(newf!=fin)
+				pkg_free(newf);
+			LOG(L_CRIT, "no more pkg\n");
+			return -1;
+		}
+		if(newf==fin)
+		{
+			fn->fname = (char*)pkg_malloc(strlen(fin)+1);
+			if(fn->fname==0)
+			{
+				pkg_free(fn);
+				LOG(L_CRIT, "no more pkg!\n");
+				return -1;
+			}
+			strcpy(fn->fname, fin);
+		} else {
+			fn->fname = newf;
+		}
+		fn->next = sr_yy_fname_list;
+		sr_yy_fname_list = fn;
+	}
+
+	finame = fn->fname;
+
+	yy_switch_to_buffer( yy_create_buffer(yyin, YY_BUF_SIZE ) );
+
+	return 0;
+
+}
+
+static int sr_pop_yy_state()
+{
+	include_stack_ptr--;
+	if (include_stack_ptr<0 )
+		return -1;
+
+	yy_delete_buffer( YY_CURRENT_BUFFER );
+	yy_switch_to_buffer(include_stack[include_stack_ptr].state);
+	line=include_stack[include_stack_ptr].line;
+	column=include_stack[include_stack_ptr].column;
+	startline=include_stack[include_stack_ptr].startline;
+	startcolumn=include_stack[include_stack_ptr].startcolumn;
+	finame = include_stack[include_stack_ptr].finame;
+	return 0;
+}
+
diff --git a/cfg.y b/cfg.y
index 6950d88..25dd635 100644
--- a/cfg.y
+++ b/cfg.y
@@ -3070,7 +3070,7 @@ extern int line;
 extern int column;
 extern int startcolumn;
 extern int startline;
-
+extern char *finame;
 
 static void get_cpos(struct cfg_pos* pos)
 {
@@ -3078,6 +3078,9 @@ static void get_cpos(struct cfg_pos* pos)
 	pos->e_line=line;
 	pos->s_col=startcolumn;
 	pos->e_col=column-1;
+	if(finame==0)
+		finame = (cfg_file!=0)?cfg_file:"default";
+	pos->fname=finame;
 }
 
 
@@ -3090,15 +3093,15 @@ static void warn_at(struct cfg_pos* p, char* format, ...)
 	vsnprintf(s, sizeof(s), format, ap);
 	va_end(ap);
 	if (p->e_line!=p->s_line)
-		LOG(L_WARN, "warning in config file, from line %d, column %d to"
+		LOG(L_WARN, "warning in config file %s, from line %d, column %d to"
 					" line %d, column %d: %s\n",
-					p->s_line, p->s_col, p->e_line, p->e_col, s);
+					p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
 	else if (p->s_col!=p->e_col)
-		LOG(L_WARN, "warning in config file, line %d, column %d-%d: %s\n",
-					p->s_line, p->s_col, p->e_col, s);
+		LOG(L_WARN, "warning in config file %s, line %d, column %d-%d: %s\n",
+					p->fname, p->s_line, p->s_col, p->e_col, s);
 	else
-		LOG(L_WARN, "warning in config file, line %d, column %d: %s\n",
-				p->s_line, p->s_col, s);
+		LOG(L_WARN, "warning in config file %s, line %d, column %d: %s\n",
+				p->fname, p->s_line, p->s_col, s);
 	cfg_warnings++;
 }
 
@@ -3113,15 +3116,15 @@ static void yyerror_at(struct cfg_pos* p, char* format, ...)
 	vsnprintf(s, sizeof(s), format, ap);
 	va_end(ap);
 	if (p->e_line!=p->s_line)
-		LOG(L_CRIT, "parse error in config file, from line %d, column %d"
+		LOG(L_CRIT, "parse error in config file %s, from line %d, column %d"
 					" to line %d, column %d: %s\n",
-					p->s_line, p->s_col, p->e_line, p->e_col, s);
+					p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
 	else if (p->s_col!=p->e_col)
-		LOG(L_CRIT, "parse error in config file, line %d, column %d-%d: %s\n",
-					p->s_line, p->s_col, p->e_col, s);
+		LOG(L_CRIT,"parse error in config file %s, line %d, column %d-%d: %s\n",
+					p->fname, p->s_line, p->s_col, p->e_col, s);
 	else
-		LOG(L_CRIT, "parse error in config file, line %d, column %d: %s\n",
-					p->s_line, p->s_col, s);
+		LOG(L_CRIT, "parse error in config file %s, line %d, column %d: %s\n",
+					p->fname, p->s_line, p->s_col, s);
 	cfg_errors++;
 }
 
diff --git a/route_struct.h b/route_struct.h
index 9274340..fcc475e 100644
--- a/route_struct.h
+++ b/route_struct.h
@@ -136,6 +136,7 @@ struct cfg_pos{
 	int e_line;
 	unsigned short s_col;
 	unsigned short e_col;
+	char *fname;
 };
 
 




More information about the sr-dev mailing list