You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
5.5 KiB

/*
//
// 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 <http://www.htdig.org/>
// 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
// <http://www.gnu.org/copyleft/lgpl.html>
//
// $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 <strings.h>
#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); }
<bracket>"/" return(T_SLASH);
<bracket>">" return(T_RIGHT_BR);
<INITIAL,bracket>{KEYWORD} {
//yylval.str = (char *)malloc(yyleng+1);
yylval.str = new char[yyleng+1];
strcpy(yylval.str,yytext);
return(T_KEYWORD);
}
<br_string>{BR_STRING} {
BEGIN(bracket);
yylval.str = new char[yyleng+1];
strcpy(yylval.str,yytext);
return(T_STRING);
}
<t_right>{NUMBER} {
//yylval.str = (char*)malloc(yyleng+1);
yylval.str = new char[yyleng+1];
strcpy(yylval.str,yytext);
return(T_NUMBER);
}
<INITIAL,bracket>: {
if (YY_START==bracket)
BEGIN(br_string);
else
BEGIN(t_right);
return(T_DELIMITER);
}
<t_right>{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);
}
<t_right>"\""[^\n]+"\"" {
yylval.str = new char[yyleng+1];
strcpy(yylval.str,yytext);
return(T_STRING);
}
<t_right>{STRING} {
//yylval.str = (char *)malloc(yyleng+1);
yylval.str = new char[yyleng+1];
strcpy(yylval.str,yytext);
return(T_STRING);
}
<t_right>\\\n
{
/* Ignore newline after "\" */
}
<t_right>[ \t]*
{
/* Ignore spaces */
}
<incl>{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);
}
<<EOF>> {
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] );
}
}
<bracket,t_right>\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!
}
%%