aboutsummaryrefslogtreecommitdiff
path: root/bbot/common-options.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bbot/common-options.cxx')
-rw-r--r--bbot/common-options.cxx740
1 files changed, 740 insertions, 0 deletions
diff --git a/bbot/common-options.cxx b/bbot/common-options.cxx
new file mode 100644
index 0000000..7f351e9
--- /dev/null
+++ b/bbot/common-options.cxx
@@ -0,0 +1,740 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bbot/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bbot/common-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bbot
+{
+ namespace cli
+ {
+ // unknown_option
+ //
+ unknown_option::
+ ~unknown_option () noexcept
+ {
+ }
+
+ void unknown_option::
+ print (::std::ostream& os) const
+ {
+ os << "unknown option '" << option ().c_str () << "'";
+ }
+
+ const char* unknown_option::
+ what () const noexcept
+ {
+ return "unknown option";
+ }
+
+ // unknown_argument
+ //
+ unknown_argument::
+ ~unknown_argument () noexcept
+ {
+ }
+
+ void unknown_argument::
+ print (::std::ostream& os) const
+ {
+ os << "unknown argument '" << argument ().c_str () << "'";
+ }
+
+ const char* unknown_argument::
+ what () const noexcept
+ {
+ return "unknown argument";
+ }
+
+ // missing_value
+ //
+ missing_value::
+ ~missing_value () noexcept
+ {
+ }
+
+ void missing_value::
+ print (::std::ostream& os) const
+ {
+ os << "missing value for option '" << option ().c_str () << "'";
+ }
+
+ const char* missing_value::
+ what () const noexcept
+ {
+ return "missing option value";
+ }
+
+ // invalid_value
+ //
+ invalid_value::
+ ~invalid_value () noexcept
+ {
+ }
+
+ void invalid_value::
+ print (::std::ostream& os) const
+ {
+ os << "invalid value '" << value ().c_str () << "' for option '"
+ << option ().c_str () << "'";
+
+ if (!message ().empty ())
+ os << ": " << message ().c_str ();
+ }
+
+ const char* invalid_value::
+ what () const noexcept
+ {
+ return "invalid option value";
+ }
+
+ // eos_reached
+ //
+ void eos_reached::
+ print (::std::ostream& os) const
+ {
+ os << what ();
+ }
+
+ const char* eos_reached::
+ what () const noexcept
+ {
+ return "end of argument stream reached";
+ }
+
+ // unexpected_group
+ //
+ unexpected_group::
+ ~unexpected_group () noexcept
+ {
+ }
+
+ void unexpected_group::
+ print (::std::ostream& os) const
+ {
+ os << "unexpected grouped argument '" << group_ << "' "
+ << "for argument '" << argument_ << "'";
+ }
+
+ const char* unexpected_group::
+ what () const noexcept
+ {
+ return "unexpected grouped argument";
+ }
+
+ // group_separator
+ //
+ group_separator::
+ ~group_separator () noexcept
+ {
+ }
+
+ void group_separator::
+ print (::std::ostream& os) const
+ {
+ bool ex (!expected_.empty ());
+ bool en (!encountered_.empty ());
+
+ if (ex)
+ {
+ os << "expected group separator '" << expected_ << "'";
+ if (en)
+ os << " instead of '" << encountered_ << "'";
+ }
+ else
+ os << "unexpected group separator '" << encountered_ << "'";
+
+ if (en)
+ os << ", use '\\" << encountered_ << "' to escape";
+ }
+
+ const char* group_separator::
+ what () const noexcept
+ {
+ bool ex (!expected_.empty ());
+ bool en (!encountered_.empty ());
+
+ return en
+ ? ex ? "wrong group separator" : "unexpected group separator"
+ : ex ? "expected group separator" : "";
+ }
+
+ // scanner
+ //
+ scanner::
+ ~scanner ()
+ {
+ }
+
+ // argv_scanner
+ //
+ bool argv_scanner::
+ more ()
+ {
+ return i_ < argc_;
+ }
+
+ const char* argv_scanner::
+ peek ()
+ {
+ if (i_ < argc_)
+ return argv_[i_];
+ else
+ throw eos_reached ();
+ }
+
+ const char* argv_scanner::
+ next ()
+ {
+ if (i_ < argc_)
+ {
+ const char* r (argv_[i_]);
+
+ if (erase_)
+ {
+ for (int i (i_ + 1); i < argc_; ++i)
+ argv_[i - 1] = argv_[i];
+
+ --argc_;
+ argv_[argc_] = 0;
+ }
+ else
+ ++i_;
+
+ ++start_position_;
+ return r;
+ }
+ else
+ throw eos_reached ();
+ }
+
+ void argv_scanner::
+ skip ()
+ {
+ if (i_ < argc_)
+ {
+ ++i_;
+ ++start_position_;
+ }
+ else
+ throw eos_reached ();
+ }
+
+ std::size_t argv_scanner::
+ position ()
+ {
+ return start_position_;
+ }
+
+ // vector_scanner
+ //
+ bool vector_scanner::
+ more ()
+ {
+ return i_ < v_.size ();
+ }
+
+ const char* vector_scanner::
+ peek ()
+ {
+ if (i_ < v_.size ())
+ return v_[i_].c_str ();
+ else
+ throw eos_reached ();
+ }
+
+ const char* vector_scanner::
+ next ()
+ {
+ if (i_ < v_.size ())
+ return v_[i_++].c_str ();
+ else
+ throw eos_reached ();
+ }
+
+ void vector_scanner::
+ skip ()
+ {
+ if (i_ < v_.size ())
+ ++i_;
+ else
+ throw eos_reached ();
+ }
+
+ std::size_t vector_scanner::
+ position ()
+ {
+ return start_position_ + i_;
+ }
+
+ // group_scanner
+ //
+ bool group_scanner::
+ more ()
+ {
+ // We don't want to call scan_group() here since that
+ // would invalidate references to previous arguments.
+ // But we do need to check that the previous group was
+ // handled.
+ //
+ if (state_ == scanned)
+ {
+ if (group_scan_.end () != group_.size ())
+ throw unexpected_group (arg_[i_][j_], group_scan_.next ());
+ }
+
+ return j_ != 0 || scan_.more ();
+ }
+
+ const char* group_scanner::
+ peek ()
+ {
+ if (state_ != peeked)
+ {
+ scan_group ();
+ state_ = peeked;
+ }
+
+ // Return unescaped.
+ return arg_[i_][j_ - 1].c_str ();
+ }
+
+ const char* group_scanner::
+ next ()
+ {
+ if (state_ != peeked)
+ scan_group ();
+ state_ = scanned;
+ // Return unescaped.
+ return arg_[i_][--j_].c_str ();
+ }
+
+ void group_scanner::
+ skip ()
+ {
+ if (state_ != peeked)
+ scan_group ();
+ state_ = skipped;
+ --j_;
+ }
+
+ std::size_t group_scanner::
+ position ()
+ {
+ return j_ == 0 ? scan_.position () : pos_ + (arg_[i_].size () - j_);
+ }
+
+ void group_scanner::
+ scan_group ()
+ {
+ // If the previous argument has been scanned, then make
+ // sure the group has been scanned (handled) as well.
+ //
+ if (state_ == scanned)
+ {
+ if (group_scan_.end () != group_.size ())
+ throw unexpected_group (arg_[i_][j_], group_scan_.next ());
+ }
+
+ // If we still have arguments in the pack, rewind the group.
+ //
+ if (j_ != 0)
+ {
+ group_scan_.reset ();
+ return;
+ }
+
+ i_ += (i_ == 0 ? 1 : -1);
+ group_.clear ();
+ group_scan_.reset ();
+ pos_ = scan_.position ();
+
+ // Note: using group_ won't cover empty groups and using
+ // j_ won't cover single-argument packs.
+ //
+ bool group (false), pack (false);
+
+ do
+ {
+ const char* a (scan_.next ());
+ size_t i (*a == '\\' ? 1 : 0);
+ separator s (sense (a + i));
+
+ if (s == none || i != 0)
+ {
+ if (arg_[i_].size () != 1)
+ arg_[i_].resize (1);
+
+ arg_[i_][0] = a + (s != none ? i : 0);
+ j_ = 1;
+ break;
+ }
+
+ // Start of a leading group for the next argument or
+ // argument pack. We will only know which once we see
+ // the closing separator.
+ //
+ if (s != open)
+ throw group_separator (a, "");
+
+ size_t n (group_.size ());
+
+ // Scan the group until the closing separator.
+ //
+ s = none;
+ while (s == none && scan_.more ())
+ {
+ a = scan_.next ();
+ i = (*a == '\\' ? 1 : 0);
+ s = sense (a + i);
+
+ if (s == none || i != 0)
+ {
+ group_.push_back (a + (s != none ? i : 0));
+ s = none;
+ }
+ }
+
+ if (s == close)
+ {
+ size_t m (group_.size ());
+
+ j_ = m - n;
+ if (j_ == 0)
+ throw group_separator ("{", "");
+
+ if (arg_[i_].size () != j_)
+ arg_[i_].resize (j_);
+
+ // Move from group_ to arg_. Add in reverse for ease
+ // of iteration.
+ //
+ for (size_t j (0); j != j_; ++j)
+ arg_[i_][j] = group_[m - j - 1];
+ group_.resize (n);
+
+ pack = true;
+ break;
+ }
+ else if (s == close_plus)
+ group = true;
+ else
+ throw group_separator ((s != none ? a : ""), "}+");
+ }
+ while (scan_.more ());
+
+ // Handle the case where we have seen the leading group
+ // but there are no more arguments.
+ //
+ if (group && j_ == 0)
+ throw group_separator ("{", "");
+
+ // Handle trailing groups, if any.
+ //
+ while (scan_.more ())
+ {
+ const char* a (scan_.peek ());
+ size_t i (*a == '\\' ? 1 : 0);
+ separator s (sense (a + i));
+
+ // Next argument, argument pack, or leading group.
+ //
+ if (s == none || s == open || i != 0)
+ break;
+
+ if (s != open_plus)
+ throw group_separator (a, "");
+
+ group = true;
+
+ // Scan the group until the closing separator.
+ //
+ scan_.next ();
+ s = none;
+ while (s == none && scan_.more ())
+ {
+ a = scan_.next ();
+ i = (*a == '\\' ? 1 : 0);
+ s = sense (a + i);
+
+ if (s == none || i != 0)
+ {
+ group_.push_back (a + (s != none ? i : 0));
+ s = none;
+ }
+ }
+
+ if (s != close)
+ throw group_separator ((s != none ? a : ""), "}");
+ }
+
+ // Handle the case where we have seen the argument pack
+ // without leading or trailing group.
+ //
+ if (pack && !group)
+ throw group_separator ("{", "");
+ }
+
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ const char* v (s.next ());
+
+ if (std::strcmp (v, "1") == 0 ||
+ std::strcmp (v, "true") == 0 ||
+ std::strcmp (v, "TRUE") == 0 ||
+ std::strcmp (v, "True") == 0)
+ x = true;
+ else if (std::strcmp (v, "0") == 0 ||
+ std::strcmp (v, "false") == 0 ||
+ std::strcmp (v, "FALSE") == 0 ||
+ std::strcmp (v, "False") == 0)
+ x = false;
+ else
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <typename X>
+ struct parser<std::pair<X, std::size_t> >
+ {
+ static void
+ parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s)
+ {
+ x.second = s.position ();
+ parser<X>::parse (x.first, xs, s);
+ }
+ };
+
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+ };
+
+ template <typename X, typename C>
+ struct parser<std::set<X, C> >
+ {
+ static void
+ parse (std::set<X, C>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+ };
+
+ template <typename K, typename V, typename C>
+ struct parser<std::map<K, V, C> >
+ {
+ static void
+ parse (std::map<K, V, C>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <typename K, typename V, typename C>
+ struct parser<std::multimap<K, V, C> >
+ {
+ static void
+ parse (std::multimap<K, V, C>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m.insert (typename std::multimap<K, V, C>::value_type (k, v));
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, bool X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ s.next ();
+ x.*M = true;
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+}
+
+#include <map>
+
+namespace bbot
+{
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+