summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2003-07-23 19:32:54 (GMT)
committerBrad King <brad.king@kitware.com>2003-07-23 19:32:54 (GMT)
commit48aedb2ba39621a75065a4b4bc5aca7ea695c65a (patch)
treea0e0608e847a321dd15e681998b2eb0565e74b23
parente093bdade050419290a1535ced1ca11fe7f8a2d5 (diff)
downloadCMake-48aedb2ba39621a75065a4b4bc5aca7ea695c65a.zip
CMake-48aedb2ba39621a75065a4b4bc5aca7ea695c65a.tar.gz
CMake-48aedb2ba39621a75065a4b4bc5aca7ea695c65a.tar.bz2
ENH: Fully implemented SOURCE_GROUP command.
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx2
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx2
-rw-r--r--Source/cmMakefile.cxx17
-rw-r--r--Source/cmSourceGroup.cxx76
-rw-r--r--Source/cmSourceGroup.h61
-rw-r--r--Source/cmSourceGroupCommand.cxx71
-rw-r--r--Source/cmSourceGroupCommand.h12
7 files changed, 165 insertions, 76 deletions
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 0d6a830..4e7df94 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -252,7 +252,7 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
std::string source = (*i)->GetFullPath();
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
sourceGroups);
- sourceGroup.AddSource(source.c_str(), *i);
+ sourceGroup.AssignSource(*i);
// while we are at it, if it is a .rule file then for visual studio 6 we
// must generate it
if ((*i)->GetSourceExtension() == "rule")
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index dbde4a7..95f0977 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -695,7 +695,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
}
cmSourceGroup& sourceGroup =
m_Makefile->FindSourceGroup(source.c_str(), sourceGroups);
- sourceGroup.AddSource(source.c_str(), *i);
+ sourceGroup.AssignSource(*i);
}
// open the project
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 6d196f8..8d4bb1e 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1535,17 +1535,21 @@ cmSourceGroup&
cmMakefile::FindSourceGroup(const char* source,
std::vector<cmSourceGroup> &groups)
{
- std::string file = source;
- std::string::size_type pos = file.rfind('/');
- if(pos != std::string::npos)
+ // First search for a group that lists the file explicitly.
+ for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
+ sg != groups.rend(); ++sg)
{
- file = file.substr(pos+1);
+ if(sg->MatchesFiles(source))
+ {
+ return *sg;
+ }
}
-
+
+ // Now search for a group whose regex matches the file.
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
sg != groups.rend(); ++sg)
{
- if(sg->Matches(file.c_str()))
+ if(sg->MatchesRegex(source))
{
return *sg;
}
@@ -1840,7 +1844,6 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
return ret;
}
-
cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
{
// check to see if it exists
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 706547d..035b643 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -16,42 +16,68 @@
=========================================================================*/
#include "cmSourceGroup.h"
-
-/**
- * The constructor initializes the group's regular expression.
- */
-cmSourceGroup::cmSourceGroup(const char* name, const char* regex):
- m_Name(name),
- m_GroupRegex(regex)
+//----------------------------------------------------------------------------
+cmSourceGroup::cmSourceGroup(const char* name, const char* regex): m_Name(name)
{
+ this->SetGroupRegex(regex);
}
-
-/**
- * Copy constructor.
- */
-cmSourceGroup::cmSourceGroup(const cmSourceGroup& r):
- m_Name(r.m_Name),
- m_GroupRegex(r.m_GroupRegex),
- m_SourceFiles(r.m_SourceFiles)
+//----------------------------------------------------------------------------
+void cmSourceGroup::SetGroupRegex(const char* regex)
{
+ if(regex)
+ {
+ m_GroupRegex.compile(regex);
+ }
+ else
+ {
+ m_GroupRegex.compile("^$");
+ }
}
-
-
-/**
- * Returns whether the given name matches the group's regular expression.
- */
-bool cmSourceGroup::Matches(const char* name)
+
+//----------------------------------------------------------------------------
+void cmSourceGroup::AddGroupFile(const char* name)
+{
+ m_GroupFiles.insert(name);
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceGroup::GetName() const
+{
+ return m_Name.c_str();
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceGroup::MatchesRegex(const char* name)
{
return m_GroupRegex.find(name);
}
+//----------------------------------------------------------------------------
+bool cmSourceGroup::MatchesFiles(const char* name)
+{
+ std::set<cmStdString>::const_iterator i = m_GroupFiles.find(name);
+ if(i != m_GroupFiles.end())
+ {
+ return true;
+ }
+ return false;
+}
-/**
- * Add a source to the group that the compiler will know how to build.
- */
-void cmSourceGroup::AddSource(const char* /* name */, const cmSourceFile* sf)
+//----------------------------------------------------------------------------
+void cmSourceGroup::AssignSource(const cmSourceFile* sf)
{
m_SourceFiles.push_back(sf);
}
+//----------------------------------------------------------------------------
+const std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() const
+{
+ return m_SourceFiles;
+}
+
+//----------------------------------------------------------------------------
+std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles()
+{
+ return m_SourceFiles;
+}
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 3158041..4308028 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -25,29 +25,56 @@ class cmSourceFile;
/** \class cmSourceGroup
* \brief Hold a group of sources as specified by a SOURCE_GROUP command.
*
- * cmSourceGroup holds all the source files and corresponding commands
- * for files matching the regular expression specified for the group.
+ * cmSourceGroup holds a regular expression and a list of files. When
+ * local generators are about to generate the rules for a target's
+ * files, the set of source groups is consulted to group files
+ * together. A file is placed into the last source group that lists
+ * the file by name. If no group lists the file, it is placed into
+ * the last group whose regex matches it.
*/
class cmSourceGroup
{
public:
cmSourceGroup(const char* name, const char* regex);
- cmSourceGroup(const cmSourceGroup&);
~cmSourceGroup() {}
- void SetGroupRegex(const char* regex)
- { m_GroupRegex.compile(regex); }
- void AddSource(const char* name, const cmSourceFile*);
- const char* GetName() const
- { return m_Name.c_str(); }
- bool Matches(const char *);
+ /**
+ * Set the regular expression for this group.
+ */
+ void SetGroupRegex(const char* regex);
+
+ /**
+ * Add a file name to the explicit list of files for this group.
+ */
+ void AddGroupFile(const char* name);
+
+ /**
+ * Get the name of this group.
+ */
+ const char* GetName() const;
+
+ /**
+ * Check if the given name matches this group's regex.
+ */
+ bool MatchesRegex(const char* name);
+
+ /**
+ * Check if the given name matches this group's explicit file list.
+ */
+ bool MatchesFiles(const char* name);
+
+ /**
+ * Assign the given source file to this group. Used only by
+ * generators.
+ */
+ void AssignSource(const cmSourceFile* sf);
/**
- * Get the list of the source files used by this target
+ * Get the list of the source files that have been assigned to this
+ * source group.
*/
- const std::vector<const cmSourceFile*> &GetSourceFiles() const
- {return m_SourceFiles;}
- std::vector<const cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;}
+ const std::vector<const cmSourceFile*>& GetSourceFiles() const;
+ std::vector<const cmSourceFile*>& GetSourceFiles();
private:
/**
@@ -61,7 +88,13 @@ private:
cmsys::RegularExpression m_GroupRegex;
/**
- * vector of all source files in this source group
+ * Set of file names explicitly added to this group.
+ */
+ std::set<cmStdString> m_GroupFiles;
+
+ /**
+ * Vector of all source files that have been assigned to
+ * this group.
*/
std::vector<const cmSourceFile*> m_SourceFiles;
};
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 2978aed..621b564 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -24,37 +24,60 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args)
this->SetError("called with incorrect number of arguments");
return false;
}
-
- if ( args[1] == "REGULAR_EXPRESSION" && args.size() == 3 )
+
+ // Get the source group with the given name.
+ cmSourceGroup* sg = m_Makefile->GetSourceGroup(args[0].c_str());
+ if(!sg)
{
- m_Makefile->AddSourceGroup(args[0].c_str(), args[2].c_str());
- return true;
+ m_Makefile->AddSourceGroup(args[0].c_str(), 0);
+ sg = m_Makefile->GetSourceGroup(args[0].c_str());
}
-
- if ( args[1] == "FILES" )
+
+ // Process arguments.
+ bool doingFiles = false;
+ for(unsigned int i=1; i < args.size(); ++i)
{
- cmSourceGroup* sg = m_Makefile->GetSourceGroup(args[0].c_str());
- if ( !sg )
+ if(args[i] == "REGULAR_EXPRESSION")
+ {
+ // Next argument must specify the regex.
+ if(i+1 < args.size())
+ {
+ ++i;
+ sg->SetGroupRegex(args[i].c_str());
+ }
+ else
+ {
+ this->SetError("REGULAR_EXPRESSION argument given without a regex.");
+ return false;
+ }
+ doingFiles = false;
+ }
+ else if(args[i] == "FILES")
{
- m_Makefile->AddSourceGroup(args[0].c_str(), 0);
- sg = m_Makefile->GetSourceGroup(args[0].c_str());
+ // Next arguments will specify files.
+ doingFiles = true;
}
- unsigned int cc;
- for ( cc = 2; cc < args.size(); cc ++ )
+ else if(doingFiles)
{
- sg->AddSource(args[cc].c_str(), 0);
+ // Convert name to full path and add to the group's list.
+ std::string src = args[i].c_str();
+ if(!cmSystemTools::FileIsFullPath(src.c_str()))
+ {
+ src = m_Makefile->GetCurrentDirectory();
+ src += "/";
+ src += args[i];
+ }
+ sg->AddGroupFile(src.c_str());
+ }
+ else
+ {
+ cmOStringStream err;
+ err << "Unknown argument \"" << args[i].c_str() << "\". "
+ << "Perhaps the FILES keyword is missing.\n";
+ this->SetError(err.str().c_str());
+ return false;
}
-
- return true;
}
- if ( args.size() == 2 )
- {
- m_Makefile->AddSourceGroup(args[0].c_str(), args[1].c_str());
- return true;
- }
-
- this->SetError("called with incorrect number of arguments");
- return false;
+ return true;
}
-
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index dea9850..1dc1ba3 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -71,10 +71,14 @@ public:
virtual const char* GetFullDocumentation()
{
return
- " SOURCE_GROUP(name regex)\n"
- "Defines a new source group. Any file whose name matches the regular "
- "expression will be placed in this group. The LAST regular expression "
- "of all defined SOURCE_GROUPs that matches the file will be selected.";
+ " SOURCE_GROUP(name [REGULAR_EXPRESSION regex] [FILES src1 src2 ...])\n"
+ "Defines a group into which sources will be placed in project files. "
+ "This is mainly used to setup file tabs in Visual Studio. "
+ "Any file whose name is listed or matches the regular expression will "
+ "be placed in this group. If a file matches multiple groups, the LAST "
+ "group that explicitly lists the file will be favored, if any. If no "
+ "group explicitly lists the file, the LAST group whose regular "
+ "expression matches the file will be favored.";
}
cmTypeMacro(cmSourceGroupCommand, cmCommand);