357 lines
11 KiB
Plaintext
357 lines
11 KiB
Plaintext
//
|
|
// The developer of the original code and/or files is Tripwire, Inc.
|
|
// Portions created by Tripwire, Inc. are copyright (C) 2000-2017 Tripwire,
|
|
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
|
|
// reserved.
|
|
//
|
|
// This program is free software. The contents of this file are subject
|
|
// to the terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 2 of the License, or (at your
|
|
// option) any later version. You may redistribute it and/or modify it
|
|
// only in compliance with the GNU General Public License.
|
|
//
|
|
// This program is distributed in the hope that it will be useful.
|
|
// However, this program is distributed AS-IS WITHOUT ANY
|
|
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
|
|
// for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
// USA.
|
|
//
|
|
// Nothing in the GNU General Public License or any other license to use
|
|
// the code or files shall permit you to use Tripwire's trademarks,
|
|
// service marks, or other intellectual property without Tripwire's
|
|
// prior written consent.
|
|
//
|
|
// If you have any questions, please contact Tripwire, Inc. at either
|
|
// info@tripwire.org or www.tripwire.org.
|
|
//
|
|
/*
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// tokens.l -- describes all the tokens for the policy language
|
|
//
|
|
*/
|
|
|
|
/* increases number of states in DFA to 5000 */
|
|
%p 5000
|
|
|
|
%{
|
|
#include "stdtwparser.h"
|
|
|
|
//#ifndef YYNEWLINE
|
|
# include "twparser/yylex.h"
|
|
# include "twparser/yyparse.h"
|
|
//#endif
|
|
|
|
#include <stdio.h>
|
|
#ifdef HAVE_MALLOC_H
|
|
#include <malloc.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
|
|
#include "core/debug.h"
|
|
|
|
#include "policyparser.h"
|
|
#include "parserhelper.h"
|
|
#include "genreparseinfo.h"
|
|
#include "core/stringutil.h"
|
|
#include "core/displayencoder.h"
|
|
|
|
|
|
|
|
/* specify that the lexer exit on EOF */
|
|
int yywrap()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/* wrapper around cDebug tracing */
|
|
void lextrace(const TCHAR*str)
|
|
{
|
|
cDebug d("\t\t\t\tlexer");
|
|
d.TraceDetail( _T("%s\n"), str);
|
|
}
|
|
|
|
// since i've replaced this with a non-va_arg yyerror,
|
|
// call this when you hit a syntax error and then call
|
|
// the non-va_arg yyerror with the result
|
|
std::string FormatSyntaxError( char ch, const char* pszAdditionalMsg = NULL )
|
|
{
|
|
// TODO:BAM MKS will call yyerror with narrow-char hard-coded string, so if
|
|
// we do it here as well, I suppose that's OK. This should be eventually
|
|
// corrected.
|
|
|
|
std::ostringstream ssErr;
|
|
ssErr << "Syntax error: \'" << ch << "\'";
|
|
if( pszAdditionalMsg )
|
|
ssErr << ", " << pszAdditionalMsg;
|
|
|
|
return ssErr.str();
|
|
}
|
|
|
|
// saves typing
|
|
#define TRACE_RETURN(x) lextrace(_T(#x)); return x
|
|
|
|
%}
|
|
|
|
/* Defining a start-condition for parsing a global definitions section */
|
|
/* in a special manner: */
|
|
%x globals
|
|
|
|
WS [ \t\r]
|
|
COMMENT #.*
|
|
BSLASH \\
|
|
DBL_QUOTE \"
|
|
DIRECTIVE @@
|
|
EOL \n
|
|
SEMICOLON ;
|
|
DOLLAR \$
|
|
COMMA \,
|
|
PIPE \|
|
|
OROR \|\|
|
|
EQUALS =
|
|
|
|
LPAREN \(
|
|
RPAREN \)
|
|
|
|
|
|
/* normal strings -- anything but our reserved symbols */
|
|
STRING ([^!\{\}>\(\)\n\r\t \,;=$#|\"]+)
|
|
|
|
|
|
/* quoted strings can contain escaped characters (including escaped quotes). Can also be empty string. */
|
|
QSTRING (\"(([^\\\"\n])|(\\.))*\")
|
|
|
|
SECTION {WS}*{DIRECTIVE}{WS}*section
|
|
IFHOST {WS}*{DIRECTIVE}{WS}*ifhost
|
|
ELSE {WS}*{DIRECTIVE}{WS}*else
|
|
ENDIF {WS}*{DIRECTIVE}{WS}*endif
|
|
ERROR {WS}*{DIRECTIVE}{WS}*error
|
|
ECHO {WS}*{DIRECTIVE}{WS}*print
|
|
END {WS}*{DIRECTIVE}{WS}*end
|
|
|
|
%%
|
|
|
|
/* Lexer state-switching code for implementing a "global definitions" section while enforcing */
|
|
/* the limited scope of such a construct. The lexer will catch anything that cannot be */
|
|
/* coerced into a variable definition, and output special warnings. */
|
|
|
|
^{SECTION}{WS}*((global)|(GLOBAL)) {
|
|
BEGIN( globals );
|
|
}
|
|
|
|
/* Are we done with the definitions section? */
|
|
<globals>^{SECTION} {
|
|
BEGIN(INITIAL);
|
|
return TWP_SECTION;
|
|
}
|
|
|
|
<globals>^{ECHO} { TRACE_RETURN(TWP_ECHO); }
|
|
|
|
/* We still need to eat white space, line continuations, and comments... */
|
|
<globals>{WS}+ {
|
|
lextrace(_T("eating spaces...")); /* eat spaces */
|
|
}
|
|
<globals>{BSLASH}{EOL} {
|
|
cParserHelper::IncrementLineNumber();
|
|
lextrace(_T("eating line continuation...")); /* eat line continuations */
|
|
}
|
|
<globals>{COMMENT} {
|
|
lextrace(_T("eating comment..."));
|
|
}
|
|
|
|
/* We still need to increment the line #, and pass the two tokens needed to */
|
|
/* do variable definitions: */
|
|
|
|
/* We still need to treat strings the same way, just return a differnt ID. TODO: */
|
|
/* Maybe create some helper functions and get rid of all this repeat code? */
|
|
<globals>{STRING} {
|
|
// we must make copy of string, otherwise another lexeme will clobber it
|
|
cDebug d("\t\t\t\tlexer::string");
|
|
|
|
// convert LPCSTR to TSTRING
|
|
cParseString *mpstring = new cParseString;
|
|
ASSERT(mpstring);
|
|
*mpstring = cStringUtil::StrToTstr( yytext );
|
|
|
|
d.TraceDetail("--> <%s>\n", mpstring->c_str());
|
|
|
|
// attach to lval
|
|
yylval.mpString = mpstring;
|
|
|
|
return TWP_GLOBAL_STRING;
|
|
}
|
|
|
|
<globals>{QSTRING} {
|
|
// we must make copy of string, otherwise another lexeme will clobber it
|
|
cDebug d("\t\t\t\tlexer::qstring");
|
|
|
|
// get rid of beginning and trailing quotes
|
|
std::string strWithQuotes = yytext;
|
|
std::string str = strWithQuotes.substr(1, strWithQuotes.size() - 2);
|
|
|
|
// convert any escape characters
|
|
TSTRING strW;
|
|
cParserUtil::InterpretEscapedString( str, strW );
|
|
|
|
d.TraceDetail(_T("read as --> <%s>\n"), strW.c_str());
|
|
|
|
// convert TSTRING to cParseString
|
|
cParseString *mpstring = new cParseString;
|
|
ASSERT(mpstring);
|
|
*mpstring = strW;
|
|
|
|
|
|
d.TraceDetail("interpreted as --> <%s>\n", mpstring->c_str());
|
|
|
|
// attach to lval
|
|
yylval.mpString = mpstring;
|
|
return TWP_GLOBAL_STRING;
|
|
}
|
|
|
|
<globals>{SEMICOLON} { TRACE_RETURN(TWP_SEMICOLON); }
|
|
<globals>{EQUALS} { TRACE_RETURN(TWP_EQUALS); }
|
|
|
|
<globals>\n { cParserHelper::IncrementLineNumber(); }
|
|
<globals>. {
|
|
std::string strError;
|
|
strError = FormatSyntaxError( yytext[0], "The global section only accepts statements of the form:\n variable = value;\n" );
|
|
|
|
// MKS defines yyerror with char*, for some stupid reason,
|
|
// so cast it away
|
|
yyerror( const_cast<char*>( strError.c_str() ) );
|
|
} /* catches anything that cannot be deemed a variable definition and exits. */
|
|
|
|
/* consume spaces */
|
|
{WS}+ {
|
|
lextrace(_T("eating spaces...")); /* eat spaces */
|
|
}
|
|
|
|
{BSLASH}{EOL} {
|
|
cParserHelper::IncrementLineNumber();
|
|
lextrace(_T("eating line continuation...")); /* eat line continuations */
|
|
}
|
|
|
|
{COMMENT} {
|
|
lextrace(_T("eating comment..."));
|
|
}
|
|
|
|
"{" { TRACE_RETURN(TWP_LBRACE); }
|
|
"}" { TRACE_RETURN(TWP_RBRACE); }
|
|
|
|
|
|
"!" { TRACE_RETURN(TWP_BANG); }
|
|
|
|
"->" { TRACE_RETURN(TWP_RARROW); }
|
|
{EQUALS} { TRACE_RETURN(TWP_EQUALS); }
|
|
|
|
{SEMICOLON} { TRACE_RETURN(TWP_SEMICOLON); }
|
|
{LPAREN} { TRACE_RETURN(TWP_LPAREN); }
|
|
{RPAREN} { TRACE_RETURN(TWP_RPAREN); }
|
|
{COMMA} { TRACE_RETURN(TWP_COMMA); }
|
|
{PIPE} { TRACE_RETURN(TWP_PIPE); }
|
|
|
|
|
|
/* variables */
|
|
{DOLLAR} { TRACE_RETURN(TWP_DOLLAR); }
|
|
{OROR} { TRACE_RETURN(TWP_OROR); }
|
|
|
|
|
|
^{SECTION} { TRACE_RETURN(TWP_SECTION); }
|
|
^{IFHOST} { TRACE_RETURN(TWP_IFHOST); }
|
|
^{ELSE} { TRACE_RETURN(TWP_ELSE); }
|
|
^{ENDIF} { TRACE_RETURN(TWP_ENDIF); }
|
|
^{ERROR} { TRACE_RETURN(TWP_ERROR); }
|
|
^{ECHO} { TRACE_RETURN(TWP_ECHO); }
|
|
^{END} { lextrace( _T( "@@end" ) ); return 0; } /* logical end of file */
|
|
|
|
|
|
{STRING} {
|
|
// we must make copy of string, otherwise another lexeme will clobber it
|
|
cDebug d("\t\t\t\tlexer::string");
|
|
|
|
// convert LPCSTR to TSTRING
|
|
cParseString *mpstring = new cParseString;
|
|
ASSERT(mpstring);
|
|
*mpstring = cStringUtil::StrToTstr( yytext );
|
|
|
|
d.TraceDetail("--> <%s>\n", mpstring->c_str());
|
|
|
|
// attach to lval
|
|
yylval.mpString = mpstring;
|
|
|
|
return TWP_STRING;
|
|
}
|
|
|
|
{QSTRING} {
|
|
// we must make copy of string, otherwise another lexeme will clobber it
|
|
cDebug d("\t\t\t\tlexer::qstring");
|
|
|
|
// get rid of beginning and trailing quotes
|
|
std::string strWithQuotes = yytext;
|
|
std::string str = strWithQuotes.substr(1, strWithQuotes.size() - 2);
|
|
|
|
// convert any escape characters
|
|
TSTRING strW;
|
|
cParserUtil::InterpretEscapedString( str, strW );
|
|
|
|
d.TraceDetail(_T("read as --> <%s>\n"), strW.c_str());
|
|
|
|
if( cPreprocessor::GetState() == cPreprocessor::STATE_ACCEPT )
|
|
{
|
|
cParserHelper::GetGenreInfo()->DoVarSubstitution( strW );
|
|
}
|
|
|
|
// convert TSTRING to cParseString
|
|
cParseString *mpstring = new cParseString;
|
|
ASSERT(mpstring);
|
|
*mpstring = strW;
|
|
|
|
|
|
#ifdef DEBUG
|
|
TSTRING strDisplay = *mpstring;
|
|
cDisplayEncoder e;
|
|
e.Encode( strDisplay );
|
|
d.TraceDetail("interpreted as --> <%s>\n", strDisplay.c_str());
|
|
#endif // DEBUG
|
|
|
|
// attach to lval
|
|
yylval.mpString = mpstring;
|
|
return TWP_STRING;
|
|
}
|
|
|
|
/* not implemented yet
|
|
^{DIRECTIVE}{WS}*include{WS}\"[^\"]\" {
|
|
|
|
// get include file name
|
|
TCHAR szFilename[iFSServices::TW_MAX_PATH];
|
|
|
|
FILE* fpIncludeFile = _tfopen( szFilename, _T("r") );
|
|
if( fpIncludeFile )
|
|
{
|
|
lex_include_file( fpIncludeFile );
|
|
|
|
fclose( fpIncludeFile );
|
|
}
|
|
}
|
|
*/
|
|
|
|
\n { cParserHelper::IncrementLineNumber(); }
|
|
. {
|
|
std::string strError;
|
|
strError = FormatSyntaxError( yytext[0] );
|
|
|
|
// MKS defines yyerror with char*, for some stupid reason,
|
|
// so cast it away
|
|
yyerror( const_cast<char*>( strError.c_str() ) );
|
|
} /* catches anything else that's not in here and quits */
|
|
|
|
|
|
%%
|
|
|
|
|
|
|