| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 | 
							
- // Qt includes 
 
- #include <QHash>
 
- #include <QStringList>
 
- #include <QTextStream>
 
- #include <QDebug>
 
- // CTK includes
 
- #include "ctkCommandLineParser.h"
 
- namespace
 
- {
 
- class CommandLineParserArgumentDescriptionBase
 
- {
 
- public:
 
-   CommandLineParserArgumentDescriptionBase(
 
-     const char* longArg, const char* shortArg, const QString& argHelp, bool ignoreRest)
 
-     {
 
-     this->LongArg = QLatin1String(longArg);
 
-     this->ShortArg = QLatin1String(shortArg);
 
-     this->ArgHelp = argHelp;
 
-     this->IgnoreRest = ignoreRest;
 
-     this->NumberOfParametersToProcess = 0;
 
-     }
 
-   virtual ~CommandLineParserArgumentDescriptionBase(){}
 
-   virtual bool addParameter(const QString& value) = 0;
 
-   QString helpText(int fieldWidth, const char charPad);
 
-   QString LongArg;
 
-   QString ShortArg;
 
-   QString ArgHelp;
 
-   bool    IgnoreRest;
 
-   int     NumberOfParametersToProcess;
 
-   QString RegularExpression;
 
-   QString ExactMatchFailedMessage;
 
-   QString ArgumentType;
 
- };
 
- // --------------------------------------------------------------------------
 
- QString CommandLineParserArgumentDescriptionBase::helpText(int fieldWidth, const char charPad)
 
- {
 
-   QString text;
 
-   QTextStream stream(&text);
 
-   stream.setFieldAlignment(QTextStream::AlignLeft);
 
-   stream.setPadChar(charPad);
 
-   if (this->LongArg.isEmpty() && !this->ArgHelp.isEmpty())
 
-     {
 
-     stream.setFieldWidth(fieldWidth);
 
-     }
 
-   if (!this->ShortArg.isEmpty())
 
-     {
 
-     stream  << QString("  %1").arg(this->ShortArg);
 
-     if(!this->LongArg.isEmpty())
 
-       {
 
-       stream << "\n";
 
-       }
 
-     }
 
-   if (!this->LongArg.isEmpty())
 
-     {
 
-     if(!this->ArgHelp.isEmpty())
 
-       {
 
-       stream.setFieldWidth(fieldWidth);
 
-       }
 
-     stream  << QString("  %1").arg(this->LongArg);
 
-     }
 
-   stream.setFieldWidth(0);
 
-   stream << this->ArgHelp << "\n";
 
-   return text;
 
- }
 
- #define CommandLineParserArgumentDescription_class(_NAME, _TYPE,                        \
 
-                                                    _NUMBEROFPARAMTOPROCESS,             \
 
-                                                    _REGEXP, _EXACTMACTHERRORMSG)        \
 
-   class CommandLineParser##_NAME##ArgumentDescription:                                  \
 
-     public CommandLineParserArgumentDescriptionBase                                     \
 
-   {                                                                                     \
 
-   public:                                                                               \
 
-     CommandLineParser##_NAME##ArgumentDescription(                                      \
 
-       const char* longArg, const char* shortArg, _TYPE * variable,                      \
 
-       const QString& argHelp, const _TYPE& defaultValue,                                \
 
-       bool ignoreRest):                                                                 \
 
-       CommandLineParserArgumentDescriptionBase(longArg , shortArg, argHelp, ignoreRest) \
 
-       {                                                                                 \
 
-       this->Variable = variable;                                                        \
 
-       this->DefaultValue = defaultValue;                                                \
 
-       this->NumberOfParametersToProcess = _NUMBEROFPARAMTOPROCESS;                      \
 
-       this->RegularExpression = _REGEXP;                                                \
 
-       this->ArgumentType = #_TYPE;                                                      \
 
-       }                                                                                 \
 
-     virtual ~ CommandLineParser##_NAME##ArgumentDescription(){}                         \
 
-      virtual bool addParameter(const QString& value);                                   \
 
-     _TYPE* Variable;                                                                    \
 
-     _TYPE DefaultValue;                                                                 \
 
-   };
 
- CommandLineParserArgumentDescription_class(String, QString, 1, ".*", "");
 
- CommandLineParserArgumentDescription_class(Boolean, bool, 0, "", "");
 
- CommandLineParserArgumentDescription_class(StringList, QStringList, -1, ".*", "");
 
- CommandLineParserArgumentDescription_class(Integer, int, 1, "-?[0-9]+",
 
-                                            "A negative or positive integer is expected.");
 
- #undef CommandLineParserArgumentDescription_class
 
- // --------------------------------------------------------------------------
 
- bool CommandLineParserStringArgumentDescription::addParameter(const QString& value)
 
