Browse Source

ENH: Added SOURCE_FILES syntax to CABLE_DEFINE_SET command.

Brad King 24 years ago
parent
commit
b9a8948ec8
2 changed files with 99 additions and 4 deletions
  1. 83 2
      Source/cmCableDefineSetCommand.cxx
  2. 16 2
      Source/cmCableDefineSetCommand.h

+ 83 - 2
Source/cmCableDefineSetCommand.cxx

@@ -36,14 +36,28 @@ bool cmCableDefineSetCommand::Invoke(std::vector<std::string>& args)
   // The first argument is the name of the set.
   // The first argument is the name of the set.
   m_SetName = *arg++;
   m_SetName = *arg++;
   
   
-  // The rest of the arguments are the elements to be placed in the set.
-  for(; arg != args.end(); ++arg)
+  // All arguments until a "SOURCE_FILES" are the elements to be placed in
+  // the set.
+  for(; (arg != args.end()) && (*arg != "SOURCE_FILES"); ++arg)
     {
     {
     // If the element cannot be added, return an error.
     // If the element cannot be added, return an error.
     // This can occur when a tag is not specified and can't be generated.
     // This can occur when a tag is not specified and can't be generated.
     if(!this->AddElement(*arg))
     if(!this->AddElement(*arg))
       { return false; }
       { return false; }
     }
     }
+
+  // If we are not at the end, the "SOURCE_FILES" keyword has been
+  // encountered.
+  if(arg != args.end())
+    {
+    // The rest of the arguments are source files to be included in
+    // any package which references the set.
+    for(++arg; arg != args.end(); ++arg)
+      {
+      if(!this->AddSourceFile(*arg))
+        { return false; }
+      }
+    }
   
   
   // Write this command's configuration output.
   // Write this command's configuration output.
   this->WriteConfiguration();
   this->WriteConfiguration();
@@ -65,6 +79,17 @@ void cmCableDefineSetCommand::WriteConfiguration() const
   
   
   // Output the code.
   // Output the code.
   os << indent << "<Set name=\"" << m_SetName.c_str() << "\">" << std::endl;
   os << indent << "<Set name=\"" << m_SetName.c_str() << "\">" << std::endl;
+  for(std::vector<std::string>::const_iterator e = m_SourceHeaders.begin();
+      e != m_SourceHeaders.end(); ++e)
+    {
+    os << indent << "  <File name=\"" << e->c_str() << "\"/>" << std::endl;
+    }
+  for(std::vector<std::string>::const_iterator e = m_InstantiationSources.begin();
+      e != m_InstantiationSources.end(); ++e)
+    {
+    os << indent << "  <File name=\"" << e->c_str()
+       << "\" purpose=\"instantiate\"/>" << std::endl;
+    }
   for(Elements::const_iterator e = m_Elements.begin();
   for(Elements::const_iterator e = m_Elements.begin();
       e != m_Elements.end(); ++e)
       e != m_Elements.end(); ++e)
     {
     {
@@ -217,3 +242,59 @@ cmCableDefineSetCommand::GenerateTag(const std::string& element,
   
   
   return false;
   return false;
 }
 }
+
+
+/**
+ * Add a source file associated with this set.  Any package referencing
+ * this set will automatically include this source file.
+ */
+bool cmCableDefineSetCommand::AddSourceFile(const std::string& file)
+{
+  // We must locate the file in the include path so that we can detect
+  // its extension, and whether there is more than one to find.
+  std::string header = file+".h";
+  m_Makefile->ExpandVariablesInString(header);
+
+  // See if the file just exists here.  The compiler's search path will
+  // locate it.
+  if(cmSystemTools::FileExists(header.c_str()))
+    {
+    m_SourceHeaders.push_back(header);
+    // See if there is a matching .txx as well.
+    std::string txx = file+".txx";
+    m_Makefile->ExpandVariablesInString(txx);
+    if(cmSystemTools::FileExists(txx.c_str()))
+      {
+      m_InstantiationSources.push_back(txx);
+      }
+    return true;
+    }
+  
+  // We must look for the file in the include search path.
+  const std::vector<std::string>& includeDirectories =
+    m_Makefile->GetIncludeDirectories();
+  
+  for(std::vector<std::string>::const_iterator dir = includeDirectories.begin();
+      dir != includeDirectories.end(); ++dir)
+    {
+    std::string path = *dir + "/" + header;
+    m_Makefile->ExpandVariablesInString(path);
+    if(cmSystemTools::FileExists(path.c_str()))
+      {
+      m_SourceHeaders.push_back(path);
+      // See if there is a matching .txx as well.
+      std::string txx = *dir + "/" + file + ".txx";
+      m_Makefile->ExpandVariablesInString(txx);
+      if(cmSystemTools::FileExists(txx.c_str()))
+        {
+        m_InstantiationSources.push_back(txx);
+        }
+      return true;
+      }
+    }
+
+  // We couldn't locate the source file.  Report the error.
+  std::string err = "couldn't find source file " + header;
+  this->SetError(err.c_str());
+  return false;
+}

+ 16 - 2
Source/cmCableDefineSetCommand.h

@@ -69,11 +69,14 @@ public:
   virtual const char* GetFullDocumentation()
   virtual const char* GetFullDocumentation()
     {
     {
     return
     return
-      "CABLE_DEFINE_SET(name_of_set [[tag1]:]memeber1 [[tag2]:]member2 ...)\n"
+      "CABLE_DEFINE_SET(name_of_set [[tag1]:]memeber1 [[tag2]:]member2 ...\n"
+      "                 [SOURCE_FILES source1 source2 ...]] )\n"
       "Generates a Set definition in the CABLE configuration.  The sets are\n"
       "Generates a Set definition in the CABLE configuration.  The sets are\n"
       "referenced in other CABLE commands by a '$' immediately followed by\n"
       "referenced in other CABLE commands by a '$' immediately followed by\n"
       "the set name (ex. $SetName).  If a the \"tag:\" syntax is not used,\n"
       "the set name (ex. $SetName).  If a the \"tag:\" syntax is not used,\n"
-      "an attempt is made to auto-generate a meaningful tag.\n";
+      "an attempt is made to auto-generate a meaningful tag.  If the\n"
+      "SOURCE_FILES keyword is given, all arguments after it refer to header\n"
+      "files to be included in any package referencing the set.\n";
     }
     }
 
 
   cmTypeMacro(cmCableDefineSetCommand, cmCableCommand);
   cmTypeMacro(cmCableDefineSetCommand, cmCableCommand);
@@ -82,6 +85,7 @@ private:
   void WriteConfiguration() const;
   void WriteConfiguration() const;
   bool AddElement(const std::string&);
   bool AddElement(const std::string&);
   bool GenerateTag(const std::string&, std::string&);
   bool GenerateTag(const std::string&, std::string&);
+  bool AddSourceFile(const std::string&);
 private:  
 private:  
   typedef std::pair<std::string, std::string>  Element;
   typedef std::pair<std::string, std::string>  Element;
   typedef std::vector<Element>  Elements;
   typedef std::vector<Element>  Elements;
@@ -95,6 +99,16 @@ private:
    * The elements to be defined in the set (before $ expansion).
    * The elements to be defined in the set (before $ expansion).
    */
    */
   Elements  m_Elements;
   Elements  m_Elements;
+  
+  /**
+   * The source headers associated with this set.
+   */
+  std::vector<std::string> m_SourceHeaders;
+  
+  /**
+   * The instantiation sources associated with this set.
+   */
+  std::vector<std::string> m_InstantiationSources;
 };
 };