summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/Options.cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2006-08-25 07:58:01 +0000
committerMichi Henning <michi@zeroc.com>2006-08-25 07:58:01 +0000
commita3443505bc1f80a5264d31c79bd6120e10da815c (patch)
treed850eedf58d7a5a50a0314d9aa96eb0cd2cf2c50 /cpp/src/IceUtil/Options.cpp
parentuse zero-copy API for primitive sequence types (diff)
downloadice-a3443505bc1f80a5264d31c79bd6120e10da815c.tar.bz2
ice-a3443505bc1f80a5264d31c79bd6120e10da815c.tar.xz
ice-a3443505bc1f80a5264d31c79bd6120e10da815c.zip
Bug 1325.
Diffstat (limited to 'cpp/src/IceUtil/Options.cpp')
-rwxr-xr-xcpp/src/IceUtil/Options.cpp252
1 files changed, 186 insertions, 66 deletions
diff --git a/cpp/src/IceUtil/Options.cpp b/cpp/src/IceUtil/Options.cpp
index ccbf4b462e3..93ca0973ee4 100755
--- a/cpp/src/IceUtil/Options.cpp
+++ b/cpp/src/IceUtil/Options.cpp
@@ -9,6 +9,7 @@
#include <IceUtil/Options.h>
#include <iostream>
+#include <set>
using namespace std;
@@ -86,11 +87,9 @@ IceUtil::Options::addOpt(const string& shortOpt, const string& longOpt, ArgType
checkArgs(shortOpt, longOpt, at == NeedArg, dflt);
- addValidOpt(shortOpt, ShortOpt, at, dflt, rt);
- addValidOpt(longOpt, LongOpt, at, dflt, rt);
+ addValidOpt(shortOpt, longOpt, at, dflt, rt);
}
-
//
// Split a command line into argv-style arguments, applying
// bash quoting rules. The return value is the arguments
@@ -113,6 +112,7 @@ IceUtil::Options::split(const string& line)
}
string::size_type end = line.find_last_not_of(IFS);
assert(end != string::npos);
+
string l(line, start, end - start + 1);
vector<string> vec;
@@ -539,29 +539,34 @@ IceUtil::Options::parse(const vector<string>& args)
pos = checkOpt(opt, LongOpt);
- if(p != string::npos)
+ if(pos->second->repeat == NoRepeat)
{
- if(pos->second.arg == NoArg && p != args[i].size() - 1)
+ set<string>::iterator seenPos = seenNonRepeatableOpts.find(opt);
+ if(seenPos != seenNonRepeatableOpts.end())
{
- string err = "`";
- err += args[i];
- err += "': option does not take an argument";
+ string err = "`--";
+ err += opt + ":' option cannot be repeated";
throw BadOpt(err);
}
- setOpt(opt, args[i].substr(p + 1), pos->second.repeat);
- argDone = true;
+ seenNonRepeatableOpts.insert(seenPos, opt);
+ string synonym = getSynonym(opt);
+ if(!synonym.empty())
+ {
+ seenNonRepeatableOpts.insert(synonym);
+ }
}
- if(pos->second.repeat == NoRepeat)
+ if(p != string::npos)
{
- set<string>::iterator seenPos = seenNonRepeatableOpts.find(opt);
- if(seenPos != seenNonRepeatableOpts.end())
+ if(pos->second->arg == NoArg && p != args[i].size() - 1)
{
- string err = "`--";
- err += opt + ":' option cannot be repeated";
+ string err = "`";
+ err += args[i];
+ err += "': option does not take an argument";
throw BadOpt(err);
}
- seenNonRepeatableOpts.insert(seenPos, opt);
+ setOpt(opt, "", args[i].substr(p + 1), pos->second->repeat);
+ argDone = true;
}
}
else if(!args[i].empty() && args[i][0] == '-')
@@ -574,25 +579,31 @@ IceUtil::Options::parse(const vector<string>& args)
opt.clear();
opt.push_back(args[i][p]);
pos = checkOpt(opt, ShortOpt);
- if(pos->second.arg == NeedArg && p != args[i].size() - 1)
+
+ if(pos->second->repeat == NoRepeat)
{
- string optArg = args[i].substr(p + 1);
- setOpt(opt, optArg, pos->second.repeat);
- argDone = true;
- break;
+ set<string>::iterator seenPos = seenNonRepeatableOpts.find(opt);
+ if(seenPos != seenNonRepeatableOpts.end())
+ {
+ string err = "`-";
+ err += opt + ":' option cannot be repeated";
+ throw BadOpt(err);
+ }
+ seenNonRepeatableOpts.insert(seenPos, opt);
+ string synonym = getSynonym(opt);
+ if(!synonym.empty())
+ {
+ seenNonRepeatableOpts.insert(synonym);
+ }
}
- }
- if(pos->second.repeat == NoRepeat)
- {
- set<string>::iterator seenPos = seenNonRepeatableOpts.find(opt);
- if(seenPos != seenNonRepeatableOpts.end())
+ if(pos->second->arg == NeedArg && p != args[i].size() - 1)
{
- string err = "`-";
- err += opt + ":' option cannot be repeated";
- throw BadOpt(err);
+ string optArg = args[i].substr(p + 1);
+ setOpt(opt, "", optArg, pos->second->repeat);
+ argDone = true;
+ break;
}
- seenNonRepeatableOpts.insert(seenPos, opt);
}
}
else
@@ -606,7 +617,7 @@ IceUtil::Options::parse(const vector<string>& args)
if(!argDone)
{
- if(pos->second.arg == NeedArg) // Need an argument that is separated by whitespace.
+ if(pos->second->arg == NeedArg) // Need an argument that is separated by whitespace.
{
if(i == args.size() - 1)
{
@@ -619,15 +630,17 @@ IceUtil::Options::parse(const vector<string>& args)
err += "' option requires an argument";
throw BadOpt(err);
}
- setOpt(opt, args[++i], pos->second.repeat);
+ setOpt(opt, "", args[++i], pos->second->repeat);
}
else
{
- setOpt(opt, "1", pos->second.repeat);
+ setOpt(opt, "", "1", pos->second->repeat);
}
}
}
+ _synonyms.clear(); // Don't need the contents anymore.
+
while(i < args.size())
{
result.push_back(args[i++]);
@@ -663,7 +676,7 @@ IceUtil::Options::isSet(const string& opt) const
}
ValidOpts::const_iterator pos = checkOptIsValid(opt);
- return pos->second.repeat == NoRepeat ? _opts.find(opt) != _opts.end() : _ropts.find(opt) != _ropts.end();
+ return pos->second->repeat == NoRepeat ? _opts.find(opt) != _opts.end() : _ropts.find(opt) != _ropts.end();
}
string
@@ -678,10 +691,10 @@ IceUtil::Options::optArg(const string& opt) const
ValidOpts::const_iterator pos = checkOptHasArg(opt);
- if(pos->second.repeat == Repeat)
+ if(pos->second->repeat == Repeat)
{
string err = "`-";
- if(pos->second.length == LongOpt)
+ if(pos->second->length == LongOpt)
{
err.push_back('-');
}
@@ -690,12 +703,12 @@ IceUtil::Options::optArg(const string& opt) const
throw APIError(err);
}
- map<string, string>::const_iterator p = _opts.find(opt);
+ Opts::const_iterator p = _opts.find(opt);
if(p == _opts.end())
{
return "";
}
- return p->second;
+ return p->second->val;
}
vector<string>
@@ -710,10 +723,10 @@ IceUtil::Options::argVec(const string& opt) const
ValidOpts::const_iterator pos = checkOptHasArg(opt);
- if(pos->second.repeat == NoRepeat)
+ if(pos->second->repeat == NoRepeat)
{
string err = "`-";
- if(pos->second.length == LongOpt)
+ if(pos->second->length == LongOpt)
{
err.push_back('-');
}
@@ -721,37 +734,50 @@ IceUtil::Options::argVec(const string& opt) const
throw APIError(err);
}
- map<string, vector<string> >::const_iterator p = _ropts.find(opt);
- return p == _ropts.end() ? vector<string>() : p->second;
+ ROpts::const_iterator p = _ropts.find(opt);
+ return p == _ropts.end() ? vector<string>() : p->second->vals;
}
void
-IceUtil::Options::addValidOpt(const string& opt, LengthType lt, ArgType at, const string& dflt, RepeatType rt)
+IceUtil::Options::addValidOpt(const string& shortOpt, const string& longOpt,
+ ArgType at, const string& dflt, RepeatType rt)
{
- if(opt.empty())
+ if(!shortOpt.empty() && _validOpts.find(shortOpt) != _validOpts.end())
{
- return;
+ string err = "`";
+ err += shortOpt;
+ err += "': duplicate option";
+ throw APIError(err);
}
-
- ValidOpts::iterator pos = _validOpts.find(opt);
- if(pos != _validOpts.end())
+ if(!longOpt.empty() && _validOpts.find(longOpt) != _validOpts.end())
{
string err = "`";
- err += opt;
+ err += longOpt;
err += "': duplicate option";
throw APIError(err);
}
- OptionDetails od;
- od.length = lt;
- od.arg = at;
- od.repeat = rt;
+ ODPtr odp = new OptionDetails;
+ odp->arg = at;
+ odp->repeat = rt;
+ odp->hasDefault = !dflt.empty();
+
+ if(!shortOpt.empty())
+ {
+ odp->length = ShortOpt;
+ _validOpts[shortOpt] = odp;
+ }
+ if(!longOpt.empty())
+ {
+ odp->length = LongOpt;
+ _validOpts[longOpt] = odp;
+ }
- _validOpts.insert(pos, ValidOpts::value_type(opt, od));
+ updateSynonyms(shortOpt, longOpt);
if(at == NeedArg && !dflt.empty())
{
- setOpt(opt, dflt, rt);
+ setOpt(shortOpt, longOpt, dflt, rt);
}
}
@@ -774,25 +800,102 @@ IceUtil::Options::checkOpt(const string& opt, LengthType lt)
}
void
-IceUtil::Options::setOpt(const string& opt, const string& val, RepeatType rt)
+IceUtil::Options::setOpt(const string& opt1, const string& opt2, const string& val, RepeatType rt)
+{
+ //
+ // opt1 and opt2 (short and long opt) can't both be empty.
+ //
+ assert(!(opt1.empty() && opt2.empty()));
+
+ if(rt == NoRepeat)
+ {
+ setNonRepeatingOpt(opt1, val);
+ setNonRepeatingOpt(opt2, val);
+ }
+ else
+ {
+ setRepeatingOpt(opt1, val);
+ setRepeatingOpt(opt2, val);
+ }
+}
+
+void
+IceUtil::Options::setNonRepeatingOpt(const string& opt, const string& val)
+{
+ if(opt.empty())
+ {
+ return;
+ }
+
+ assert(_opts.find(opt) == _opts.end());
+
+ OValPtr ovp = new OptionValue;
+ ovp->val = val;
+ _opts[opt] = ovp;
+
+ const string synonym = getSynonym(opt);
+ if(!synonym.empty())
+ {
+ _opts[synonym] = ovp;
+ }
+}
+
+void
+IceUtil::Options::setRepeatingOpt(const string& opt, const string& val)
{
- if(rt == Repeat)
+ if(opt.empty())
+ {
+ return;
+ }
+
+ ValidOpts::const_iterator vpos = _validOpts.find(opt);
+ assert(vpos != _validOpts.end());
+
+ ROpts::iterator pos = _ropts.find(opt);
+ const string synonym = getSynonym(opt);
+ ROpts::iterator spos = _ropts.find(synonym);
+
+ if(pos != _ropts.end())
+ {
+ assert(_validOpts.find(opt) != _validOpts.end());
+ assert(vpos->second->repeat == Repeat);
+
+ _ropts[opt] = pos->second;
+ if(vpos->second->hasDefault && pos->second->vals.size() == 1)
+ {
+ pos->second->vals[0] = val;
+ vpos->second->hasDefault = false;
+ }
+ else
+ {
+ pos->second->vals.push_back(val);
+ }
+ }
+ else if(spos != _ropts.end())
{
- ROpts::iterator pos = _ropts.find(opt);
- if(pos != _ropts.end())
+ assert(_validOpts.find(synonym) != _validOpts.end());
+ assert(_validOpts.find(synonym)->second->repeat == Repeat);
+
+ _ropts[synonym] = spos->second;
+ if(vpos->second->hasDefault && spos->second->vals.size() == 1)
{
- pos->second.push_back(val);
+ spos->second->vals[0] = val;
+ vpos->second->hasDefault = false;
}
else
{
- vector<string> vec;
- vec.push_back(val);
- _ropts.insert(pos, ROpts::value_type(opt, vec));
+ spos->second->vals.push_back(val);
}
}
else
{
- _opts[opt] = val;
+ OVecPtr ovp = new OptionValueVector;
+ ovp->vals.push_back(val);
+ _ropts[opt] = ovp;
+ if(!synonym.empty())
+ {
+ _ropts[synonym] = ovp;
+ }
}
}
@@ -814,10 +917,10 @@ IceUtil::Options::ValidOpts::const_iterator
IceUtil::Options::checkOptHasArg(const string& opt) const
{
ValidOpts::const_iterator pos = checkOptIsValid(opt);
- if(pos->second.arg == NoArg)
+ if(pos->second->arg == NoArg)
{
string err = "`-";
- if(pos->second.length == LongOpt)
+ if(pos->second->length == LongOpt)
{
err.push_back('-');
}
@@ -827,3 +930,20 @@ IceUtil::Options::checkOptHasArg(const string& opt) const
}
return pos;
}
+
+void
+IceUtil::Options::updateSynonyms(const ::std::string& shortOpt, const ::std::string& longOpt)
+{
+ if(!shortOpt.empty() && !longOpt.empty())
+ {
+ _synonyms[shortOpt] = longOpt;
+ _synonyms[longOpt] = shortOpt;
+ }
+}
+
+string
+IceUtil::Options::getSynonym(const ::std::string& optName) const
+{
+ Synonyms::const_iterator pos = _synonyms.find(optName);
+ return pos != _synonyms.end() ? pos->second : "";
+}