[PATCH setup 08/11] Factor out StringChoiceOption

Jon Turney jon.turney@dronecode.org.uk
Tue Aug 10 17:02:25 GMT 2021


Factor out logic for 'a string option which is one of a set of choices'
from CompactOsStringOption as StringChoiceOption.

v2:
Allow different behaviour for option without a choice, and option absent.

Future work: This doesn't say anything other that "Error during option
processing" if you've given an invalid choice string, or left it out
when it's required, because libgetopt++ doesn't output anything, just
returns success or failure after processing the command line arguments.
---
 io_stream_cygfile.cc                          | 52 +++++-------------
 libgetopt++/Makefile.am                       |  3 +-
 .../include/getopt++/StringChoiceOption.h     | 41 ++++++++++++++
 libgetopt++/src/StringChoiceOption.cc         | 54 +++++++++++++++++++
 4 files changed, 109 insertions(+), 41 deletions(-)
 create mode 100644 libgetopt++/include/getopt++/StringChoiceOption.h
 create mode 100644 libgetopt++/src/StringChoiceOption.cc

diff --git a/io_stream_cygfile.cc b/io_stream_cygfile.cc
index a9150e7..52ef735 100644
--- a/io_stream_cygfile.cc
+++ b/io_stream_cygfile.cc
@@ -20,7 +20,7 @@
 #include "mount.h"
 #include "compactos.h"
 
-#include "getopt++/StringOption.h"
+#include "getopt++/StringChoiceOption.h"
 
 #include <stdlib.h>
 #include <errno.h>
@@ -30,45 +30,17 @@
 #include "IOStreamProvider.h"
 #include "LogSingleton.h"
 
-/* Option '--compact-os ALGORITHM' */
-class CompactOsStringOption : public StringOption
-{
-public:
-  CompactOsStringOption ();
-  virtual Result Process (char const *optarg, int prefixIndex) /* override */;
-  operator int () const { return intval; }
-private:
-  int intval;
-};
-
-CompactOsStringOption::CompactOsStringOption ()
-: StringOption ("", '\0', "compact-os",
-    "Compress installed files with Compact OS "
-    "(xpress4k, xpress8k, xpress16k, lzx)", false),
-  intval (-1)
-{
-}
-
-Option::Result CompactOsStringOption::Process (char const *optarg, int prefixIndex)
-{
-  Result res = StringOption::Process (optarg, prefixIndex);
-  if (res != Ok)
-    return res;
-  const std::string& strval = *this;
-  if (strval == "xpress4k")
-    intval = FILE_PROVIDER_COMPRESSION_XPRESS4K;
-  else if (strval == "xpress8k")
-    intval = FILE_PROVIDER_COMPRESSION_XPRESS8K;
-  else if (strval == "xpress16k")
-    intval = FILE_PROVIDER_COMPRESSION_XPRESS16K;
-  else if (strval == "lzx")
-    intval = FILE_PROVIDER_COMPRESSION_LZX;
-  else
-    return Failed;
-  return Ok;
-}
-
-static CompactOsStringOption CompactOsOption;
+static StringChoiceOption::StringChoices algs({
+    {"xpress4k", FILE_PROVIDER_COMPRESSION_XPRESS4K},
+    {"xpress8k", FILE_PROVIDER_COMPRESSION_XPRESS8K},
+    {"xpress16k", FILE_PROVIDER_COMPRESSION_XPRESS16K},
+    {"lzx", FILE_PROVIDER_COMPRESSION_LZX},
+  });
+
+static StringChoiceOption CompactOsOption(algs,
+    '\0', "compact-os",
+    "Compress installed files with Compact OS (xpress4k, xpress8k, xpress16k, lzx)",
+    true, -1, FILE_PROVIDER_COMPRESSION_LZX);
 
 /* completely private iostream registration class */
 class CygFileProvider : public IOStreamProvider
