mirror of
https://github.com/reactos/CMake.git
synced 2024-12-14 23:29:57 +00:00
de955e4b6d
This converts the KWSys license to a pure 3-clause OSI-approved BSD License. We drop the previous license clause requiring modified versions to be plainly marked. We also update the KWSys copyright to cover the full development time range.
860 lines
27 KiB
C++
860 lines
27 KiB
C++
/*============================================================================
|
|
KWSys - Kitware System Library
|
|
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
|
|
|
Distributed under the OSI-approved BSD License (the "License");
|
|
see accompanying file Copyright.txt for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the License for more information.
|
|
============================================================================*/
|
|
#include "kwsysPrivate.h"
|
|
#include KWSYS_HEADER(CommandLineArguments.hxx)
|
|
|
|
#include KWSYS_HEADER(Configure.hxx)
|
|
#include KWSYS_HEADER(String.hxx)
|
|
|
|
#include KWSYS_HEADER(stl/vector)
|
|
#include KWSYS_HEADER(stl/map)
|
|
#include KWSYS_HEADER(stl/set)
|
|
#include KWSYS_HEADER(ios/sstream)
|
|
#include KWSYS_HEADER(ios/iostream)
|
|
|
|
// Work-around CMake dependency scanning limitation. This must
|
|
// duplicate the above list of headers.
|
|
#if 0
|
|
# include "CommandLineArguments.hxx.in"
|
|
# include "Configure.hxx.in"
|
|
# include "kwsys_stl.hxx.in"
|
|
# include "kwsys_ios_sstream.h.in"
|
|
# include "kwsys_ios_iostream.h.in"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning (disable: 4786)
|
|
#endif
|
|
|
|
#if defined(__sgi) && !defined(__GNUC__)
|
|
# pragma set woff 1375 /* base class destructor not virtual */
|
|
#endif
|
|
|
|
#if 0
|
|
# define CommandLineArguments_DEBUG(x) \
|
|
kwsys_ios::cout << __LINE__ << " CLA: " << x << kwsys_ios::endl
|
|
#else
|
|
# define CommandLineArguments_DEBUG(x)
|
|
#endif
|
|
|
|
namespace KWSYS_NAMESPACE
|
|
{
|
|
|
|
//----------------------------------------------------------------------------
|
|
//============================================================================
|
|
struct CommandLineArgumentsCallbackStructure
|
|
{
|
|
const char* Argument;
|
|
int ArgumentType;
|
|
CommandLineArguments::CallbackType Callback;
|
|
void* CallData;
|
|
void* Variable;
|
|
int VariableType;
|
|
const char* Help;
|
|
};
|
|
|
|
class CommandLineArgumentsVectorOfStrings :
|
|
public kwsys_stl::vector<kwsys::String> {};
|
|
class CommandLineArgumentsSetOfStrings :
|
|
public kwsys_stl::set<kwsys::String> {};
|
|
class CommandLineArgumentsMapOfStrucs :
|
|
public kwsys_stl::map<kwsys::String,
|
|
CommandLineArgumentsCallbackStructure> {};
|
|
|
|
class CommandLineArgumentsInternal
|
|
{
|
|
public:
|
|
CommandLineArgumentsInternal()
|
|
{
|
|
this->UnknownArgumentCallback = 0;
|
|
this->ClientData = 0;
|
|
this->LastArgument = 0;
|
|
}
|
|
|
|
typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
|
|
typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
|
|
typedef kwsys::String String;
|
|
typedef CommandLineArgumentsSetOfStrings SetOfStrings;
|
|
|
|
VectorOfStrings Argv;
|
|
String Argv0;
|
|
CallbacksMap Callbacks;
|
|
|
|
CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
|
|
void* ClientData;
|
|
|
|
VectorOfStrings::size_type LastArgument;
|
|
|
|
VectorOfStrings UnusedArguments;
|
|
};
|
|
//============================================================================
|
|
//----------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
CommandLineArguments::CommandLineArguments()
|
|
{
|
|
this->Internals = new CommandLineArguments::Internal;
|
|
this->Help = "";
|
|
this->LineLength = 80;
|
|
this->StoreUnusedArgumentsFlag = false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
CommandLineArguments::~CommandLineArguments()
|
|
{
|
|
delete this->Internals;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::Initialize(int argc, const char* const argv[])
|
|
{
|
|
int cc;
|
|
|
|
this->Initialize();
|
|
this->Internals->Argv0 = argv[0];
|
|
for ( cc = 1; cc < argc; cc ++ )
|
|
{
|
|
this->ProcessArgument(argv[cc]);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::Initialize(int argc, char* argv[])
|
|
{
|
|
this->Initialize(argc, static_cast<const char* const*>(argv));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::Initialize()
|
|
{
|
|
this->Internals->Argv.clear();
|
|
this->Internals->LastArgument = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::ProcessArgument(const char* arg)
|
|
{
|
|
this->Internals->Argv.push_back(arg);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool CommandLineArguments::GetMatchedArguments(
|
|
kwsys_stl::vector<kwsys_stl::string>* matches,
|
|
const kwsys_stl::string& arg)
|
|
{
|
|
matches->clear();
|
|
CommandLineArguments::Internal::CallbacksMap::iterator it;
|
|
|
|
// Does the argument match to any we know about?
|
|
for ( it = this->Internals->Callbacks.begin();
|
|
it != this->Internals->Callbacks.end();
|
|
it ++ )
|
|
{
|
|
const CommandLineArguments::Internal::String& parg = it->first;
|
|
CommandLineArgumentsCallbackStructure *cs = &it->second;
|
|
if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
|
|
cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT)
|
|
{
|
|
if ( arg == parg )
|
|
{
|
|
matches->push_back(parg);
|
|
}
|
|
}
|
|
else if ( arg.find( parg ) == 0 )
|
|
{
|
|
matches->push_back(parg);
|
|
}
|
|
}
|
|
return matches->size() > 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int CommandLineArguments::Parse()
|
|
{
|
|
kwsys_stl::vector<kwsys_stl::string>::size_type cc;
|
|
kwsys_stl::vector<kwsys_stl::string> matches;
|
|
if ( this->StoreUnusedArgumentsFlag )
|
|
{
|
|
this->Internals->UnusedArguments.clear();
|
|
}
|
|
for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
|
|
{
|
|
const kwsys_stl::string& arg = this->Internals->Argv[cc];
|
|
CommandLineArguments_DEBUG("Process argument: " << arg);
|
|
this->Internals->LastArgument = cc;
|
|
if ( this->GetMatchedArguments(&matches, arg) )
|
|
{
|
|
// Ok, we found one or more arguments that match what user specified.
|
|
// Let's find the longest one.
|
|
CommandLineArguments::Internal::VectorOfStrings::size_type kk;
|
|
CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0;
|
|
CommandLineArguments::Internal::String::size_type maxlen = 0;
|
|
for ( kk = 0; kk < matches.size(); kk ++ )
|
|
{
|
|
if ( matches[kk].size() > maxlen )
|
|
{
|
|
maxlen = matches[kk].size();
|
|
maxidx = kk;
|
|
}
|
|
}
|
|
// So, the longest one is probably the right one. Now see if it has any
|
|
// additional value
|
|
CommandLineArgumentsCallbackStructure *cs
|
|
= &this->Internals->Callbacks[matches[maxidx]];
|
|
const kwsys_stl::string& sarg = matches[maxidx];
|
|
if ( cs->Argument != sarg )
|
|
{
|
|
abort();
|
|
}
|
|
switch ( cs->ArgumentType )
|
|
{
|
|
case NO_ARGUMENT:
|
|
// No value
|
|
if ( !this->PopulateVariable(cs, 0) )
|
|
{
|
|
return 0;
|
|
}
|
|
break;
|
|
case SPACE_ARGUMENT:
|
|
if ( cc == this->Internals->Argv.size()-1 )
|
|
{
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
CommandLineArguments_DEBUG("This is a space argument: " << arg
|
|
<< " value: " << this->Internals->Argv[cc+1].c_str());
|
|
// Value is the next argument
|
|
if ( !this->PopulateVariable(cs, this->Internals->Argv[cc+1].c_str()) )
|
|
{
|
|
return 0;
|
|
}
|
|
cc ++;
|
|
break;
|
|
case EQUAL_ARGUMENT:
|
|
if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' )
|
|
{
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
// Value is everythng followed the '=' sign
|
|
if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1) )
|
|
{
|
|
return 0;
|
|
}
|
|
break;
|
|
case CONCAT_ARGUMENT:
|
|
// Value is whatever follows the argument
|
|
if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size()) )
|
|
{
|
|
return 0;
|
|
}
|
|
break;
|
|
case MULTI_ARGUMENT:
|
|
// Suck in all the rest of the arguments
|
|
CommandLineArguments_DEBUG("This is a multi argument: " << arg);
|
|
for (cc++; cc < this->Internals->Argv.size(); ++ cc )
|
|
{
|
|
const kwsys_stl::string& marg = this->Internals->Argv[cc];
|
|
CommandLineArguments_DEBUG(" check multi argument value: " << marg);
|
|
if ( this->GetMatchedArguments(&matches, marg) )
|
|
{
|
|
CommandLineArguments_DEBUG("End of multi argument " << arg << " with value: " << marg);
|
|
break;
|
|
}
|
|
CommandLineArguments_DEBUG(" populate multi argument value: " << marg);
|
|
if ( !this->PopulateVariable(cs, marg.c_str()) )
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
if ( cc != this->Internals->Argv.size() )
|
|
{
|
|
CommandLineArguments_DEBUG("Again End of multi argument " << arg);
|
|
cc--;
|
|
continue;
|
|
}
|
|
break;
|
|
default:
|
|
kwsys_ios::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << kwsys_ios::endl;
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Handle unknown arguments
|
|
if ( this->Internals->UnknownArgumentCallback )
|
|
{
|
|
if ( !this->Internals->UnknownArgumentCallback(arg.c_str(),
|
|
this->Internals->ClientData) )
|
|
{
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
else if ( this->StoreUnusedArgumentsFlag )
|
|
{
|
|
CommandLineArguments_DEBUG("Store unused argument " << arg);
|
|
this->Internals->UnusedArguments.push_back(arg.c_str());
|
|
}
|
|
else
|
|
{
|
|
kwsys_ios::cerr << "Got unknown argument: \"" << arg.c_str() << "\"" << kwsys_ios::endl;
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
|
|
{
|
|
CommandLineArguments::Internal::VectorOfStrings::size_type size
|
|
= this->Internals->Argv.size() - this->Internals->LastArgument + 1;
|
|
CommandLineArguments::Internal::VectorOfStrings::size_type cc;
|
|
|
|
// Copy Argv0 as the first argument
|
|
char** args = new char*[ size ];
|
|
args[0] = new char[ this->Internals->Argv0.size() + 1 ];
|
|
strcpy(args[0], this->Internals->Argv0.c_str());
|
|
int cnt = 1;
|
|
|
|
// Copy everything after the LastArgument, since that was not parsed.
|
|
for ( cc = this->Internals->LastArgument+1;
|
|
cc < this->Internals->Argv.size(); cc ++ )
|
|
{
|
|
args[cnt] = new char[ this->Internals->Argv[cc].size() + 1];
|
|
strcpy(args[cnt], this->Internals->Argv[cc].c_str());
|
|
cnt ++;
|
|
}
|
|
*argc = cnt;
|
|
*argv = args;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv)
|
|
{
|
|
CommandLineArguments::Internal::VectorOfStrings::size_type size
|
|
= this->Internals->UnusedArguments.size() + 1;
|
|
CommandLineArguments::Internal::VectorOfStrings::size_type cc;
|
|
|
|
// Copy Argv0 as the first argument
|
|
char** args = new char*[ size ];
|
|
args[0] = new char[ this->Internals->Argv0.size() + 1 ];
|
|
strcpy(args[0], this->Internals->Argv0.c_str());
|
|
int cnt = 1;
|
|
|
|
// Copy everything after the LastArgument, since that was not parsed.
|
|
for ( cc = 0;
|
|
cc < this->Internals->UnusedArguments.size(); cc ++ )
|
|
{
|
|
kwsys::String &str = this->Internals->UnusedArguments[cc];
|
|
args[cnt] = new char[ str.size() + 1];
|
|
strcpy(args[cnt], str.c_str());
|
|
cnt ++;
|
|
}
|
|
*argc = cnt;
|
|
*argv = args;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv)
|
|
{
|
|
int cc;
|
|
for ( cc = 0; cc < argc; ++ cc )
|
|
{
|
|
delete [] (*argv)[cc];
|
|
}
|
|
delete [] *argv;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::AddCallback(const char* argument, ArgumentTypeEnum type,
|
|
CallbackType callback, void* call_data, const char* help)
|
|
{
|
|
CommandLineArgumentsCallbackStructure s;
|
|
s.Argument = argument;
|
|
s.ArgumentType = type;
|
|
s.Callback = callback;
|
|
s.CallData = call_data;
|
|
s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
|
|
s.Variable = 0;
|
|
s.Help = help;
|
|
|
|
this->Internals->Callbacks[argument] = s;
|
|
this->GenerateHelp();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
|
VariableTypeEnum vtype, void* variable, const char* help)
|
|
{
|
|
CommandLineArgumentsCallbackStructure s;
|
|
s.Argument = argument;
|
|
s.ArgumentType = type;
|
|
s.Callback = 0;
|
|
s.CallData = 0;
|
|
s.VariableType = vtype;
|
|
s.Variable = variable;
|
|
s.Help = help;
|
|
|
|
this->Internals->Callbacks[argument] = s;
|
|
this->GenerateHelp();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
#define CommandLineArgumentsAddArgumentMacro(type, ctype) \
|
|
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, \
|
|
ctype* variable, const char* help) \
|
|
{ \
|
|
this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, variable, help); \
|
|
}
|
|
|
|
CommandLineArgumentsAddArgumentMacro(BOOL, bool)
|
|
CommandLineArgumentsAddArgumentMacro(INT, int)
|
|
CommandLineArgumentsAddArgumentMacro(DOUBLE, double)
|
|
CommandLineArgumentsAddArgumentMacro(STRING, char*)
|
|
CommandLineArgumentsAddArgumentMacro(STL_STRING, kwsys_stl::string)
|
|
|
|
CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, kwsys_stl::vector<bool>)
|
|
CommandLineArgumentsAddArgumentMacro(VECTOR_INT, kwsys_stl::vector<int>)
|
|
CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, kwsys_stl::vector<double>)
|
|
CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, kwsys_stl::vector<char*>)
|
|
CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, kwsys_stl::vector<kwsys_stl::string>)
|
|
|
|
//----------------------------------------------------------------------------
|
|
#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
|
|
void CommandLineArguments::AddBooleanArgument(const char* argument, \
|
|
ctype* variable, const char* help) \
|
|
{ \
|
|
this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \
|
|
CommandLineArguments::type##_TYPE, variable, help); \
|
|
}
|
|
|
|
CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool)
|
|
CommandLineArgumentsAddBooleanArgumentMacro(INT, int)
|
|
CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double)
|
|
CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*)
|
|
CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string)
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::SetClientData(void* client_data)
|
|
{
|
|
this->Internals->ClientData = client_data;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::SetUnknownArgumentCallback(
|
|
CommandLineArguments::ErrorCallbackType callback)
|
|
{
|
|
this->Internals->UnknownArgumentCallback = callback;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char* CommandLineArguments::GetHelp(const char* arg)
|
|
{
|
|
CommandLineArguments::Internal::CallbacksMap::iterator it
|
|
= this->Internals->Callbacks.find(arg);
|
|
if ( it == this->Internals->Callbacks.end() )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Since several arguments may point to the same argument, find the one this
|
|
// one point to if this one is pointing to another argument.
|
|
CommandLineArgumentsCallbackStructure *cs = &(it->second);
|
|
for(;;)
|
|
{
|
|
CommandLineArguments::Internal::CallbacksMap::iterator hit
|
|
= this->Internals->Callbacks.find(cs->Help);
|
|
if ( hit == this->Internals->Callbacks.end() )
|
|
{
|
|
break;
|
|
}
|
|
cs = &(hit->second);
|
|
}
|
|
return cs->Help;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::SetLineLength(unsigned int ll)
|
|
{
|
|
if ( ll < 9 || ll > 1000 )
|
|
{
|
|
return;
|
|
}
|
|
this->LineLength = ll;
|
|
this->GenerateHelp();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char* CommandLineArguments::GetArgv0()
|
|
{
|
|
return this->Internals->Argv0.c_str();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
unsigned int CommandLineArguments::GetLastArgument()
|
|
{
|
|
return static_cast<unsigned int>(this->Internals->LastArgument + 1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::GenerateHelp()
|
|
{
|
|
kwsys_ios::ostringstream str;
|
|
|
|
// Collapse all arguments into the map of vectors of all arguments that do
|
|
// the same thing.
|
|
CommandLineArguments::Internal::CallbacksMap::iterator it;
|
|
typedef kwsys_stl::map<CommandLineArguments::Internal::String,
|
|
CommandLineArguments::Internal::SetOfStrings > MapArgs;
|
|
MapArgs mp;
|
|
MapArgs::iterator mpit, smpit;
|
|
for ( it = this->Internals->Callbacks.begin();
|
|
it != this->Internals->Callbacks.end();
|
|
it ++ )
|
|
{
|
|
CommandLineArgumentsCallbackStructure *cs = &(it->second);
|
|
mpit = mp.find(cs->Help);
|
|
if ( mpit != mp.end() )
|
|
{
|
|
mpit->second.insert(it->first);
|
|
mp[it->first].insert(it->first);
|
|
}
|
|
else
|
|
{
|
|
mp[it->first].insert(it->first);
|
|
}
|
|
}
|
|
for ( it = this->Internals->Callbacks.begin();
|
|
it != this->Internals->Callbacks.end();
|
|
it ++ )
|
|
{
|
|
CommandLineArgumentsCallbackStructure *cs = &(it->second);
|
|
mpit = mp.find(cs->Help);
|
|
if ( mpit != mp.end() )
|
|
{
|
|
mpit->second.insert(it->first);
|
|
smpit = mp.find(it->first);
|
|
CommandLineArguments::Internal::SetOfStrings::iterator sit;
|
|
for ( sit = smpit->second.begin(); sit != smpit->second.end(); sit++ )
|
|
{
|
|
mpit->second.insert(*sit);
|
|
}
|
|
mp.erase(smpit);
|
|
}
|
|
else
|
|
{
|
|
mp[it->first].insert(it->first);
|
|
}
|
|
}
|
|
|
|
// Find the length of the longest string
|
|
CommandLineArguments::Internal::String::size_type maxlen = 0;
|
|
for ( mpit = mp.begin();
|
|
mpit != mp.end();
|
|
mpit ++ )
|
|
{
|
|
CommandLineArguments::Internal::SetOfStrings::iterator sit;
|
|
for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
|
|
{
|
|
CommandLineArguments::Internal::String::size_type clen = sit->size();
|
|
switch ( this->Internals->Callbacks[*sit].ArgumentType )
|
|
{
|
|
case CommandLineArguments::NO_ARGUMENT: clen += 0; break;
|
|
case CommandLineArguments::CONCAT_ARGUMENT: clen += 3; break;
|
|
case CommandLineArguments::SPACE_ARGUMENT: clen += 4; break;
|
|
case CommandLineArguments::EQUAL_ARGUMENT: clen += 4; break;
|
|
}
|
|
if ( clen > maxlen )
|
|
{
|
|
maxlen = clen;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create format for that string
|
|
char format[80];
|
|
sprintf(format, " %%-%ds ", static_cast<unsigned int>(maxlen));
|
|
|
|
maxlen += 4; // For the space before and after the option
|
|
|
|
// Print help for each option
|
|
for ( mpit = mp.begin();
|
|
mpit != mp.end();
|
|
mpit ++ )
|
|
{
|
|
CommandLineArguments::Internal::SetOfStrings::iterator sit;
|
|
for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
|
|
{
|
|
str << kwsys_ios::endl;
|
|
char argument[100];
|
|
sprintf(argument, "%s", sit->c_str());
|
|
switch ( this->Internals->Callbacks[*sit].ArgumentType )
|
|
{
|
|
case CommandLineArguments::NO_ARGUMENT: break;
|
|
case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "opt"); break;
|
|
case CommandLineArguments::SPACE_ARGUMENT: strcat(argument, " opt"); break;
|
|
case CommandLineArguments::EQUAL_ARGUMENT: strcat(argument, "=opt"); break;
|
|
case CommandLineArguments::MULTI_ARGUMENT: strcat(argument, " opt opt ..."); break;
|
|
}
|
|
char buffer[80];
|
|
sprintf(buffer, format, argument);
|
|
str << buffer;
|
|
}
|
|
const char* ptr = this->Internals->Callbacks[mpit->first].Help;
|
|
size_t len = strlen(ptr);
|
|
int cnt = 0;
|
|
while ( len > 0)
|
|
{
|
|
// If argument with help is longer than line length, split it on previous
|
|
// space (or tab) and continue on the next line
|
|
CommandLineArguments::Internal::String::size_type cc;
|
|
for ( cc = 0; ptr[cc]; cc ++ )
|
|
{
|
|
if ( *ptr == ' ' || *ptr == '\t' )
|
|
{
|
|
ptr ++;
|
|
len --;
|
|
}
|
|
}
|
|
if ( cnt > 0 )
|
|
{
|
|
for ( cc = 0; cc < maxlen; cc ++ )
|
|
{
|
|
str << " ";
|
|
}
|
|
}
|
|
CommandLineArguments::Internal::String::size_type skip = len;
|
|
if ( skip > this->LineLength - maxlen )
|
|
{
|
|
skip = this->LineLength - maxlen;
|
|
for ( cc = skip-1; cc > 0; cc -- )
|
|
{
|
|
if ( ptr[cc] == ' ' || ptr[cc] == '\t' )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if ( cc != 0 )
|
|
{
|
|
skip = cc;
|
|
}
|
|
}
|
|
str.write(ptr, static_cast<kwsys_ios::streamsize>(skip));
|
|
str << kwsys_ios::endl;
|
|
ptr += skip;
|
|
len -= skip;
|
|
cnt ++;
|
|
}
|
|
}
|
|
/*
|
|
// This can help debugging help string
|
|
str << endl;
|
|
unsigned int cc;
|
|
for ( cc = 0; cc < this->LineLength; cc ++ )
|
|
{
|
|
str << cc % 10;
|
|
}
|
|
str << endl;
|
|
*/
|
|
this->Help = str.str();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
bool* variable, const kwsys_stl::string& value)
|
|
{
|
|
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
|
|
value == "TRUE" || value == "true" || value == "True" ||
|
|
value == "yes" || value == "Yes" || value == "YES" )
|
|
{
|
|
*variable = true;
|
|
}
|
|
else
|
|
{
|
|
*variable = false;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
int* variable, const kwsys_stl::string& value)
|
|
{
|
|
char* res = 0;
|
|
*variable = static_cast<int>(strtol(value.c_str(), &res, 10));
|
|
//if ( res && *res )
|
|
// {
|
|
// Can handle non-int
|
|
// }
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
double* variable, const kwsys_stl::string& value)
|
|
{
|
|
char* res = 0;
|
|
*variable = strtod(value.c_str(), &res);
|
|
//if ( res && *res )
|
|
// {
|
|
// Can handle non-double
|
|
// }
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
char** variable, const kwsys_stl::string& value)
|
|
{
|
|
if ( *variable )
|
|
{
|
|
delete [] *variable;
|
|
*variable = 0;
|
|
}
|
|
*variable = new char[ value.size() + 1 ];
|
|
strcpy(*variable, value.c_str());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
kwsys_stl::string* variable, const kwsys_stl::string& value)
|
|
{
|
|
*variable = value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value)
|
|
{
|
|
bool val = false;
|
|
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
|
|
value == "TRUE" || value == "true" || value == "True" ||
|
|
value == "yes" || value == "Yes" || value == "YES" )
|
|
{
|
|
val = true;
|
|
}
|
|
variable->push_back(val);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
kwsys_stl::vector<int>* variable, const kwsys_stl::string& value)
|
|
{
|
|
char* res = 0;
|
|
variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
|
|
//if ( res && *res )
|
|
// {
|
|
// Can handle non-int
|
|
// }
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
kwsys_stl::vector<double>* variable, const kwsys_stl::string& value)
|
|
{
|
|
char* res = 0;
|
|
variable->push_back(strtod(value.c_str(), &res));
|
|
//if ( res && *res )
|
|
// {
|
|
// Can handle non-int
|
|
// }
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value)
|
|
{
|
|
char* var = new char[ value.size() + 1 ];
|
|
strcpy(var, value.c_str());
|
|
variable->push_back(var);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void CommandLineArguments::PopulateVariable(
|
|
kwsys_stl::vector<kwsys_stl::string>* variable,
|
|
const kwsys_stl::string& value)
|
|
{
|
|
variable->push_back(value);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
|
|
const char* value)
|
|
{
|
|
// Call the callback
|
|
if ( cs->Callback )
|
|
{
|
|
if ( !cs->Callback(cs->Argument, value, cs->CallData) )
|
|
{
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
}
|
|
CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " << value);
|
|
if ( cs->Variable )
|
|
{
|
|
kwsys_stl::string var = "1";
|
|
if ( value )
|
|
{
|
|
var = value;
|
|
}
|
|
switch ( cs->VariableType )
|
|
{
|
|
case CommandLineArguments::INT_TYPE:
|
|
this->PopulateVariable(static_cast<int*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::DOUBLE_TYPE:
|
|
this->PopulateVariable(static_cast<double*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::STRING_TYPE:
|
|
this->PopulateVariable(static_cast<char**>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::STL_STRING_TYPE:
|
|
this->PopulateVariable(static_cast<kwsys_stl::string*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::BOOL_TYPE:
|
|
this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::VECTOR_BOOL_TYPE:
|
|
this->PopulateVariable(static_cast<kwsys_stl::vector<bool>*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::VECTOR_INT_TYPE:
|
|
this->PopulateVariable(static_cast<kwsys_stl::vector<int>*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::VECTOR_DOUBLE_TYPE:
|
|
this->PopulateVariable(static_cast<kwsys_stl::vector<double>*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::VECTOR_STRING_TYPE:
|
|
this->PopulateVariable(static_cast<kwsys_stl::vector<char*>*>(cs->Variable), var);
|
|
break;
|
|
case CommandLineArguments::VECTOR_STL_STRING_TYPE:
|
|
this->PopulateVariable(static_cast<kwsys_stl::vector<kwsys_stl::string>*>(cs->Variable), var);
|
|
break;
|
|
default:
|
|
kwsys_ios::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
|
|
this->Internals->LastArgument --;
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
} // namespace KWSYS_NAMESPACE
|