Module: sip-router Branch: master Commit: d20565193c1176312a29d75710d494707abdf6a5 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d2056519...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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; };