From a1c59d04b8d5ce972c34bd1e5abd941b55655029 Mon Sep 17 00:00:00 2001 From: marha <marha@users.sourceforge.net> Date: Wed, 1 Sep 2010 15:05:15 +0000 Subject: Make it possible to use more complicated expressions in if statements --- tools/mhmake/src/flexskel.cc | 3 - tools/mhmake/src/mhmakefileparser.cpp | 136 ++++++++++++++++++++++++++++++++++ tools/mhmake/src/mhmakefileparser.h | 3 + tools/mhmake/src/mhmakelexer.l | 38 +++++++--- tools/mhmake/src/util.h | 2 +- 5 files changed, 169 insertions(+), 13 deletions(-) (limited to 'tools/mhmake/src') diff --git a/tools/mhmake/src/flexskel.cc b/tools/mhmake/src/flexskel.cc index 43c395dba..a08f23fd3 100644 --- a/tools/mhmake/src/flexskel.cc +++ b/tools/mhmake/src/flexskel.cc @@ -806,9 +806,6 @@ void YY_@_CLASS::yyunput( YY_@_CHAR c, YY_@_CHAR *yy_bp ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } - if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) - yy_cp[-2] = '\n'; - *--yy_cp = c; /* note: the formal parameter *must* be called "yy_bp" for this diff --git a/tools/mhmake/src/mhmakefileparser.cpp b/tools/mhmake/src/mhmakefileparser.cpp index 35d379cd0..e87f46887 100644 --- a/tools/mhmake/src/mhmakefileparser.cpp +++ b/tools/mhmake/src/mhmakefileparser.cpp @@ -100,6 +100,10 @@ static inline size_t SkipMakeExpr(const string &Expr,size_t i) { i=SkipMakeExpr(Expr,i); } +#ifdef _DEBUG + if (i>=Expr.length()) + throw(string(") not found in ")+Expr); +#endif Char=Expr[i++]; } return i; @@ -1181,3 +1185,135 @@ void mhmakefileparser::CreateUSED_ENVVARS() m_Variables[USED_ENVVARS]=Val; } +static string s_TrueString("1"); +static string s_FalseString("0"); + +static string AndExpression(const string &First, const string &Second) +{ + if (First.empty() || First==s_FalseString) + { + return g_EmptyString; + } + else + { + return Second.empty() || Second==s_FalseString ? g_EmptyString : s_TrueString; + } +} + +static string OrExpression(const string &First, const string &Second) +{ + if (First.empty() || First==s_FalseString) + { + return Second.empty() || Second==s_FalseString ? g_EmptyString : s_TrueString; + } + else + { + return s_TrueString; + } +} + +string mhmakefileparser::ResolveExpression(const string &InExpr,string &Rest) const +{ + unsigned i=0; + string Ret; + string Expr=InExpr; + + Rest=g_EmptyString; + + while (i<Expr.length()) + { + while (strchr(" \t\r",Expr[i])) i++; + switch (Expr[i]) + { + case '!': + if (Expr[i+1]!='=') + { + Ret=ResolveExpression(Expr.substr(i+1),Expr); + Ret = Ret.empty() || Ret==s_FalseString ? s_TrueString : g_EmptyString; + i=0; + } + else + { + Ret = Ret!=ResolveExpression(Expr.substr(i+2),Expr) ? s_TrueString : g_EmptyString; + i=0; + } + break; + case '&': + if (Expr[i+1]!='&') + { + Ret+=Expr[i++]; + } + else + { + Ret=AndExpression(Ret,ResolveExpression(Expr.substr(i+2),Expr)); + i=0; + } + break; + case '|': + if (Expr[i+1]!='|') + { + Ret+=Expr[i++]; + } + else + { + Ret=OrExpression(Ret,ResolveExpression(Expr.substr(i+2),Expr)); + i=0; + } + break; + case '(': + if (Ret=="defined") + { + Ret=IsDefined(ResolveExpression(Expr.substr(i+1),Expr)) ? s_TrueString : g_EmptyString; + } + else + { + Ret+=ResolveExpression(Expr.substr(i+1),Expr); + } + i=0; + break; + case ')': + Rest=Expr.substr(i+1); + return Ret; + break; + case '"': + { + i++; + while (i<Expr.length()) + { + char Char=Expr[i++]; + if (Char=='"') + break; + Ret+=Char; + } + } + break; + case '=': + if (Expr[i+1]!='=') + { + Ret+=Expr[i++]; + } + else + { + Ret = Ret==ResolveExpression(Expr.substr(i+2),Expr) ? s_TrueString : g_EmptyString; + i=0; + } + break; + default: + Ret+=Expr[i++]; + break; + } + } + return Ret; +} +/////////////////////////////////////////////////////////////////////////////// +bool mhmakefileparser::IsExprTrue(const string &EqualExpr) const +{ + string Expr=ExpandExpression(EqualExpr); + string Rest; + Expr=ResolveExpression(Expr,Rest); + if (Expr.empty() || Expr==s_FalseString) + return false; + else + return true; +} + diff --git a/tools/mhmake/src/mhmakefileparser.h b/tools/mhmake/src/mhmakefileparser.h index 048435f34..73d3979dc 100644 --- a/tools/mhmake/src/mhmakefileparser.h +++ b/tools/mhmake/src/mhmakefileparser.h @@ -103,6 +103,8 @@ protected: set< const fileinfo* , less_fileinfo > m_Targets; // List of targets that are build by this makefile static mh_time_t m_sBuildTime; +private: + string mhmakefileparser::ResolveExpression(const string &InExpr,string &Rest) const; public: #ifdef _DEBUG @@ -228,6 +230,7 @@ public: /* Functions to handle variables */ bool IsDefined(const string &Var) const; bool IsEqual(const string &EqualExpr) const; + bool IsExprTrue(const string &EqualExpr) const; string ExpandExpression(const string &Expr) const; string ExpandMacro(const string &Expr) const; string ExpandVar(const string &Var) const; diff --git a/tools/mhmake/src/mhmakelexer.l b/tools/mhmake/src/mhmakelexer.l index d64d7cc5c..59aaad0ca 100644 --- a/tools/mhmake/src/mhmakelexer.l +++ b/tools/mhmake/src/mhmakelexer.l @@ -337,11 +337,13 @@ load_makefile { ^[ \t]*if[ \t]*\\[ \t\r]*\n[ \t]* { BEGIN(IF); m_Line++; + m_curtoken=g_EmptyString; return mhmakeparser::NEWLINE; } ^[ \t]*if[ \t]+ { BEGIN(IF); + m_curtoken=g_EmptyString; return mhmakeparser::NEWLINE; } @@ -417,12 +419,12 @@ load_makefile { } } -<IFEQ,IFNEQ>[ \t]*\\[ \t\r]*\n[ \t]* { m_Line++; m_curtoken += g_SpaceString;} +<IF,IFEQ,IFNEQ>[ \t]*\\[ \t\r]*\n[ \t]* { m_Line++; m_curtoken += g_SpaceString;} -<IFEQ,IFNEQ>\r /* skip */ +<IF,IFEQ,IFNEQ>\r /* skip */ -<IFEQ,IFNEQ>[^\\\r\n]+ | -<IFEQ,IFNEQ>\\ { m_curtoken += (const char *)yytext; } +<IF,IFEQ,IFNEQ>[^\\\r\n]+ | +<IF,IFEQ,IFNEQ>\\ { m_curtoken += (const char *)yytext; } /*****************************************************************************/ <IFNEQ>\n { @@ -442,10 +444,8 @@ load_makefile { } /*****************************************************************************/ -<IF,IFDEF,IFNDEF>[ \t\r]* /* skip */ - - /*---------------------------------------------------------------------------*/ -<IF>[a-zA-Z0-9_]+ { +<IF>[ \t\r]*[a-zA-Z0-9_]+[ \t\r]*\n { + unput( '\n' ); m_IndentStack.push(0); string Val=GetParser()->ExpandVar((const char *)yytext); if (Val.empty() || Val=="0") @@ -461,6 +461,26 @@ load_makefile { } } + /*---------------------------------------------------------------------------*/ +<IF>\n { + unput( yytext[0] ); + m_IndentStack.push(0); + if (GetParser()->IsExprTrue(m_curtoken)) + { + PRINTF(("%s %d: Not Skipping ifeq %s: depth %d\n",m_InputFileName.c_str(),m_Line,m_curtoken.c_str(),m_IndentStack.size())); + BEGIN(INITIAL); + } + else + { + PRINTF(("%s %d: Skipping ifeq %s: depth %d\n",m_InputFileName.c_str(),m_Line,m_curtoken.c_str(),m_IndentStack.size())); + m_IndentSkip=m_IndentStack.size(); + BEGIN(SKIPUNTILELSEORENDIF); + } +} + + /*****************************************************************************/ +<IFDEF,IFNDEF>[ \t\r]* /* skip */ + /*---------------------------------------------------------------------------*/ <IFDEF>[a-zA-Z0-9_]+ { m_IndentStack.push(0); @@ -523,7 +543,7 @@ load_makefile { } /*---------------------------------------------------------------------------*/ -<SKIPUNTILELSEORENDIF>\n[ ]*if(def|ndef|eq|neq) { +<SKIPUNTILELSEORENDIF>\n[ ]*if(def|ndef|eq|neq)? { m_Line++; m_IndentStack.push(0); PRINTF(("%s %d: %s: depth %d\n",m_InputFileName.c_str(),m_Line,yytext+1,m_IndentStack.size())); diff --git a/tools/mhmake/src/util.h b/tools/mhmake/src/util.h index ef874eb96..62efbd245 100644 --- a/tools/mhmake/src/util.h +++ b/tools/mhmake/src/util.h @@ -50,7 +50,7 @@ #define PLATFORM "linux" #endif -#define MHMAKEVER "2.1.0" +#define MHMAKEVER "2.2.0" class makecommand { -- cgit v1.2.3