aboutsummaryrefslogtreecommitdiff
path: root/tools/mhmake/src
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mhmake/src')
-rw-r--r--tools/mhmake/src/bisondata/lalr1.cc5
-rw-r--r--tools/mhmake/src/build.cpp70
-rw-r--r--tools/mhmake/src/flexlexer.h8
-rw-r--r--tools/mhmake/src/functions.cpp291
-rw-r--r--tools/mhmake/src/mhmake.cpp14
-rw-r--r--tools/mhmake/src/mhmakefileparser.cpp167
-rw-r--r--tools/mhmake/src/mhmakefileparser.h118
-rw-r--r--tools/mhmake/src/mhmakelexer.l115
-rw-r--r--tools/mhmake/src/mhmakeparser.y90
-rw-r--r--tools/mhmake/src/util.cpp48
-rw-r--r--tools/mhmake/src/util.h44
11 files changed, 584 insertions, 386 deletions
diff --git a/tools/mhmake/src/bisondata/lalr1.cc b/tools/mhmake/src/bisondata/lalr1.cc
index 25dd01938..fdc033a1d 100644
--- a/tools/mhmake/src/bisondata/lalr1.cc
+++ b/tools/mhmake/src/bisondata/lalr1.cc
@@ -153,6 +153,11 @@ b4_user_stype
void set_debug_level (debug_level_type l);
#endif
+ position *GetCurPos(void)
+ {
+ return &yylocation_stack_[1].begin;
+ }
+
private:
/// Report a syntax error.
/// \param loc where the syntax error is found.
diff --git a/tools/mhmake/src/build.cpp b/tools/mhmake/src/build.cpp
index 682a98410..5976a8632 100644
--- a/tools/mhmake/src/build.cpp
+++ b/tools/mhmake/src/build.cpp
@@ -400,14 +400,33 @@ mh_pid_t mhmakefileparser::MakeDirsCommand(const string &Params) const
}
/*****************************************************************************/
-mh_pid_t mhmakefileparser::EchoCommand(const string &Params) const
+static string RemoveQuotes(const string &StrIn)
{
+ char FirstChar=StrIn[0];
+ string Ret=StrIn;
+ if (FirstChar=='"')
+ {
+ int Len=Ret.length()-1;
+ if (Ret[Len]=='"')
+ Ret=Ret.substr(1,Len-1);
+ }
+ else if (FirstChar=='\'')
+ {
+ int Len=Ret.length()-1;
+ if (Ret[Len]=='\'')
+ Ret=Ret.substr(1,Len-1);
+ }
+ return Ret;
+}
+mh_pid_t mhmakefileparser::EchoCommand(const string &ParamsIn) const
+{
+ string Params=f_strip(ParamsIn);
// Find the first > character
size_t Pos=Params.find_first_of('>');
if (Pos==string::npos)
{
// Just echo it
- cout << Params << endl;
+ cout << RemoveQuotes(Params) << endl;
}
else
{
@@ -432,9 +451,7 @@ mh_pid_t mhmakefileparser::EchoCommand(const string &Params) const
cerr << "Error opening file "<<Filename<<endl;
return (mh_pid_t)-1;
}
- int Begin=0;
- while (Params[Begin]==' ' || Params[Begin] == '\t') Begin++; // Strip leading white space
- string EchoStr=Params.substr(Begin,Pos-1)+"\n";
+ string EchoStr=RemoveQuotes(Params.substr(0,Pos-1))+"\n";
if (EchoStr.length()!=fwrite(EchoStr.c_str(),1,EchoStr.length(),pfFile))
{
cerr << "Error writing file "<<Filename<<endl;
@@ -656,10 +673,28 @@ static const string &GetComspec()
}
/*****************************************************************************/
-string mhmakefileparser::GetFullCommand(string Command)
+static string GetExecutableFromCommand(const string &FullCommand)
+{
+ string Ret;
+ FILE *pFile=fopen(FullCommand.c_str(),"r");
+ if (!pFile)
+ return Ret;
+ char Line[MAX_PATH];
+ if (fgets(Line,MAX_PATH,pFile) && Line[0]=='#' && Line[1]=='!')
+ {
+ Ret=Line+2;
+ Ret.resize(Ret.length()-1);
+ Ret=QuoteFileName(Ret)+" ";
+ }
+ fclose(pFile);
+ return Ret;
+}
+
+/*****************************************************************************/
+string mhmakefileparser::GetFullCommand(const string &CommandIn)
{
- map<string,string>::iterator pFound=m_CommandCache.find(Command);
- string OriCommand=Command;
+ map<string,string>::iterator pFound=m_CommandCache.find(CommandIn);
+ string Command=CommandIn;
if (pFound==m_CommandCache.end())
{
bool Found=false;
@@ -688,11 +723,10 @@ string mhmakefileparser::GetFullCommand(string Command)
}
else
{
- static bool s_Py2ExeInstalled=true;
/* First check for special internal commands */
- if (OriCommand=="del")
+ if (CommandIn=="del")
{
- m_CommandCache[OriCommand]="del";
+ m_CommandCache[CommandIn]="del";
return Command;
}
// Try with different extensions
@@ -710,13 +744,23 @@ string mhmakefileparser::GetFullCommand(string Command)
Found=true;
Command=GetPythonExe()+QuoteFileName(FullCommand);
}
+ else
+ {
+ // also search without extension, if found look inside the file if we find an executable to use
+ FullCommand=SearchCommand(Command);
+ if (!FullCommand.empty())
+ {
+ Found=true;
+ Command=GetExecutableFromCommand(FullCommand)+QuoteFileName(FullCommand);
+ }
+ }
}
}
if (!Found)
{
Command=GetComspec()+QuoteFileName(Command);
}
- m_CommandCache[OriCommand]=Command;
+ m_CommandCache[CommandIn]=Command;
return Command;
}
return pFound->second;
@@ -1374,7 +1418,7 @@ mh_time_t mhmakefileparser::StartBuildTarget(fileinfo* pTarget,bool bCheckTarget
mh_time_t TargetDate=pTarget->GetDate();
mh_time_t YoungestDate=TargetDate;
- bool MakeTarget=!TargetDate.DoesExist();
+ bool MakeTarget=!TargetDate.DoesExist(); // When the target does not exist, always build when a rule is found. This also makes sure the autodepscan will be done in case the target does not exist yet
if (!pRule || !pRule->GetCommands().size())
{
diff --git a/tools/mhmake/src/flexlexer.h b/tools/mhmake/src/flexlexer.h
index 08acef335..33132dc93 100644
--- a/tools/mhmake/src/flexlexer.h
+++ b/tools/mhmake/src/flexlexer.h
@@ -151,13 +151,13 @@ public:
string m_InputFileName;
string m_curtoken;
mystack m_IncludeStack;
- mhmakefileparser *m_pParser;
- mhmakefileparser *GetParser()
+ mhmakefileparser *m_pMakefileParser;
+ mhmakefileparser *GetParser(void)
{
- return m_pParser;
+ return m_pMakefileParser;
}
public:
- string &GetInputFilename()
+ string &GetInputFilename(void)
{
return m_InputFileName;
}
diff --git a/tools/mhmake/src/functions.cpp b/tools/mhmake/src/functions.cpp
index 61ae6c1e4..1071d2604 100644
--- a/tools/mhmake/src/functions.cpp
+++ b/tools/mhmake/src/functions.cpp
@@ -54,12 +54,42 @@ funcdef mhmakefileparser::m_FunctionsDef[]= {
,{"strip" ,&mhmakefileparser::f_strip}
,{"which" ,&mhmakefileparser::f_which}
,{"foreach" ,&mhmakefileparser::f_foreach}
+ ,{"eval" ,&mhmakefileparser::f_eval}
+ ,{"sort" ,&mhmakefileparser::f_sort}
+ ,{"error" ,&mhmakefileparser::f_error}
+ ,{"info" ,&mhmakefileparser::f_info}
+ ,{"warning" ,&mhmakefileparser::f_warning}
};
map<string,function_f> mhmakefileparser::m_Functions;
bool mhmakefileparser::m_FunctionsInitialised;
+inline const char *NextCharExprItem(const char *pTmp,string &Output,char Char)
+{
+ const char *pStart=pTmp;
+ while (*pTmp)
+ {
+ char CurChar=*pTmp;
+ if (CurChar==Char)
+ break;
+ pTmp++;
+ if (CurChar=='$' && *pTmp!='$')
+ pTmp=SkipMakeExpr(pTmp);
+ }
+
+ const char *pStop=pTmp;
+ if (*pTmp) pTmp++;
+
+ while (pStart<pStop && (*pStart==' ' || *pStart == '\t')) pStart++;
+ pStop--;
+ while (pStart<=pStop && (*pStop==' ' || *pStop == '\t')) pStop--;
+ pStop++;
+
+ Output=string(pStart,pStop);
+ return pTmp;
+}
+
///////////////////////////////////////////////////////////////////////////////
// Loop over a list of filenames
static string IterList(const string &List,string (*iterFunc)(const string &FileName,void *pArg), void *pArg=NULL)
@@ -100,11 +130,12 @@ void mhmakefileparser::InitFuncs(void)
static string TrimString(const string &Input)
{
unsigned Start=0;
- while (strchr(" \t",Input[Start])) Start++;
+ const char *pInput=Input.c_str();
+ while (strchr(" \t",pInput[Start])) Start++;
if (Start>=Input.size())
return g_EmptyString;
size_t Stop=Input.size()-1;
- while (strchr(" \t",Input[Stop])) Stop--;
+ while (strchr(" \t",pInput[Stop])) Stop--;
return Input.substr(Start,Stop-Start+1);
}
@@ -119,8 +150,9 @@ static string filter(const string &FileName, void *pvFilter)
return g_EmptyString;
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_filter(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_filter(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
size_t ipos=Arg.find(',');
#ifdef _DEBUG
if (ipos==string::npos) {
@@ -137,8 +169,9 @@ string mhmakefileparser::f_filter(const string & Arg, const string *pOriExpr) co
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_filterout(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_filterout(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
size_t ipos=Arg.find(',');
#ifdef _DEBUG
if (ipos==string::npos) {
@@ -175,9 +208,52 @@ string mhmakefileparser::f_filterout(const string & Arg, const string *pOriExpr)
return Ret;
}
+class varstack_t : public vector< pair<bool,string> >
+{
+ mhmakefileparser *m_pMakefileParser;
+public:
+ varstack_t(mhmakefileparser *pMakefileParser)
+ : m_pMakefileParser(pMakefileParser)
+ {
+ }
+ void PushArg(int ArgNr, const string &Value)
+ {
+ char szVarName[10];
+ ::sprintf(szVarName,"%d",ArgNr);
+ string VarName(szVarName);
+ string VarVal;
+ if (m_pMakefileParser->GetVariable(VarName,VarVal))
+ vector< pair<bool,string> >::push_back(pair<bool,string>(true, VarVal));
+ else
+ vector< pair<bool,string> >::push_back(pair<bool,string>(false,g_EmptyString));
+ m_pMakefileParser->SetVariable(VarName,Value);
+ }
+ void RestoreArgs()
+ {
+ vector< pair<bool,string> >::iterator It=begin();
+ int ArgNr=0;
+ while (It!=end())
+ {
+ char szVarName[10];
+ ::sprintf(szVarName,"%d",ArgNr);
+ string VarName(szVarName);
+ if (It->first)
+ m_pMakefileParser->SetVariable(VarName, It->second);
+ else
+ {
+ m_pMakefileParser->DeleteVariable(VarName);
+ }
+ It++;
+ ArgNr++;
+ }
+ }
+};
+
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_call(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_call(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
+ varstack_t VarStack((mhmakefileparser*)this);
const char *pTmp=Arg.c_str();
bool LastCharIsComma=Arg[Arg.length()-1]==',';
@@ -191,6 +267,9 @@ string mhmakefileparser::f_call(const string & Arg, const string *pOriExpr) cons
throw string("call to non existing function ")+Func;
}
#endif
+ // the 0 argument is the function itself
+ VarStack.PushArg(0,Func);
+
Func=pFunc->second;
int i=0;
while (*pTmp || LastCharIsComma) {
@@ -199,23 +278,20 @@ string mhmakefileparser::f_call(const string & Arg, const string *pOriExpr) cons
string Repl;
pTmp=NextCharItem(pTmp,Repl,',');
i++;
- char Tmp[10];
- ::sprintf(Tmp,"$(%d)",i);
- size_t Len=::strlen(Tmp);
- size_t Pos=Func.find(Tmp);
- while (Func.npos!=Pos)
- {
- Func=Func.substr(0,Pos)+Repl+Func.substr(Pos+Len);
- Pos=Func.find(Tmp,Pos+Len);
- }
+ VarStack.PushArg(i,Repl);
}
- return ExpandExpression(Func);
+ string Ret=ExpandExpression(Func);
+
+ VarStack.RestoreArgs();
+
+ return Ret;
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_subst(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_subst(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string FromString;
@@ -250,8 +326,9 @@ string mhmakefileparser::f_subst(const string & Arg, const string *pOriExpr) con
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_patsubst(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_patsubst(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string FromString;
@@ -274,8 +351,9 @@ string mhmakefileparser::f_patsubst(const string & Arg, const string *pOriExpr)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_concat(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_concat(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string JoinString;
@@ -311,24 +389,27 @@ string mhmakefileparser::f_concat(const string & Arg, const string *pOriExpr) co
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_if(const string & Arg, const string *pOriExpr) const
+// Make sure to only expand the expression which the condition is true for
+string mhmakefileparser::f_if(const string & Arg) const
{
const char *pTmp=Arg.c_str();
string Cond;
- pTmp=NextCharItem(pTmp,Cond,',');
+ pTmp=NextCharExprItem(pTmp,Cond,',');
+ Cond=ExpandExpression(Cond);
string Ret;
if (Cond.empty())
{
- pTmp=NextCharItem(pTmp,Ret,',');
+ pTmp=NextCharExprItem(pTmp,Ret,',');
}
- NextCharItem(pTmp,Ret,',');
- return Ret;
+ NextCharExprItem(pTmp,Ret,',');
+ return ExpandExpression(Ret);
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_findstring(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_findstring(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string find;
pTmp=NextCharItem(pTmp,find,',');
@@ -342,8 +423,9 @@ string mhmakefileparser::f_findstring(const string & Arg, const string *pOriExpr
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_firstword(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_firstword(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
string FirstWord;
NextItem(Arg.c_str(),FirstWord);
return FirstWord;
@@ -402,15 +484,15 @@ static string wildcard(const string &Arg, void *pvVar)
return Ret;
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_wildcard(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_wildcard(const string & Arg) const
{
- return IterList(Arg, wildcard, (void*)this);
+ return IterList(ExpandExpression(Arg), wildcard, (void*)this);
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_exist(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_exist(const string & Arg) const
{
- string File=TrimString(Arg);
+ string File=TrimString(ExpandExpression(Arg));
fileinfo *pFile=GetFileInfo(File,m_MakeDir);
if (pFile->Exists())
{
@@ -421,8 +503,9 @@ string mhmakefileparser::f_exist(const string & Arg, const string *pOriExpr) con
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_filesindirs(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_filesindirs(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string strFiles;
@@ -476,9 +559,9 @@ string mhmakefileparser::f_filesindirs(const string & Arg, const string *pOriExp
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_fullname(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_fullname(const string & Arg) const
{
- string File=TrimString(Arg);
+ string File=TrimString(ExpandExpression(Arg));
fileinfo *pFile=GetFileInfo(File,m_MakeDir);
return pFile->GetQuotedFullFileName();
}
@@ -492,9 +575,9 @@ static string basename(const string &FileName,void*)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_basename(const string & FileNames, const string *pOriExpr) const
+string mhmakefileparser::f_basename(const string & FileNames) const
{
- return IterList(FileNames,basename);
+ return IterList(ExpandExpression(FileNames),basename);
}
///////////////////////////////////////////////////////////////////////////////
@@ -515,9 +598,9 @@ static string notdir(const string &FileName,void*)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_notdir(const string & FileNames, const string *pOriExpr) const
+string mhmakefileparser::f_notdir(const string & FileNames) const
{
- return IterList(FileNames,notdir);
+ return IterList(ExpandExpression(FileNames),notdir);
}
///////////////////////////////////////////////////////////////////////////////
@@ -527,14 +610,15 @@ static string addprefix(const string &FileName,void *pPrefix)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_addprefix(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_addprefix(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string PreFix;
pTmp=NextCharItem(pTmp,PreFix,',');
#ifdef _DEBUG
if (g_PrintAdditionalInfo && PreFix.empty()) {
- cout << "Warning: empty prefix in expression: " << *pOriExpr << endl;
+ cout << "Warning: empty prefix in expression: " << ArgIn << endl;
}
#endif
string FileNames;
@@ -549,8 +633,9 @@ static string addsuffix(const string &FileName,void *pSuffix)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_addsuffix(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_addsuffix(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string SufFix;
pTmp=NextCharItem(pTmp,SufFix,',');
@@ -566,8 +651,9 @@ string mhmakefileparser::f_addsuffix(const string & Arg, const string *pOriExpr)
///////////////////////////////////////////////////////////////////////////////
// Returns the n-th word number
-string mhmakefileparser::f_word(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_word(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
string strNum;
@@ -599,8 +685,9 @@ string mhmakefileparser::f_word(const string & Arg, const string *pOriExpr) cons
///////////////////////////////////////////////////////////////////////////////
// Returns the number of words
-string mhmakefileparser::f_words(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_words(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
const char *pTmp=Arg.c_str();
int NrWords=0;
char szNumber[10];
@@ -617,15 +704,16 @@ string mhmakefileparser::f_words(const string & Arg, const string *pOriExpr) con
///////////////////////////////////////////////////////////////////////////////
// Search for a command in the enivornment path
-string mhmakefileparser::f_which(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_which(const string & Arg) const
{
- return SearchCommand(Arg);
+ return SearchCommand(ExpandExpression(Arg));
}
///////////////////////////////////////////////////////////////////////////////
// Removes leading and trailing space
-string mhmakefileparser::f_strip(const string & Arg, const string *pOriExpr) const
+string mhmakefileparser::f_strip(const string & ArgIn) const
{
+ string Arg=ExpandExpression(ArgIn);
string::const_iterator pFirst=Arg.begin();
string::const_iterator pLast=Arg.end();
while (strchr(" \t\r\n",*pFirst) && pFirst!=pLast) pFirst++;
@@ -642,10 +730,13 @@ static string dir(const string &FileName, void *)
size_t Pos=FileName.find_last_of(OSPATHSEP);
if (Pos==string::npos)
{
+ #ifdef _WIN32
+ Pos=FileName.find_last_of('/');
+ if (Pos==string::npos)
+ #endif
return g_EmptyString;
}
- else
- {
+
string Ret=g_EmptyString;
Ret+=FileName.substr(0,Pos+1);
if (FileName[0]=='"' && FileName.end()[-1]=='"')
@@ -653,17 +744,16 @@ static string dir(const string &FileName, void *)
return Ret;
}
-}
-
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_dir(const string & FileNames, const string *pOriExpr) const
+string mhmakefileparser::f_dir(const string & FileNames) const
{
- return IterList(FileNames,dir);
+ return IterList(ExpandExpression(FileNames),dir);
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_shell(const string & Command, const string *pOriExpr) const
+string mhmakefileparser::f_shell(const string & CommandIn) const
{
+ string Command=ExpandExpression(CommandIn);
string Output;
#ifdef _DEBUG
@@ -733,9 +823,9 @@ static string relpath(const string &FileName,void *pvDir)
///////////////////////////////////////////////////////////////////////////////
// Make a path name relative to the current directory
-string mhmakefileparser::f_relpath(const string & FileNames, const string *pOriExpr) const
+string mhmakefileparser::f_relpath(const string & FileNames) const
{
- return IterList(FileNames,relpath,(void*)&m_MakeDir);
+ return IterList(ExpandExpression(FileNames),relpath,(void*)&m_MakeDir);
}
///////////////////////////////////////////////////////////////////////////////
@@ -752,9 +842,9 @@ static string makeupper(const string &FileName,void *)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_toupper(const string & FileNames, const string *pOriExpr) const
+string mhmakefileparser::f_toupper(const string & FileNames) const
{
- return IterList(FileNames,makeupper);
+ return IterList(ExpandExpression(FileNames),makeupper);
}
///////////////////////////////////////////////////////////////////////////////
@@ -771,9 +861,9 @@ static string makelower(const string &FileName, void *)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_tolower(const string & FileNames, const string *pOriExpr) const
+string mhmakefileparser::f_tolower(const string & FileNames) const
{
- return IterList(FileNames,makelower);
+ return IterList(ExpandExpression(FileNames),makelower);
}
///////////////////////////////////////////////////////////////////////////////
@@ -792,36 +882,26 @@ static string expandexpr(const string &VarVal, void *pvVar)
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_foreach(const string & ExpandedArg, const string *pOriExpr) const
+string mhmakefileparser::f_foreach(const string & Arg) const
{
-#ifdef _DEBUG
- if (pOriExpr->substr(0,8)!="foreach ")
- throw(string("wrong assumption in foreach expression: ")+*pOriExpr);
-#endif
- const char *pTmp=ExpandedArg.c_str();
+ const char *pTmp=Arg.c_str();
expanedexpr_arg Args;
Args.pParser=(mhmakefileparser*)this;
- pTmp=NextCharItem(pTmp,Args.Var,',');
+ pTmp=NextCharExprItem(pTmp,Args.Var,',');
+ Args.Var=ExpandExpression(Args.Var);
if (Args.Var.empty())
- throw(string("Wrong syntax in foreach instruction. Should give the variable a name."));
+ throw(string("Wrong syntax in foreach instruction: '")+Arg+"'. Variable may not be empty.");
string Items;
- pTmp=NextCharItem(pTmp,Items,',');
+ pTmp=NextCharExprItem(pTmp,Items,',');
+ Items=ExpandExpression(Items);
if (Items.empty())
return g_EmptyString; /* No items specified, so nothing needs to be done */
- /* for the next item we need to use the original expression because we need to re-expand it using Var for each entry
- in Items */
- int Pos=pOriExpr->find_first_of(',',0);
- if (Pos==string::npos)
- throw(string("expected , in ")+*pOriExpr);
- Pos=pOriExpr->find_first_of(',',Pos+1);
- if (Pos==string::npos)
- throw(string("expected two ,'s in ")+*pOriExpr);
- Args.Expr=pOriExpr->substr(Pos+1);
+ pTmp=NextCharExprItem(pTmp,Args.Expr,',');
/* Save the variable to be able to restore it after the foreach expansion */
string VarVal;
@@ -840,3 +920,64 @@ string mhmakefileparser::f_foreach(const string & ExpandedArg, const string *pOr
return Ret;
}
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_eval(const string & Arg) const
+{
+ ((mhmakefileparser*)this)->ParseString(ExpandExpression(Arg)+"\n");
+ return g_EmptyString;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string AddToList(const string &String, void *pvList)
+{
+ vector<string> *pList=(vector<string>*)pvList;
+ pList->push_back(String);
+ return g_EmptyString;
+}
+
+string mhmakefileparser::f_sort(const string & Arg) const
+{
+ string ExpandedArg=ExpandExpression(Arg);
+ vector<string> List;
+ IterList(ExpandedArg, AddToList, (void*)&List);
+ sort(List.begin(),List.end());
+ string Prev;
+ vector<string>::iterator It=List.begin();
+ string Ret;
+ bool First=true;
+ while (It!=List.end())
+ {
+ string This=*It++;
+ if (This!=Prev)
+ {
+ Prev=This;
+ if (!First)
+ Ret+=" ";
+ else
+ First=false;
+ Ret+=This;
+ }
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_error(const string & Arg) const
+{
+ throw(GetFileNameLineNo()+ExpandExpression(Arg));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_warning(const string & Arg) const
+{
+ cout << GetFileNameLineNo() << ExpandExpression(Arg) << endl;
+ return g_EmptyString;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_info(const string & Arg) const
+{
+ cout << ExpandExpression(Arg) << endl;
+ return g_EmptyString;
+}
+
diff --git a/tools/mhmake/src/mhmake.cpp b/tools/mhmake/src/mhmake.cpp
index ce2e8f7a7..ef515b0b2 100644
--- a/tools/mhmake/src/mhmake.cpp
+++ b/tools/mhmake/src/mhmake.cpp
@@ -105,9 +105,9 @@ int __CDECL main(int argc, char* argv[])
LOADEDMAKEFILES::iterator LoadMakIt=g_LoadedMakefiles.begin();
while (LoadMakIt!=g_LoadedMakefiles.end())
{
- (*LoadMakIt)->m_pParser->BuildIncludedMakefiles();
- (*LoadMakIt)->m_pParser->ParseBuildedIncludeFiles();
- (*LoadMakIt)->m_pParser->CheckEnv();
+ (*LoadMakIt)->m_pMakefileParser->BuildIncludedMakefiles();
+ (*LoadMakIt)->m_pMakefileParser->ParseBuildedIncludeFiles();
+ (*LoadMakIt)->m_pMakefileParser->CheckEnv();
LoadMakIt++;
}
@@ -121,16 +121,16 @@ int __CDECL main(int argc, char* argv[])
g_Clean=true;
}
fileinfo *pTarget=GetFileInfo(*It,pFirstMakefile->m_MakeDir);
- pFirstMakefile->m_pParser->BuildTarget(pTarget);
+ pFirstMakefile->m_pMakefileParser->BuildTarget(pTarget);
It++;
}
}
else
{
- fileinfo *pFirstTarget=pFirstMakefile->m_pParser->GetFirstTarget();
+ fileinfo *pFirstTarget=pFirstMakefile->m_pMakefileParser->GetFirstTarget();
if (pFirstTarget)
{
- pFirstMakefile->m_pParser->BuildTarget(pFirstTarget);
+ pFirstMakefile->m_pMakefileParser->BuildTarget(pFirstTarget);
}
else
cout << "Warning: no targets in makefile. Nothing to be build.\nMHMAKECONF defined?\n";
@@ -139,7 +139,7 @@ int __CDECL main(int argc, char* argv[])
}
catch (string Message)
{
- cerr << "Error occured: " << Message << endl;
+ cerr << "*** Error -> " << Message << endl;
#ifdef _DEBUG
if (g_DumpOnError)
{
diff --git a/tools/mhmake/src/mhmakefileparser.cpp b/tools/mhmake/src/mhmakefileparser.cpp
index b198c1ca8..1b1119641 100644
--- a/tools/mhmake/src/mhmakefileparser.cpp
+++ b/tools/mhmake/src/mhmakefileparser.cpp
@@ -25,8 +25,22 @@
#include "mhmakefileparser.h"
#include "rule.h"
#include "flexlexer.h"
+#include "mhmakeparser.hpp"
commandqueue mhmakefileparser::sm_CommandQueue;
+stack<yy::mhmakeparser*> mhmakefileparser::sm_ParserStack; // Keeps track of the currently active parser
+
+string mhmakefileparser::GetFileNameLineNo(void)
+{
+ if (!sm_ParserStack.empty())
+ {
+ yy::mhmakeparser* pParser=sm_ParserStack.top();
+ yy::position *pPos=pParser->GetCurPos();
+ return pParser->GetInputFilename()+":"+stringify(pPos->line)+" ";
+ }
+ else
+ return g_EmptyString; // Currently not parsing, this is a run-time error after parsing
+}
///////////////////////////////////////////////////////////////////////////////
int mhmakefileparser::ParseFile(const fileinfo *pFileInfo, const fileinfo *pMakeDir)
@@ -45,13 +59,33 @@ int mhmakefileparser::ParseFile(const fileinfo *pFileInfo, const fileinfo *pMake
}
mhmakeFlexLexer theLexer(&yyin);
- m_ptheLexer=&theLexer;
+
theLexer.m_InputFileName=pFileInfo->GetFullFileName();
- theLexer.m_pParser=this;
- int Ret=parse();
+ theLexer.m_pMakefileParser=this;
+
+ yy::mhmakeparser Parser(this,&theLexer);
+ sm_ParserStack.push(&Parser);
+ int Ret=Parser.parse();
+ sm_ParserStack.pop();
return Ret;
}
+///////////////////////////////////////////////////////////////////////////////
+int mhmakefileparser::ParseString(const string &StringIn)
+{
+ basic_istringstream<char> yyin(StringIn.c_str());
+
+ mhmakeFlexLexer theLexer(&yyin);
+
+ theLexer.m_InputFileName=string("eval(")+StringIn+")";
+ theLexer.m_pMakefileParser=this;
+
+ yy::mhmakeparser Parser(this,&theLexer);
+ sm_ParserStack.push(&Parser);
+ int Ret=Parser.parse();
+ sm_ParserStack.pop();
+ return Ret;
+}
///////////////////////////////////////////////////////////////////////////////
bool mhmakefileparser::IsDefined(const string &Var) const
@@ -76,33 +110,6 @@ static inline size_t SkipUntilQuote(const string &Expr,size_t i,char Char)
}
///////////////////////////////////////////////////////////////////////////////
-static inline size_t SkipMakeExpr(const string &Expr,size_t i)
-{
- char Char=Expr[i++];
- char EndChar;
- if (Char=='(')
- EndChar=')';
- else if (Char=='{')
- EndChar='}';
- else
- return i;
- Char=Expr[i++];
- while (Char!=EndChar)
- {
- if (Char=='$')
- {
- i=SkipMakeExpr(Expr,i);
- }
-#ifdef _DEBUG
- if (i>=Expr.length())
- throw(string(1,EndChar)+" not found in "+Expr);
-#endif
- Char=Expr[i++];
- }
- return i;
-}
-
-///////////////////////////////////////////////////////////////////////////////
// Splits expression on the Item, but the item may not occur within
// a macro or quoted string
static pair<string,string> SplitExpr(const string &Expr,char Item)
@@ -160,52 +167,39 @@ bool mhmakefileparser::IsEqual(const string &EqualExpr) const
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::ExpandExpression(const string &Expr) const
+inline string mhmakefileparser::ExpandExpression(const string &ExprIn) const
{
- bool Recurse;
- string Ret(Expr);
- do
+ bool Recurse=true;
+ string Ret(ExprIn);
+ while (Recurse)
{
Recurse=false;
- Ret=ExpandExpressionRecurse(Ret,Recurse);
- }
- while (Recurse);
- return Ret;
-}
+ string Expr(Ret);
+ Ret.clear();
-///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::ExpandExpressionRecurse(const string &Expr, bool &Recurse) const
-{
- //((mhmakefileparser*)this)->m_InExpandExpression++;
size_t i=0;
size_t Length=Expr.size();
- string Ret;
string ToAdd;
while (i<Length)
{
char Char=Expr[i++];
if (Char=='$')
{
- char CharNext=Expr[i];
- if (CharNext=='$')
- {
- ToAdd="$";
- i++;
- }
- else
- {
size_t inew=SkipMakeExpr(Expr,i);
i++;
if (inew>i)
{
- ToAdd=ExpandMacro(Expr.substr(i,inew-i-1),Recurse);
+ ToAdd=ExpandMacro(Expr.substr(i,inew-i-1));
i=inew;
}
else
{
// This is a single character expression
- ToAdd=ExpandMacro(string(1,Expr[i-1]),Recurse);
+ ToAdd=ExpandMacro(string(1,Expr[i-1]));
}
+ if (ToAdd.find('$')!=string::npos && ToAdd.length()!=1)
+ {
+ Recurse=true;
}
Ret+=ToAdd;
}
@@ -214,20 +208,25 @@ string mhmakefileparser::ExpandExpressionRecurse(const string &Expr, bool &Recur
Ret+=Char;
}
}
-
+ }
return Ret;
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::ExpandMacro(const string &Expr, bool &Recurse) const
+string mhmakefileparser::ExpandMacro(const string &Expr) const
{
- string ExpandedExpr=ExpandExpressionRecurse(Expr,Recurse);
-
- const char *pTmp=ExpandedExpr.c_str();
+ const char *pTmp=Expr.c_str();
/* First remove leading spaces */
while (*pTmp==' ' || *pTmp=='\t') pTmp++;
const char *pVar=pTmp;
- while (*pTmp && *pTmp!=' ' && *pTmp!='\t' && *pTmp!=':') pTmp++;
+ while (*pTmp && *pTmp!=' ' && *pTmp!='\t' && *pTmp!=':')
+ {
+ if (*pTmp=='$' && pTmp[1]) // We have a macro expansion inside a macro expansion, so recurse Do not consider isolated $ (This was a $$)
+ {
+ return ExpandMacro(ExpandExpression(Expr));
+ }
+ pTmp++;
+ }
const char *pVarEnd=pTmp;
char Type=*pTmp++;
while (*pTmp && (*pTmp==' ' || *pTmp=='\t')) pTmp++;
@@ -245,8 +244,8 @@ string mhmakefileparser::ExpandMacro(const string &Expr, bool &Recurse) const
const char *pStop=pSrc;
while (*pStop!='=') pStop++;
const char *pTo=pStop+1;
- string SrcStr(pSrc,pStop);
- string ToStr(pTo);
+ string SrcStr(ExpandExpression(string(pSrc,pStop)));
+ string ToStr(pTo); // Do not expand yet to be able to use % inside a macro
#ifdef WIN32
if (IsFileName)
{
@@ -263,31 +262,20 @@ string mhmakefileparser::ExpandMacro(const string &Expr, bool &Recurse) const
}
else if (Type==' ' || Type == '\t')
{
- string Func(pVar,pVarEnd);
string Arg(pTmp);
- if (Recurse)
- {
- #ifdef _DEBUG
- if (!(Arg.find('%')!=string::npos && Arg.find('$')!=string::npos))
- throw(string("Bug in mhmake: expected a % and $ sign: ")+Arg);
- #endif
- return string("$(")+ExpandedExpr+")"; // we cannot call the function yet since there is still a $(*%*) macro to resolve. so
- // return it a a macro again so it can be resolved when the % is resolved
- // remark that the current test is not completely safe because the % could be out of
- // the $ macro
- }
+ string Func(pVar,pVarEnd);
function_f pFunc=m_Functions[Func];
#ifdef _DEBUG
if (pFunc)
{
- return (this->*pFunc)(Arg, &Expr);
+ return (this->*pFunc)(Arg);
}
else
{
- throw string("Unknown function specified in macro: ")+Func;
+ throw GetFileNameLineNo() + "Unknown function specified in macro: "+Func;
}
#else
- return (this->*pFunc)(Arg, &Expr);
+ return (this->*pFunc)(Arg);
#endif
}
else
@@ -301,21 +289,15 @@ string mhmakefileparser::ExpandMacro(const string &Expr, bool &Recurse) const
}
else
{
- if (ExpandedExpr.find('%')!=string::npos)
- {
- // we have encountered a *%* macro. This means a previous subst is not yet finished. so return
- // it back as a macro so it can be expanded again later when the % is replaced
- Recurse=true;
- return string("$(")+ExpandedExpr+")";
- }
#ifdef _DEBUG
- else if (ExpandedExpr.find('$')!=string::npos)
- throw(string("Bug in mhmake: wasn't expecting a $ sign in: ")+ExpandedExpr);
+ if (Expr.find('$')!=string::npos && Expr.length()!=1)
+ throw(string("Bug in mhmake: wasn't expecting a $ sign in: ")+Expr);
#endif
+ string Ret=ExpandVar(Expr);
+ if (Ret.length()>1)
+ return ExpandExpression(Ret);
else
- {
- return ExpandExpression(ExpandVar(ExpandedExpr));
- }
+ return Ret;
}
}
@@ -348,6 +330,10 @@ string mhmakefileparser::ExpandVar(const string &Var) const
return m_RuleThatIsBuild->GetPrerequisits();
case '/':
return OSPATHSEPSTR;
+ case '$':
+ return Var;
+ case 'n':
+ return "\n";
default:
break;
}
@@ -360,9 +346,12 @@ string mhmakefileparser::ExpandVar(const string &Var) const
case '@': // return full target file name
case '*': // return stem
case '^': // return all prerequisits
+ case '$': // $$ expansion
return Var; // To make comparing of rules more accurate
case '/':
return OSPATHSEPSTR;
+ case 'n':
+ return "\n";
default:
break;
}
diff --git a/tools/mhmake/src/mhmakefileparser.h b/tools/mhmake/src/mhmakefileparser.h
index 581d243b0..82e783dd0 100644
--- a/tools/mhmake/src/mhmakefileparser.h
+++ b/tools/mhmake/src/mhmakefileparser.h
@@ -30,7 +30,7 @@ class rule;
#include "flexlexer.h"
class mhmakefileparser;
-typedef string (mhmakefileparser::*function_f)(const string &, const string *) const;
+typedef string (mhmakefileparser::*function_f)(const string &) const;
struct funcdef
{
@@ -49,16 +49,17 @@ typedef map<fileinfo*, autodeps_entry_t > autodeps_t;
namespace yy
{
class location;
+ class mhmakeparser;
}
class mhmakefileparser : public refbase
{
+ friend class yy::mhmakeparser;
+
private:
static commandqueue sm_CommandQueue;
-protected:
- mhmakeFlexLexer *m_ptheLexer;
+ static stack<yy::mhmakeparser*> sm_ParserStack; // Keeps track of the currently active parser
private:
- int m_yyloc;
fileinfo *m_RuleThatIsBuild;
vector<string> m_ToBeIncludeAfterBuild;
vector<string> m_MakefilesToLoad;
@@ -185,14 +186,28 @@ public:
SetAutoDepsDirty(); /* This is to be sure that all new calculated md5 strings are saved. */
}
- void SetVariable(string Var,string Val)
+ void SetVariable(const string &Var, const string &Val)
{
m_Variables[Var]=Val;
}
- void DeleteVariable(string Var)
+ void DeleteVariable(const string &Var)
{
m_Variables.erase(Var);
}
+ bool GetVariable(const string &Var, string &Val)
+ {
+ map<string,string>::const_iterator pIt=m_Variables.find(Var);
+ if (pIt==m_Variables.end())
+ {
+ return false;
+ }
+ else
+ {
+ Val = pIt->second;
+ return true;
+ }
+ }
+
void EnableAutoDepRescan(void)
{
m_ForceAutoDepRescan=true;
@@ -237,10 +252,6 @@ public:
#endif
free(m_pEnv);
}
- int yylex (YYSTYPE* yylval, yy::location* yylloc)
- {
- return m_ptheLexer->yylex(yylval,yylloc);
- }
virtual int parse()
{
@@ -248,14 +259,14 @@ public:
}
int ParseFile(const fileinfo *pFileInfo,const fileinfo *pMakeDir=NULL);
+ int ParseString(const string &StringIn);
/* 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 ExpandExpressionRecurse(const string &Expr, bool &Recurse) const;
- string ExpandMacro(const string &Expr, bool &Recurse) const;
+ string ExpandMacro(const string &Expr) const;
string ExpandVar(const string &Var) const;
void PrintVariables(bool Expand=false) const;
@@ -265,33 +276,38 @@ public:
static map<string,function_f> m_Functions;
static bool m_FunctionsInitialised;
static void InitFuncs(void);
- string f_filter(const string &, const string *pOriExpr) const;
- string f_call(const string &, const string *pOriExpr) const;
- string f_if(const string &, const string *pOriExpr) const;
- string f_findstring(const string &, const string *pOriExpr) const;
- string f_firstword(const string &, const string *pOriExpr) const;
- string f_wildcard(const string &, const string *pOriExpr) const;
- string f_subst(const string &, const string *pOriExpr) const;
- string f_patsubst(const string &, const string *pOriExpr) const;
- string f_concat(const string &, const string *pOriExpr) const;
- string f_basename(const string & Arg, const string *pOriExpr) const;
- string f_notdir(const string & Arg, const string *pOriExpr) const;
- string f_dir(const string & Arg, const string *pOriExpr) const;
- string f_shell(const string & Arg, const string *pOriExpr) const;
- string f_relpath(const string & Arg, const string *pOriExpr) const;
- string f_toupper(const string & Arg, const string *pOriExpr) const;
- string f_tolower(const string & Arg, const string *pOriExpr) const;
- string f_exist(const string & Arg, const string *pOriExpr) const;
- string f_filesindirs(const string & Arg, const string *pOriExpr) const;
- string f_fullname(const string & Arg, const string *pOriExpr) const;
- string f_addprefix(const string & Arg, const string *pOriExpr) const;
- string f_addsuffix(const string & Arg, const string *pOriExpr) const;
- string f_filterout(const string & Arg, const string *pOriExpr) const;
- string f_word(const string & Arg, const string *pOriExpr) const;
- string f_words(const string & Arg, const string *pOriExpr) const;
- string f_strip(const string & Arg, const string *pOriExpr) const;
- string f_which(const string & Arg, const string *pOriExpr) const;
- string f_foreach(const string & Arg, const string *pOriExpr) const;
+ string f_filter(const string &) const;
+ string f_call(const string &) const;
+ string f_if(const string &) const;
+ string f_findstring(const string &) const;
+ string f_firstword(const string &) const;
+ string f_wildcard(const string &) const;
+ string f_subst(const string &) const;
+ string f_patsubst(const string &) const;
+ string f_concat(const string &) const;
+ string f_basename(const string & Arg) const;
+ string f_notdir(const string & Arg) const;
+ string f_dir(const string & Arg) const;
+ string f_shell(const string & Arg) const;
+ string f_relpath(const string & Arg) const;
+ string f_toupper(const string & Arg) const;
+ string f_tolower(const string & Arg) const;
+ string f_exist(const string & Arg) const;
+ string f_filesindirs(const string & Arg) const;
+ string f_fullname(const string & Arg) const;
+ string f_addprefix(const string & Arg) const;
+ string f_addsuffix(const string & Arg) const;
+ string f_filterout(const string & Arg) const;
+ string f_word(const string & Arg) const;
+ string f_words(const string & Arg) const;
+ string f_strip(const string & Arg) const;
+ string f_which(const string & Arg) const;
+ string f_foreach(const string & Arg) const;
+ string f_eval(const string & Arg) const;
+ string f_sort(const string & Arg) const;
+ string f_error(const string & Arg) const;
+ string f_info(const string & Arg) const;
+ string f_warning(const string & Arg) const;
fileinfo* GetFirstTarget() const
{
@@ -372,7 +388,7 @@ public:
bool IgnoreError;
return ExecuteCommand(Command, IgnoreError, pOutput);
}
- string GetFullCommand(string Command);
+ string GetFullCommand(const string &Command);
static void InitBuildTime();
@@ -386,8 +402,30 @@ public:
const string &GetPythonExe() const;
int SearchPath(const char *szCommand, const char *pExt, size_t Len, char *szFullCommand,char **pFilePart) const;
mh_pid_t OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const;
+
+ static string GetFileNameLineNo(void);
};
+class mhmakeparserbase
+{
+protected:
+ mhmakefileparser *m_pMakefile;
+ mhmakeFlexLexer *m_ptheLexer;
+public:
+ mhmakeparserbase(mhmakefileparser *pMakefile, mhmakeFlexLexer *pLexer)
+ : m_pMakefile(pMakefile), m_ptheLexer(pLexer)
+ {
+ }
+ int yylex (YYSTYPE* yylval, yy::location* yylloc)
+ {
+ return m_ptheLexer->yylex(yylval,yylloc);
+ }
+ string &GetInputFilename(void) const
+ {
+ return m_ptheLexer->GetInputFilename();
+ }
+
+};
#endif
diff --git a/tools/mhmake/src/mhmakelexer.l b/tools/mhmake/src/mhmakelexer.l
index f27fec31a..aa396ceaf 100644
--- a/tools/mhmake/src/mhmakelexer.l
+++ b/tools/mhmake/src/mhmakelexer.l
@@ -95,7 +95,7 @@ static void ReplaceCurlyBraces(string &String)
/* -------------- rules section -------------- */
%x INCLUDE IFDEF IF IFNDEF SKIPUNTILELSEORENDIF QUOTE MAKEEXPRES SINGLEQUOTE COMMANDPARSE
-%x IFEQ IFNEQ ERRORMACRO MESSAGEMACRO REPARSEMACRO LOAD_MAKEFILE
+%x IFEQ IFNEQ LOAD_MAKEFILE
%x DEFINE
%{
@@ -463,7 +463,7 @@ load_makefile {
<IF,IFEQ,IFNEQ>\r /* skip */
-<IF,IFEQ,IFNEQ>[^\\\r\n\$]+ |
+<IF,IFEQ,IFNEQ>[^\\\r\n\$#]+ |
<IF,IFEQ,IFNEQ>[\\\$] { m_curtoken += (const char *)yytext; }
/*****************************************************************************/
@@ -608,7 +608,7 @@ load_makefile {
}
/*---------------------------------------------------------------------------*/
-[ \t]*#[^\n]* {
+<INITIAL,COMMANDPARSE,IF,IFEQ,IFNEQ>[ \t]*#[^\n]* {
PRINTF(("%s %d: -COMMENT: %s\n",m_InputFileName.c_str(),lineno(),yytext));
}
@@ -678,7 +678,7 @@ export {
return yy::mhmakeparser::token::STRING;
}
-([a-zA-Z0-9\\\._\~\-\+%\@<&;/\*\|]|\\\ |\\#)+ {
+([a-zA-Z0-9\\\._\~\-\+%\@<&;/\*\|\[\]]|\\\ |\\#)+ {
PRINTF(("%s %d: STRING: %s\n",m_InputFileName.c_str(),lineno(),yytext));
yylval->theString=(const char *)yytext;
return yy::mhmakeparser::token::STRING;
@@ -701,6 +701,11 @@ export {
m_curtoken+=g_SpaceString;
}
+<DEFINE>\n {
+ inclineno();
+ m_curtoken+=(const char *)yytext;
+}
+
<DEFINE>. {
m_curtoken+=(const char *)yytext;
}
@@ -734,33 +739,6 @@ export {
}
/*---------------------------------------------------------------------------*/
-\$[\(\{][ \t]*error[ \t]+ {
- m_BraceIndent++;
- PRINTF(("%s %d: BEGIN ERROR MACRO $(: %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
- BEGIN(ERRORMACRO);
- m_curtoken=g_EmptyString;
- return yy::mhmakeparser::token::NEWLINE; // Make sure that the previous lines are matched by the bison parser (so that all variables until here are defined)
-}
-
- /*---------------------------------------------------------------------------*/
-\$[\(\{][ \t]*(message|info)[ \t]+ {
- m_BraceIndent++;
- PRINTF(("%s %d: BEGIN MESSAGE MACRO $(: %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
- BEGIN(MESSAGEMACRO);
- m_curtoken=g_EmptyString;
- return yy::mhmakeparser::token::NEWLINE; // Make sure that the previous lines are matched by the bison parser (so that all variables until here are defined)
-}
-
- /*---------------------------------------------------------------------------*/
-\$[\(\{][ \t]*reparse[ \t]+ {
- m_BraceIndent++;
- PRINTF(("%s %d: BEGIN REPARSE MACRO $(: %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
- BEGIN(REPARSEMACRO);
- m_curtoken=g_EmptyString;
- return yy::mhmakeparser::token::NEWLINE;
-}
-
- /*---------------------------------------------------------------------------*/
\$[<@/$] {
PRINTF(("%s %d: DOLLAREXPR: %s\n",m_InputFileName.c_str(),lineno(),yytext));
yylval->theString=(const char *)yytext;
@@ -833,11 +811,6 @@ export {
m_curtoken+='#';
}
- /*---------------------------------------------------------------------------*/
-<COMMANDPARSE>[ \t]*#[^\n]* {
- PRINTF(("%s %d: -COMMENT: %s\n",m_InputFileName.c_str(),lineno(),yytext));
-}
-
/*****************************************************************************/
<QUOTE>\" {
PRINTF(("%s %d: QUOTEDSTRING: %s\n",m_InputFileName.c_str(),lineno(),yytext));
@@ -875,58 +848,6 @@ export {
}
/*****************************************************************************/
-<ERRORMACRO>[\)\}] {
- m_BraceIndent--;
- PRINTF(("%s %d: CLOSE BRACE ERROR MACRO ): %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
- if (!m_BraceIndent)
- {
- PRINTF(("%s %d: ERRORMACRO: %s\n",m_InputFileName.c_str(),lineno(),m_curtoken.c_str()));
- throw string("\n-> ")+m_InputFileName.c_str()+"("+stringify(lineno())+") : "+GetParser()->ExpandExpression(m_curtoken);
- } else {
- m_curtoken+=(const char *)yytext;
-}
-}
-
- /*****************************************************************************/
-<MESSAGEMACRO>[\)\}] {
- m_BraceIndent--;
- PRINTF(("%s %d: CLOSE BRACE MESSAGE MACRO ): %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
- if (!m_BraceIndent)
- {
- PRINTF(("%s %d: MESSAGEMACRO: %s\n",m_InputFileName.c_str(),lineno(),yytext));
- cerr<<m_InputFileName.c_str()<<"("<<stringify(lineno())+") : "<<GetParser()->ExpandExpression(m_curtoken)<<endl;
- BEGIN(INITIAL);
- } else {
- m_curtoken+=(const char *)yytext;
- }
-}
-
- /*****************************************************************************/
-<REPARSEMACRO>[\)\}] {
- m_BraceIndent--;
- PRINTF(("%s %d: CLOSE BRACE REPARSE MACRO ): %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
- if (!m_BraceIndent)
- {
- PRINTF(("%s %d: REPARSEMACRO: %s\n",m_InputFileName.c_str(),lineno(),yytext));
- string Deps=GetParser()->ExpandExpression(m_curtoken);
- PRINTF(("%s %d: REPARSEMACRO expanded: %s\n",m_InputFileName.c_str(),lineno(),Deps.c_str()));
- string::const_reverse_iterator It=Deps.rbegin()+1; // +1 because we don't want the latest brace
- string::const_reverse_iterator ItBeg=Deps.rend();
- while (It!= ItBeg)
- {
- char Char=*It++;
- if (Char==';') Char='\n';
- unput(Char);
- }
- BEGIN(INITIAL);
- }
- else
- {
- m_curtoken+=(const char *)yytext;
- }
-}
-
- /*****************************************************************************/
<MAKEEXPRES>[\)\}] {
m_BraceIndent--;
PRINTF(("%s %d: CLOSE BRACE MAKEEXPRES MACRO ): %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
@@ -945,22 +866,32 @@ export {
}
/*---------------------------------------------------------------------------*/
-<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>\$[\(\{] {
+<MAKEEXPRES>\$[\(\{] {
m_BraceIndent++;
PRINTF(("%s %d: MACRO extra $(: %d\n",m_InputFileName.c_str(),lineno(),m_BraceIndent));
m_curtoken+=(const char *)yytext;
}
/*---------------------------------------------------------------------------*/
-<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>[^$\(\)\{\}\r\n\\]+ |
-<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>[\(\$\\\{] {
+<MAKEEXPRES>[\(\{] {
+ m_BraceIndent++;
m_curtoken+=(const char *)yytext;
}
-<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>[ \t\r]*\\[ \t\r]*\n[ \t\r]* {
+
+ /*---------------------------------------------------------------------------*/
+<MAKEEXPRES>[^$\(\)\{\}\r\n\\]+ |
+<MAKEEXPRES>[\(\$\\\{] {
+ m_curtoken+=(const char *)yytext;
+}
+<MAKEEXPRES>[ \t\r]*\\[ \t\r]*\n[ \t\r]* {
inclineno();
m_curtoken+=g_SpaceString;
}
+<MAKEEXPRES>\n {
+ throw m_InputFileName + "(" + stringify(lineno()) + "): End of line inside macro is not allowed";
+}
+
<SKIPUNTILELSEORENDIF><<EOF>> {
throw string("Missing endif or else statement. #else or #endif used?");
}
diff --git a/tools/mhmake/src/mhmakeparser.y b/tools/mhmake/src/mhmakeparser.y
index 4c54ebd29..847cda48a 100644
--- a/tools/mhmake/src/mhmakeparser.y
+++ b/tools/mhmake/src/mhmakeparser.y
@@ -23,9 +23,9 @@
%require "2.4.1"
%defines
%define parser_class_name "mhmakeparser"
-%define parser_base_class_name "mhmakefileparser"
-%define parser_class_constructor_init ": mhmakefileparser(CommandLineVariables)"
-%define parser_class_constructor_param "const map<string,string> &CommandLineVariables"
+%define parser_base_class_name "mhmakeparserbase"
+%define parser_class_constructor_init ": mhmakeparserbase(pMakefile,pLexer)"
+%define parser_class_constructor_param "mhmakefileparser *pMakefile, mhmakeFlexLexer *pLexer"
%error-verbose
%code requires {
@@ -67,10 +67,10 @@ const char Test[]="dit is een test";
%%
file : statements
{
- if (m_pCurrentItems)
+ if (m_pMakefile->m_pCurrentItems)
{
- PRINTF(("Adding rule : %s\n",(*m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
- AddRule();
+ PRINTF(("Adding rule : %s\n",(*m_pMakefile->m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
+ m_pMakefile->AddRule();
}
}
;
@@ -85,6 +85,9 @@ space : SPACE |
statement: NEWLINE |
SPACE |
+ DOLLAREXPR NEWLINE {
+ m_pMakefile->ExpandExpression($1);
+ } |
includemak |
ruledef |
phonyrule |
@@ -97,46 +100,46 @@ statement: NEWLINE |
vpathrule |
COMMAND
{
- if (!m_pCurrentRule)
+ if (!m_pMakefile->m_pCurrentRule)
{
- m_pCurrentRule=refptr<rule>(new rule(this));
+ m_pMakefile->m_pCurrentRule=refptr<rule>(new rule(m_pMakefile));
}
- m_pCurrentRule->AddCommand($1);
+ m_pMakefile->m_pCurrentRule->AddCommand($1);
PRINTF(("Adding command : %s\n",$1.c_str()));
}
;
includemak:
{
- if (m_pCurrentItems)
+ if (m_pMakefile->m_pCurrentItems)
{
- PRINTF(("Adding rule : %s\n",(*m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
- AddRule();
+ PRINTF(("Adding rule : %s\n",(*m_pMakefile->m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
+ m_pMakefile->AddRule();
}
} INCLUDEMAK
;
ruledef: expression_nocolorequal rulecolon maybeemptyexpression
{
- if (m_pCurrentItems)
+ if (m_pMakefile->m_pCurrentItems)
{
- PRINTF(("Adding rule : %s\n",(*m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
- AddRule();
+ PRINTF(("Adding rule : %s\n",(*m_pMakefile->m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
+ m_pMakefile->AddRule();
}
- m_pCurrentItems=new fileinfoarray;
- m_pCurrentDeps=new fileinfoarray;
+ m_pMakefile->m_pCurrentItems=new fileinfoarray;
+ m_pMakefile->m_pCurrentDeps=new fileinfoarray;
#ifdef _DEBUG
- if (!ExpandExpression($1).size())
+ if (!m_pMakefile->ExpandExpression($1).size())
{
throw string("Empty left hand side in rule: ") + $1 + " : " + $3;
}
#endif
- SplitToItems(ExpandExpression($1),*m_pCurrentItems);
- SplitToItems(ExpandExpression($3),*m_pCurrentDeps);
- m_DoubleColonRule= ($2==1) ;
+ m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($1),*m_pMakefile->m_pCurrentItems);
+ m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($3),*m_pMakefile->m_pCurrentDeps);
+ m_pMakefile->m_DoubleColonRule= ($2==1) ;
PRINTF(("Defining rule %s : %s\n",$1.c_str(),$3.c_str()));
- PRINTF((" Expanded to %s : %s\n",ExpandExpression($1).c_str(),ExpandExpression($3).c_str()));
+ PRINTF((" Expanded to %s : %s\n",m_pMakefile->ExpandExpression($1).c_str(),m_pMakefile->ExpandExpression($3).c_str()));
}
;
@@ -147,7 +150,7 @@ rulecolon: COLON {$$=0;} |
phonyrule: PHONY COLON expression
{
vector<fileinfo*> Items;
- SplitToItems(ExpandExpression($3),Items);
+ m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($3),Items);
vector<fileinfo*>::iterator pIt=Items.begin();
while (pIt!=Items.end())
{
@@ -155,7 +158,7 @@ phonyrule: PHONY COLON expression
pIt++;
}
PRINTF(("Defining phony rule : %s\n",$3.c_str()));
- PRINTF((" Expanded to : %s\n",ExpandExpression($3).c_str()));
+ PRINTF((" Expanded to : %s\n",m_pMakefile->ExpandExpression($3).c_str()));
}
NEWLINE
;
@@ -163,20 +166,27 @@ phonyrule: PHONY COLON expression
autodepsrule: AUTODEPS COLON expression
{
vector<fileinfo*> Items;
- SplitToItems(ExpandExpression($3),Items);
+ m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($3),Items);
vector<fileinfo*>::iterator pIt=Items.begin();
while (pIt!=Items.end())
{
- (*pIt)->SetAutoDepsScan(this);
+ (*pIt)->SetAutoDepsScan(m_pMakefile);
pIt++;
}
PRINTF(("Defining autodeps rule : %s\n",$3.c_str()));
- PRINTF((" Expanded to : %s\n",ExpandExpression($3).c_str()));
+ PRINTF((" Expanded to : %s\n",m_pMakefile->ExpandExpression($3).c_str()));
}
NEWLINE
;
-exportrule: EXPORT space exportstrings NEWLINE
+exportrule: EXPORT space exportstrings NEWLINE |
+ EXPORT space STRING EQUAL maybeemptyexpression
+ {
+ string Val=m_pMakefile->ExpandExpression($5);
+ m_pMakefile->SetVariable($3,Val);
+ m_pMakefile->SetExport($3,Val);
+ PRINTF(("Exporting %s : %s\n",$3.c_str(), Val.c_str()));
+ }
;
exportstrings : exportstring |
@@ -185,49 +195,49 @@ exportstrings : exportstring |
exportstring : STRING
{
- SetExport($1,ExpandExpression(ExpandVar($1)));
- PRINTF(("Exporting %s : %s\n",$1.c_str(),ExpandExpression(ExpandVar($1)).c_str()));
+ m_pMakefile->SetExport($1,m_pMakefile->ExpandExpression(m_pMakefile->ExpandVar($1)));
+ PRINTF(("Exporting %s : %s\n",$1.c_str(),m_pMakefile->ExpandExpression(m_pMakefile->ExpandVar($1)).c_str()));
}
;
vpathrule: VPATH space nonspaceexpression space expression NEWLINE
{
- SetvPath(ExpandExpression($3),ExpandExpression($5));
- PRINTF(("Setting vpath %s to %s\n",$3.c_str(),ExpandExpression($5).c_str()));
+ m_pMakefile->SetvPath(m_pMakefile->ExpandExpression($3),m_pMakefile->ExpandExpression($5));
+ PRINTF(("Setting vpath %s to %s\n",$3.c_str(),m_pMakefile->ExpandExpression($5).c_str()));
}
;
varassignment: VARDEF VARVAL
{
- m_Variables[f_strip($1,NULL)]=$2;
- PRINTF(("Defining variable %s to %s\n",f_strip($1,NULL).c_str(), $2.c_str()));
+ m_pMakefile->m_Variables[m_pMakefile->f_strip($1)]=$2;
+ PRINTF(("Defining variable %s to %s\n",m_pMakefile->f_strip($1).c_str(), $2.c_str()));
}
| STRING EQUAL maybeemptyexpression
{
- m_Variables[$1]=$3;
+ m_pMakefile->m_Variables[$1]=$3;
PRINTF(("Setting variable %s to %s\n",$1.c_str(), $3.c_str()));
}
;
imvarassignment: STRING IMEQUAL maybeemptyexpression
{
- m_Variables[$1]=ExpandExpression($3);
- PRINTF(("Setting variable %s to %s\n",$1.c_str(), m_Variables[$1].c_str()));
+ m_pMakefile->m_Variables[$1]=m_pMakefile->ExpandExpression($3);
+ PRINTF(("Setting variable %s to %s\n",$1.c_str(), m_pMakefile->m_Variables[$1].c_str()));
}
;
pvarassignment: STRING PEQUAL maybeemptyexpression
{
- m_Variables[$1]=ExpandVar($1)+g_SpaceString+$3;
+ m_pMakefile->m_Variables[$1]=m_pMakefile->ExpandVar($1)+g_SpaceString+$3;
PRINTF(("Adding to variable %s: %s\n",$1.c_str(), $3.c_str()));
}
;
optvarassignment: STRING OPTEQUAL maybeemptyexpression
{
- if (!IsDefined($1))
+ if (!m_pMakefile->IsDefined($1))
{
- m_Variables[$1]=$3;
+ m_pMakefile->m_Variables[$1]=$3;
PRINTF(("Setting variable %s to %s\n",$1.c_str(), $3.c_str()));
}
}
diff --git a/tools/mhmake/src/util.cpp b/tools/mhmake/src/util.cpp
index 1f531e493..8b7d2b164 100644
--- a/tools/mhmake/src/util.cpp
+++ b/tools/mhmake/src/util.cpp
@@ -593,7 +593,7 @@ void loadedmakefile::LoadMakefile()
cout << "Loading makefile "<<m_Makefile->GetQuotedFullFileName()<<endl;
#endif
- m_pParser=refptr<mhmakefileparser>(new yy::mhmakeparser(m_CommandLineVars));
+ m_pMakefileParser=refptr<mhmakefileparser>(new mhmakefileparser(m_CommandLineVars));
// Add the MAKECMDGOALS environment variable
string MakeCmdGoals;
@@ -608,7 +608,7 @@ void loadedmakefile::LoadMakefile()
MakeCmdGoals+=*TarIt;
TarIt++;
}
- m_pParser->SetVariable("MAKECMDGOALS",MakeCmdGoals);
+ m_pMakefileParser->SetVariable("MAKECMDGOALS",MakeCmdGoals);
string BaseAutoMak;
@@ -616,29 +616,29 @@ void loadedmakefile::LoadMakefile()
fileinfo *pDepFile;
if (sm_Statics.m_MhMakeConf)
{
- BaseAutoMak=m_pParser->ExpandVar(BASEAUTOMAK);
+ BaseAutoMak=m_pMakefileParser->ExpandVar(BASEAUTOMAK);
if (BaseAutoMak.empty())
{
BaseAutoMak="makefile";
- m_pParser->SetVariable(BASEAUTOMAK,BaseAutoMak);
+ m_pMakefileParser->SetVariable(BASEAUTOMAK,BaseAutoMak);
}
const fileinfo *pBeforeMakefile=GetFileInfo(BaseAutoMak+".before",sm_Statics.m_MhMakeConf);
- int result=m_pParser->ParseFile(pBeforeMakefile,m_MakeDir);
+ int result=m_pMakefileParser->ParseFile(pBeforeMakefile,m_MakeDir);
if (result)
{
throw string("Error parsing ")+pBeforeMakefile->GetQuotedFullFileName();
}
- m_pParser->UpdateDate(pBeforeMakefile->GetDate());
+ m_pMakefileParser->UpdateDate(pBeforeMakefile->GetDate());
// Now parse the automaticly generated dependency file, which needs to be in the objdir directory
- string ObjDirName=m_pParser->ExpandExpression("$(OBJDIR)");
+ string ObjDirName=m_pMakefileParser->ExpandExpression("$(OBJDIR)");
if (!ObjDirName.size())
{
throw string("When making use of MHMAKECONF, you have to define OBJDIR in makefile.before");
}
pDepFile=GetFileInfo(ObjDirName+OSPATHSEPSTR "." + m_Makefile->GetName()+ ".dep",m_MakeDir);
- m_pParser->SetVariable(AUTODEPFILE,pDepFile->GetQuotedFullFileName());
+ m_pMakefileParser->SetVariable(AUTODEPFILE,pDepFile->GetQuotedFullFileName());
}
else
{
@@ -663,14 +663,14 @@ void loadedmakefile::LoadMakefile()
sprintf(ID,"_%lx",md5_finish32( &ctx));
pDepFile=GetFileInfo(string(".") + m_Makefile->GetName()+ ".dep"+ID,m_MakeDir);
- m_pParser->SetVariable(AUTODEPFILE,pDepFile->GetQuotedFullFileName());
+ m_pMakefileParser->SetVariable(AUTODEPFILE,pDepFile->GetQuotedFullFileName());
}
if (pDepFile->Exists())
- m_pParser->LoadAutoDepsFile(pDepFile); /* Already load this autodep file before parsing of the makefile to avoid needless rebuilds. */
+ m_pMakefileParser->LoadAutoDepsFile(pDepFile); /* Already load this autodep file before parsing of the makefile to avoid needless rebuilds. */
- //m_pParser->yydebug=1;
- int result=m_pParser->ParseFile(m_Makefile,m_MakeDir);
+ //m_pMakefileParser->yydebug=1;
+ int result=m_pMakefileParser->ParseFile(m_Makefile,m_MakeDir);
if (result)
{
throw string("Error parsing ")+m_Makefile->GetQuotedFullFileName();
@@ -678,40 +678,40 @@ void loadedmakefile::LoadMakefile()
#ifdef _DEBUG
/* Check if the makefile has changed the AUTODEPFILE variable, if so generate a warning that a
* rebuild could happen for the rules defined for making included makefiles */
- if (m_pParser->ExpandVar(AUTODEPFILE)!=pDepFile->GetQuotedFullFileName())
+ if (m_pMakefileParser->ExpandVar(AUTODEPFILE)!=pDepFile->GetQuotedFullFileName())
{
cout << "\n\nWARNING:\n makefile '"<< m_Makefile->GetQuotedFullFileName() <<"' re-defines AUTODEPFILE\n from '"<< pDepFile->GetQuotedFullFileName() <<"'\n to '"<<
- m_pParser->ExpandVar(AUTODEPFILE) << "'\n (may cause needless rebuilds when having rules for included makefiles!!!!!)\n\n\n";
+ m_pMakefileParser->ExpandVar(AUTODEPFILE) << "'\n (may cause needless rebuilds when having rules for included makefiles!!!!!)\n\n\n";
}
if (g_PrintAdditionalInfo)
{
- if (m_pParser->GetFirstTarget())
- cout<<"First target of "<<m_Makefile->GetQuotedFullFileName()<<" is "<<m_pParser->GetFirstTarget()->GetQuotedFullFileName()<<endl;
+ if (m_pMakefileParser->GetFirstTarget())
+ cout<<"First target of "<<m_Makefile->GetQuotedFullFileName()<<" is "<<m_pMakefileParser->GetFirstTarget()->GetQuotedFullFileName()<<endl;
else
cout<<"No First target for "<<m_Makefile->GetQuotedFullFileName()<<endl;
}
#endif
- m_pParser->UpdateDate(m_Makefile->GetDate());
+ m_pMakefileParser->UpdateDate(m_Makefile->GetDate());
if (sm_Statics.m_MhMakeConf)
{
fileinfo *pAfterMakefile=GetFileInfo(BaseAutoMak+".after",sm_Statics.m_MhMakeConf);
- int result=m_pParser->ParseFile(pAfterMakefile);
+ int result=m_pMakefileParser->ParseFile(pAfterMakefile);
if (result) {
throw string("Error parsing ")+pAfterMakefile->GetQuotedFullFileName();
}
- m_pParser->UpdateDate(pAfterMakefile->GetDate());
+ m_pMakefileParser->UpdateDate(pAfterMakefile->GetDate());
}
bool ForceAutoDepRescan=g_ForceAutoDepRescan;
if (pDepFile->Exists())
- m_pParser->LoadAutoDepsFile(pDepFile);
+ m_pMakefileParser->LoadAutoDepsFile(pDepFile);
else
ForceAutoDepRescan=true;
if (ForceAutoDepRescan)
- m_pParser->EnableAutoDepRescan();
+ m_pMakefileParser->EnableAutoDepRescan();
- vector<string> &MakefilesToLoad=m_pParser->GetMakefilesToLoad();
+ vector<string> &MakefilesToLoad=m_pMakefileParser->GetMakefilesToLoad();
vector<string>::iterator It=MakefilesToLoad.begin();
while (It!=MakefilesToLoad.end())
{
@@ -739,7 +739,7 @@ void loadedmakefile::LoadMakefile()
g_LoadedMakefiles.push_back(pLoadedMakefile);
/* If there is a rule to build the makefile, first check if it needs to be rebuild */
- m_pParser->BuildTarget(pLoadedMakefile->m_Makefile);
+ m_pMakefileParser->BuildTarget(pLoadedMakefile->m_Makefile);
pLoadedMakefile->LoadMakefile();
}
It++;
@@ -780,7 +780,7 @@ void DumpVarsAndRules()
cout << "Variables of makefile " << (*LoadMakIt)->m_Makefile->GetQuotedFullFileName() << endl;
for (i=0; i<80; i++) cout << "_";
cout << endl;
- (*LoadMakIt)->m_pParser->PrintVariables(true);
+ (*LoadMakIt)->m_pMakefileParser->PrintVariables(true);
cout << endl;
LoadMakIt++;
}
diff --git a/tools/mhmake/src/util.h b/tools/mhmake/src/util.h
index f789584a1..68cb032d7 100644
--- a/tools/mhmake/src/util.h
+++ b/tools/mhmake/src/util.h
@@ -50,7 +50,7 @@
#define PLATFORM "linux"
#endif
-#define MHMAKEVER "2.4.5"
+#define MHMAKEVER "3.0.0"
class makecommand
{
@@ -139,6 +139,46 @@ inline const char *NextCharItem(const char *pTmp,string &Output,char Char)
}
///////////////////////////////////////////////////////////////////////////////
+inline const char *SkipMakeExpr(const char *pMacro)
+{
+#ifdef _DEBUG
+ const char *pMacroIn=pMacro;
+#endif
+ char Char=*pMacro++;
+ char EndChar;
+ if (Char=='(')
+ EndChar=')';
+ else if (Char=='{')
+ EndChar='}';
+ else
+ return pMacro;
+ Char=*pMacro++;
+ while (Char!=EndChar)
+ {
+ if (Char=='$')
+ {
+ pMacro=SkipMakeExpr(pMacro);
+ } else if (Char=='(')
+ {
+ pMacro=SkipMakeExpr(pMacro-1);
+ }
+#ifdef _DEBUG
+ if (!*pMacro)
+ throw(string(1,EndChar)+" not found in "+pMacroIn);
+#endif
+ Char=*pMacro++;
+ }
+ return pMacro;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+inline size_t SkipMakeExpr(const string &Expr,size_t i)
+{
+ const char *pTmp=Expr.c_str();
+ return SkipMakeExpr(pTmp+i)-pTmp;
+}
+
+///////////////////////////////////////////////////////////////////////////////
string Substitute(const string &ToSubst,const string &SrcStr,const string &ToStr);
@@ -170,7 +210,7 @@ struct loadedmakefile : public refbase
map<string,string> m_CommandLineVars;
vector<string> m_CommandLineTargets;
- refptr<mhmakefileparser> m_pParser;
+ refptr<mhmakefileparser> m_pMakefileParser;
loadedmakefile(const fileinfo *pDir, vector<string> &Args,const string &Makefile=g_EmptyString);