public inbox for cygwin-apps@cygwin.com
 help / color / mirror / Atom feed
From: Jon Turney <jon.turney@dronecode.org.uk>
To: cygwin-apps@cygwin.com
Cc: Jon Turney <jon.turney@dronecode.org.uk>
Subject: [PATCH setup 08/11] Factor out StringChoiceOption
Date: Tue, 10 Aug 2021 18:02:25 +0100	[thread overview]
Message-ID: <20210810170228.1690-9-jon.turney@dronecode.org.uk> (raw)
In-Reply-To: <20210810170228.1690-1-jon.turney@dronecode.org.uk>

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


  parent reply	other threads:[~2021-08-10 17:04 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-10 17:02 [PATCH setup 00/11] Add options to choose symlink type (v2) Jon Turney
2021-08-10 17:02 ` [PATCH setup 01/11] Add support for creating WSL symlinks Jon Turney
2021-08-10 17:02 ` [PATCH setup 02/11] Add support for creating native symlinks Jon Turney
2021-08-10 17:02 ` [PATCH setup 03/11] Factor out the iteration over archive files to install Jon Turney
2021-08-10 17:02 ` [PATCH setup 04/11] Add seek() method to archive and compress file classes Jon Turney
2021-08-10 17:02 ` [PATCH setup 05/11] Add separate symlink-creation phase when extracting archive Jon Turney
2021-08-10 17:02 ` [PATCH setup 06/11] Enable SeCreateSymbolicLink privilege Jon Turney
2021-08-11  8:46   ` Corinna Vinschen
2021-09-14 11:53     ` Jon Turney
2021-08-10 17:02 ` [PATCH setup 07/11] Add symlink capabilities to user-agent telemetry Jon Turney
2021-08-10 17:02 ` Jon Turney [this message]
2021-08-10 17:02 ` [PATCH setup 09/11] Add a command line option to choose symlink type used Jon Turney
2021-08-10 17:02 ` [PATCH setup 10/11] Propagate --symlink-type setting to post-install scripts Jon Turney
2021-08-10 17:02 ` [PATCH setup 11/11] Default symlink mode from CYGWIN env var Jon Turney
2021-09-14 11:53 ` [PATCH setup 00/11] Add options to choose symlink type (v2) Jon Turney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210810170228.1690-9-jon.turney@dronecode.org.uk \
    --to=jon.turney@dronecode.org.uk \
    --cc=cygwin-apps@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).