- {
 
-   // Validate value
 
-   QRegExp regexp(this->RegularExpression);
 
-   if (!regexp.exactMatch(value))
 
-     {
 
-     return false;
 
-     }
 
-   (*this->Variable).clear();
 
-   (*this->Variable).append(value);
 
-   return true;
 
- }
 
- // --------------------------------------------------------------------------
 
- bool CommandLineParserBooleanArgumentDescription::addParameter(const QString& value)
 
- {
 
-   *this->Variable = (value == "true");
 
-   return true;
 
- }
 
- // --------------------------------------------------------------------------
 
- bool CommandLineParserStringListArgumentDescription::addParameter(const QString& value)
 
- {
 
-   // Validate value
 
-   QRegExp regexp(this->RegularExpression);
 
-   if (!regexp.exactMatch(value))
 
-     {
 
-     return false;
 
-     }
 
-   *this->Variable << value;
 
-   return true;
 
- }
 
- // --------------------------------------------------------------------------
 
- bool CommandLineParserIntegerArgumentDescription::addParameter(const QString& value)
 
- {
 
-   // Validate value
 
-   QRegExp regexp(this->RegularExpression);
 
-   if (!regexp.exactMatch(value))
 
-     {
 
-     return false;
 
-     }
 
-   *this->Variable = value.toInt();
 
-   return true;
 
- }
 
- }
 
- // --------------------------------------------------------------------------
 
- // ctkCommandLineParser::ctkInternal class
 
- // --------------------------------------------------------------------------
 
- class ctkCommandLineParser::ctkInternal
 
- {
 
- public:
 
-   ctkInternal():Debug(false),FieldWidth(0){}
 
-   
 
-   CommandLineParserArgumentDescriptionBase* argumentDescription(const QString& argument);
 
-   
 
-   QList<CommandLineParserArgumentDescriptionBase*>          ArgumentDescriptionList;
 
-   QHash<QString, CommandLineParserArgumentDescriptionBase*> ArgNameToArgumentDescriptionMap;
 
-   
 
-   #define ctkCommandLineParser_ctkInternal_declare_map(_NAME) \
 
-     QHash<QString, CommandLineParser##_NAME##ArgumentDescription*>       \
 
-       LongArgTo##_NAME##ArgumentDescriptionMap;                          \
 
-     QHash<QString, CommandLineParser##_NAME##ArgumentDescription*>       \
 
-       ShortArgTo##_NAME##ArgumentDescriptionMap;
 
-   
 
-   ctkCommandLineParser_ctkInternal_declare_map(String);
 
-   ctkCommandLineParser_ctkInternal_declare_map(Boolean);
 
-   ctkCommandLineParser_ctkInternal_declare_map(StringList);
 
-   ctkCommandLineParser_ctkInternal_declare_map(Integer);
 
-   
 
-   #undef ctkCommandLineParser_ctkInternal_declare_map
 
-   
 
-   QStringList UnparsedArguments; 
 
-   QStringList ProcessedArguments;
 
-   QString     ErrorString;
 
-   bool        Debug;
 
-   int         FieldWidth;
 
- };
 
- // --------------------------------------------------------------------------
 
- // ctkCommandLineParser::ctkInternal methods
 
- // --------------------------------------------------------------------------
 
- CommandLineParserArgumentDescriptionBase* 
 
-   ctkCommandLineParser::ctkInternal::argumentDescription(const QString& argument)
 
- {
 
-   if (this->ArgNameToArgumentDescriptionMap.contains(argument))
 
-     {
 
-     return this->ArgNameToArgumentDescriptionMap[argument];
 
-     }
 
-   return 0;
 
- }
 
- // --------------------------------------------------------------------------
 
- // ctkCommandLineParser methods
 
- // --------------------------------------------------------------------------
 
- ctkCommandLineParser::ctkCommandLineParser()
 
- {
 
-   this->Internal = new ctkInternal();
 
- }
 
- // --------------------------------------------------------------------------
 
- ctkCommandLineParser::~ctkCommandLineParser()
 
- {
 
-   delete this->Internal;
 
- }
 
- // --------------------------------------------------------------------------
 
- bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
 
