ENH: Removed out-of-date commands CABLE_WRAP_TCL CABLE_CLASS_SET and CONFIGURE_GCCXML
This commit is contained in:
parent
c83a8ac286
commit
5a418b0e00
@ -12,7 +12,6 @@ cmCommands.cxx
|
|||||||
cmTarget.cxx
|
cmTarget.cxx
|
||||||
cmCustomCommand.cxx
|
cmCustomCommand.cxx
|
||||||
cmCacheManager.cxx
|
cmCacheManager.cxx
|
||||||
cmCableClassSet.cxx
|
|
||||||
cmSourceGroup.cxx
|
cmSourceGroup.cxx
|
||||||
cmListFileCache.cxx
|
cmListFileCache.cxx
|
||||||
cmake.h
|
cmake.h
|
||||||
@ -28,7 +27,6 @@ cmCommands.h
|
|||||||
cmTarget.h
|
cmTarget.h
|
||||||
cmCustomCommand.h
|
cmCustomCommand.h
|
||||||
cmCacheManager.h
|
cmCacheManager.h
|
||||||
cmCableClassSet.h
|
|
||||||
cmSourceGroup.h
|
cmSourceGroup.h
|
||||||
cmListFileCache.h
|
cmListFileCache.h
|
||||||
)
|
)
|
||||||
|
@ -29,7 +29,6 @@ cmCommands.o \
|
|||||||
cmTarget.o \
|
cmTarget.o \
|
||||||
cmCustomCommand.o \
|
cmCustomCommand.o \
|
||||||
cmCacheManager.o \
|
cmCacheManager.o \
|
||||||
cmCableClassSet.o \
|
|
||||||
cmListFileCache.o \
|
cmListFileCache.o \
|
||||||
cmSourceGroup.o
|
cmSourceGroup.o
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ cmUnixMakefileGenerator.o : $(DEPENDS)
|
|||||||
cmCommands.o : $(DEPENDS) $(srcdir)/*Command*.cxx
|
cmCommands.o : $(DEPENDS) $(srcdir)/*Command*.cxx
|
||||||
cmTarget.o : $(DEPENDS)
|
cmTarget.o : $(DEPENDS)
|
||||||
cmCacheManager.o : $(DEPENDS)
|
cmCacheManager.o : $(DEPENDS)
|
||||||
cmCableClassSet.o: $(DEPENDS)
|
|
||||||
cmSourceGroup.o : $(DEPENDS)
|
cmSourceGroup.o : $(DEPENDS)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,752 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#include "cmCableClassSet.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add to the set of required sources to define the class.
|
|
||||||
*/
|
|
||||||
void cmCableClass::AddSources(const Sources& sources)
|
|
||||||
{
|
|
||||||
for(Sources::const_iterator s = sources.begin(); s != sources.end(); ++s)
|
|
||||||
{
|
|
||||||
m_Sources.insert(*s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add to the set of required sources to define the class.
|
|
||||||
*/
|
|
||||||
void cmCableClass::AddSource(const char* source)
|
|
||||||
{
|
|
||||||
m_Sources.insert(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The destructor frees all the cmCableClass instances in the set.
|
|
||||||
*/
|
|
||||||
cmCableClassSet::~cmCableClassSet()
|
|
||||||
{
|
|
||||||
for(CableClassMap::const_iterator i = m_CableClassMap.begin();
|
|
||||||
i != m_CableClassMap.end(); ++i)
|
|
||||||
{
|
|
||||||
delete i->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a class to the set.
|
|
||||||
* Automatically replace ">>" with "> >" to prevent template class name
|
|
||||||
* problems after replacements.
|
|
||||||
*/
|
|
||||||
void cmCableClassSet::AddClass(const char* in_name,
|
|
||||||
cmCableClass* cableClass)
|
|
||||||
{
|
|
||||||
cmStdString name = in_name;
|
|
||||||
for(cmStdString::size_type pos = name.find(">>");
|
|
||||||
pos != cmStdString::npos; pos = name.find(">>", pos+2))
|
|
||||||
{
|
|
||||||
name.replace(pos, 2, "> >");
|
|
||||||
}
|
|
||||||
m_CableClassMap.insert(CableClassMap::value_type(name, cableClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a source to every class in the set. This should only be done after
|
|
||||||
* all classes have been inserted.
|
|
||||||
*/
|
|
||||||
void cmCableClassSet::AddSource(const char* name)
|
|
||||||
{
|
|
||||||
for(CableClassMap::iterator c = m_CableClassMap.begin();
|
|
||||||
c != m_CableClassMap.end(); ++c)
|
|
||||||
{
|
|
||||||
c->second->AddSource(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the internal CableClassMap used to store the set.
|
|
||||||
*/
|
|
||||||
size_t cmCableClassSet::Size() const
|
|
||||||
{
|
|
||||||
return m_CableClassMap.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a begin iterator to the internal CableClassMap used to store the
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
cmCableClassSet::CableClassMap::const_iterator cmCableClassSet::Begin() const
|
|
||||||
{
|
|
||||||
return m_CableClassMap.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an end iterator to the internal CableClassMap used to store the
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
cmCableClassSet::CableClassMap::const_iterator cmCableClassSet::End() const
|
|
||||||
{
|
|
||||||
return m_CableClassMap.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A utility class to generate element combinations from all possible
|
|
||||||
* substitutions of set members into a $ token.
|
|
||||||
*/
|
|
||||||
class ElementCombinationGenerator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ElementCombinationGenerator(const char* in_element, cmMakefile* in_makefile,
|
|
||||||
cmCableClassSet* out_set):
|
|
||||||
m_Makefile(in_makefile), m_OutputSet(out_set)
|
|
||||||
{
|
|
||||||
this->ParseInputElement(in_element);
|
|
||||||
}
|
|
||||||
~ElementCombinationGenerator();
|
|
||||||
|
|
||||||
void Generate();
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Represent a substitution.
|
|
||||||
*/
|
|
||||||
class Substitution
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Substitution() {}
|
|
||||||
void Bind(const cmStdString& in_code, const cmCableClass* in_class)
|
|
||||||
{
|
|
||||||
m_Code = in_code;
|
|
||||||
m_Class = in_class;
|
|
||||||
}
|
|
||||||
const cmCableClass* GetClass() const
|
|
||||||
{ return m_Class; }
|
|
||||||
const cmStdString& GetCode() const
|
|
||||||
{ return m_Code; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The cmCableClass associated with this substitution.
|
|
||||||
*/
|
|
||||||
const cmCableClass* m_Class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The code to be used for the substitution.
|
|
||||||
*/
|
|
||||||
cmStdString m_Code;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to the parts of an input string of code, possibly with
|
|
||||||
* $SomeSetName tokens in it. An indivitual Portion will be either
|
|
||||||
* a StringPortion, which has no substitutions, or a ReplacePortion,
|
|
||||||
* which has only a substitution, and no hard-coded text.
|
|
||||||
*
|
|
||||||
* This is used by cmCableClassSet::GenerateElementCombinations() to
|
|
||||||
* hold the pieces of a string after the set substitution tokens
|
|
||||||
* have been extracted.
|
|
||||||
*/
|
|
||||||
class Portion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Get the C++ code corresponding to this Portion of a string.
|
|
||||||
*/
|
|
||||||
virtual cmStdString GetCode() const =0;
|
|
||||||
/**
|
|
||||||
* Get the class corresponding to this Portion of a string. This is NULL
|
|
||||||
* for StringPortion, and points to a cmCableClass for ReplacePortion.
|
|
||||||
*/
|
|
||||||
virtual const cmCableClass* GetClass() const
|
|
||||||
{ return NULL; }
|
|
||||||
virtual ~Portion() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represent a hard-coded part of an input string, that has no substitutions
|
|
||||||
* in it. The tag for this part of a string is always empty.
|
|
||||||
*/
|
|
||||||
class StringPortion: public Portion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
StringPortion(const cmStdString& in_code): m_Code(in_code) {}
|
|
||||||
virtual cmStdString GetCode() const
|
|
||||||
{ return m_Code; }
|
|
||||||
virtual const cmCableClass* GetClass() const
|
|
||||||
{ return NULL; }
|
|
||||||
virtual ~StringPortion() {}
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* Hold this Portion's contribution to the output string.
|
|
||||||
*/
|
|
||||||
cmStdString m_Code;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represent the "$SomeSetName" portion of an input string. This has a
|
|
||||||
* reference to the Substitution holding the real output to generate.
|
|
||||||
*/
|
|
||||||
class ReplacePortion;
|
|
||||||
friend class ReplacePortion;
|
|
||||||
class ReplacePortion: public Portion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ReplacePortion(const Substitution& in_substitution):
|
|
||||||
m_Substitution(in_substitution) {}
|
|
||||||
virtual cmStdString GetCode() const
|
|
||||||
{ return m_Substitution.GetCode(); }
|
|
||||||
virtual const cmCableClass* GetClass() const
|
|
||||||
{ return m_Substitution.GetClass(); }
|
|
||||||
virtual ~ReplacePortion() {}
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* Refer to the real Substitution for this Portion's contribution.
|
|
||||||
*/
|
|
||||||
const Substitution& m_Substitution;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::list<Portion*> Portions;
|
|
||||||
typedef std::map<const cmCableClassSet*, Substitution*> Substitutions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The makefile in which to lookup set names.
|
|
||||||
*/
|
|
||||||
cmMakefile* m_Makefile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The cmCableClassSet instance to be filled with combinations.
|
|
||||||
*/
|
|
||||||
cmCableClassSet* m_OutputSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class name parsed out for this element, before set expansion.
|
|
||||||
*/
|
|
||||||
cmStdString m_ClassName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The tag name parsed out or generated for this element.
|
|
||||||
*/
|
|
||||||
cmStdString m_Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The set of sources parsed out for this element.
|
|
||||||
*/
|
|
||||||
cmCableClass::Sources m_Sources;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parts of the input string after parsing of the tokens.
|
|
||||||
*/
|
|
||||||
Portions m_Portions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map from substitution's Set to actual Substitution.
|
|
||||||
*/
|
|
||||||
Substitutions m_Substitutions;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Generate(Substitutions::const_iterator);
|
|
||||||
void ParseInputElement(const char*);
|
|
||||||
void SplitClassName();
|
|
||||||
cmStdString ParseSetName(cmStdString::const_iterator&,
|
|
||||||
cmStdString::const_iterator) const;
|
|
||||||
void FindTagSource();
|
|
||||||
bool GenerateTag(const cmStdString&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor frees portions and substitutions that were allocated by
|
|
||||||
* constructor.
|
|
||||||
*/
|
|
||||||
ElementCombinationGenerator
|
|
||||||
::~ElementCombinationGenerator()
|
|
||||||
{
|
|
||||||
// Free the string portions that were allocated.
|
|
||||||
for(Portions::iterator portion = m_Portions.begin();
|
|
||||||
portion != m_Portions.end(); ++portion)
|
|
||||||
{
|
|
||||||
delete *portion;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the substitutions that were allocated.
|
|
||||||
for(Substitutions::iterator sub = m_Substitutions.begin();
|
|
||||||
sub != m_Substitutions.end(); ++sub)
|
|
||||||
{
|
|
||||||
delete sub->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate all element combinations possible with the set of
|
|
||||||
* substitutions available. The given output set is filled with
|
|
||||||
* all the combinations.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ElementCombinationGenerator
|
|
||||||
::Generate()
|
|
||||||
{
|
|
||||||
// If there are no substitutions to be made, just generate this
|
|
||||||
// single combination.
|
|
||||||
if(m_Substitutions.empty())
|
|
||||||
{
|
|
||||||
cmCableClass* cableClass = new cmCableClass(m_Tag);
|
|
||||||
cableClass->AddSources(m_Sources);
|
|
||||||
m_OutputSet->AddClass(m_ClassName.c_str(), cableClass);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We must generate all combinations of substitutions.
|
|
||||||
// Begin the recursion with the first substitution.
|
|
||||||
this->Generate(m_Substitutions.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal helper to Generate() which generates all
|
|
||||||
* combinations in a recursive, depth-first order.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ElementCombinationGenerator
|
|
||||||
::Generate(Substitutions::const_iterator substitution)
|
|
||||||
{
|
|
||||||
// Test our position in the list of substitutions to be bound.
|
|
||||||
if(substitution == m_Substitutions.end())
|
|
||||||
{
|
|
||||||
// All substitutions have been prepared. Generate this combination.
|
|
||||||
cmStdString tag = m_Tag;
|
|
||||||
cmStdString code = "";
|
|
||||||
|
|
||||||
// The set of sources for the generated combination. It will
|
|
||||||
// always include the sources parsed from the original element
|
|
||||||
// string.
|
|
||||||
cmCableClass::Sources sources = m_Sources;
|
|
||||||
|
|
||||||
// Put together all the pieces, with substitutions.
|
|
||||||
for(Portions::const_iterator i = m_Portions.begin();
|
|
||||||
i != Portions::const_iterator(m_Portions.end()); ++i)
|
|
||||||
{
|
|
||||||
// See if there is a class associated with this portion.
|
|
||||||
const cmCableClass* curClassPortion = (*i)->GetClass();
|
|
||||||
if(curClassPortion)
|
|
||||||
{
|
|
||||||
// Append the tag from the class portion.
|
|
||||||
tag.append(curClassPortion->GetTag());
|
|
||||||
|
|
||||||
// Include any sources needed by the class in this combination's set.
|
|
||||||
for(cmCableClass::Sources::const_iterator
|
|
||||||
s = curClassPortion->SourcesBegin();
|
|
||||||
s != curClassPortion->SourcesEnd(); ++s)
|
|
||||||
{
|
|
||||||
sources.insert(*s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the portion's code to this combination's code.
|
|
||||||
code.append((*i)->GetCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this combination to the output set.
|
|
||||||
cmCableClass* cableClass = new cmCableClass(tag);
|
|
||||||
cableClass->AddSources(sources);
|
|
||||||
m_OutputSet->AddClass(code.c_str(), cableClass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get the set for this substitution.
|
|
||||||
const cmCableClassSet* set = substitution->first;
|
|
||||||
if(set == m_OutputSet)
|
|
||||||
{
|
|
||||||
// We cannot iterate over the set currently being defined.
|
|
||||||
cmSystemTools::Error("CABLE class set self-reference!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare an iterator to the next substitution.
|
|
||||||
Substitutions::const_iterator nextSubstitution = substitution;
|
|
||||||
++nextSubstitution;
|
|
||||||
|
|
||||||
// We must iterate over all possible values for this substitution.
|
|
||||||
for(cmCableClassSet::CableClassMap::const_iterator element = set->Begin();
|
|
||||||
element != set->End(); ++element)
|
|
||||||
{
|
|
||||||
// Bind the substitution to this element.
|
|
||||||
substitution->second->Bind(element->first, element->second);
|
|
||||||
|
|
||||||
// Move on to the next substitution.
|
|
||||||
this->Generate(nextSubstitution);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called from constructor. Parses the given string to extract the
|
|
||||||
* class information specified.
|
|
||||||
*
|
|
||||||
* The format of the string is
|
|
||||||
* [tag:]class_name[;source1;source2;...]
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ElementCombinationGenerator
|
|
||||||
::ParseInputElement(const char* in_element)
|
|
||||||
{
|
|
||||||
// A regular expression to match the tagged element specification.
|
|
||||||
cmRegularExpression taggedElement =
|
|
||||||
"^([A-Za-z_0-9]*)[ \t]*:[ \t]*([^:].*|::.*)$";
|
|
||||||
|
|
||||||
// A regular expression to match the element when more source files are given.
|
|
||||||
cmRegularExpression sourcesRemain("^([^;]*);(.*)$");
|
|
||||||
|
|
||||||
cmStdString elementWithoutTag;
|
|
||||||
cmStdString sourceString;
|
|
||||||
bool tagGiven = false;
|
|
||||||
|
|
||||||
// See if the element was tagged, and if so, pull off the tag.
|
|
||||||
if(taggedElement.find(in_element))
|
|
||||||
{
|
|
||||||
// A tag was given. Use it.
|
|
||||||
tagGiven = true;
|
|
||||||
m_Tag = taggedElement.match(1);
|
|
||||||
elementWithoutTag = taggedElement.match(2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No tag was given. We will try to generate it later.
|
|
||||||
elementWithoutTag = in_element;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Separate the class name.
|
|
||||||
if(sourcesRemain.find(elementWithoutTag.c_str()))
|
|
||||||
{
|
|
||||||
m_ClassName = sourcesRemain.match(1);
|
|
||||||
sourceString = sourcesRemain.match(2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_ClassName = elementWithoutTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find any source files specified with the ";source" syntax.
|
|
||||||
while(sourcesRemain.find(sourceString.c_str()))
|
|
||||||
{
|
|
||||||
m_Sources.insert(sourcesRemain.match(1));
|
|
||||||
sourceString = sourcesRemain.match(2);
|
|
||||||
}
|
|
||||||
if(sourceString != "")
|
|
||||||
{
|
|
||||||
m_Sources.insert(sourceString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no tag was given, try to generate one.
|
|
||||||
if(!tagGiven)
|
|
||||||
{
|
|
||||||
if(!this->GenerateTag(m_ClassName))
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("Cannot generate tag for class name: ",
|
|
||||||
m_ClassName.c_str(),
|
|
||||||
"\nPlease supply one with the \"tag:..\" syntax.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is a .h with the name of the tag, add it as a source.
|
|
||||||
this->FindTagSource();
|
|
||||||
|
|
||||||
// Split the class name up into portions for the combination
|
|
||||||
// generation method.
|
|
||||||
this->SplitClassName();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the class name into portions. Plain text in the string is
|
|
||||||
* held by a StringPortion, and a $ token for replacement is
|
|
||||||
* represented by a ReplacePortion.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ElementCombinationGenerator
|
|
||||||
::SplitClassName()
|
|
||||||
{
|
|
||||||
// Break the input code into blocks alternating between literal code and
|
|
||||||
// set-substitution tokens (like $SomeSetName).
|
|
||||||
cmStdString currentPortion = "";
|
|
||||||
for(cmStdString::const_iterator c=m_ClassName.begin();
|
|
||||||
c != m_ClassName.end(); ++c)
|
|
||||||
{
|
|
||||||
// Look for the '$' to mark the beginning of a token.
|
|
||||||
if(*c != '$')
|
|
||||||
{
|
|
||||||
currentPortion.insert(currentPortion.end(), *c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If there is a portion of the string, record it.
|
|
||||||
if(currentPortion.length() > 0)
|
|
||||||
{
|
|
||||||
m_Portions.push_back(new StringPortion(currentPortion));
|
|
||||||
currentPortion = "";
|
|
||||||
}
|
|
||||||
// Skip over the '$' character.
|
|
||||||
++c;
|
|
||||||
// Get element set name token.
|
|
||||||
cmStdString setName = this->ParseSetName(c, m_ClassName.end());
|
|
||||||
|
|
||||||
// We have a complete set name. Look it up in makefile's data
|
|
||||||
// collection.
|
|
||||||
cmData* d = m_Makefile->LookupData(setName.c_str());
|
|
||||||
// This should be a dynamic_cast, but we don't want to require RTTI.
|
|
||||||
cmCableClassSet* set = static_cast<cmCableClassSet*>(d);
|
|
||||||
if(set)
|
|
||||||
{
|
|
||||||
// We have a valid set name. Prepare the substitution entry
|
|
||||||
// for it.
|
|
||||||
Substitution* sub;
|
|
||||||
if(m_Substitutions.count(set) == 0)
|
|
||||||
{
|
|
||||||
sub = new Substitution();
|
|
||||||
m_Substitutions[set] = sub;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sub = m_Substitutions[set];
|
|
||||||
}
|
|
||||||
m_Portions.push_back(new ReplacePortion(*sub));
|
|
||||||
setName = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Invalid set name. Complain.
|
|
||||||
cmSystemTools::Error("Unknown name of CABLE class set: ",
|
|
||||||
setName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let the loop look at this character again.
|
|
||||||
--c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is a final portion of the string, record it.
|
|
||||||
if(currentPortion.length() > 0)
|
|
||||||
{
|
|
||||||
m_Portions.push_back(new StringPortion(currentPortion));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse out the name of a Set specified after a $ in the element's string.
|
|
||||||
* This is called with "c" pointing to the first character after the $,
|
|
||||||
* and "end" equal to the string's end iterator.
|
|
||||||
*
|
|
||||||
* Returns the set name after parsing. "c" will point to the first
|
|
||||||
* character after the end of the set name.
|
|
||||||
*/
|
|
||||||
cmStdString
|
|
||||||
ElementCombinationGenerator
|
|
||||||
::ParseSetName(cmStdString::const_iterator& c, cmStdString::const_iterator end) const
|
|
||||||
{
|
|
||||||
cmStdString setName = "";
|
|
||||||
|
|
||||||
// Check for the $(setName) syntax.
|
|
||||||
// If the first character after the '$' is a left paren, we scan for the
|
|
||||||
// matching paren, and take everything in-between as the set name.
|
|
||||||
if((c != end) && (*c == '('))
|
|
||||||
{
|
|
||||||
unsigned int depth = 1;
|
|
||||||
++c;
|
|
||||||
while(c != end)
|
|
||||||
{
|
|
||||||
char ch = *c++;
|
|
||||||
if(ch == '(') { ++depth; }
|
|
||||||
else if(ch == ')') { --depth; }
|
|
||||||
if(depth == 0) { break; }
|
|
||||||
setName.insert(setName.end(), ch);
|
|
||||||
}
|
|
||||||
return setName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The $(setName) syntax was not used.
|
|
||||||
// Look for all characters that can be part of a qualified C++
|
|
||||||
// identifier.
|
|
||||||
while(c != end)
|
|
||||||
{
|
|
||||||
char ch = *c;
|
|
||||||
if(((ch >= 'a') && (ch <= 'z'))
|
|
||||||
|| ((ch >= 'A') && (ch <= 'Z'))
|
|
||||||
|| ((ch >= '0') && (ch <= '9'))
|
|
||||||
|| (ch == '_') || (ch == ':'))
|
|
||||||
{
|
|
||||||
setName.insert(setName.end(), ch);
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return setName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* After the tag for an element has been determined, but before
|
|
||||||
* combination expansion is done, this is called to search for a
|
|
||||||
* header file in the makefile's include path with the name of the
|
|
||||||
* tag. This makes specifying lists of classes that are declared in
|
|
||||||
* header files with their own name very convenient.
|
|
||||||
*/
|
|
||||||
void ElementCombinationGenerator::FindTagSource()
|
|
||||||
{
|
|
||||||
// If there is no tag, don't bother with this step.
|
|
||||||
if(m_Tag == "")
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the makefile's include path.
|
|
||||||
const std::vector<std::string>& includePath =
|
|
||||||
m_Makefile->GetIncludeDirectories();
|
|
||||||
|
|
||||||
// Search the path for a file called "(m_Tag).h".
|
|
||||||
for(std::vector<std::string>::const_iterator dir = includePath.begin();
|
|
||||||
dir != includePath.end(); ++dir)
|
|
||||||
{
|
|
||||||
cmStdString filePath = *dir;
|
|
||||||
m_Makefile->ExpandVariablesInString(filePath);
|
|
||||||
filePath += "/"+m_Tag+".h";
|
|
||||||
if(cmSystemTools::FileExists(filePath.c_str()))
|
|
||||||
{
|
|
||||||
m_Sources.insert(m_Tag+".h");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the string representing a set element, automatically generate
|
|
||||||
* the element tag for it. This function determines how the output
|
|
||||||
* language of all CABLE-generated wrappers will look.
|
|
||||||
*/
|
|
||||||
bool ElementCombinationGenerator::GenerateTag(const cmStdString& element)
|
|
||||||
{
|
|
||||||
// Hold the regular expressions for matching against the element.
|
|
||||||
cmRegularExpression regex;
|
|
||||||
|
|
||||||
// If the element's code begins in a $, it is referring to a set name.
|
|
||||||
// The set's elements have their own tags, so we don't need one.
|
|
||||||
regex.compile("^[ \t]*\\$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{ m_Tag = ""; return true; }
|
|
||||||
|
|
||||||
// Test for simple integer
|
|
||||||
regex.compile("^[ \t]*([0-9]*)[ \t]*$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{
|
|
||||||
m_Tag = "_";
|
|
||||||
m_Tag.append(regex.match(1));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for basic integer type
|
|
||||||
regex.compile("^[ \t]*(unsigned[ ]|signed[ ])?[ \t]*(char|short|int|long|long[ ]long)[ \t]*$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{
|
|
||||||
m_Tag = "_";
|
|
||||||
if(regex.match(1) == "unsigned ")
|
|
||||||
{ m_Tag.append("u"); }
|
|
||||||
if(regex.match(2) == "long long")
|
|
||||||
{ m_Tag.append("llong"); }
|
|
||||||
else
|
|
||||||
{ m_Tag.append(regex.match(2)); }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for basic floating-point type
|
|
||||||
regex.compile("^[ \t]*(long[ ])?[ \t]*(float|double)[ \t]*$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{
|
|
||||||
m_Tag = "_";
|
|
||||||
if(static_cast<int>(regex.start(1)) > 0 && regex.match(1) == "long ")
|
|
||||||
{
|
|
||||||
m_Tag.append("l");
|
|
||||||
}
|
|
||||||
m_Tag.append(regex.match(2));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for basic wide-character type
|
|
||||||
regex.compile("^[ \t]*(wchar_t)[ \t]*$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{
|
|
||||||
m_Tag = "_wchar";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for type name (possibly with template arguments).
|
|
||||||
regex.compile("^[ \t]*([A-Za-z_][A-Za-z0-9_]*)(<.*)?[ \t]*$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{
|
|
||||||
// The tag is the same as the type. If there were template arguments,
|
|
||||||
// they are ignored since they may have their own tags.
|
|
||||||
m_Tag = regex.match(1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for a name with a single namespace qualifier.
|
|
||||||
regex.compile("^[ \t]*([A-Za-z_][A-Za-z0-9_]*)::([A-Za-z_][A-Za-z0-9_]*)(<.*)?[ \t]*$");
|
|
||||||
if(regex.find(element))
|
|
||||||
{
|
|
||||||
// The tag is the same as the namespace and type concatenated together.
|
|
||||||
m_Tag = regex.match(1);
|
|
||||||
m_Tag.append(regex.match(2));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't generate a tag.
|
|
||||||
m_Tag = "";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an element in string form, parse out the information from it,
|
|
||||||
* generate the combinations of set substitutions, and add all the
|
|
||||||
* elements that result.
|
|
||||||
*/
|
|
||||||
void cmCableClassSet::ParseAndAddElement(const char* in_element,
|
|
||||||
cmMakefile* makefile)
|
|
||||||
{
|
|
||||||
// Create an object to handle the generation.
|
|
||||||
ElementCombinationGenerator combinationGenerator(in_element, makefile, this);
|
|
||||||
|
|
||||||
// Generate the combinations.
|
|
||||||
combinationGenerator.Generate();
|
|
||||||
}
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#ifndef cmCableClassSet_h
|
|
||||||
#define cmCableClassSet_h
|
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
|
||||||
#include "cmData.h"
|
|
||||||
#include "cmMakefile.h"
|
|
||||||
|
|
||||||
|
|
||||||
/** \class cmCableClass
|
|
||||||
* \brief Holds one class and the set of header files needed to use it.
|
|
||||||
*/
|
|
||||||
class cmCableClass
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::set<cmStdString> Sources;
|
|
||||||
cmCableClass() {}
|
|
||||||
cmCableClass(const cmStdString& tag): m_Tag(tag) {}
|
|
||||||
|
|
||||||
void AddSources(const Sources& sources);
|
|
||||||
void AddSource(const char*);
|
|
||||||
|
|
||||||
Sources::const_iterator SourcesBegin() const { return m_Sources.begin(); }
|
|
||||||
Sources::const_iterator SourcesEnd() const { return m_Sources.end(); }
|
|
||||||
|
|
||||||
const cmStdString& GetTag() const { return m_Tag; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The tag name of this class.
|
|
||||||
*/
|
|
||||||
cmStdString m_Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the set of source files (headers) needed to define this class.
|
|
||||||
*/
|
|
||||||
Sources m_Sources;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \class cmCableClassSet
|
|
||||||
* \brief Holds a set of classes, each with their own set of required headers.
|
|
||||||
*/
|
|
||||||
class cmCableClassSet: public cmData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmCableClassSet(const char* name): cmData(name) {}
|
|
||||||
virtual ~cmCableClassSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The set is stored internally as a map from class name to cmCableClass
|
|
||||||
* instance.
|
|
||||||
*/
|
|
||||||
typedef std::map<cmStdString, cmCableClass*> CableClassMap;
|
|
||||||
|
|
||||||
void AddClass(const char*, cmCableClass*);
|
|
||||||
void AddSource(const char* name);
|
|
||||||
size_t Size() const;
|
|
||||||
CableClassMap::const_iterator Begin() const;
|
|
||||||
CableClassMap::const_iterator End() const;
|
|
||||||
|
|
||||||
void ParseAndAddElement(const char*, cmMakefile*);
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The set is stored internally as a map from class name to cmCableClass
|
|
||||||
* instance.
|
|
||||||
*/
|
|
||||||
CableClassMap m_CableClassMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#include "cmCableClassSetCommand.h"
|
|
||||||
#include "cmCacheManager.h"
|
|
||||||
#include "cmTarget.h"
|
|
||||||
|
|
||||||
// cmCableClassSetCommand
|
|
||||||
bool cmCableClassSetCommand::InitialPass(std::vector<std::string> const& argsIn)
|
|
||||||
{
|
|
||||||
if(argsIn.size() < 2)
|
|
||||||
{
|
|
||||||
this->SetError("called with incorrect number of arguments");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::vector<std::string> args;
|
|
||||||
cmSystemTools::ExpandListArguments(argsIn, args);
|
|
||||||
|
|
||||||
// The first argument is the name of the set.
|
|
||||||
std::vector<std::string>::const_iterator arg = args.begin();
|
|
||||||
m_ClassSetName = *arg++;
|
|
||||||
|
|
||||||
// Create the new class set.
|
|
||||||
cmCableClassSet* classSet = new cmCableClassSet(m_ClassSetName.c_str());
|
|
||||||
|
|
||||||
// Add all the regular entries.
|
|
||||||
for(; (arg != args.end()) && (*arg != "SOURCES_BEGIN"); ++arg)
|
|
||||||
{
|
|
||||||
classSet->ParseAndAddElement(arg->c_str(), m_Makefile);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add any sources that are associated with all the members.
|
|
||||||
if(arg != args.end())
|
|
||||||
{
|
|
||||||
for(++arg; arg != args.end(); ++arg)
|
|
||||||
{
|
|
||||||
classSet->AddSource(arg->c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the class set in the makefile.
|
|
||||||
m_Makefile->RegisterData(classSet);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#ifndef cmCableClassSetCommand_h
|
|
||||||
#define cmCableClassSetCommand_h
|
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
|
||||||
#include "cmCommand.h"
|
|
||||||
#include "cmCableClassSet.h"
|
|
||||||
|
|
||||||
/** \class cmCableClassSetCommand
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class cmCableClassSetCommand : public cmCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmCableClassSetCommand() {}
|
|
||||||
virtual ~cmCableClassSetCommand() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a virtual constructor for the command.
|
|
||||||
*/
|
|
||||||
virtual cmCommand* Clone()
|
|
||||||
{
|
|
||||||
return new cmCableClassSetCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when the command is first encountered in
|
|
||||||
* the CMakeLists.txt file.
|
|
||||||
*/
|
|
||||||
virtual bool InitialPass(std::vector<std::string> const& args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the command as specified in CMakeList.txt.
|
|
||||||
*/
|
|
||||||
virtual const char* GetName() { return "CABLE_CLASS_SET";}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Succinct documentation.
|
|
||||||
*/
|
|
||||||
virtual const char* GetTerseDocumentation()
|
|
||||||
{
|
|
||||||
return "Define a set of classes for use in other CABLE commands.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More documentation.
|
|
||||||
*/
|
|
||||||
virtual const char* GetFullDocumentation()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
"CABLE_CLASS_SET(set_name class1 class2 ...)\n"
|
|
||||||
"Defines a set with the given name containing classes and their\n"
|
|
||||||
"associated header files. The set can later be used by other CABLE\n"
|
|
||||||
"commands.";
|
|
||||||
}
|
|
||||||
|
|
||||||
cmTypeMacro(cmCableClassSetCommand, cmCommand);
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The name of the class set.
|
|
||||||
*/
|
|
||||||
std::string m_ClassSetName;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,562 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#include "cmCableWrapTclCommand.h"
|
|
||||||
#include "cmCacheManager.h"
|
|
||||||
#include "cmTarget.h"
|
|
||||||
#include "cmGeneratedFileStream.h"
|
|
||||||
#include "cmMakeDepend.h"
|
|
||||||
|
|
||||||
#include "cmData.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* One instance of this is associated with the makefile to hold a
|
|
||||||
* vector of the GCC-XML flags pre-parsed from the string in the
|
|
||||||
* cache. The first cmCableWrapTclCommand to need it creates the
|
|
||||||
* instance. The others find it and use it.
|
|
||||||
*/
|
|
||||||
class cmCableWrapTclCommand::cmGccXmlFlagsParser: public cmData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmGccXmlFlagsParser(const char* name): cmData(name) {}
|
|
||||||
|
|
||||||
void Parse(const char*);
|
|
||||||
void AddParsedFlags(std::vector<std::string>& resultArgs);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void AddFlag(const std::string&);
|
|
||||||
|
|
||||||
std::vector<std::string> m_Flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
void cmCableWrapTclCommand::cmGccXmlFlagsParser::Parse(const char* in_flags)
|
|
||||||
{
|
|
||||||
// Prepare a work string for searching.
|
|
||||||
std::string flags = in_flags;
|
|
||||||
|
|
||||||
// Look for " -" separating arguments.
|
|
||||||
|
|
||||||
// The first argument starts at the first "-" character.
|
|
||||||
std::string::size_type leftPos = flags.find_first_of("-");
|
|
||||||
if(leftPos == std::string::npos) { return; }
|
|
||||||
std::string::size_type rightPos = flags.find(" -", leftPos);
|
|
||||||
while(rightPos != std::string::npos)
|
|
||||||
{
|
|
||||||
// Pull out and store this argument.
|
|
||||||
this->AddFlag(flags.substr(leftPos, rightPos-leftPos));
|
|
||||||
|
|
||||||
// The next argument starts at the '-' from the previously found " -".
|
|
||||||
leftPos = rightPos+1;
|
|
||||||
rightPos = flags.find(" -", leftPos);
|
|
||||||
}
|
|
||||||
// Pull out and store the last argument.
|
|
||||||
this->AddFlag(flags.substr(leftPos, std::string::npos));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cmCableWrapTclCommand::cmGccXmlFlagsParser
|
|
||||||
::AddParsedFlags(std::vector<std::string>& resultArgs)
|
|
||||||
{
|
|
||||||
for(std::vector<std::string>::const_iterator flag = m_Flags.begin();
|
|
||||||
flag != m_Flags.end(); ++flag)
|
|
||||||
{
|
|
||||||
resultArgs.push_back(*flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by Parse() to insert a parsed flag. Strips trailing whitespace from
|
|
||||||
* the argument.
|
|
||||||
*
|
|
||||||
* Includes a hack to split "-o /dev/null" into two arguments since
|
|
||||||
* the parser only splits arguments with " -" occurrences.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
cmCableWrapTclCommand::cmGccXmlFlagsParser
|
|
||||||
::AddFlag(const std::string& flag)
|
|
||||||
{
|
|
||||||
std::string tmp = flag.substr(0, flag.find_last_not_of(" \t")+1);
|
|
||||||
if(tmp == "-o /dev/null")
|
|
||||||
{
|
|
||||||
m_Flags.push_back("-o");
|
|
||||||
m_Flags.push_back("/dev/null");
|
|
||||||
}
|
|
||||||
else if(tmp == "-D__int64='long long'")
|
|
||||||
{
|
|
||||||
m_Flags.push_back("-D__int64='long");
|
|
||||||
m_Flags.push_back("long'");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Flags.push_back(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmCableWrapTclCommand::cmCableWrapTclCommand():
|
|
||||||
m_CableClassSet(NULL), m_MakeDepend(new cmMakeDepend)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cmCableWrapTclCommand::~cmCableWrapTclCommand()
|
|
||||||
{
|
|
||||||
if(m_CableClassSet)
|
|
||||||
{
|
|
||||||
delete m_CableClassSet;
|
|
||||||
}
|
|
||||||
delete m_MakeDepend;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// cmCableWrapTclCommand
|
|
||||||
bool cmCableWrapTclCommand::InitialPass(std::vector<std::string> const& argsIn)
|
|
||||||
{
|
|
||||||
if(argsIn.size() < 2)
|
|
||||||
{
|
|
||||||
this->SetError("called with incorrect number of arguments");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::vector<std::string> args;
|
|
||||||
cmSystemTools::ExpandListArguments(argsIn, args);
|
|
||||||
|
|
||||||
// Prepare to iterate through the arguments.
|
|
||||||
std::vector<std::string>::const_iterator arg = args.begin();
|
|
||||||
|
|
||||||
// The first argument is the name of the target.
|
|
||||||
m_TargetName = *arg++;
|
|
||||||
|
|
||||||
// Create the new class set.
|
|
||||||
m_CableClassSet = new cmCableClassSet(m_TargetName.c_str());
|
|
||||||
|
|
||||||
// Add all the regular entries.
|
|
||||||
for(; (arg != args.end()) && (*arg != "SOURCES_BEGIN"); ++arg)
|
|
||||||
{
|
|
||||||
m_CableClassSet->ParseAndAddElement(arg->c_str(), m_Makefile);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add any sources that are associated with all the members.
|
|
||||||
if(arg != args.end())
|
|
||||||
{
|
|
||||||
for(++arg; arg != args.end(); ++arg)
|
|
||||||
{
|
|
||||||
m_CableClassSet->AddSource(arg->c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->GenerateCableFiles();
|
|
||||||
|
|
||||||
// Add the source list to the target.
|
|
||||||
m_Makefile->GetTargets()[m_TargetName.c_str()].GetSourceLists().push_back(m_TargetName);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the files that CABLE will use to generate the wrappers.
|
|
||||||
*/
|
|
||||||
void cmCableWrapTclCommand::GenerateCableFiles() const
|
|
||||||
{
|
|
||||||
// Make sure the dependency generator is ready to go.
|
|
||||||
m_MakeDepend->SetMakefile(m_Makefile);
|
|
||||||
|
|
||||||
// Each wrapped class may have an associated "tag" that represents
|
|
||||||
// an alternative name without funky C++ syntax in it. This makes
|
|
||||||
// it easier to refer to the class in a Tcl script. We will also
|
|
||||||
// use the tags to make easy-to-read, unique file names for each
|
|
||||||
// class's wrapper. Count the number of times each tag is used.
|
|
||||||
// Warn if a tag is used more than once.
|
|
||||||
std::map<cmStdString, unsigned int> tagCounts;
|
|
||||||
for(cmCableClassSet::CableClassMap::const_iterator
|
|
||||||
c = m_CableClassSet->Begin(); c != m_CableClassSet->End(); ++c)
|
|
||||||
{
|
|
||||||
std::string tag = c->second->GetTag();
|
|
||||||
if((++tagCounts[tag] > 1) && (tag != ""))
|
|
||||||
{
|
|
||||||
std::string message =
|
|
||||||
"CABLE_WRAP_TCL has found two classes with the tag "+tag
|
|
||||||
+" for target "+m_TargetName;
|
|
||||||
cmSystemTools::Message(message.c_str(), "Warning");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Each class wrapper will be written into its own CABLE "group"
|
|
||||||
// file. This should hold the names of the groups generated so that
|
|
||||||
// the package configuration file can tell cable how to generate the
|
|
||||||
// package initialization code.
|
|
||||||
std::vector<std::string> groupTags;
|
|
||||||
|
|
||||||
// Setup the output directory name and make sure it exists.
|
|
||||||
std::string outDir = m_Makefile->GetCurrentOutputDirectory();
|
|
||||||
cmSystemTools::MakeDirectory((outDir+"/Tcl").c_str());
|
|
||||||
|
|
||||||
// Write out the cable configuration files with one class per group.
|
|
||||||
// Try to name the groups based on their class's tag, but use an
|
|
||||||
// index to disambiguate tag repeats (mostly used for empty tags).
|
|
||||||
std::map<cmStdString, unsigned int> tagIndexes;
|
|
||||||
for(cmCableClassSet::CableClassMap::const_iterator
|
|
||||||
c = m_CableClassSet->Begin(); c != m_CableClassSet->End(); ++c)
|
|
||||||
{
|
|
||||||
// Construct the group's tag-based name, with index if necessary.
|
|
||||||
std::string tag = c->second->GetTag();
|
|
||||||
std::string groupTag;
|
|
||||||
if(tagCounts[tag] > 1)
|
|
||||||
{
|
|
||||||
unsigned int tagIndex = tagIndexes[tag]++;
|
|
||||||
std::strstream indexStrStream;
|
|
||||||
indexStrStream << tagIndex << std::ends;
|
|
||||||
std::string indexStr = indexStrStream.str();
|
|
||||||
groupTag = "_"+indexStr;
|
|
||||||
}
|
|
||||||
if(tag != "")
|
|
||||||
{
|
|
||||||
groupTag += "_"+tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save this group tag in the list of tags for the main package
|
|
||||||
// configuration file below.
|
|
||||||
groupTags.push_back(groupTag);
|
|
||||||
|
|
||||||
// Actually generate the class's configuration file.
|
|
||||||
this->GenerateCableClassFiles(c->first.c_str(), *(c->second),
|
|
||||||
groupTag.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the output file names.
|
|
||||||
std::string packageConfigName = outDir+"/Tcl/"+m_TargetName+"_config.xml";
|
|
||||||
std::string packageTclFileName = "Tcl/"+m_TargetName+"_tcl";
|
|
||||||
std::string packageTclFullName = outDir+"/"+packageTclFileName;
|
|
||||||
|
|
||||||
// Generate the main package configuration file for CABLE. This
|
|
||||||
// just lists the "group" files generated above.
|
|
||||||
cmGeneratedFileStream packageConfig(packageConfigName.c_str());
|
|
||||||
if(packageConfig)
|
|
||||||
{
|
|
||||||
packageConfig <<
|
|
||||||
"<CableConfiguration package=\"" << m_TargetName.c_str() << "\">\n";
|
|
||||||
for(std::vector<std::string>::const_iterator g = groupTags.begin();
|
|
||||||
g != groupTags.end(); ++g)
|
|
||||||
{
|
|
||||||
packageConfig <<
|
|
||||||
" <Group name=\"" << m_TargetName.c_str() << g->c_str() << "\"/>\n";
|
|
||||||
}
|
|
||||||
packageConfig <<
|
|
||||||
"</CableConfiguration>\n";
|
|
||||||
|
|
||||||
packageConfig.close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("Error opening CABLE configuration file for writing: ",
|
|
||||||
packageConfigName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the rule to run CABLE for the package configuration file.
|
|
||||||
std::string command = "${CABLE}";
|
|
||||||
m_Makefile->ExpandVariablesInString(command);
|
|
||||||
std::vector<std::string> depends;
|
|
||||||
depends.push_back(command);
|
|
||||||
std::vector<std::string> commandArgs;
|
|
||||||
commandArgs.push_back(packageConfigName);
|
|
||||||
commandArgs.push_back("-tcl");
|
|
||||||
std::string tmp = packageTclFullName+".cxx";
|
|
||||||
commandArgs.push_back(tmp);
|
|
||||||
|
|
||||||
depends.push_back(packageConfigName);
|
|
||||||
|
|
||||||
std::vector<std::string> outputs;
|
|
||||||
outputs.push_back(packageTclFullName+".cxx");
|
|
||||||
|
|
||||||
m_Makefile->AddCustomCommand(packageConfigName.c_str(),
|
|
||||||
command.c_str(),
|
|
||||||
commandArgs,
|
|
||||||
depends,
|
|
||||||
outputs, m_TargetName.c_str());
|
|
||||||
|
|
||||||
// Add the generated source to the package target's source list.
|
|
||||||
cmSourceFile file;
|
|
||||||
file.SetName(packageTclFileName.c_str(), outDir.c_str(), "cxx", false);
|
|
||||||
// Set dependency hints.
|
|
||||||
file.GetDepends().push_back("WrapTclFacility/wrapCalls.h");
|
|
||||||
m_Makefile->AddSource(file, m_TargetName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cmCableWrapTclCommand::GenerateCableClassFiles(const char* name,
|
|
||||||
const cmCableClass& c,
|
|
||||||
const char* groupTag) const
|
|
||||||
{
|
|
||||||
std::string outDir = m_Makefile->GetCurrentOutputDirectory();
|
|
||||||
|
|
||||||
std::string className = name;
|
|
||||||
std::string groupName = m_TargetName+groupTag;
|
|
||||||
std::string classConfigName = outDir+"/Tcl/"+groupName+"_config_tcl.xml";
|
|
||||||
std::string classCxxName = outDir+"/Tcl/"+groupName+"_cxx.cc";
|
|
||||||
std::string classXmlName = outDir+"/Tcl/"+groupName+"_cxx.xml";
|
|
||||||
std::string classTclFileName = "Tcl/"+groupName+"_tcl";
|
|
||||||
std::string classTclFullName = outDir+"/"+classTclFileName;
|
|
||||||
|
|
||||||
cmGeneratedFileStream classConfig(classConfigName.c_str());
|
|
||||||
if(classConfig)
|
|
||||||
{
|
|
||||||
classConfig <<
|
|
||||||
"<CableConfiguration source=\"" << classXmlName.c_str() << "\" "
|
|
||||||
"group=\"" << groupName.c_str() << "\">\n";
|
|
||||||
for(cmCableClass::Sources::const_iterator source = c.SourcesBegin();
|
|
||||||
source != c.SourcesEnd(); ++source)
|
|
||||||
{
|
|
||||||
classConfig <<
|
|
||||||
" <Header name=\"" << source->c_str() << "\"/>\n";
|
|
||||||
}
|
|
||||||
classConfig <<
|
|
||||||
" <Class name=\"_wrap_::wrapper::Wrapper\">\n";
|
|
||||||
if(c.GetTag() != "")
|
|
||||||
{
|
|
||||||
classConfig <<
|
|
||||||
" <AlternateName name=\"" << c.GetTag().c_str() << "\"/>\n";
|
|
||||||
}
|
|
||||||
classConfig <<
|
|
||||||
" </Class>\n"
|
|
||||||
"</CableConfiguration>\n";
|
|
||||||
|
|
||||||
classConfig.close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("Error opening CABLE configuration file for writing: ",
|
|
||||||
classConfigName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
cmGeneratedFileStream classCxx(classCxxName.c_str());
|
|
||||||
if(classCxx)
|
|
||||||
{
|
|
||||||
for(cmCableClass::Sources::const_iterator source = c.SourcesBegin();
|
|
||||||
source != c.SourcesEnd(); ++source)
|
|
||||||
{
|
|
||||||
classCxx <<
|
|
||||||
"#include \"" << source->c_str() << "\"\n";
|
|
||||||
}
|
|
||||||
classCxx <<
|
|
||||||
"\n"
|
|
||||||
"namespace _wrap_\n"
|
|
||||||
"{\n"
|
|
||||||
"\n"
|
|
||||||
"struct wrapper\n"
|
|
||||||
"{\n"
|
|
||||||
" typedef ::" << className.c_str() << " Wrapper;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"template <typename T> void Eat(T) {}\n"
|
|
||||||
"\n"
|
|
||||||
"void InstantiateMemberDeclarations()\n"
|
|
||||||
"{\n"
|
|
||||||
" Eat(sizeof(wrapper::Wrapper));\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
classCxx.close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("Error opening file for writing: ",
|
|
||||||
classCxxName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the rule to have GCC-XML parse the classes to be wrapped.
|
|
||||||
{
|
|
||||||
std::string command = this->GetGccXmlFromCache();
|
|
||||||
std::vector<std::string> depends;
|
|
||||||
depends.push_back(command);
|
|
||||||
|
|
||||||
// Get the dependencies of the file.
|
|
||||||
const cmDependInformation* dependInfo =
|
|
||||||
m_MakeDepend->FindDependencies(classCxxName.c_str());
|
|
||||||
if(dependInfo)
|
|
||||||
{
|
|
||||||
for(cmDependInformation::DependencySet::const_iterator d =
|
|
||||||
dependInfo->m_DependencySet.begin();
|
|
||||||
d != dependInfo->m_DependencySet.end(); ++d)
|
|
||||||
{
|
|
||||||
// Make sure the full path is given. If not, the dependency was
|
|
||||||
// not found.
|
|
||||||
if((*d)->m_FullPath != "")
|
|
||||||
{
|
|
||||||
depends.push_back((*d)->m_FullPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> commandArgs;
|
|
||||||
this->AddGccXmlFlagsFromCache(commandArgs);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string tmp = "-I";
|
|
||||||
tmp += m_Makefile->GetStartDirectory();
|
|
||||||
commandArgs.push_back(tmp.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& includes =
|
|
||||||
m_Makefile->GetIncludeDirectories();
|
|
||||||
for(std::vector<std::string>::const_iterator i = includes.begin();
|
|
||||||
i != includes.end(); ++i)
|
|
||||||
{
|
|
||||||
std::string tmp = "-I";
|
|
||||||
tmp += i->c_str();
|
|
||||||
m_Makefile->ExpandVariablesInString(tmp);
|
|
||||||
commandArgs.push_back(tmp.c_str());
|
|
||||||
}
|
|
||||||
std::string tmp = "-fxml=";
|
|
||||||
tmp += classXmlName;
|
|
||||||
commandArgs.push_back(tmp);
|
|
||||||
commandArgs.push_back(classCxxName);
|
|
||||||
|
|
||||||
std::vector<std::string> outputs;
|
|
||||||
outputs.push_back(classXmlName);
|
|
||||||
|
|
||||||
m_Makefile->AddCustomCommand(classCxxName.c_str(),
|
|
||||||
command.c_str(),
|
|
||||||
commandArgs,
|
|
||||||
depends,
|
|
||||||
outputs, m_TargetName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the rule to run cable on the GCC-XML output to generate wrappers.
|
|
||||||
{
|
|
||||||
std::string command = this->GetCableFromCache();
|
|
||||||
std::vector<std::string> depends;
|
|
||||||
depends.push_back(command);
|
|
||||||
std::vector<std::string > commandArgs;
|
|
||||||
commandArgs.push_back(classConfigName);
|
|
||||||
commandArgs.push_back("-tcl");
|
|
||||||
std::string tmp = classTclFullName+".cxx";
|
|
||||||
commandArgs.push_back(tmp);
|
|
||||||
|
|
||||||
depends.push_back(classConfigName);
|
|
||||||
depends.push_back(classXmlName);
|
|
||||||
|
|
||||||
std::vector<std::string> outputs;
|
|
||||||
outputs.push_back(classTclFullName+".cxx");
|
|
||||||
|
|
||||||
m_Makefile->AddCustomCommand(classConfigName.c_str(),
|
|
||||||
command.c_str(),
|
|
||||||
commandArgs, depends,
|
|
||||||
outputs, m_TargetName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the generated source to the package's source list.
|
|
||||||
cmSourceFile file;
|
|
||||||
file.SetName(classTclFileName.c_str(), outDir.c_str(), "cxx", false);
|
|
||||||
// Set dependency hints.
|
|
||||||
for(cmCableClass::Sources::const_iterator source = c.SourcesBegin();
|
|
||||||
source != c.SourcesEnd(); ++source)
|
|
||||||
{
|
|
||||||
file.GetDepends().push_back(*source);
|
|
||||||
}
|
|
||||||
file.GetDepends().push_back("WrapTclFacility/wrapCalls.h");
|
|
||||||
m_Makefile->AddSource(file, m_TargetName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the "GCCXML" cache entry value. If there is no cache entry for GCCXML,
|
|
||||||
* one will be created and initialized to NOTFOUND.
|
|
||||||
*/
|
|
||||||
std::string cmCableWrapTclCommand::GetGccXmlFromCache() const
|
|
||||||
{
|
|
||||||
const char* gccxml =
|
|
||||||
m_Makefile->GetDefinition("GCCXML");
|
|
||||||
if(gccxml)
|
|
||||||
{ return gccxml; }
|
|
||||||
|
|
||||||
m_Makefile->AddCacheDefinition("GCCXML",
|
|
||||||
"NOTFOUND",
|
|
||||||
"Path to GCC-XML executable.",
|
|
||||||
cmCacheManager::FILEPATH);
|
|
||||||
return "NOTFOUND";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the "GCCXML_FLAGS" cache entry value. If there is no cache
|
|
||||||
* entry for GCCXML_FLAGS, one will be created and initialized "".
|
|
||||||
*/
|
|
||||||
std::string cmCableWrapTclCommand::GetGccXmlFlagsFromCache() const
|
|
||||||
{
|
|
||||||
const char* gccxmlFlags =
|
|
||||||
m_Makefile->GetDefinition("GCCXML_FLAGS");
|
|
||||||
if(gccxmlFlags)
|
|
||||||
{ return gccxmlFlags; }
|
|
||||||
|
|
||||||
m_Makefile->AddCacheDefinition(
|
|
||||||
"GCCXML_FLAGS",
|
|
||||||
"",
|
|
||||||
"Flags to GCC-XML to get it to parse the native compiler's headers.",
|
|
||||||
cmCacheManager::STRING);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the "CABLE" cache entry value. If there is no cache entry for CABLE,
|
|
||||||
* one will be created and initialized to NOTFOUND.
|
|
||||||
*/
|
|
||||||
std::string cmCableWrapTclCommand::GetCableFromCache() const
|
|
||||||
{
|
|
||||||
const char* cable =
|
|
||||||
m_Makefile->GetDefinition("CABLE");
|
|
||||||
if(cable)
|
|
||||||
{ return cable; }
|
|
||||||
|
|
||||||
m_Makefile->AddCacheDefinition("CABLE",
|
|
||||||
"NOTFOUND",
|
|
||||||
"Path to CABLE executable.",
|
|
||||||
cmCacheManager::FILEPATH);
|
|
||||||
return "NOTFOUND";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse flags from the result of GetGccXmlFlagsFromCache() and push
|
|
||||||
* them onto the back of the given vector, in order. This uses an
|
|
||||||
* instance of cmGccXmlFlagsParser associated with the makefile so
|
|
||||||
* that parsing need only be done once.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
cmCableWrapTclCommand
|
|
||||||
::AddGccXmlFlagsFromCache(std::vector<std::string>& resultArgs) const
|
|
||||||
{
|
|
||||||
cmGccXmlFlagsParser* parser = 0;
|
|
||||||
|
|
||||||
// See if the instance already exists with the parsed flags.
|
|
||||||
cmData* data = m_Makefile->LookupData("cmGccXmlFlagsParser");
|
|
||||||
if(data)
|
|
||||||
{
|
|
||||||
// Yes, use it.
|
|
||||||
parser = static_cast<cmGccXmlFlagsParser*>(data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No, create the instance and ask it to parse the flags.
|
|
||||||
parser = new cmGccXmlFlagsParser("cmGccXmlFlagsParser");
|
|
||||||
m_Makefile->RegisterData(parser);
|
|
||||||
parser->Parse(this->GetGccXmlFlagsFromCache().c_str());
|
|
||||||
parser->Parse(m_Makefile->GetDefineFlags());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the parsed flags in the single instance.
|
|
||||||
parser->AddParsedFlags(resultArgs);
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#ifndef cmCableWrapTclCommand_h
|
|
||||||
#define cmCableWrapTclCommand_h
|
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
|
||||||
#include "cmCommand.h"
|
|
||||||
#include "cmCableClassSet.h"
|
|
||||||
|
|
||||||
class cmMakeDepend;
|
|
||||||
|
|
||||||
/** \class cmCableWrapTclCommand
|
|
||||||
* \brief Define a command that wraps a set of classes in Tcl.
|
|
||||||
*/
|
|
||||||
class cmCableWrapTclCommand : public cmCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmCableWrapTclCommand();
|
|
||||||
virtual ~cmCableWrapTclCommand();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a virtual constructor for the command.
|
|
||||||
*/
|
|
||||||
virtual cmCommand* Clone()
|
|
||||||
{
|
|
||||||
return new cmCableWrapTclCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when the command is first encountered in
|
|
||||||
* the CMakeLists.txt file.
|
|
||||||
*/
|
|
||||||
virtual bool InitialPass(std::vector<std::string> const& args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the command as specified in CMakeList.txt.
|
|
||||||
*/
|
|
||||||
virtual const char* GetName() { return "CABLE_WRAP_TCL";}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Succinct documentation.
|
|
||||||
*/
|
|
||||||
virtual const char* GetTerseDocumentation()
|
|
||||||
{
|
|
||||||
return "Wrap a set of classes in Tcl.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More documentation.
|
|
||||||
*/
|
|
||||||
virtual const char* GetFullDocumentation()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
"CABLE_WRAP_TCL(target class1 class2 ...)\n"
|
|
||||||
"Wrap the given set of classes in Tcl using the CABLE tool. The set\n"
|
|
||||||
"of source files produced for the given package name will be added to\n"
|
|
||||||
"a source list with the given name.";
|
|
||||||
}
|
|
||||||
|
|
||||||
cmTypeMacro(cmCableWrapTclCommand, cmCommand);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void GenerateCableFiles() const;
|
|
||||||
void GenerateCableClassFiles(const char*, const cmCableClass&, const char*) const;
|
|
||||||
std::string GetGccXmlFromCache() const;
|
|
||||||
std::string GetGccXmlFlagsFromCache() const;
|
|
||||||
std::string GetCableFromCache() const;
|
|
||||||
void AddGccXmlFlagsFromCache(std::vector<std::string>&) const;
|
|
||||||
|
|
||||||
class cmGccXmlFlagsParser;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The name of the package of wrappers to produce.
|
|
||||||
*/
|
|
||||||
std::string m_TargetName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the source list into which the files needed for the package
|
|
||||||
* will be placed.
|
|
||||||
*/
|
|
||||||
std::string m_SourceListName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The set of classes to be wrapped in the package. This is also implicitly
|
|
||||||
* added to the makefile as another set.
|
|
||||||
*/
|
|
||||||
cmCableClassSet* m_CableClassSet;
|
|
||||||
|
|
||||||
///! The dependency generator.
|
|
||||||
cmMakeDepend* m_MakeDepend;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -29,10 +29,7 @@
|
|||||||
#include "cmAuxSourceDirectoryCommand.cxx"
|
#include "cmAuxSourceDirectoryCommand.cxx"
|
||||||
#include "cmBuildCommand.cxx"
|
#include "cmBuildCommand.cxx"
|
||||||
#include "cmBuildNameCommand.cxx"
|
#include "cmBuildNameCommand.cxx"
|
||||||
#include "cmCableClassSetCommand.cxx"
|
|
||||||
#include "cmCableWrapTclCommand.cxx"
|
|
||||||
#include "cmConfigureFileCommand.cxx"
|
#include "cmConfigureFileCommand.cxx"
|
||||||
#include "cmConfigureGccXmlCommand.cxx"
|
|
||||||
#include "cmCreateTestSourceList.cxx"
|
#include "cmCreateTestSourceList.cxx"
|
||||||
#include "cmElseCommand.cxx"
|
#include "cmElseCommand.cxx"
|
||||||
#include "cmEnableTestingCommand.cxx"
|
#include "cmEnableTestingCommand.cxx"
|
||||||
@ -97,10 +94,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
|
|||||||
commands.push_back(new cmAuxSourceDirectoryCommand);
|
commands.push_back(new cmAuxSourceDirectoryCommand);
|
||||||
commands.push_back(new cmBuildCommand);
|
commands.push_back(new cmBuildCommand);
|
||||||
commands.push_back(new cmBuildNameCommand);
|
commands.push_back(new cmBuildNameCommand);
|
||||||
commands.push_back(new cmCableClassSetCommand);
|
|
||||||
commands.push_back(new cmCableWrapTclCommand);
|
|
||||||
commands.push_back(new cmConfigureFileCommand);
|
commands.push_back(new cmConfigureFileCommand);
|
||||||
commands.push_back(new cmConfigureGccXmlCommand);
|
|
||||||
commands.push_back(new cmCreateTestSourceList);
|
commands.push_back(new cmCreateTestSourceList);
|
||||||
commands.push_back(new cmElseCommand);
|
commands.push_back(new cmElseCommand);
|
||||||
commands.push_back(new cmEnableTestingCommand);
|
commands.push_back(new cmEnableTestingCommand);
|
||||||
|
@ -1,263 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#include "cmConfigureGccXmlCommand.h"
|
|
||||||
#include "cmCacheManager.h"
|
|
||||||
|
|
||||||
cmConfigureGccXmlCommand::cmConfigureGccXmlCommand()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cmConfigureGccXmlCommand::~cmConfigureGccXmlCommand()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// cmConfigureGccXmlCommand
|
|
||||||
bool cmConfigureGccXmlCommand::InitialPass(std::vector<std::string> const& args)
|
|
||||||
{
|
|
||||||
if(args.size() != 2)
|
|
||||||
{
|
|
||||||
this->SetError("called with incorrect number of arguments");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the cache entry already exists, we are done.
|
|
||||||
std::string cacheName = args[1];
|
|
||||||
const char* cacheValue =
|
|
||||||
m_Makefile->GetDefinition(cacheName.c_str());
|
|
||||||
if(cacheValue && (std::string(cacheValue) != ""))
|
|
||||||
{ return true; }
|
|
||||||
|
|
||||||
// Get the gccxml support directory location. This is based on the
|
|
||||||
// executable location.
|
|
||||||
if(!this->GetSupportDirectory(args[0].c_str()))
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
||||||
// On Windows, we will just look at VcInclude/FLAGS.txt for now.
|
|
||||||
if(!this->FindVcIncludeFlags())
|
|
||||||
{ return false; }
|
|
||||||
#else
|
|
||||||
// On UNIX, we have to determine which compiler is being used, and
|
|
||||||
// attempt to use that compiler's support directory.
|
|
||||||
if(this->CompilerIsGCC())
|
|
||||||
{
|
|
||||||
if(!this->FindGccIncludeFlags())
|
|
||||||
{ return false; }
|
|
||||||
}
|
|
||||||
else if(this->CompilerIsMipsPro())
|
|
||||||
{
|
|
||||||
if(!this->FindMproIncludeFlags())
|
|
||||||
{ return false; }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->SetError("Compiler is not supported by GCC-XML!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add the cache entry with the flags found.
|
|
||||||
m_Makefile->AddCacheDefinition(
|
|
||||||
cacheName.c_str(),
|
|
||||||
m_Flags.c_str(),
|
|
||||||
"Flags to GCC-XML to get it to parse the native compiler's headers.",
|
|
||||||
cmCacheManager::STRING);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the location of the GCC-XML executable, find the root of the
|
|
||||||
* support library tree. Subdirectories of the returned location should
|
|
||||||
* contain the compiler-specific support libraries.
|
|
||||||
*/
|
|
||||||
bool cmConfigureGccXmlCommand::GetSupportDirectory(const char* exeLoc)
|
|
||||||
{
|
|
||||||
std::string gccxml = exeLoc;
|
|
||||||
m_Makefile->ExpandVariablesInString(gccxml);
|
|
||||||
|
|
||||||
if(!cmSystemTools::FileExists(gccxml.c_str()))
|
|
||||||
{
|
|
||||||
std::string err = "Can't find GCC-XML at given path: ";
|
|
||||||
err += gccxml;
|
|
||||||
this->SetError(err.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dir;
|
|
||||||
std::string file;
|
|
||||||
// Get the directory (also converts to unix slashes).
|
|
||||||
cmSystemTools::SplitProgramPath(gccxml.c_str(), dir, file);
|
|
||||||
|
|
||||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
|
||||||
// On UNIX platforms, we must replace the "/bin" suffix with
|
|
||||||
// "/share/GCC_XML". If there is no "/bin" suffix, we will assume
|
|
||||||
// that the user has put everything in one directory, and not change
|
|
||||||
// the path.
|
|
||||||
if(dir.substr(dir.length()-4, 4) == "/bin")
|
|
||||||
{
|
|
||||||
dir = dir.substr(0, dir.length()-4) + "/share/GCC_XML";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_SupportDir = dir;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the flags needed to use the Visual C++ support library.
|
|
||||||
*/
|
|
||||||
bool cmConfigureGccXmlCommand::FindVcIncludeFlags()
|
|
||||||
{
|
|
||||||
std::string fname = m_SupportDir+"/VcInclude/FLAGS.txt";
|
|
||||||
std::ifstream flagsFile(fname.c_str());
|
|
||||||
|
|
||||||
if(!flagsFile)
|
|
||||||
{
|
|
||||||
std::string err = "Cannot open GCC-XML flags file \""+fname+"\".";
|
|
||||||
this->SetError(err.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Replace this with a real implementation.
|
|
||||||
char buf[4096];
|
|
||||||
flagsFile.getline(buf, 4096);
|
|
||||||
if(!flagsFile)
|
|
||||||
{
|
|
||||||
std::string err = "Error reading from GCC-XML flags file \""+fname+"\".";
|
|
||||||
this->SetError(err.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Flags = buf;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the flags needed to use the GCC support library.
|
|
||||||
*/
|
|
||||||
bool cmConfigureGccXmlCommand::FindGccIncludeFlags()
|
|
||||||
{
|
|
||||||
std::string supportDir = m_SupportDir+"/GccInclude";
|
|
||||||
if(!cmSystemTools::FileIsDirectory(supportDir.c_str()))
|
|
||||||
{
|
|
||||||
std::string err = "No GCC support library for GCC-XML. Couldn't find directory \""+supportDir+"\".";
|
|
||||||
this->SetError(err.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to run the find_gcc_options command.
|
|
||||||
std::string command = supportDir+"/find_gcc_options";
|
|
||||||
std::string flags;
|
|
||||||
if(!cmSystemTools::RunCommand(command.c_str(), flags))
|
|
||||||
{
|
|
||||||
this->SetError("Could not run find_gcc_options!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strip newline from end of flags.
|
|
||||||
if((flags.length() > 0)
|
|
||||||
&& (flags[flags.length()-1] == '\n'))
|
|
||||||
{
|
|
||||||
flags = flags.substr(0, flags.length()-1);
|
|
||||||
if((flags.length() > 0)
|
|
||||||
&& (flags[flags.length()-1] == '\r'))
|
|
||||||
{
|
|
||||||
flags = flags.substr(0, flags.length()-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the result of the command as the flags.
|
|
||||||
m_Flags = flags;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the flags needed to use the MIPSpro support library.
|
|
||||||
*/
|
|
||||||
bool cmConfigureGccXmlCommand::FindMproIncludeFlags()
|
|
||||||
{
|
|
||||||
std::string supportDir = m_SupportDir+"/MproInclude";
|
|
||||||
if(!cmSystemTools::FileIsDirectory(supportDir.c_str()))
|
|
||||||
{
|
|
||||||
std::string err = "No MIPSpro support library for GCC-XML. Couldn't find directory \""+supportDir+"\".";
|
|
||||||
this->SetError(err.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to run the find_mpro_options command.
|
|
||||||
std::string command = supportDir+"/find_mpro_options";
|
|
||||||
std::string flags;
|
|
||||||
if(!cmSystemTools::RunCommand(command.c_str(), flags))
|
|
||||||
{
|
|
||||||
this->SetError("Could not run find_mpro_options!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strip newline from end of flags.
|
|
||||||
if((flags.length() > 0)
|
|
||||||
&& (flags[flags.length()-1] == '\n'))
|
|
||||||
{
|
|
||||||
flags = flags.substr(0, flags.length()-1);
|
|
||||||
if((flags.length() > 0)
|
|
||||||
&& (flags[flags.length()-1] == '\r'))
|
|
||||||
{
|
|
||||||
flags = flags.substr(0, flags.length()-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the result of the command as the flags.
|
|
||||||
m_Flags = flags;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the compiler is GCC.
|
|
||||||
*/
|
|
||||||
bool cmConfigureGccXmlCommand::CompilerIsGCC() const
|
|
||||||
{
|
|
||||||
const char* isGNU = m_Makefile->GetDefinition("CMAKE_COMPILER_IS_GNUCXX");
|
|
||||||
return (isGNU && !cmSystemTools::IsOff(isGNU));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the compiler is MipsPro.
|
|
||||||
*/
|
|
||||||
bool cmConfigureGccXmlCommand::CompilerIsMipsPro() const
|
|
||||||
{
|
|
||||||
const char* compiler = m_Makefile->GetDefinition("CMAKE_CXX_COMPILER");
|
|
||||||
if(!compiler) { return false; }
|
|
||||||
std::string command = compiler;
|
|
||||||
command += " -version 2>&1";
|
|
||||||
std::string output;
|
|
||||||
if(!cmSystemTools::RunCommand(command.c_str(), output, 0, false))
|
|
||||||
{ return false; }
|
|
||||||
if(output.find("MIPSpro") != std::string::npos)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: Insight Segmentation & Registration Toolkit
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Insight Consortium. All rights reserved.
|
|
||||||
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#ifndef cmConfigureGccXmlCommand_h
|
|
||||||
#define cmConfigureGccXmlCommand_h
|
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
|
||||||
#include "cmCommand.h"
|
|
||||||
|
|
||||||
/** \class cmConfigureGccXmlCommand
|
|
||||||
* \brief Define a command that configures flags for GCC-XML to run.
|
|
||||||
*/
|
|
||||||
class cmConfigureGccXmlCommand : public cmCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmConfigureGccXmlCommand();
|
|
||||||
virtual ~cmConfigureGccXmlCommand();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a virtual constructor for the command.
|
|
||||||
*/
|
|
||||||
virtual cmCommand* Clone()
|
|
||||||
{
|
|
||||||
return new cmConfigureGccXmlCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when the command is first encountered in
|
|
||||||
* the CMakeLists.txt file.
|
|
||||||
*/
|
|
||||||
virtual bool InitialPass(std::vector<std::string> const& args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the command as specified in CMakeList.txt.
|
|
||||||
*/
|
|
||||||
virtual const char* GetName() { return "CONFIGURE_GCCXML";}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Succinct documentation.
|
|
||||||
*/
|
|
||||||
virtual const char* GetTerseDocumentation()
|
|
||||||
{
|
|
||||||
return "Configure the flags needed for GCC-XML to run.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More documentation.
|
|
||||||
*/
|
|
||||||
virtual const char* GetFullDocumentation()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
"CONFIGURE_GCCXML(exe_location flags_def)\n"
|
|
||||||
"Configures the flags GCC-XML needs to parse source code just as\n"
|
|
||||||
"the current compiler would. This includes using the compiler's\n"
|
|
||||||
"standard header files. First argument is input of the full path to\n"
|
|
||||||
"the GCC-XML executable. The second argument should be the name of\n"
|
|
||||||
"a cache entry to set with the flags chosen.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
cmTypeMacro(cmConfigureGccXmlCommand, cmCommand);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool GetSupportDirectory(const char*);
|
|
||||||
bool FindVcIncludeFlags();
|
|
||||||
bool FindGccIncludeFlags();
|
|
||||||
bool FindMproIncludeFlags();
|
|
||||||
bool CompilerIsGCC() const;
|
|
||||||
bool CompilerIsMipsPro() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_SupportDir;
|
|
||||||
std::string m_Flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -244,6 +244,13 @@ void cmMakefile::ExecuteCommand(std::string &name,
|
|||||||
delete usedCommand;
|
delete usedCommand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if((name == "CABLE_WRAP_TCL") || (name == "CABLE_CLASS_SET") ||
|
||||||
|
(name == "CONFIGURE_GCCXML"))
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("The command ", name.c_str(),
|
||||||
|
" is not implemented in this version of CMake.\n"
|
||||||
|
"Contact cable@public.kitware.com for more information.");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("unknown CMake command:", name.c_str(),
|
cmSystemTools::Error("unknown CMake command:", name.c_str(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user