aboutsummaryrefslogtreecommitdiff
path: root/odb/option-parsers.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/option-parsers.hxx')
-rw-r--r--odb/option-parsers.hxx201
1 files changed, 156 insertions, 45 deletions
diff --git a/odb/option-parsers.hxx b/odb/option-parsers.hxx
index a8fc1f5..a974a7c 100644
--- a/odb/option-parsers.hxx
+++ b/odb/option-parsers.hxx
@@ -5,6 +5,7 @@
#ifndef ODB_OPTION_PARSERS_HXX
#define ODB_OPTION_PARSERS_HXX
+#include <vector>
#include <sstream>
#include <odb/option-types.hxx>
@@ -12,72 +13,183 @@
namespace cli
{
+ // Return true if there is a database prefix.
+ //
+ template <typename V>
+ bool
+ parse_option_value (std::string const& o, std::string const& ov,
+ database& k, V& v)
+ {
+ bool r (false);
+ std::string::size_type p = ov.find (':');
+
+ std::string vstr;
+ if (p != std::string::npos)
+ {
+ std::string kstr (ov, 0, p);
+
+ // See if this prefix resolves to the database name. If not,
+ // assume there is no prefix.
+ //
+ std::istringstream ks (kstr);
+
+ if (ks >> k && ks.eof ())
+ {
+ r = true;
+ vstr.assign (ov, p + 1, std::string::npos);
+ }
+ }
+
+ if (!r)
+ vstr = ov; // Use the whole value.
+
+ if (!vstr.empty ())
+ {
+ std::istringstream vs (vstr);
+
+ if (!(vs >> v && vs.eof ()))
+ throw invalid_value (o, ov);
+ }
+ else
+ v = V ();
+
+ return r;
+ }
+
+ // Specialization for std::string.
+ //
+ bool
+ parse_option_value (std::string const&, std::string const& ov,
+ database& k, std::string& v)
+ {
+ bool r (false);
+ std::string::size_type p = ov.find (':');
+
+ if (p != std::string::npos)
+ {
+ std::string kstr (ov, 0, p);
+
+ // See if this prefix resolves to the database name. If not,
+ // assume there is no prefix.
+ //
+ std::istringstream ks (kstr);
+
+ if (ks >> k && ks.eof ())
+ {
+ r = true;
+ v.assign (ov, p + 1, std::string::npos);
+ }
+ }
+
+ if (!r)
+ v = ov; // Use the whole value.
+
+ return r;
+ }
+
template <typename V>
struct parser<database_map<V> >
{
+ typedef database_map<V> map;
+
static void
- parse (database_map<V>& m, bool& xs, scanner& s)
+ parse (map& m, bool& xs, scanner& s)
{
- typedef database_map<V> map;
-
xs = true;
std::string o (s.next ());
if (s.more ())
{
- std::string ov (s.next ());
- std::string::size_type p = ov.find (':');
+ database k;
+ V v;
- if (p != std::string::npos)
+ if (parse_option_value (o, s.next (), k, v))
+ m[k] = v; // Override any old value.
+ else
{
- std::string kstr (ov, 0, p);
- std::string vstr (ov, p + 1);
-
- // See if this prefix resolves to the database name. If not,
- // assume there is no prefix.
+ // No database prefix is specified which means it applies to
+ // all the databases. We also don't want to override database-
+ // specific values, so use insert().
//
- database k;
- std::istringstream ks (kstr);
+ m.insert (typename map::value_type (database::common, v));
+ m.insert (typename map::value_type (database::mssql, v));
+ m.insert (typename map::value_type (database::mysql, v));
+ m.insert (typename map::value_type (database::oracle, v));
+ m.insert (typename map::value_type (database::pgsql, v));
+ m.insert (typename map::value_type (database::sqlite, v));
+ }
+ }
+ else
+ throw missing_value (o);
+ }
+ };
- if (ks >> k && ks.eof ())
- {
- V v = V ();
+ template <typename V>
+ struct parser<database_map<std::vector<V> > >
+ {
+ typedef database_map<std::vector<V> > map;
- if (!vstr.empty ())
- {
- std::istringstream vs (vstr);
+ static void
+ parse (map& m, bool& xs, scanner& s)
+ {
+ xs = true;
+ std::string o (s.next ());
- if (!(vs >> v && vs.eof ()))
- throw invalid_value (o, ov);
- }
+ if (s.more ())
+ {
+ database k;
+ V v;
- m[k] = v; // Override any old value.
- return;
- }
+ if (parse_option_value (o, s.next (), k, v))
+ m[k].push_back (v);
+ else
+ {
+ // No database prefix is specified which means it applies to
+ // all the databases.
+ //
+ m[database::common].push_back (v);
+ m[database::mssql].push_back (v);
+ m[database::mysql].push_back (v);
+ m[database::oracle].push_back (v);
+ m[database::pgsql].push_back (v);
+ m[database::sqlite].push_back (v);
}
+ }
+ else
+ throw missing_value (o);
+ }
+ };
- // No database prefix is specified which means it applies to
- // all the databases.
- //
- V v = V ();
+ template <typename V>
+ struct parser<database_map<std::set<V> > >
+ {
+ typedef database_map<std::set<V> > map;
- if (!ov.empty ())
- {
- std::istringstream vs (ov);
+ static void
+ parse (map& m, bool& xs, scanner& s)
+ {
+ xs = true;
+ std::string o (s.next ());
- if (!(vs >> v && vs.eof ()))
- throw invalid_value (o, ov);
- }
+ if (s.more ())
+ {
+ database k;
+ V v;
- // We don't want to override database-specific values, so use
- // insert().
- //
- m.insert (typename map::value_type (database::common, v));
- m.insert (typename map::value_type (database::mssql, v));
- m.insert (typename map::value_type (database::mysql, v));
- m.insert (typename map::value_type (database::oracle, v));
- m.insert (typename map::value_type (database::pgsql, v));
- m.insert (typename map::value_type (database::sqlite, v));
+ if (parse_option_value (o, s.next (), k, v))
+ m[k].insert (v);
+ else
+ {
+ // No database prefix is specified which means it applies to
+ // all the databases.
+ //
+ m[database::common].insert (v);
+ m[database::mssql].insert (v);
+ m[database::mysql].insert (v);
+ m[database::oracle].insert (v);
+ m[database::pgsql].insert (v);
+ m[database::sqlite].insert (v);
+ }
}
else
throw missing_value (o);
@@ -85,5 +197,4 @@ namespace cli
};
}
-
#endif // ODB_OPTION_PARSERS_HXX