Pārlūkot izejas kodu

ENH: commandlineparser - Added StrictMode property

Can be used to teach the parser to stop parsing the arguments and
return False when an unknown argument is encountered.

By default StrictMode is disabled
Jean-Christophe Fillion-Robin 15 gadi atpakaļ
vecāks
revīzija
353dc9155d

+ 47 - 0
Libs/Core/Testing/Cpp/ctkCommandLineParserTest1.cpp

@@ -702,5 +702,52 @@ int ctkCommandLineParserTest1(int, char*[])
     return EXIT_FAILURE;
   }
 
+  // Test16 - Check if strictMode works
+  settings.clear();
+
+  ctkCommandLineParser parser16(&settings);
+  parser16.enableSettings();
+  parser16.addArgument("--test-bool", "", QVariant::Bool);
+  parser16.setStrictModeEnabled(true);
+
+  QStringList arguments16;
+  arguments16 << "ctkCommandLineParserTest1";
+  arguments16 << "--test-bool";
+
+  // parseArguments should NOT fail
+  ok = false;
+  parsedArgs = parser16.parseArguments(arguments16, &ok);
+  if (!ok)
+  {
+    qCritical() << "Test16-1 - parsing arguments failed.";
+    return EXIT_FAILURE;
+  }
+
+  // Since two identical arguments are provided, parseArguments should fail
+  arguments16.clear();
+  arguments16 << "ctkCommandLineParserTest1";
+  arguments16 << "--test-bool";
+  arguments16 << "--test-bool";
+  ok = false;
+  parsedArgs = parser16.parseArguments(arguments16, &ok);
+  if (ok)
+  {
+    qCritical() << "Test16-2 - parsing arguments should fail.";
+    return EXIT_FAILURE;
+  }
+
+  // Since an unknown argument is provided, parseArguments should fail
+  arguments16.clear();
+  arguments16 << "ctkCommandLineParserTest1";
+  arguments16 << "--test-bool";
+  arguments16 << "test-bool";
+  ok = false;
+  parsedArgs = parser16.parseArguments(arguments16, &ok);
+  if (ok)
+  {
+    qCritical() << "Test16-3 - parsing arguments should fail.";
+    return EXIT_FAILURE;
+  }
+
   return EXIT_SUCCESS;
 }

+ 31 - 2
Libs/Core/ctkCommandLineParser.cpp

@@ -197,7 +197,7 @@ class ctkCommandLineParser::ctkInternal
 public:
   ctkInternal(QSettings* settings)
     : Debug(false), FieldWidth(0), UseQSettings(false),
-      Settings(settings), MergeSettings(true)
+      Settings(settings), MergeSettings(true), StrictMode(false)
   {}
 
   ~ctkInternal() { qDeleteAll(ArgumentDescriptionList); }
@@ -221,6 +221,7 @@ public:
   QString     DisableQSettingsLongArg;
   QString     DisableQSettingsShortArg;
   bool        MergeSettings;
+  bool        StrictMode;
 };
 
 // --------------------------------------------------------------------------
@@ -284,6 +285,7 @@ QHash<QString, QVariant> ctkCommandLineParser::parseArguments(const QStringList&
     }
   }
 
+  bool error = false;
   bool ignoreRest = false;
   bool useSettings = this->Internal->UseQSettings;
   CommandLineParserArgumentDescription * currentArgDesc = 0;
@@ -305,6 +307,12 @@ QHash<QString, QVariant> ctkCommandLineParser::parseArguments(const QStringList&
     if (!(argument.startsWith(this->Internal->LongPrefix)
       || argument.startsWith(this->Internal->ShortPrefix)))
     {
+      if (this->Internal->StrictMode)
+        {
+        this->Internal->ErrorString = QString("Unknown argument %1").arg(argument);
+        error = true;
+        break;
+        }
       this->Internal->UnparsedArguments << argument;
       continue;
     }
@@ -312,6 +320,12 @@ QHash<QString, QVariant> ctkCommandLineParser::parseArguments(const QStringList&
     // Skip if argument has already been parsed ...
     if (this->Internal->ProcessedArguments.contains(argument))
       {
+      if (this->Internal->StrictMode)
+        {
+        this->Internal->ErrorString = QString("Argument %1 already processed !").arg(argument);
+        error = true;
+        break;
+        }
       qDebug() << "Skipping argument" << argument << " - Already processed !";
       continue;
       }
@@ -430,11 +444,20 @@ QHash<QString, QVariant> ctkCommandLineParser::parseArguments(const QStringList&
       }
     else
       {
+      if (this->Internal->StrictMode)
+        {
+        this->Internal->ErrorString = QString("Unknown argument %1").arg(argument);
+        error = true;
+        break;
+        }
       this->Internal->UnparsedArguments << argument;
       }
     }
 
-  if (ok) *ok = true;
+  if (ok)
+    {
+    *ok = !error;
+    }
 
   QSettings* settings = 0;
   if (this->Internal->UseQSettings && useSettings)
@@ -725,3 +748,9 @@ void ctkCommandLineParser::setArgumentPrefix(const QString& longPrefix, const QS
   this->Internal->ShortPrefix = shortPrefix;
 }
 
+// --------------------------------------------------------------------------
+void ctkCommandLineParser::setStrictModeEnabled(bool strictMode)
+{
+  this->Internal->StrictMode = strictMode;
+}
+

+ 9 - 0
Libs/Core/ctkCommandLineParser.h

@@ -360,6 +360,15 @@ public:
    */
   bool settingsEnabled() const;
 
+
+  /**
+    * Can be used to teach the parser to stop parsing the arguments and return False when
+    * an unknown argument is encountered. By default <code>StrictMode</code> is disabled.
+    *
+    * @see parseArguments(const QStringList &, bool*)
+    */
+  void setStrictModeEnabled(bool strictMode);
+
 private:
   class ctkInternal;
   ctkInternal * Internal;