From b320c441ab5ad04ea4a6766d0a178fc7c0ea4105 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Sun, 31 Oct 2010 19:30:18 +0000
Subject: Make sure implicit rule searching is taking the extra dependencies
 into account

---
 tools/mhmake/src/build.cpp  | 61 ++++++++++++++++++++++++++++++------------
 tools/mhmake/src/fileinfo.h | 15 +++--------
 tools/mhmake/src/rule.cpp   | 65 ++++++++++++++++++++++++++-------------------
 tools/mhmake/src/rule.h     |  9 ++++---
 tools/mhmake/src/util.h     |  2 +-
 5 files changed, 92 insertions(+), 60 deletions(-)

(limited to 'tools/mhmake/src')

diff --git a/tools/mhmake/src/build.cpp b/tools/mhmake/src/build.cpp
index 3a6af155c..9efa90932 100644
--- a/tools/mhmake/src/build.cpp
+++ b/tools/mhmake/src/build.cpp
@@ -1563,14 +1563,14 @@ mh_time_t mhmakefileparser::StartBuildTarget(fileinfo* pTarget,bool bCheckTarget
 
   if (!pRule || !pRule->GetCommands().size())
   {
-    vector< pair<fileinfo*,refptr<rule> > > Result;
+    implicitruledep_t Result;
 
     IMPLICITRULE::SearchImplicitRule(pTarget,Result);
 
-    vector< pair<fileinfo*,refptr<rule> > >::iterator ResultIt=Result.begin();
+    implicitruledep_t::iterator ResultIt=Result.begin();
     while (ResultIt!=Result.end())
     {
-      if (ResultIt->first==NULL)
+      if (ResultIt->first.empty())
       {
         pRule=ResultIt->second;
         pTarget->SetRule(pRule);
@@ -1585,40 +1585,67 @@ mh_time_t mhmakefileparser::StartBuildTarget(fileinfo* pTarget,bool bCheckTarget
       }
       else if (!IMPLICITRULE::PushRule(ResultIt->second))
       {
+        /* We have to check all the implicitrule dependencies, only when they all can be build,
+           the implicit rule matches */
         #ifdef _DEBUG
+        fileinfo *pYoungestTarget;
         m_ImplicitSearch++;
         #endif
-        fileinfo* pNewTarget=ResultIt->first;
-        mh_time_t DepDate=BuildTarget(pNewTarget);
-        if (!DepDate.DoesExist())
+        mh_time_t ThisYoungestDate=YoungestDate;
+        vector<fileinfo*>::iterator ImplicitRuleDepsIt=ResultIt->first.begin();
+        while (ImplicitRuleDepsIt!=ResultIt->first.end())
         {
-          pNewTarget=ResultIt->second->GetMakefile()->SearchvPath(pNewTarget);
-          if (pNewTarget!=NULL)
-            DepDate=pNewTarget->GetDate();
+          fileinfo *pNewTarget=*ImplicitRuleDepsIt;
+          mh_time_t DepDate=BuildTarget(pNewTarget);
+          if (!DepDate.DoesExist())
+          {
+            pNewTarget=ResultIt->second->GetMakefile()->SearchvPath(pNewTarget);
+            if (pNewTarget!=NULL)
+            {
+              *ImplicitRuleDepsIt=pNewTarget;  /* The file was elsewere so we have to update the dependencies */
+              DepDate=pNewTarget->GetDate();
+            }
+          }
+          if (!DepDate.DoesExist())
+            break;
+          if (DepDate.IsNewer(ThisYoungestDate))
+          {
+            ThisYoungestDate=DepDate;
+            #ifdef _DEBUG
+            pYoungestTarget=pNewTarget;
+            #endif
+          }
+          ImplicitRuleDepsIt++;
         }
+        
         IMPLICITRULE::PopRule(ResultIt->second);
         #ifdef _DEBUG
         m_ImplicitSearch--;
         #endif
-        if (DepDate.DoesExist())
+        if (ImplicitRuleDepsIt==ResultIt->first.end()) // All deps exists
         {
-          if (DepDate.IsNewer(YoungestDate))
-            YoungestDate=DepDate;
+          ThisYoungestDate=YoungestDate;
           pRule=ResultIt->second;
-          pTarget->AddMainDep(pNewTarget);
+          pTarget->InsertDeps(ResultIt->first);
           pTarget->SetRule(pRule);  /* This is an implicit rule so do not add the target */
           #ifdef _DEBUG
           if (g_PrintAdditionalInfo)
           {
-            cout<<"Found implicit rule for "<<pTarget->GetQuotedFullFileName()<<". Dependent "<<ResultIt->first->GetQuotedFullFileName()<<endl;
+            cout<<"Found implicit rule for "<<pTarget->GetQuotedFullFileName()<<". Dependents:\n";
+            vector<fileinfo*>::iterator ImplicitRuleDepsIt=ResultIt->first.begin();
+            while (ImplicitRuleDepsIt!=ResultIt->first.end())
+            {
+              cout<<"  "<<(*ImplicitRuleDepsIt)->GetQuotedFullFileName()<<endl;
+              ImplicitRuleDepsIt++;
+            }
             pRule->PrintCommands(pTarget);
           }
           #endif
-          if (DepDate.IsNewer(TargetDate))
+          if (ThisYoungestDate.IsNewer(TargetDate))
           {
             #ifdef _DEBUG
-            if (pRule,g_pPrintDependencyCheck && DepDate.IsExistingFile() && TargetDate.IsExistingFile())
-              cout<<"Going to build "<<pTarget->GetQuotedFullFileName()<<" because "<<ResultIt->first->GetQuotedFullFileName()<<" is more recent\n";
+            if (pRule,g_pPrintDependencyCheck && ThisYoungestDate.IsExistingFile() && TargetDate.IsExistingFile())
+              cout<<"Going to build "<<pTarget->GetQuotedFullFileName()<<" because "<<pYoungestTarget->GetQuotedFullFileName()<<" is more recent\n";
             #endif
             MakeTarget=true;
           }
diff --git a/tools/mhmake/src/fileinfo.h b/tools/mhmake/src/fileinfo.h
index bb5e0ce71..1d70f0df1 100644
--- a/tools/mhmake/src/fileinfo.h
+++ b/tools/mhmake/src/fileinfo.h
@@ -257,6 +257,7 @@ public:
 
   void InsertDeps(vector<fileinfo*> &Deps)
   {
+    #ifdef _DEBUG
     vector<fileinfo*> NewDeps;
     vector<fileinfo*>::const_iterator It=Deps.begin();
     vector<fileinfo*>::const_iterator ItEnd=Deps.end();
@@ -274,17 +275,9 @@ public:
     }
     if (NewDeps.size())
       m_Deps.insert(m_Deps.begin(),NewDeps.begin(),NewDeps.end());
-  }
-  void AddMainDep(fileinfo* pMainDep)
-  {
-    if (&*pMainDep==this)
-    {
-      #ifdef _DEBUG
-      cout << GetQuotedFullFileName()<<" is directly dependent on itself\n";
-      #endif
-      return;
-    }
-    m_Deps.insert(m_Deps.begin(),pMainDep);
+    #else
+      m_Deps.insert(m_Deps.begin(),Deps.begin(),Deps.end());
+    #endif
   }
   vector<fileinfo*> &GetDeps(void)
   {
diff --git a/tools/mhmake/src/rule.cpp b/tools/mhmake/src/rule.cpp
index cee38ddb9..0beb29c39 100644
--- a/tools/mhmake/src/rule.cpp
+++ b/tools/mhmake/src/rule.cpp
@@ -28,19 +28,19 @@
 refptr<rule> NullRule;
 
 set<rule*> IMPLICITRULE::m_ImplicitRuleRecurseDetStack;
-vector<pair<fileinfo *, vector<pair< fileinfo *,refptr<rule> > > > > IMPLICITRULE::m_ImplicitRules;
+vector<implicitrule_t> IMPLICITRULE::m_ImplicitRules;
 
 makecommand g_MakeCommand;  // Order is important since sm_Statics is using g_MakeCommand
 const string g_QuoteString("\""); // Order is important since sm_Statics is using g_QuoteString
 loadedmakefile::loadedmakefile_statics loadedmakefile::sm_Statics;
 
 ///////////////////////////////////////////////////////////////////////////////
-static bool FindDep(fileinfo *pDep, vector<pair<fileinfo*,refptr<rule> > >*pImplicitRule,refptr<rule> &Rule)
+static bool FindDep(fileinfo *pTarget, implicitruledep_t *pImplicitRule,refptr<rule> &Rule)
 {
-  vector<pair<fileinfo*,refptr<rule> > >::iterator SecIt=pImplicitRule->begin();
+  implicitruledep_t::iterator SecIt=pImplicitRule->begin();
   while (SecIt!=pImplicitRule->end())
   {
-    if (SecIt->first==pDep)
+    if (SecIt->first.empty())
     {
       #ifdef _DEBUG
       // Check if the rule has the same commands
@@ -52,9 +52,9 @@ static bool FindDep(fileinfo *pDep, vector<pair<fileinfo*,refptr<rule> > >*pImpl
       {
         string ErrorMessage;
         if (bCommandsDifferent)
-          ErrorMessage += "Implicit Rule '"+ pDep->GetFullFileName() + "' defined twice with different commands\n";
+          ErrorMessage += "Implicit Rule '"+ pTarget->GetFullFileName() + "' defined twice with different commands\n";
         else
-          ErrorMessage += "Implicit Rule '"+ pDep->GetFullFileName() + "' defined twice with same commands\n";
+          ErrorMessage += "Implicit Rule '"+ pTarget->GetFullFileName() + "' defined twice with same commands\n";
         ErrorMessage += "Command 1: makedir = " + SecIt->second->GetMakefile()->GetMakeDir()->GetQuotedFullFileName()+ "\n";
 
         vector<string>::const_iterator It;
@@ -87,7 +87,7 @@ static bool FindDep(fileinfo *pDep, vector<pair<fileinfo*,refptr<rule> > >*pImpl
       {
         if (pOldMakefile->ExpandExpression(*OldIt)!=pNewMakefile->ExpandExpression(*NewIt))
         {
-          string ErrorMessage = string("Implicit Rule '") + pDep->GetFullFileName() + "' defined twice with different commands\n";
+          string ErrorMessage = string("Implicit Rule '") + pTarget->GetFullFileName() + "' defined twice with different commands\n";
           ErrorMessage += "Command 1: makedir = " + pOldMakefile->GetMakeDir()->GetQuotedFullFileName()+ "\n";
           ErrorMessage += "  " + pOldMakefile->ExpandExpression(*OldIt) + "\n";
           ErrorMessage += "Command 2: makedir = " + pNewMakefile->GetMakeDir()->GetQuotedFullFileName()+ "\n";
@@ -117,8 +117,8 @@ void IMPLICITRULE::AddImplicitRule(fileinfo *pTarget,const vector<fileinfo*> &De
     return;
   }
   // first search if there is already the same target in the current list of implicit rules
-  vector<pair<fileinfo*,refptr<rule> > >* pImplicitRule=NULL;
-  vector<pair<fileinfo *, vector<pair< fileinfo *,refptr<rule> > > > >::iterator RuleIt=m_ImplicitRules.begin();
+  implicitruledep_t* pImplicitRule=NULL;
+  vector<implicitrule_t>::iterator RuleIt=m_ImplicitRules.begin();
   while (RuleIt!=m_ImplicitRules.end())
   {
     if (pTarget==RuleIt->first)
@@ -128,46 +128,45 @@ void IMPLICITRULE::AddImplicitRule(fileinfo *pTarget,const vector<fileinfo*> &De
     RuleIt++;
   }
   if (!pImplicitRule)
-{
+  {
     // Add a new entry
-    m_ImplicitRules.push_back(pair<fileinfo *, vector<pair< fileinfo *,refptr<rule> > > >(pTarget,vector<pair<fileinfo*,refptr<rule> > >()));
+    m_ImplicitRules.push_back(implicitrule_t(pTarget,implicitruledep_t()));
     pImplicitRule=&((m_ImplicitRules.end()-1)->second);
   }
 
   if (Deps.size())
   {
+    #ifdef _DEBUG
     vector<fileinfo*>::const_iterator DepIt=Deps.begin();
     while (DepIt!=Deps.end())
     {
-      #ifdef _DEBUG
       if (*DepIt==pTarget)
         throw(string("Implicit rule : ")+pTarget->GetFullFileName()+" is directly dependent on itself. This is not allowed.");
-      #endif
-      if (!FindDep(*DepIt,pImplicitRule,Rule))
-        pImplicitRule->push_back(pair<fileinfo*,refptr<rule> >(*DepIt,Rule));
       DepIt++;
     }
+    #endif
+    pImplicitRule->push_back(pair<vector<fileinfo*>,refptr<rule> >(Deps,Rule));
   }
   else
   {
-    if (!FindDep(NULL,pImplicitRule,Rule))
-      pImplicitRule->push_back(pair<fileinfo*,refptr<rule> >((fileinfo*)NULL,Rule));
+    if (!FindDep(pTarget,pImplicitRule,Rule))
+      pImplicitRule->push_back(pair<vector<fileinfo*>, refptr<rule> >(vector<fileinfo*>(), Rule));
   }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-void IMPLICITRULE::SearchImplicitRule(const fileinfo *pTarget,vector< pair<fileinfo*,refptr<rule> > >&Result)
+void IMPLICITRULE::SearchImplicitRule(const fileinfo *pTarget, implicitruledep_t &Result)
 {
   string TargetFileName=pTarget->GetFullFileName();
 
-  vector<pair<fileinfo *, vector<pair< fileinfo *,refptr<rule> > > > >::iterator ImpRegExIt=m_ImplicitRules.begin();
+  vector<implicitrule_t>::iterator ImpRegExIt=m_ImplicitRules.begin();
   while (ImpRegExIt!=m_ImplicitRules.end())
   {
     matchres Res;
 
     if (PercentMatch(TargetFileName,ImpRegExIt->first->GetFullFileName(),&Res))
     {
-      vector<pair<fileinfo*,refptr<rule> > >::iterator ResIt=ImpRegExIt->second.begin();
+      implicitruledep_t::iterator ResIt=ImpRegExIt->second.begin();
       while (ResIt!=ImpRegExIt->second.end())
       {
 #ifdef _DEBUG
@@ -177,9 +176,12 @@ void IMPLICITRULE::SearchImplicitRule(const fileinfo *pTarget,vector< pair<filei
         }
 #endif
         ResIt->second->SetStem(Res.m_Stem);
-        if (ResIt->first!=NULL)
+        vector<fileinfo*> Deps;
+        const fileinfo *pMakeDir=ResIt->second->GetMakefile()->GetMakeDir();
+        vector<fileinfo*>::iterator It=ResIt->first.begin();
+        while (It!=ResIt->first.end())
         {
-          string Dependent=ReplaceWithStem(ResIt->first->GetFullFileName(),Res.m_Stem);
+          string Dependent=ReplaceWithStem((*It)->GetFullFileName(),Res.m_Stem);
           #ifdef _DEBUG
           if (Dependent.length()>MAX_PATH)
           {
@@ -187,10 +189,10 @@ void IMPLICITRULE::SearchImplicitRule(const fileinfo *pTarget,vector< pair<filei
             throw(string("Filename too long in implicit rule search: ")+Dependent+"\nProbably some infinit loop in the implicit rules search.\n");
           }
           #endif
-          Result.push_back(pair<fileinfo*,refptr<rule> >(GetFileInfo(Dependent,ResIt->second->GetMakefile()->GetMakeDir()),ResIt->second));
+          Deps.push_back(GetFileInfo(Dependent,pMakeDir));
+          It++;
         }
-        else
-          Result.push_back(pair<fileinfo*,refptr<rule> >((fileinfo*)NULL,ResIt->second));
+        Result.push_back(pair<vector<fileinfo*>,refptr<rule> >(Deps, ResIt->second));
         ResIt++;
       }
     }
@@ -246,14 +248,21 @@ void rule::SetTargetsIsBuilding(const fileinfo *pSrc)
 ///////////////////////////////////////////////////////////////////////////////
 void IMPLICITRULE::PrintImplicitRules()
 {
-  vector<pair<fileinfo *, vector<pair< fileinfo *,refptr<rule> > > > >::iterator ImpRegExIt=m_ImplicitRules.begin();
+  vector<implicitrule_t>::iterator ImpRegExIt=m_ImplicitRules.begin();
   while (ImpRegExIt!=m_ImplicitRules.end())
   {
-    vector<pair<fileinfo*,refptr<rule> > >::iterator SecIt=ImpRegExIt->second.begin();
+    implicitruledep_t::iterator SecIt=ImpRegExIt->second.begin();
     cout << ImpRegExIt->first->GetFullFileName() << " :\n";
     while (SecIt!=ImpRegExIt->second.end())
     {
-      cout << "  : " << SecIt->first <<endl;
+      cout << "  :";
+      vector<fileinfo*>::iterator DepIt=SecIt->first.begin();
+      while (DepIt!=SecIt->first.end())
+      {
+        cout << " " << (*DepIt)->GetQuotedFullFileName() <<endl;
+        DepIt++;
+      }
+      cout << endl;
       if (SecIt->second)
       {
         SecIt->second->PrintCommands();
diff --git a/tools/mhmake/src/rule.h b/tools/mhmake/src/rule.h
index 3b288e3d2..7cc287600 100644
--- a/tools/mhmake/src/rule.h
+++ b/tools/mhmake/src/rule.h
@@ -74,13 +74,16 @@ public:
   void SetTargetsIsBuilding(const fileinfo *pSrc);
 };
 
+typedef vector<pair<vector<fileinfo*>,refptr<rule> > > implicitruledep_t;
+typedef pair<fileinfo *, implicitruledep_t > implicitrule_t;
+
 class IMPLICITRULE
 {
   static set<rule*> m_ImplicitRuleRecurseDetStack;
-  static vector<pair<fileinfo *, vector<pair< fileinfo *,refptr<rule> > > > > m_ImplicitRules;  // Use a vector and not a map because the order of the implicit rules is important
+  static vector<implicitrule_t> m_ImplicitRules;  // Use a vector and not a map because the order of the implicit rules is important
 public:
-  static void AddImplicitRule(fileinfo *pTarget,const vector<fileinfo*> &Deps,refptr<rule> pRule);
-  static void SearchImplicitRule(const fileinfo *pTarget,vector< pair<fileinfo*,refptr<rule> > >&Result);
+  static void AddImplicitRule(fileinfo *pTarget,const vector<fileinfo*> &Deps, refptr<rule> pRule);
+  static void SearchImplicitRule(const fileinfo *pTarget, implicitruledep_t &Result);
   static void PrintImplicitRules();
   static bool PushRule(rule *pRule)
   {
diff --git a/tools/mhmake/src/util.h b/tools/mhmake/src/util.h
index 60809cd85..4a4b75488 100644
--- a/tools/mhmake/src/util.h
+++ b/tools/mhmake/src/util.h
@@ -50,7 +50,7 @@
 #define PLATFORM     "linux"
 #endif
 
-#define MHMAKEVER    "2.3.15"
+#define MHMAKEVER    "2.3.16"
 
 class makecommand
 {
-- 
cgit v1.2.3