diff options
author | marha <marha@users.sourceforge.net> | 2010-11-01 15:42:39 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-11-01 15:42:39 +0000 |
commit | c3d55347b14c80f553ab8c487baded1a44acf68c (patch) | |
tree | c2f8ea3bfe70d8d3cde803fd854879b44e2c4f4e | |
parent | 6ed6717dee7a472ae12f3f0e3c526c68425da8e7 (diff) | |
download | vcxsrv-c3d55347b14c80f553ab8c487baded1a44acf68c.tar.gz vcxsrv-c3d55347b14c80f553ab8c487baded1a44acf68c.tar.bz2 vcxsrv-c3d55347b14c80f553ab8c487baded1a44acf68c.zip |
Implemented foreach function.
wildcard can now have multiple arguments
-rw-r--r-- | tools/mhmake/src/functions.cpp | 130 | ||||
-rw-r--r-- | tools/mhmake/src/mhmakefileparser.cpp | 2 | ||||
-rw-r--r-- | tools/mhmake/src/mhmakefileparser.h | 59 | ||||
-rw-r--r-- | tools/mhmake/src/mhmakeparser.y | 4 |
4 files changed, 136 insertions, 59 deletions
diff --git a/tools/mhmake/src/functions.cpp b/tools/mhmake/src/functions.cpp index 1602112c3..61ae6c1e4 100644 --- a/tools/mhmake/src/functions.cpp +++ b/tools/mhmake/src/functions.cpp @@ -53,6 +53,7 @@ funcdef mhmakefileparser::m_FunctionsDef[]= { ,{"words" ,&mhmakefileparser::f_words}
,{"strip" ,&mhmakefileparser::f_strip}
,{"which" ,&mhmakefileparser::f_which}
+ ,{"foreach" ,&mhmakefileparser::f_foreach}
};
map<string,function_f> mhmakefileparser::m_Functions;
@@ -118,7 +119,7 @@ static string filter(const string &FileName, void *pvFilter) return g_EmptyString;
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_filter(const string & Arg) const
+string mhmakefileparser::f_filter(const string & Arg, const string *pOriExpr) const
{
size_t ipos=Arg.find(',');
#ifdef _DEBUG
@@ -136,7 +137,7 @@ string mhmakefileparser::f_filter(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_filterout(const string & Arg) const
+string mhmakefileparser::f_filterout(const string & Arg, const string *pOriExpr) const
{
size_t ipos=Arg.find(',');
#ifdef _DEBUG
@@ -175,7 +176,7 @@ string mhmakefileparser::f_filterout(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_call(const string & Arg) const
+string mhmakefileparser::f_call(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -213,7 +214,7 @@ string mhmakefileparser::f_call(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_subst(const string & Arg) const
+string mhmakefileparser::f_subst(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -249,7 +250,7 @@ string mhmakefileparser::f_subst(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_patsubst(const string & Arg) const
+string mhmakefileparser::f_patsubst(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -273,7 +274,7 @@ string mhmakefileparser::f_patsubst(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_concat(const string & Arg) const
+string mhmakefileparser::f_concat(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -310,7 +311,7 @@ string mhmakefileparser::f_concat(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_if(const string & Arg) const
+string mhmakefileparser::f_if(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -326,7 +327,7 @@ string mhmakefileparser::f_if(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_findstring(const string & Arg) const
+string mhmakefileparser::f_findstring(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
string find;
@@ -341,7 +342,7 @@ string mhmakefileparser::f_findstring(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_firstword(const string & Arg) const
+string mhmakefileparser::f_firstword(const string & Arg, const string *pOriExpr) const
{
string FirstWord;
NextItem(Arg.c_str(),FirstWord);
@@ -349,9 +350,11 @@ string mhmakefileparser::f_firstword(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_wildcard(const string & Arg) const
+static string wildcard(const string &Arg, void *pvVar)
{
- fileinfo *pFileSpec=GetFileInfo(TrimString(Arg),m_MakeDir); /* Use GetFileInfo to make the relative path absolute */
+ mhmakefileparser *pParser=(mhmakefileparser*)pvVar;
+
+ fileinfo *pFileSpec=GetFileInfo(Arg,pParser->GetMakeDir()); /* Use GetFileInfo to make the relative path absolute */
fileinfo *pDir=pFileSpec->GetDir();
#ifdef WIN32
struct _finddata_t FileInfo;
@@ -398,9 +401,14 @@ string mhmakefileparser::f_wildcard(const string & Arg) const #endif
return Ret;
}
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_wildcard(const string & Arg, const string *pOriExpr) const
+{
+ return IterList(Arg, wildcard, (void*)this);
+}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_exist(const string & Arg) const
+string mhmakefileparser::f_exist(const string & Arg, const string *pOriExpr) const
{
string File=TrimString(Arg);
fileinfo *pFile=GetFileInfo(File,m_MakeDir);
@@ -413,7 +421,7 @@ string mhmakefileparser::f_exist(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_filesindirs(const string & Arg) const
+string mhmakefileparser::f_filesindirs(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -468,7 +476,7 @@ string mhmakefileparser::f_filesindirs(const string & Arg) const }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_fullname(const string & Arg) const
+string mhmakefileparser::f_fullname(const string & Arg, const string *pOriExpr) const
{
string File=TrimString(Arg);
fileinfo *pFile=GetFileInfo(File,m_MakeDir);
@@ -484,7 +492,7 @@ static string basename(const string &FileName,void*) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_basename(const string & FileNames) const
+string mhmakefileparser::f_basename(const string & FileNames, const string *pOriExpr) const
{
return IterList(FileNames,basename);
}
@@ -507,7 +515,7 @@ static string notdir(const string &FileName,void*) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_notdir(const string & FileNames) const
+string mhmakefileparser::f_notdir(const string & FileNames, const string *pOriExpr) const
{
return IterList(FileNames,notdir);
}
@@ -519,14 +527,14 @@ static string addprefix(const string &FileName,void *pPrefix) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_addprefix(const string & Arg) const
+string mhmakefileparser::f_addprefix(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
string PreFix;
pTmp=NextCharItem(pTmp,PreFix,',');
#ifdef _DEBUG
- if (PreFix.empty()) {
- throw ("Wrong number of arguments in function addprefix");
+ if (g_PrintAdditionalInfo && PreFix.empty()) {
+ cout << "Warning: empty prefix in expression: " << *pOriExpr << endl;
}
#endif
string FileNames;
@@ -541,7 +549,7 @@ static string addsuffix(const string &FileName,void *pSuffix) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_addsuffix(const string & Arg) const
+string mhmakefileparser::f_addsuffix(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
string SufFix;
@@ -558,7 +566,7 @@ string mhmakefileparser::f_addsuffix(const string & Arg) const ///////////////////////////////////////////////////////////////////////////////
// Returns the n-th word number
-string mhmakefileparser::f_word(const string & Arg) const
+string mhmakefileparser::f_word(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
@@ -591,7 +599,7 @@ string mhmakefileparser::f_word(const string & Arg) const ///////////////////////////////////////////////////////////////////////////////
// Returns the number of words
-string mhmakefileparser::f_words(const string & Arg) const
+string mhmakefileparser::f_words(const string & Arg, const string *pOriExpr) const
{
const char *pTmp=Arg.c_str();
int NrWords=0;
@@ -609,14 +617,14 @@ string mhmakefileparser::f_words(const string & Arg) const ///////////////////////////////////////////////////////////////////////////////
// Search for a command in the enivornment path
-string mhmakefileparser::f_which(const string & Arg) const
+string mhmakefileparser::f_which(const string & Arg, const string *pOriExpr) const
{
return SearchCommand(Arg);
}
///////////////////////////////////////////////////////////////////////////////
// Removes leading and trailing space
-string mhmakefileparser::f_strip(const string & Arg) const
+string mhmakefileparser::f_strip(const string & Arg, const string *pOriExpr) const
{
string::const_iterator pFirst=Arg.begin();
string::const_iterator pLast=Arg.end();
@@ -648,13 +656,13 @@ static string dir(const string &FileName, void *) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_dir(const string & FileNames) const
+string mhmakefileparser::f_dir(const string & FileNames, const string *pOriExpr) const
{
return IterList(FileNames,dir);
}
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_shell(const string & Command) const
+string mhmakefileparser::f_shell(const string & Command, const string *pOriExpr) const
{
string Output;
@@ -725,7 +733,7 @@ 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 mhmakefileparser::f_relpath(const string & FileNames, const string *pOriExpr) const
{
return IterList(FileNames,relpath,(void*)&m_MakeDir);
}
@@ -744,7 +752,7 @@ static string makeupper(const string &FileName,void *) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_toupper(const string & FileNames) const
+string mhmakefileparser::f_toupper(const string & FileNames, const string *pOriExpr) const
{
return IterList(FileNames,makeupper);
}
@@ -763,8 +771,72 @@ static string makelower(const string &FileName, void *) }
///////////////////////////////////////////////////////////////////////////////
-string mhmakefileparser::f_tolower(const string & FileNames) const
+string mhmakefileparser::f_tolower(const string & FileNames, const string *pOriExpr) const
{
return IterList(FileNames,makelower);
}
+///////////////////////////////////////////////////////////////////////////////
+struct expanedexpr_arg
+{
+ string Var;
+ mhmakefileparser *pParser;
+ string Expr;
+};
+
+static string expandexpr(const string &VarVal, void *pvVar)
+{
+ expanedexpr_arg *pArg=(expanedexpr_arg*)pvVar;
+ pArg->pParser->SetVariable(pArg->Var,VarVal);
+ return pArg->pParser->ExpandExpression(pArg->Expr);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_foreach(const string & ExpandedArg, const string *pOriExpr) const
+{
+#ifdef _DEBUG
+ if (pOriExpr->substr(0,8)!="foreach ")
+ throw(string("wrong assumption in foreach expression: ")+*pOriExpr);
+#endif
+ const char *pTmp=ExpandedArg.c_str();
+
+ expanedexpr_arg Args;
+ Args.pParser=(mhmakefileparser*)this;
+ pTmp=NextCharItem(pTmp,Args.Var,',');
+
+ if (Args.Var.empty())
+ throw(string("Wrong syntax in foreach instruction. Should give the variable a name."));
+
+ string Items;
+ pTmp=NextCharItem(pTmp,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);
+
+ /* Save the variable to be able to restore it after the foreach expansion */
+ string VarVal;
+ map<string,string>::const_iterator pVal=m_Variables.find(Args.Var);
+ if (pVal!=m_Variables.end())
+ VarVal=pVal->second;
+
+ string Ret=IterList(Items,expandexpr,(void*)&Args);
+
+ /* Restore the variable to it's original value */
+ if (pVal!=m_Variables.end())
+ Args.pParser->SetVariable(Args.Var,VarVal);
+ else
+ Args.pParser->DeleteVariable(Args.Var);
+
+ return Ret;
+}
+
diff --git a/tools/mhmake/src/mhmakefileparser.cpp b/tools/mhmake/src/mhmakefileparser.cpp index a2d4537a0..38c5cd3ac 100644 --- a/tools/mhmake/src/mhmakefileparser.cpp +++ b/tools/mhmake/src/mhmakefileparser.cpp @@ -288,7 +288,7 @@ string mhmakefileparser::ExpandMacro(const string &Expr, bool &Recurse) const #ifdef _DEBUG
if (pFunc)
{
- return (this->*pFunc)(Arg);
+ return (this->*pFunc)(Arg, &Expr);
}
else
{
diff --git a/tools/mhmake/src/mhmakefileparser.h b/tools/mhmake/src/mhmakefileparser.h index 6bdaa911d..f1c9cb280 100644 --- a/tools/mhmake/src/mhmakefileparser.h +++ b/tools/mhmake/src/mhmakefileparser.h @@ -36,7 +36,7 @@ struct TOKENVALUE };
class mhmakefileparser;
-typedef string (mhmakefileparser::*function_f)(const string &) const;
+typedef string (mhmakefileparser::*function_f)(const string &, const string *) const;
struct funcdef
{
@@ -189,6 +189,10 @@ public: {
m_Variables[Var]=Val;
}
+ void DeleteVariable(string Var)
+ {
+ m_Variables.erase(Var);
+ }
void EnableAutoDepRescan(void)
{
m_ForceAutoDepRescan=true;
@@ -251,32 +255,33 @@ public: static map<string,function_f> m_Functions;
static bool m_FunctionsInitialised;
static void InitFuncs(void);
- 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_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;
fileinfo* GetFirstTarget() const
{
diff --git a/tools/mhmake/src/mhmakeparser.y b/tools/mhmake/src/mhmakeparser.y index f1ab48606..515caf6e5 100644 --- a/tools/mhmake/src/mhmakeparser.y +++ b/tools/mhmake/src/mhmakeparser.y @@ -184,8 +184,8 @@ vpathrule: VPATH SPACE nonspaceexpression SPACE expression NEWLINE varassignment: VARDEF VARVAL
{
- m_Variables[f_strip($1)]=$2;
- PRINTF(("Defining variable %s to %s\n",f_strip($1).c_str(), $2.c_str()));
+ m_Variables[f_strip($1,NULL)]=$2;
+ PRINTF(("Defining variable %s to %s\n",f_strip($1,NULL).c_str(), $2.c_str()));
}
| STRING EQUAL maybeemptyexpression
{
|