aboutsummaryrefslogtreecommitdiff
path: root/tools/mhmake/src
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-09-01 15:05:15 +0000
committermarha <marha@users.sourceforge.net>2010-09-01 15:05:15 +0000
commita1c59d04b8d5ce972c34bd1e5abd941b55655029 (patch)
treebb62b1ec94277a10de7bc22bba9ac62e74878b5d /tools/mhmake/src
parente09e8cbeb878fc881b6987280e18ce5430318451 (diff)
downloadvcxsrv-a1c59d04b8d5ce972c34bd1e5abd941b55655029.tar.gz
vcxsrv-a1c59d04b8d5ce972c34bd1e5abd941b55655029.tar.bz2
vcxsrv-a1c59d04b8d5ce972c34bd1e5abd941b55655029.zip
Make it possible to use more complicated expressions in if statements
Diffstat (limited to 'tools/mhmake/src')
-rw-r--r--tools/mhmake/src/flexskel.cc3
-rw-r--r--tools/mhmake/src/mhmakefileparser.cpp136
-rw-r--r--tools/mhmake/src/mhmakefileparser.h3
-rw-r--r--tools/mhmake/src/mhmakelexer.l38
-rw-r--r--tools/mhmake/src/util.h2
5 files changed, 169 insertions, 13 deletions
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")
@@ -462,6 +462,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);
if (GetParser()->IsDefined((const char *)yytext))
@@ -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
{