ENH: Fully implemented SOURCE_GROUP command.
This commit is contained in:
parent
e093bdade0
commit
48aedb2ba3
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
file = file.substr(pos+1);
|
||||
}
|
||||
|
||||
// First search for a group that lists the file explicitly.
|
||||
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
|
||||
sg != groups.rend(); ++sg)
|
||||
{
|
||||
if(sg->Matches(file.c_str()))
|
||||
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->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
|
||||
|
|
|
@ -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("^$");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSourceGroup::AddGroupFile(const char* name)
|
||||
{
|
||||
m_GroupFiles.insert(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given name matches the group's regular expression.
|
||||
*/
|
||||
bool cmSourceGroup::Matches(const char* 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* Get the list of the source files used by this target
|
||||
* Add a file name to the explicit list of files for this group.
|
||||
*/
|
||||
const std::vector<const cmSourceFile*> &GetSourceFiles() const
|
||||
{return m_SourceFiles;}
|
||||
std::vector<const cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;}
|
||||
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 that have been assigned to this
|
||||
* source group.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -25,36 +25,59 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( args[1] == "REGULAR_EXPRESSION" && args.size() == 3 )
|
||||
{
|
||||
m_Makefile->AddSourceGroup(args[0].c_str(), args[2].c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( args[1] == "FILES" )
|
||||
{
|
||||
// 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(), 0);
|
||||
sg = m_Makefile->GetSourceGroup(args[0].c_str());
|
||||
}
|
||||
unsigned int cc;
|
||||
for ( cc = 2; cc < args.size(); cc ++ )
|
||||
|
||||
// Process arguments.
|
||||
bool doingFiles = false;
|
||||
for(unsigned int i=1; i < args.size(); ++i)
|
||||
{
|
||||
sg->AddSource(args[cc].c_str(), 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( args.size() == 2 )
|
||||
if(args[i] == "REGULAR_EXPRESSION")
|
||||
{
|
||||
m_Makefile->AddSourceGroup(args[0].c_str(), args[1].c_str());
|
||||
return true;
|
||||
// Next argument must specify the regex.
|
||||
if(i+1 < args.size())
|
||||
{
|
||||
++i;
|
||||
sg->SetGroupRegex(args[i].c_str());
|
||||
}
|
||||
|
||||
this->SetError("called with incorrect number of arguments");
|
||||
else
|
||||
{
|
||||
this->SetError("REGULAR_EXPRESSION argument given without a regex.");
|
||||
return false;
|
||||
}
|
||||
doingFiles = false;
|
||||
}
|
||||
else if(args[i] == "FILES")
|
||||
{
|
||||
// Next arguments will specify files.
|
||||
doingFiles = true;
|
||||
}
|
||||
else if(doingFiles)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue