ENH: Removed out-of-date commands CABLE_WRAP_TCL CABLE_CLASS_SET and CONFIGURE_GCCXML

This commit is contained in:
Brad King 2002-04-17 14:54:48 -04:00
parent c83a8ac286
commit 5a418b0e00
12 changed files with 7 additions and 2011 deletions

View File

@ -12,7 +12,6 @@ cmCommands.cxx
cmTarget.cxx
cmCustomCommand.cxx
cmCacheManager.cxx
cmCableClassSet.cxx
cmSourceGroup.cxx
cmListFileCache.cxx
cmake.h
@ -28,7 +27,6 @@ cmCommands.h
cmTarget.h
cmCustomCommand.h
cmCacheManager.h
cmCableClassSet.h
cmSourceGroup.h
cmListFileCache.h
)

View File

@ -29,7 +29,6 @@ cmCommands.o \
cmTarget.o \
cmCustomCommand.o \
cmCacheManager.o \
cmCableClassSet.o \
cmListFileCache.o \
cmSourceGroup.o
@ -50,7 +49,6 @@ cmUnixMakefileGenerator.o : $(DEPENDS)
cmCommands.o : $(DEPENDS) $(srcdir)/*Command*.cxx
cmTarget.o : $(DEPENDS)
cmCacheManager.o : $(DEPENDS)
cmCableClassSet.o: $(DEPENDS)
cmSourceGroup.o : $(DEPENDS)

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -29,10 +29,7 @@
#include "cmAuxSourceDirectoryCommand.cxx"
#include "cmBuildCommand.cxx"
#include "cmBuildNameCommand.cxx"
#include "cmCableClassSetCommand.cxx"
#include "cmCableWrapTclCommand.cxx"
#include "cmConfigureFileCommand.cxx"
#include "cmConfigureGccXmlCommand.cxx"
#include "cmCreateTestSourceList.cxx"
#include "cmElseCommand.cxx"
#include "cmEnableTestingCommand.cxx"
@ -97,10 +94,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmAuxSourceDirectoryCommand);
commands.push_back(new cmBuildCommand);
commands.push_back(new cmBuildNameCommand);
commands.push_back(new cmCableClassSetCommand);
commands.push_back(new cmCableWrapTclCommand);
commands.push_back(new cmConfigureFileCommand);
commands.push_back(new cmConfigureGccXmlCommand);
commands.push_back(new cmCreateTestSourceList);
commands.push_back(new cmElseCommand);
commands.push_back(new cmEnableTestingCommand);

View File

@ -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;
}

View File

@ -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

View File

@ -244,6 +244,13 @@ void cmMakefile::ExecuteCommand(std::string &name,
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
{
cmSystemTools::Error("unknown CMake command:", name.c_str(),