123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- /*=========================================================================
- Library: CTK
-
- Copyright (c) 2010 Kitware Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.commontk.org/LICENSE
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- =========================================================================*/
- /*=========================================================================
-
- Program: ParaView
- Module: $RCSfile: vtkCommandOptions.h,v $
- Copyright (c) Kitware, Inc.
- All rights reserved.
- See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 notice for more information.
- =========================================================================*/
- // Qt includes
- #include <QDebug>
- #include <QString>
- #include <QLatin1String>
- #include <QSettings>
- #include <QHash>
- #include <QList>
- #include <QPointer>
- #include <QStringList>
- // CTK includes
- #include <ctkUtils.h>
- #include "ctkVTKCommandOptions.h"
- // VTKSYS includes
- #include <vtksys/CommandLineArguments.hxx>
- // --------------------------------------------------------------------------
- class ctkVTKCommandOptionsPrivate: public ctkPrivate<ctkVTKCommandOptions>
- {
- public:
- typedef ctkVTKCommandOptionsPrivate Self;
- ctkVTKCommandOptionsPrivate();
- ~ctkVTKCommandOptionsPrivate();
- void cleanArgcArgv();
- /// Callback executed when an unknown arguments is parsed
- static int unknownArgumentHandler(const char* argument, void* call_data);
- /// If case the --ignore-rest flag has been specified, this method will
- /// catch the first argument parsed and add it to the ignoredArguments list.
- /// If not, it will call the virtual method 'wrongArgument(const char* argument)'
- bool checkForIgnoreRestFlag(const char* argument);
- /// Callback executed when a deprecated arguments is parsed
- static int deprecatedArgumentHandler(const char* argument, const char* value, void* call_data);
-
- /// Since vtksys::CommandLineArguments will only update char*, returns
- /// a valid char* pointer that it could use.
- char** mapQStringPtrToCharPtr(QString* qStringPtr);
- /// Since vtksys::CommandLineArguments will only update std::vector<std::string>*, returns
- /// a valid std::vector<std::string>* pointer that it could use.
- std::vector<std::string>* mapQStringListPtrToStringVectorPtr(QStringList* qStringListPtr);
- /// If required, sync the updated char* with the corresponding QString*
- void syncQStringPtrWithCharPtr();
- /// If required, sync the updated std::vector<std::string> with the corresponding QStringList*
- void syncQStringListPtrWithStringVectorPtr();
- vtksys::CommandLineArguments CMD;
- QString UnknownArgument;
- QString ErrorMessage;
- bool HelpSelected;
- bool DisableSettings;
- bool IgnoreRest;
- QStringList IgnoredArguments;
- int Argc;
- char** Argv;
- QPointer<QSettings> Settings;
- int ProcessType; // GUI, Batch, Daemon, ...
-
- QHash<QString*, char**> QStringPointerToCharPointerMap;
- QHash<QStringList*, std::vector<std::string>*> QStringListPointerToStringVectorPointerMap;
- };
- //-----------------------------------------------------------------------------
- // ctkVTKCommandOptionsPrivate methods
- // --------------------------------------------------------------------------
- ctkVTKCommandOptionsPrivate::ctkVTKCommandOptionsPrivate()
- {
- this->CMD.SetUnknownArgumentCallback(ctkVTKCommandOptionsPrivate::unknownArgumentHandler);
- this->CMD.SetClientData(this);
- this->Argc = 0;
- this->Argv = 0;
- this->HelpSelected = false;
- this->DisableSettings = false;
- this->IgnoreRest = false;
- }
- // --------------------------------------------------------------------------
- ctkVTKCommandOptionsPrivate::~ctkVTKCommandOptionsPrivate()
- {
- this->cleanArgcArgv();
- foreach (QString* qStringPtr, this->QStringPointerToCharPointerMap.keys())
- {
- delete this->QStringPointerToCharPointerMap[qStringPtr];
- }
- foreach (QStringList* qStringListPtr, this->QStringListPointerToStringVectorPointerMap.keys())
- {
- delete this->QStringListPointerToStringVectorPointerMap[qStringListPtr];
- }
- }
- // --------------------------------------------------------------------------
- void ctkVTKCommandOptionsPrivate::cleanArgcArgv()
- {
- int cc;
- if (this->Argv)
- {
- for (cc = 0; cc < this->Argc; cc++)
- {
- delete [] this->Argv[cc];
- }
- delete [] this->Argv;
- this->Argv = 0;
- }
- }
- //----------------------------------------------------------------------------
- int ctkVTKCommandOptionsPrivate::unknownArgumentHandler(const char* argument,
- void* call_data)
- {
- ctkVTKCommandOptionsPrivate* self =
- static_cast<ctkVTKCommandOptionsPrivate*>(call_data);
- if (self)
- {
- self->UnknownArgument = QString::fromLatin1(argument);
- return self->checkForIgnoreRestFlag(argument);
- }
- return 0;
- }
- //----------------------------------------------------------------------------
- bool ctkVTKCommandOptionsPrivate::checkForIgnoreRestFlag(const char* argument)
- {
- CTK_P(ctkVTKCommandOptions);
- if (this->IgnoreRest)
- {
- this->IgnoredArguments << QLatin1String(argument);
- return true;
- }
- else
- {
- return p->wrongArgument(argument);
- }
- }
- //----------------------------------------------------------------------------
- int ctkVTKCommandOptionsPrivate::deprecatedArgumentHandler(const char* argument,
- const char* , void* call_data)
- {
- //qDebug() << "UnknownArgumentHandler: " << argument;
- ctkVTKCommandOptionsPrivate* self = static_cast<ctkVTKCommandOptionsPrivate*>(call_data);
- if (self)
- {
- return self->ctk_p()->deprecatedArgument(argument);
- }
- return 0;
- }
- // --------------------------------------------------------------------------
- char** ctkVTKCommandOptionsPrivate::mapQStringPtrToCharPtr(QString* qStringPtr)
- {
- Q_ASSERT(!this->QStringPointerToCharPointerMap.contains(qStringPtr));
- char** charPtr = new char*; // Create a new pointer
- *charPtr = 0; // Initialize to 0
- this->QStringPointerToCharPointerMap[qStringPtr] = charPtr;
- return charPtr;
- }
- // --------------------------------------------------------------------------
- std::vector<std::string>*
- ctkVTKCommandOptionsPrivate::mapQStringListPtrToStringVectorPtr(QStringList* qStringListPtr)
- {
- Q_ASSERT(!this->QStringListPointerToStringVectorPointerMap.contains(qStringListPtr));
- std::vector<std::string>* vectorPtr = new std::vector<std::string>(); // Create a new vector
- this->QStringListPointerToStringVectorPointerMap[qStringListPtr] = vectorPtr;
- return vectorPtr;
- }
- // --------------------------------------------------------------------------
- void ctkVTKCommandOptionsPrivate::syncQStringPtrWithCharPtr()
- {
- foreach(QString* qStringPtr, this->QStringPointerToCharPointerMap.keys())
- {
- char** charPtr = this->QStringPointerToCharPointerMap[qStringPtr];
- Q_ASSERT(charPtr);
- // Update QString only if the content pointed by charPtr is valid
- if (*charPtr)
- {
- qStringPtr->clear();
- qStringPtr->append(QLatin1String(*charPtr));
- }
- }
- }
- // --------------------------------------------------------------------------
- void ctkVTKCommandOptionsPrivate::syncQStringListPtrWithStringVectorPtr()
- {
- foreach(QStringList* qStringListPtr, this->QStringListPointerToStringVectorPointerMap.keys())
- {
- std::vector<std::string>* vectorPtr =
- this->QStringListPointerToStringVectorPointerMap[qStringListPtr];
- Q_ASSERT(vectorPtr);
- // Update QString only if vectorPtr is not empty
- if (vectorPtr->size() > 0)
- {
- qStringListPtr->clear();
- QStringList convertedVector;
- ctk::stlVectorToQList(*vectorPtr, convertedVector);
- qStringListPtr->append(convertedVector);
- }
- }
- }
- //-----------------------------------------------------------------------------
- // ctkVTKCommandOptions methods
- // --------------------------------------------------------------------------
- ctkVTKCommandOptions::ctkVTKCommandOptions(QSettings* _settings)
- {
- CTK_INIT_PRIVATE(ctkVTKCommandOptions);
- Q_ASSERT(_settings);
- CTK_D(ctkVTKCommandOptions);
- d->Settings = _settings;
- }
- //----------------------------------------------------------------------------
- ctkVTKCommandOptions::~ctkVTKCommandOptions()
- {
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::printAdditionalInfo()
- {
- CTK_D(ctkVTKCommandOptions);
- qDebug() << "ctkVTKCommandOptions:" << this << endl
- << " HelpSelected:" << this->helpSelected() << endl
- << " DisableSettings:" << d->DisableSettings << endl
- << " IgnoreRest:" << d->IgnoreRest << endl
- << " IgnoredArguments:" << d->IgnoredArguments;
- }
- //----------------------------------------------------------------------------
- CTK_GET_CXX(ctkVTKCommandOptions, QString, errorMessage, ErrorMessage);
- CTK_GET_CXX(ctkVTKCommandOptions, QString, unknownArgument, UnknownArgument);
- CTK_GET_CXX(ctkVTKCommandOptions, bool, helpSelected, HelpSelected);
- CTK_GET_CXX(ctkVTKCommandOptions, bool, disableSettings, DisableSettings);
- CTK_GET_CXX(ctkVTKCommandOptions, QSettings*, settings, Settings);
- CTK_GET_CXX(ctkVTKCommandOptions, bool, ignoreRest, IgnoreRest);
- CTK_GET_CXX(ctkVTKCommandOptions, QStringList, ignoredArguments, IgnoredArguments);
- //----------------------------------------------------------------------------
- CTK_GET_CXX(ctkVTKCommandOptions, int, processType, ProcessType);
- CTK_SET_CXX(ctkVTKCommandOptions, int, setProcessType, ProcessType);
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::initialize()
- {
- }
- //----------------------------------------------------------------------------
- QString ctkVTKCommandOptions::help()
- {
- CTK_D(ctkVTKCommandOptions);
- d->CMD.SetLineLength(300);
- return QLatin1String(d->CMD.GetHelp());
- }
- //----------------------------------------------------------------------------
- bool ctkVTKCommandOptions::postProcess(int, const char* const*)
- {
- return true;
- }
- //----------------------------------------------------------------------------
- bool ctkVTKCommandOptions::parse(int argc, const char* const argv[])
- {
- CTK_D(ctkVTKCommandOptions);
- d->CMD.Initialize(argc, argv);
- this->initialize();
- this->addBooleanArgument("--help", "/?", &d->HelpSelected,
- "Displays available command line arguments.");
- this->addBooleanArgument("--disable-settings", 0, &d->DisableSettings,
- "Start application ignoring user settings.");
- this->addBooleanArgument("--ignore-rest", "--", &d->IgnoreRest,
- "Ignores the rest of the labeled arguments following this flag.");
- // Get options from the command line
- bool res1 = d->CMD.Parse();
- bool res2 = this->postProcess(argc, argv);
- //qDebug() << "Res1:" << res1 << ", Res2:" << res2;
- d->cleanArgcArgv();
- d->CMD.GetRemainingArguments(&d->Argc, &d->Argv);
- if (d->DisableSettings)
- {
- this->disableCurrentSettings();
- }
- d->syncQStringPtrWithCharPtr();
- d->syncQStringListPtrWithStringVectorPtr();
- // Since CommandLineArguments include arg0 in the list
- // of remaining arguments, let's create a temporary list and remove it.
- QStringList _remaingingArguments = this->remainingArguments();
- _remaingingArguments.removeFirst();
- // Update ignored arguments list
- d->IgnoredArguments << _remaingingArguments;
-
- return res1 && res2;
- }
- //----------------------------------------------------------------------------
- QStringList ctkVTKCommandOptions::remainingArguments()
- {
- CTK_D(ctkVTKCommandOptions);
- QStringList tmp;
- for(int i=0; i < d->Argc; ++i)
- {
- tmp << d->Argv[i];
- }
- return tmp;
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::remainingArguments(int* argc, char*** argv)
- {
- CTK_D(ctkVTKCommandOptions);
- *argc = d->Argc;
- *argv = d->Argv;
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::addDeprecatedArgument(const char* longarg, const char* shortarg,
- const char* arghelp, int type)
- {
- CTK_D(ctkVTKCommandOptions);
- // If it is for settings or not for the current process do nothing
- if((type & ctkVTKCommandOptions::QSETTINGS_ONLY) ||
- !(type & d->ProcessType || type == ctkVTKCommandOptions::ALL))
- {
- return;
- }
-
- // Add a callback for the deprecated argument handling
- d->CMD.AddCallback(longarg, vtksys::CommandLineArguments::NO_ARGUMENT,
- ctkVTKCommandOptionsPrivate::deprecatedArgumentHandler, this, arghelp);
- if(shortarg)
- {
- d->CMD.AddCallback(shortarg, vtksys::CommandLineArguments::NO_ARGUMENT,
- ctkVTKCommandOptionsPrivate::deprecatedArgumentHandler, this, arghelp);
- }
- }
- //----------------------------------------------------------------------------
- bool ctkVTKCommandOptions::deprecatedArgument(const char* argument)
- {
- CTK_D(ctkVTKCommandOptions);
- d->ErrorMessage = QString(" %1").arg(d->CMD.GetHelp(argument));
- return false;
- }
- //----------------------------------------------------------------------------
- bool ctkVTKCommandOptions::wrongArgument(const char* argument)
- {
- Q_UNUSED(argument);
- return false;
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::addBooleanArgument(const char* longarg, const char* shortarg,
- bool* var, const char* arghelp,
- bool defaultValue, int type)
- {
- CTK_D(ctkVTKCommandOptions);
- // Attempt to read from settings only if longarg is different from '--disable-settings'.
- if (QLatin1String(longarg) != "--disable-settings")
- {
- *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toBool();
-
- if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
- {
- return;
- }
- }
- // If the process type matches then add the argument to the command line
- if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
- {
- d->CMD.AddBooleanArgument(longarg, var, arghelp);
- if (shortarg)
- {
- d->CMD.AddBooleanArgument(shortarg, var, longarg);
- }
- }
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::addArgument(const char* longarg, const char* shortarg, QString* var,
- const char* arghelp, const QString& defaultValue, int type)
- {
- CTK_D(ctkVTKCommandOptions);
- *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toString();
-
- if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
- {
- return;
- }
-
- if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
- {
- char ** charstar = d->mapQStringPtrToCharPtr(var);
- typedef vtksys::CommandLineArguments argT;
- d->CMD.AddArgument(longarg, argT::EQUAL_ARGUMENT, charstar, arghelp);
- if ( shortarg )
- {
- d->CMD.AddArgument(shortarg, argT::EQUAL_ARGUMENT, charstar, longarg);
- }
- }
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::addArgument(const char* longarg, const char* shortarg,
- QStringList* var, const char* arghelp,
- const QStringList& defaultValue, int type)
- {
- CTK_D(ctkVTKCommandOptions);
- *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toStringList();
-
- if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
- {
- return;
- }
-
- if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
- {
- std::vector<std::string>* vectorPtr = d->mapQStringListPtrToStringVectorPtr(var);
- typedef vtksys::CommandLineArguments argT;
- d->CMD.AddArgument(longarg, argT::MULTI_ARGUMENT, vectorPtr, arghelp);
- if (shortarg)
- {
- d->CMD.AddArgument(shortarg, argT::MULTI_ARGUMENT, vectorPtr, longarg);
- }
- }
- }
- //----------------------------------------------------------------------------
- void ctkVTKCommandOptions::addArgument(const char* longarg, const char* shortarg, int* var,
- const char* arghelp, int defaultValue, int type)
- {
- CTK_D(ctkVTKCommandOptions);
- *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toInt();
-
- if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
- {
- return;
- }
-
- if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
- {
- typedef vtksys::CommandLineArguments argT;
- d->CMD.AddArgument(longarg, argT::EQUAL_ARGUMENT, var, arghelp);
- if (shortarg)
- {
- d->CMD.AddArgument(shortarg, argT::EQUAL_ARGUMENT, var, longarg);
- }
- }
- }
- //----------------------------------------------------------------------------
- int ctkVTKCommandOptions::indexOfLastParsedArgument()
- {
- CTK_D(ctkVTKCommandOptions);
- return d->CMD.GetLastArgument();
- }
|