- {
 
-   // Reset
 
-   this->Internal->UnparsedArguments.clear();
 
-   this->Internal->ProcessedArguments.clear();
 
-   this->Internal->ErrorString.clear();
 
-   bool ignoreRest = false;
 
-   CommandLineParserArgumentDescriptionBase * currentArgDesc = 0;
 
-   for(int i = 1; i < arguments.size(); ++i)
 
-     {
 
-     QString argument = arguments.at(i);
 
-     if (this->Internal->Debug) { qDebug() << "Processing" << argument; }
 
-     // should argument be ignored ?
 
-     if (ignoreRest)
 
-       {
 
-       this->Internal->UnparsedArguments << argument;
 
-       continue;
 
-       }
 
-     // Skip if argument has already been parsed ...
 
-     if (this->Internal->ProcessedArguments.contains(argument))
 
-       {
 
-       qDebug() << "Skipping argument" << argument << " - Already processed !";
 
-       continue;
 
-       }
 
-     // Retrieve corresponding argument description
 
-     currentArgDesc = this->Internal->argumentDescription(argument);
 
-     // Is there a corresponding argument description ?
 
-     if (currentArgDesc)
 
-       {
 
-       this->Internal->ProcessedArguments << currentArgDesc->ShortArg << currentArgDesc->LongArg;
 
-       int numberOfParametersToProcess = currentArgDesc->NumberOfParametersToProcess;
 
-       ignoreRest = currentArgDesc->IgnoreRest;
 
-       // Is the number of parameters associated with the argument being processed known ?
 
-       if (numberOfParametersToProcess == 0)
 
-         {
 
-         currentArgDesc->addParameter("true");
 
-         }
 
-       else if (numberOfParametersToProcess > 0)
 
-         {
 
-         QString missingParameterError =
 
-             "Argument %1 has %2 value(s) associated whereas exacly %3 are expected.";
 
-         for(int j=1; j <= numberOfParametersToProcess; ++j)
 
-           {
 
-           if (i + j >= arguments.size())
 
-             {
 
-             this->Internal->ErrorString = 
 
-                 missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
 
-             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
 
-             return false;
 
-             }
 
-           QString parameter = arguments.at(i + j);
 
-           if (this->Internal->Debug)
 
-             {
 
-             qDebug() << "Processing parameter" << j << ", value:" << parameter;
 
-             }
 
-           if (this->argumentAdded(parameter))
 
-             {
 
-             this->Internal->ErrorString =
 
-                 missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
 
-             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
 
-             return false;
 
-             }
 
-           if (!currentArgDesc->addParameter(parameter))
 
-             {
 
-             this->Internal->ErrorString = QString(
 
-                 "Value(s) associated with argument %1 are incorrect. %2").
 
-                 arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
 
-             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
 
-             return false;
 
-             }
 
-           }
 
-         // Update main loop increment
 
-         i = i + numberOfParametersToProcess;
 
-         }
 
-       else if (numberOfParametersToProcess == -1)
 
-         {
 
-         if (this->Internal->Debug)
 
-           {
 
-           qDebug() << "Proccessing StringList ...";
 
-           }
 
-         int j = 1;
 
-         while(j + i < arguments.size())
 
-           {
 
-           if (this->argumentAdded(arguments.at(j + i)))
 
-             {
 
-             if (this->Internal->Debug)
 
-               {
 
-               qDebug() << "No more parameter for" << argument;
 
-               }
 
-             break;
 
-             }
 
-           QString parameter = arguments.at(j + i);
 
-           if (this->Internal->Debug)
 
-             {
 
-             qDebug() << "Processing parameter" << j << ", value:" << parameter;
 
-             }
 
-           if (!currentArgDesc->addParameter(parameter))
 
-             {
 
-             this->Internal->ErrorString = QString(
 
-                 "Value(s) associated with argument %1 are incorrect. %2").
 
-                 arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
 
-             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
 
-             return false;
 
-             }
 
-           j++;
 
-           }
 
-         // Update main loop increment
 
-         i = i + j;
 
-         }
 
-       }
 
-     else
 
-       {
 
-       this->Internal->UnparsedArguments << argument;
 
-       }
 
-     }
 
-   return true;
 
- }
 
- // -------------------------------------------------------------------------
 
- QString ctkCommandLineParser::errorString()
 
- {
 
-   return this->Internal->ErrorString;
 
- }
 
- // -------------------------------------------------------------------------
 
- const QStringList& ctkCommandLineParser::unparsedArguments()
 
- {
 
-   return this->Internal->UnparsedArguments;
 
- }
 
- // -------------------------------------------------------------------------
 
- #define ctkCommandLineParser_addArgument_cxx_core(_NAME, _TYPE)                 \
 
-   /* Make sure it's not already added */                                                   \
 
-   bool added = this->Internal->LongArgTo##_NAME##ArgumentDescriptionMap.contains(longarg); \
 
-   Q_ASSERT(!added);                                                                        \
 
-   if (added) { return; }                                                                   \
 
-                                                                                            \
 
-   added = this->Internal->ShortArgTo##_NAME##ArgumentDescriptionMap.contains(shortarg);    \
 
-   Q_ASSERT(!added);                                                                        \
 
-   if (added) { return; }                                                                   \
 
-                                                                                            \
 
-   CommandLineParser##_NAME##ArgumentDescription * argDesc =                                \
 
-     new CommandLineParser##_NAME##ArgumentDescription(longarg, shortarg, var,              \
 
-                                                       argHelp, defaultValue, ignoreRest);  \
 
