Several of Scylla's options (in db/config.hh) have the type "string_map"
(unordered_map<sstring, sstring>). The intent was such options could get
multiple "key=value" settings. However, this never actually worked correctly,
and had two bugs:
1. Any option name with a space in it would fail, for example:
$ scylla --logger-log-level 'BatchLog Manager=info'
error: the argument ('BatchLog Manager=info') for option '--level'
is invalid
2. Trying to set multiple entries in the map did *not* work. For example,
$ scylla --logger-log-level a=info --logger-log-level b=info
error: option '--level' cannot be specified more than once
The problem is that boost::program_options does not actually understand
unordered_map<sstring, sstring>: It doesn't know it is a container (it
only recognizes std::vector) so it doesn't allow multiple options, and
it doesn't know how to convert a string to it, so it uses boost::lexical_cast
which for strings, cuts the string at a space...
The solution is to write a custom "validate()" function overload, which
boost::program_options uses to validate (and consume) options into object
types it doesn't understand by default. Getting this function in the right
place in the code was a difficult exercise, but here it is, a working
implementation :-) And it fixes the above two bugs.
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>