diff --git a/libgetopt++/Makefile.am b/libgetopt++/Makefile.am
index 34dc6fd..c20c17d 100644
--- a/libgetopt++/Makefile.am
+++ b/libgetopt++/Makefile.am
@@ -26,7 +26,7 @@ TESTS = tests/OptionSet tests/optioniterator tests/BoolOptionTest
 
 libgetopt___la_SOURCES = src/GetOption.cc src/Option.cc src/BoolOption.cc \
 	src/OptionSet.cc \
-	src/StringArrayOption.cc src/StringOption.cc
+	src/StringArrayOption.cc src/StringChoiceOption.cc src/StringOption.cc
 
 libgetopt___la_LDFLAGS = -version-info 1:1:0 -no-undefined
 
@@ -36,6 +36,7 @@ getoptinclude_HEADERS = include/getopt++/Option.h \
   include/getopt++/GetOption.h \
   include/getopt++/OptionSet.h \
   include/getopt++/StringArrayOption.h \
+  include/getopt++/StringChoiceOption.h \
   include/getopt++/StringOption.h
 
 tests_testoption_SOURCES = tests/testoption.cc
diff --git a/libgetopt++/include/getopt++/StringChoiceOption.h b/libgetopt++/include/getopt++/StringChoiceOption.h
new file mode 100644
index 0000000..8800712
--- /dev/null
+++ b/libgetopt++/include/getopt++/StringChoiceOption.h
@@ -0,0 +1,41 @@
+/*
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ */
+
+#ifndef _STRINGCHOICEOPTION_H_
+#define _STRINGCHOICEOPTION_H_
+
+#include <vector>
+#include <getopt++/StringOption.h>
+
+class StringChoiceOption : public StringOption
+{
+public:
+  typedef std::vector<std::pair<const char *, int>> StringChoices;
+
+  StringChoiceOption(StringChoices choices,
+                     char shortopt, char const *longopt = 0,
+                     std::string const &shorthelp = std::string(),
+                     bool const optional = true,   // option without choice string is permitted
+                     int const defaultvalue = -1,  // value when option is absent
+                     int const impliedvalue = -1); // value when option is present without choice string
+
+  virtual ~ StringChoiceOption ();
+  virtual Result Process (char const *, int);
+  operator int () const { return intval; }
+
+private:
+  StringChoices choices;
+  int intval;
+  int _impliedvalue;
+};
+
+#endif // _STRINGCHOICEOPTION_H_
diff --git a/libgetopt++/src/StringChoiceOption.cc b/libgetopt++/src/StringChoiceOption.cc
new file mode 100644
index 0000000..185d56a
--- /dev/null
+++ b/libgetopt++/src/StringChoiceOption.cc
@@ -0,0 +1,54 @@
+/*
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ */
+
+#include <getopt++/StringChoiceOption.h>
+
+StringChoiceOption::StringChoiceOption (StringChoices _choices,
+                                        char shortopt,
+                                        char const *longopt,
+                                        std::string const &shorthelp,
+                                        bool const optional,
+                                        int const defaultvalue,
+                                        int const impliedvalue) :
+  StringOption ("", shortopt, longopt, shorthelp, optional),
+  choices(_choices), intval (defaultvalue), _impliedvalue(impliedvalue)
+{
+};
+
+StringChoiceOption::~ StringChoiceOption () {};
+
+Option::Result
+StringChoiceOption::Process (char const *optarg, int prefixIndex)
+{
+  Result res = StringOption::Process (optarg, prefixIndex);
+  if (res != Ok)
+    return res;
+
+  const std::string& strval = *this;
+  if (strval.empty())
+    {
+      intval = _impliedvalue;
+      return Ok;
+    }
+
+  for (StringChoiceOption::StringChoices::const_iterator i = choices.begin();
+       i != choices.end();
+       i++)
+    {
+      if (strval == i->first)
+        {
+          intval = i->second;
+          return Ok;
+        }
+    }
+
+  return Failed;
+}
-- 
2.32.0



More information about the Cygwin-apps mailing list