-                                                                                            \
 
-   Q_ASSERT(!(longarg == 0 && shortarg == 0));                                              \
 
-   if (longarg == 0 && shortarg == 0) { return; }                                           \
 
-   if (longarg != 0)                                                                        \
 
-     {                                                                                      \
 
-     this->Internal->LongArgTo##_NAME##ArgumentDescriptionMap[longarg] = argDesc;           \
 
-     int argWidth = QString(longarg).length() + 7;                                          \
 
-     if (argWidth > this->Internal->FieldWidth)                                             \
 
-       {                                                                                    \
 
-       this->Internal->FieldWidth = argWidth;                                               \
 
-       }                                                                                    \
 
-     }                                                                                      \
 
-   if (shortarg != 0)                                                                       \
 
-     {                                                                                      \
 
-     this->Internal->ShortArgTo##_NAME##ArgumentDescriptionMap[shortarg] = argDesc;         \
 
-     int argWidth = QString(shortarg).length() + 7;                                         \
 
-     if (argWidth > this->Internal->FieldWidth)                                             \
 
-       {                                                                                    \
 
-       this->Internal->FieldWidth = argWidth;                                               \
 
-       }                                                                                    \
 
-     }                                                                                      \
 
-   this->Internal->ArgNameToArgumentDescriptionMap[longarg] = argDesc;                      \
 
-   this->Internal->ArgNameToArgumentDescriptionMap[shortarg] = argDesc;                     \
 
-   this->Internal->ArgumentDescriptionList << argDesc;
 
-   // -------------------------------------------------------------------------
 
-   #define ctkCommandLineParser_addArgument_cxx(_NAME, _TYPE)                        \
 
-     void ctkCommandLineParser::add##_NAME##Argument(const char* longarg,            \
 
-       const char* shortarg, _TYPE* var, const QString& argHelp, const _TYPE& defaultValue,     \
 
-       bool ignoreRest)                                                                         \
 
-     {                                                                                          \
 
-     ctkCommandLineParser_addArgument_cxx_core(_NAME, _TYPE);                        \
 
-     }
 
-   // -------------------------------------------------------------------------
 
-   #define ctkCommandLineParser_addArgument_cxx_without_ignore_rest(_NAME, _TYPE)    \
 
-     void ctkCommandLineParser::add##_NAME##Argument(const char* longarg,            \
 
-       const char* shortarg, _TYPE* var, const QString& argHelp, const _TYPE& defaultValue)     \
 
-     {                                                                                          \
 
-     bool ignoreRest = false;                                                                   \
 
-     ctkCommandLineParser_addArgument_cxx_core(_NAME, _TYPE);                        \
 
-     }
 
- // --------------------------------------------------------------------------
 
- ctkCommandLineParser_addArgument_cxx(String, QString);
 
- ctkCommandLineParser_addArgument_cxx(Boolean, bool);
 
- ctkCommandLineParser_addArgument_cxx_without_ignore_rest(StringList, QStringList);
 
- ctkCommandLineParser_addArgument_cxx(Integer, int);
 
- #undef ctkCommandLineParser_addArgument_cxx
 
- // --------------------------------------------------------------------------
 
- bool ctkCommandLineParser::setExactMatchRegularExpression(
 
-     const QString& argument, const QString& expression, const QString& exactMatchFailedMessage)
 
- {
 
-   CommandLineParserArgumentDescriptionBase * argDesc =
 
-       this->Internal->argumentDescription(argument);
 
-   if (!argDesc)
 
-     {
 
-     return false;
 
-     }
 
-   if (argDesc->ArgumentType == "bool")
 
-     {
 
-     return false;
 
-     }
 
-   argDesc->RegularExpression = expression;
 
-   argDesc->ExactMatchFailedMessage = exactMatchFailedMessage;
 
-   return true;
 
- }
 
- // --------------------------------------------------------------------------
 
- QString ctkCommandLineParser::helpText(const char charPad)
 
- {
 
-   QString text;
 
-   QTextStream stream(&text);
 
-   // Loop over argument descriptions
 
-   foreach(CommandLineParserArgumentDescriptionBase* argDesc,
 
-           this->Internal->ArgumentDescriptionList)
 
-     {
 
-     stream << argDesc->helpText(this->Internal->FieldWidth, charPad);
 
-     }
 
-   return text;
 
- }
 
- // --------------------------------------------------------------------------
 
- bool ctkCommandLineParser::argumentAdded(const QString& argument)
 
- {
 
-   return this->Internal->ArgNameToArgumentDescriptionMap.contains(argument);
 
- }
 
- // --------------------------------------------------------------------------
 
- bool ctkCommandLineParser::argumentParsed(const QString& argument)
 
- {
 
-   return this->Internal->ProcessedArguments.contains(argument);
 
- }
 
 
  |