aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-06-22 21:25:45 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-06-22 21:25:45 +0100
commit250954caec217fea30d097277fd877accb57d475 (patch)
tree8ca0a3f989a396b881502c0706bca324443c7b6b
parenta9c7b3713a0d96786f76b7efb22c1f7090d9c417 (diff)
downloadpaludis-250954caec217fea30d097277fd877accb57d475.tar.gz
paludis-250954caec217fea30d097277fd877accb57d475.tar.xz
Warn if an --option is specified multiple times
-rw-r--r--paludis/args/args_handler.cc14
-rw-r--r--paludis/args/args_option.cc2
-rw-r--r--paludis/args/args_option.hh32
-rw-r--r--paludis/args/args_visitor.cc40
-rw-r--r--paludis/args/args_visitor.hh3
-rw-r--r--src/clients/cave/cmd_fix_linkage.cc6
-rw-r--r--src/clients/cave/cmd_import.cc2
-rw-r--r--src/clients/cave/cmd_purge.cc2
-rw-r--r--src/clients/cave/cmd_sync.cc2
-rw-r--r--src/clients/cave/resolve_cmdline.cc6
10 files changed, 78 insertions, 31 deletions
diff --git a/paludis/args/args_handler.cc b/paludis/args/args_handler.cc
index a1e9939..c5734f5 100644
--- a/paludis/args/args_handler.cc
+++ b/paludis/args/args_handler.cc
@@ -24,6 +24,7 @@
#include <paludis/util/system.hh>
#include <paludis/util/join.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/iterator_funcs.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
@@ -37,6 +38,7 @@
#include <sstream>
#include <list>
#include <map>
+#include <set>
using namespace paludis;
using namespace paludis::args;
@@ -197,6 +199,9 @@ ArgsHandler::run(
args.push_back(option);
}
+ ArgsIterator last_weak_arg(args.empty() ? args.end() : prev(args.end()));
+ ArgsOptionSpecifiedness specifiedness(args.empty() ? aos_specified : aos_weak);
+
args.insert(args.end(), argseq->begin(), argseq->end());
ArgsIterator argit(args.begin()), arge(args.end());
@@ -229,13 +234,13 @@ ArgsHandler::run(
throw BadArgument("--no-" + arg);
std::string remaining_chars;
- ArgsVisitor visitor(&argit, arge, env_prefix, remaining_chars, true);
+ ArgsVisitor visitor(&argit, arge, env_prefix, remaining_chars, true, specifiedness);
it->second->accept(visitor);
}
else
{
std::string remaining_chars;
- ArgsVisitor visitor(&argit, arge, env_prefix, remaining_chars, false);
+ ArgsVisitor visitor(&argit, arge, env_prefix, remaining_chars, false, specifiedness);
it->second->accept(visitor);
}
}
@@ -258,7 +263,7 @@ ArgsHandler::run(
throw BadArgument(std::string("-") + *c);
}
- ArgsVisitor visitor(&argit, arge, env_prefix, remaining_chars, false);
+ ArgsVisitor visitor(&argit, arge, env_prefix, remaining_chars, false, specifiedness);
it->second->accept(visitor);
if (maybe_second_char_used && remaining_chars.empty())
@@ -272,6 +277,9 @@ ArgsHandler::run(
else
_imp->parameters.push_back(arg);
}
+
+ if (aos_weak == specifiedness && last_weak_arg == argit)
+ specifiedness = aos_specified;
}
_imp->parameters.insert(_imp->parameters.end(), argit, ArgsIterator(args.end()));
diff --git a/paludis/args/args_option.cc b/paludis/args/args_option.cc
index 1140448..7628b61 100644
--- a/paludis/args/args_option.cc
+++ b/paludis/args/args_option.cc
@@ -64,7 +64,7 @@ ArgsOption::ArgsOption(ArgsGroup * const g, const std::string & our_long_name,
_long_name(our_long_name),
_short_name(our_short_name),
_description(our_description),
- _specified(false)
+ _specified(aos_not)
{
g->add(this);
g->section()->handler()->add_option(this, our_long_name, our_short_name);
diff --git a/paludis/args/args_option.hh b/paludis/args/args_option.hh
index 1a35d6d..6131ccc 100644
--- a/paludis/args/args_option.hh
+++ b/paludis/args/args_option.hh
@@ -59,6 +59,13 @@ namespace paludis
class StringSetArg;
class StringSequenceArg;
+ enum ArgsOptionSpecifiedness
+ {
+ aos_not,
+ aos_weak,
+ aos_specified
+ };
+
/**
* Base class for a command line option.
*
@@ -77,7 +84,7 @@ namespace paludis
const char _short_name;
const std::string _description;
- bool _specified;
+ ArgsOptionSpecifiedness _specified;
ArgsOption(const ArgsOption &);
void operator= (const ArgsOption &);
@@ -127,17 +134,27 @@ namespace paludis
/**
* Fetch whether or not we were specified on the
- * command line.
+ * command line (or as an env var).
*/
virtual bool specified() const
{
- return _specified;
+ return _specified != aos_not;
+ }
+
+ /**
+ * Fetch whether or not we were explicitly (not
+ * an env var) specified. Used to catch -x y -x z
+ * where -x takes a single value.
+ */
+ virtual bool explicitly_specified() const
+ {
+ return _specified == aos_specified;
}
/**
* Set the value returned by specified().
*/
- virtual void set_specified(const bool value)
+ virtual void set_specified(const ArgsOptionSpecifiedness value)
{
_specified = value;
}
@@ -435,7 +452,12 @@ namespace paludis
return _other->specified();
}
- virtual void set_specified(const bool value)
+ virtual bool explicitly_specified() const
+ {
+ return _other->explicitly_specified();
+ }
+
+ virtual void set_specified(const ArgsOptionSpecifiedness value)
{
_other->set_specified(value);
}
diff --git a/paludis/args/args_visitor.cc b/paludis/args/args_visitor.cc
index af8ec03..d39cccb 100644
--- a/paludis/args/args_visitor.cc
+++ b/paludis/args/args_visitor.cc
@@ -27,6 +27,7 @@
#include <paludis/util/join.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/pimp-impl.hh>
+#include <paludis/util/log.hh>
#include <algorithm>
#include <sstream>
@@ -45,26 +46,29 @@ namespace paludis
std::string env_prefix;
std::string & remaining_chars;
bool no;
+ ArgsOptionSpecifiedness specifiedness;
Imp(
ArgsHandler::ArgsIterator * i,
ArgsHandler::ArgsIterator e,
std::string p,
std::string & s,
- bool n) :
+ bool n,
+ ArgsOptionSpecifiedness sp) :
args_index(i),
args_end(e),
env_prefix(p),
remaining_chars(s),
- no(n)
+ no(n),
+ specifiedness(sp)
{
}
};
}
ArgsVisitor::ArgsVisitor(ArgsHandler::ArgsIterator * ai, ArgsHandler::ArgsIterator ae,
- const std::string & env_prefix, std::string & s, bool n) :
- _imp(ai, ae, env_prefix, s, n)
+ const std::string & env_prefix, std::string & s, bool n, ArgsOptionSpecifiedness p) :
+ _imp(ai, ae, env_prefix, s, n, p)
{
}
@@ -85,8 +89,12 @@ void ArgsVisitor::visit(StringArg & arg)
{
if (! _imp->no)
{
+ if (arg.explicitly_specified())
+ Log::get_instance()->message("args.specified_twice", ll_warning, lc_context)
+ << "Option '--" << arg.long_name() << "' was specified more than once, but it does not take multiple values";
+
std::string p(get_param(arg));
- arg.set_specified(true);
+ arg.set_specified(_imp->specifiedness);
arg.set_argument(p);
if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), p.c_str(), 1);
@@ -95,7 +103,7 @@ void ArgsVisitor::visit(StringArg & arg)
throw BadArgument("--no-" + arg.long_name());
else
{
- arg.set_specified(false);
+ arg.set_specified(aos_not);
if (! _imp->env_prefix.empty())
unsetenv(env_name(arg.long_name()).c_str());
}
@@ -110,7 +118,7 @@ void ArgsVisitor::visit(SwitchArg & arg)
{
if (! _imp->no)
{
- arg.set_specified(true);
+ arg.set_specified(_imp->specifiedness);
if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), "1", 1);
}
@@ -118,7 +126,7 @@ void ArgsVisitor::visit(SwitchArg & arg)
throw BadArgument("--no-" + arg.long_name());
else
{
- arg.set_specified(false);
+ arg.set_specified(aos_not);
if (! _imp->env_prefix.empty())
unsetenv(env_name(arg.long_name()).c_str());
}
@@ -128,7 +136,11 @@ void ArgsVisitor::visit(IntegerArg & arg)
{
if (! _imp->no)
{
- arg.set_specified(true);
+ if (arg.explicitly_specified())
+ Log::get_instance()->message("args.specified_twice", ll_warning, lc_context)
+ << "Option '--" << arg.long_name() << "' was specified more than once, but it does not take multiple values";
+
+ arg.set_specified(_imp->specifiedness);
std::string param;
if ((! _imp->remaining_chars.empty()) && (std::string::npos == _imp->remaining_chars.find_first_not_of("0123456789")))
@@ -160,7 +172,11 @@ void ArgsVisitor::visit(EnumArg & arg)
{
if (! _imp->no)
{
- arg.set_specified(true);
+ if (arg.explicitly_specified())
+ Log::get_instance()->message("args.specified_twice", ll_warning, lc_context)
+ << "Option '--" << arg.long_name() << "' was specified more than once, but it does not take multiple values";
+
+ arg.set_specified(_imp->specifiedness);
std::string p;
if (_imp->remaining_chars.length() == 1)
@@ -183,7 +199,7 @@ void ArgsVisitor::visit(StringSetArg & arg)
{
if (! _imp->no)
{
- arg.set_specified(true);
+ arg.set_specified(_imp->specifiedness);
std::string param = get_param(arg);
arg.add_argument(param);
@@ -200,7 +216,7 @@ void ArgsVisitor::visit(StringSequenceArg & arg)
{
if (! _imp->no)
{
- arg.set_specified(true);
+ arg.set_specified(_imp->specifiedness);
std::string param = get_param(arg);
arg.add_argument(param);
diff --git a/paludis/args/args_visitor.hh b/paludis/args/args_visitor.hh
index 8f95036..fa68a08 100644
--- a/paludis/args/args_visitor.hh
+++ b/paludis/args/args_visitor.hh
@@ -76,7 +76,8 @@ namespace paludis
ArgsHandler::ArgsIterator,
const std::string &,
std::string & remaining_chars,
- bool no);
+ bool no,
+ ArgsOptionSpecifiedness specifiedness);
~ArgsVisitor();
diff --git a/src/clients/cave/cmd_fix_linkage.cc b/src/clients/cave/cmd_fix_linkage.cc
index b690b1d..051e2fe 100644
--- a/src/clients/cave/cmd_fix_linkage.cc
+++ b/src/clients/cave/cmd_fix_linkage.cc
@@ -144,8 +144,8 @@ FixLinkageCommand::run(
cmdline.run(args, "CAVE", "CAVE_FIX_LINKAGE_OPTIONS", "CAVE_FIX_LINKAGE_CMDLINE",
args::ArgsHandlerOptions() + args::aho_separate_after_dashes);
- resolve_cmdline.resolution_options.a_lazy.set_specified(true);
- resolve_cmdline.execution_options.a_preserve_world.set_specified(true);
+ resolve_cmdline.resolution_options.a_lazy.set_specified(args::aos_weak);
+ resolve_cmdline.execution_options.a_preserve_world.set_specified(args::aos_weak);
resolve_cmdline.run(cmdline.separate_after_dashes_args(),
"CAVE", "CAVE_RESOLVE_OPTIONS", "CAVE_RESOLVE_CMDLINE");
@@ -162,7 +162,7 @@ FixLinkageCommand::run(
resolve_cmdline.resolution_options.verify(env);
if (cmdline.a_execute.specified())
- resolve_cmdline.resolution_options.a_execute.set_specified(true);
+ resolve_cmdline.resolution_options.a_execute.set_specified(args::aos_specified);
auto libraries(std::make_shared<Sequence<std::string>>());
for (auto l(cmdline.a_libraries.begin_args()), l_end(cmdline.a_libraries.end_args()) ;
diff --git a/src/clients/cave/cmd_import.cc b/src/clients/cave/cmd_import.cc
index d7a59a6..55a01cf 100644
--- a/src/clients/cave/cmd_import.cc
+++ b/src/clients/cave/cmd_import.cc
@@ -300,7 +300,7 @@ ImportCommand::run(
resolve_cmdline.resolution_options.verify(env);
if (cmdline.a_execute.specified())
- resolve_cmdline.resolution_options.a_execute.set_specified(true);
+ resolve_cmdline.resolution_options.a_execute.set_specified(args::aos_specified);
std::shared_ptr<Sequence<std::pair<std::string, std::string> > > targets(std::make_shared<Sequence<std::pair<std::string, std::string> >>());
targets->push_back(std::make_pair(stringify((*ids->begin())->name()), ""));
diff --git a/src/clients/cave/cmd_purge.cc b/src/clients/cave/cmd_purge.cc
index b67dc95..1a252ba 100644
--- a/src/clients/cave/cmd_purge.cc
+++ b/src/clients/cave/cmd_purge.cc
@@ -104,7 +104,7 @@ PurgeCommand::run(
cmdline.resolution_options->apply_shortcuts();
cmdline.resolution_options->verify(env);
- cmdline.resolution_options->a_purge.set_specified(true);
+ cmdline.resolution_options->a_purge.set_specified(args::aos_weak);
cmdline.resolution_options->a_purge.add_argument("*/*");
return resolve_common(env, *cmdline.resolution_options, *cmdline.execution_options, *cmdline.display_options,
diff --git a/src/clients/cave/cmd_sync.cc b/src/clients/cave/cmd_sync.cc
index 87330d7..a12f060 100644
--- a/src/clients/cave/cmd_sync.cc
+++ b/src/clients/cave/cmd_sync.cc
@@ -390,7 +390,7 @@ SyncCommand::run(
repos.insert((*p)->name());
if (1 == repos.size())
- cmdline.a_sequential.set_specified(true);
+ cmdline.a_sequential.set_specified(args::aos_weak);
cout << fuc(fs_heading(), fv<'s'>("Starting sync"));
diff --git a/src/clients/cave/resolve_cmdline.cc b/src/clients/cave/resolve_cmdline.cc
index ba9cc8f..82abf30 100644
--- a/src/clients/cave/resolve_cmdline.cc
+++ b/src/clients/cave/resolve_cmdline.cc
@@ -471,7 +471,7 @@ ResolveCommandLineResolutionOptions::apply_shortcuts()
if (! a_slots.specified())
a_slots.set_argument("best");
if (! a_no_follow_installed_dependencies.specified())
- a_no_follow_installed_dependencies.set_specified(true);
+ a_no_follow_installed_dependencies.set_specified(args::aos_weak);
}
if (a_complete.specified())
@@ -483,7 +483,7 @@ ResolveCommandLineResolutionOptions::apply_shortcuts()
if (! a_slots.specified())
a_slots.set_argument("all");
if (! a_follow_installed_build_dependencies.specified())
- a_follow_installed_build_dependencies.set_specified(true);
+ a_follow_installed_build_dependencies.set_specified(args::aos_weak);
if (! a_reinstall_scm.specified())
a_reinstall_scm.set_argument("weekly");
}
@@ -499,7 +499,7 @@ ResolveCommandLineResolutionOptions::apply_shortcuts()
if (! a_slots.specified())
a_slots.set_argument("all");
if (! a_follow_installed_build_dependencies.specified())
- a_follow_installed_build_dependencies.set_specified(true);
+ a_follow_installed_build_dependencies.set_specified(args::aos_weak);
}
}