/* // // conf_lexer.lxx // // This lexical parser is used to parse ht://Dig config // files. // // Note: The resulting .cxx file produces warnings of unused // labels. As at 2003-06-02, these have been manually // removed, but they will reappear when (f)lex is re-run. // // Part of the ht://Dig package // Copyright (c) 1999-2004 The ht://Dig Group // For copyright details, see the file COPYING in your distribution // or the GNU Library General Public License (LGPL) version 2 or later // // // $Id: conf_lexer.lxx,v 1.12 2004/06/10 14:48:38 angusgb Exp $ // */ %{ #ifdef HAVE_CONFIG_H #include "htconfig.h" #endif /* HAVE_CONFIG_H */ %} %option yylineno noyywrap nounput %x t_right %x incl %x bracket %x br_string %{ #ifdef HAVE_STRINGS_H #include #endif #include "HtConfiguration.h" //#include "Dictionary.h" #include "conf_parser.h" #define MAX_INCLUDE_DEPTH 10 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; String *name_stack[MAX_INCLUDE_DEPTH]; int lineno_stack[MAX_INCLUDE_DEPTH]; int include_stack_ptr = 0; %} KEYWORD [a-zA-Z_][a-zA-Z_0-9/]* NUMBER [0-9]+ STRING [\x21-\xff]+ BR_STRING [^ \n\t<>]+ %% ^[[:space:]]*#.*\n /* Ignore comments */ ^[[:space:]]*\n /* Ignore empty lines */ <*>[ \t]+ /* Ignore spaces */ include[ \t]*: BEGIN(incl); "<" { BEGIN(bracket); return(T_LEFT_BR); } "/" return(T_SLASH); ">" return(T_RIGHT_BR); {KEYWORD} { //yylval.str = (char *)malloc(yyleng+1); yylval.str = new char[yyleng+1]; strcpy(yylval.str,yytext); return(T_KEYWORD); } {BR_STRING} { BEGIN(bracket); yylval.str = new char[yyleng+1]; strcpy(yylval.str,yytext); return(T_STRING); } {NUMBER} { //yylval.str = (char*)malloc(yyleng+1); yylval.str = new char[yyleng+1]; strcpy(yylval.str,yytext); return(T_NUMBER); } : { if (YY_START==bracket) BEGIN(br_string); else BEGIN(t_right); return(T_DELIMITER); } {STRING}\\\n { //yylval.str = (char *)malloc(yyleng+1-2); yylval.str = new char[yyleng+1-2]; //strcpy(yylval.str,yytext); memcpy(yylval.str,yytext,yyleng-2); yylval.str[yyleng-2]='\0'; return(T_STRING); } "\""[^\n]+"\"" { yylval.str = new char[yyleng+1]; strcpy(yylval.str,yytext); return(T_STRING); } {STRING} { //yylval.str = (char *)malloc(yyleng+1); yylval.str = new char[yyleng+1]; strcpy(yylval.str,yytext); return(T_STRING); } \\\n { /* Ignore newline after "\" */ } [ \t]* { /* Ignore spaces */ } {STRING} { /* got the include file name */ if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) { fprintf(stderr,"Includes nested too deeply\n"); // exit(1); // Seems too harsh! return(T_NEWLINE); } include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; HtConfiguration* config= HtConfiguration::config(); // handle ${var} in file name String ParsedFilename = config->ParseString(yytext); if (ParsedFilename[0] != '/') { // Given file name not fully qualified // so strip dir. name from current one String str; if (include_stack_ptr > 1) str = *name_stack[include_stack_ptr-2]; else // still at top level config str = config->getFileName(); int len = str.lastIndexOf('/') + 1; if (len > 0) { // Current name has directory path // component, so use it for new name str.chop(str.length() - len); str << ParsedFilename; ParsedFilename = str; } } yyin = fopen( ParsedFilename.get(), "r" ); if ( ! yyin ) { fprintf(stderr,"can't find file: %s\n",yytext); // exit(1); // Seems too harsh! include_stack_ptr--; return(T_NEWLINE); } name_stack[include_stack_ptr-1] = new String(ParsedFilename.get()); lineno_stack[include_stack_ptr-1] = yylineno; yylineno = 1; yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) ); BEGIN(INITIAL); } <> { if ( include_stack_ptr <= 0 ) { static int termnext = 0; // fix to allow unterminated final line if (++termnext <= 1) return(T_NEWLINE); termnext = 0; // in case we're called again yyterminate(); } else { delete name_stack[include_stack_ptr-1]; yylineno = lineno_stack[include_stack_ptr-1]; yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( include_stack[--include_stack_ptr] ); } } \n { BEGIN(INITIAL); return(T_NEWLINE); } ^[[:space:]]+ \n <*>.|\n { HtConfiguration* config= HtConfiguration::config(); String str; if (include_stack_ptr > 0) str = *name_stack[include_stack_ptr-1]; else // still at top level config str = config->getFileName(); fprintf(stderr,"Unknown char in file %s line %d: %s\n",str.get(),yylineno,yytext); // exit(1); // Seems too harsh! } %%