aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-03-31 12:24:18 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-03-31 12:24:18 +0100
commit03d686de567d9ca698de606086b4d12adfbd5580 (patch)
treed6100fdaf5b8d2b14b5f7006daf2a5aa84aa90d8
parentd8dc618b102dfb12679020c6623713e7252d9fa2 (diff)
downloadpaludis-03d686de567d9ca698de606086b4d12adfbd5580.tar.gz
paludis-03d686de567d9ca698de606086b4d12adfbd5580.tar.xz
Treat -xY like -x Y if -x is an EnumArg
Fixes: ticket:849
-rw-r--r--paludis/args/args_handler.cc25
-rw-r--r--paludis/args/args_visitor.cc90
-rw-r--r--paludis/args/args_visitor.hh26
3 files changed, 96 insertions, 45 deletions
diff --git a/paludis/args/args_handler.cc b/paludis/args/args_handler.cc
index 758fbf0..8f8ed4c 100644
--- a/paludis/args/args_handler.cc
+++ b/paludis/args/args_handler.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007, 2008, 2009 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -181,12 +181,10 @@ ArgsHandler::run(
args.insert(args.end(), argseq->begin(), argseq->end());
ArgsIterator argit(args.begin()), arge(args.end());
- ArgsVisitor visitor(&argit, arge, env_prefix);
for ( ; argit != arge; ++argit )
{
std::string arg = *argit;
- visitor.set_no(false);
if (arg == "--")
{
@@ -205,23 +203,42 @@ ArgsHandler::run(
it = _imp->longopts.find(arg);
if (it == _imp->longopts.end())
throw BadArgument("--no-" + arg);
- visitor.set_no(true);
+
+ char second_char_or_zero('\0');
+ ArgsVisitor visitor(&argit, arge, env_prefix, second_char_or_zero, true);
it->second->accept(visitor);
}
else
+ {
+ char second_char_or_zero('\0');
+ ArgsVisitor visitor(&argit, arge, env_prefix, second_char_or_zero, false);
it->second->accept(visitor);
+ }
}
else if (arg[0] == '-')
{
arg.erase(0, 1);
for (std::string::iterator c = arg.begin(); c != arg.end(); ++c)
{
+ bool maybe_second_char_used(false);
+ char second_char_or_zero('\0');
+ if (2 == arg.length() && c == arg.begin())
+ {
+ maybe_second_char_used = true;
+ second_char_or_zero = arg[1];
+ }
+
std::map<char, ArgsOption *>::iterator it = _imp->shortopts.find(*c);
if (it == _imp->shortopts.end())
{
throw BadArgument(std::string("-") + *c);
}
+
+ ArgsVisitor visitor(&argit, arge, env_prefix, second_char_or_zero, false);
it->second->accept(visitor);
+
+ if (maybe_second_char_used && '\0' == second_char_or_zero)
+ break;
}
}
else
diff --git a/paludis/args/args_visitor.cc b/paludis/args/args_visitor.cc
index 9c4fbb7..71857d2 100644
--- a/paludis/args/args_visitor.cc
+++ b/paludis/args/args_visitor.cc
@@ -1,6 +1,6 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007, 2008, 2009 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -26,6 +26,7 @@
#include <paludis/util/system.hh>
#include <paludis/util/join.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
#include <algorithm>
#include <sstream>
@@ -34,32 +35,60 @@
using namespace paludis;
using namespace paludis::args;
+namespace paludis
+{
+ template <>
+ struct Implementation<ArgsVisitor>
+ {
+ ArgsHandler::ArgsIterator * args_index;
+ ArgsHandler::ArgsIterator args_end;
+ std::string env_prefix;
+ char & second_char_or_zero;
+ bool no;
+
+ Implementation(
+ ArgsHandler::ArgsIterator * i,
+ ArgsHandler::ArgsIterator e,
+ std::string p,
+ char & s,
+ bool n) :
+ args_index(i),
+ args_end(e),
+ env_prefix(p),
+ second_char_or_zero(s),
+ no(n)
+ {
+ }
+ };
+}
+
ArgsVisitor::ArgsVisitor(ArgsHandler::ArgsIterator * ai, ArgsHandler::ArgsIterator ae,
- const std::string & env_prefix) :
- _args_index(ai),
- _args_end(ae),
- _env_prefix(env_prefix),
- _no(false)
+ const std::string & env_prefix, char & s, bool n) :
+ PrivateImplementationPattern<ArgsVisitor>(new Implementation<ArgsVisitor>(ai, ae, env_prefix, s, n))
+{
+}
+
+ArgsVisitor::~ArgsVisitor()
{
}
const std::string &
ArgsVisitor::get_param(const ArgsOption & arg)
{
- if (++(*_args_index) == _args_end)
+ if (++(*_imp->args_index) == _imp->args_end)
throw MissingValue("--" + arg.long_name());
- return **_args_index;
+ return **_imp->args_index;
}
void ArgsVisitor::visit(StringArg & arg)
{
- if (! _no)
+ if (! _imp->no)
{
std::string p(get_param(arg));
arg.set_specified(true);
arg.set_argument(p);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), p.c_str(), 1);
}
else
@@ -73,10 +102,10 @@ void ArgsVisitor::visit(AliasArg & arg)
void ArgsVisitor::visit(SwitchArg & arg)
{
- if (! _no)
+ if (! _imp->no)
{
arg.set_specified(true);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), "1", 1);
}
else if (! arg.can_be_negated())
@@ -84,14 +113,14 @@ void ArgsVisitor::visit(SwitchArg & arg)
else
{
arg.set_specified(false);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
unsetenv(env_name(arg.long_name()).c_str());
}
}
void ArgsVisitor::visit(IntegerArg & arg)
{
- if (! _no)
+ if (! _imp->no)
{
arg.set_specified(true);
std::string param = get_param(arg);
@@ -100,7 +129,7 @@ void ArgsVisitor::visit(IntegerArg & arg)
int a(destringify<int>(param));
arg.set_argument(a);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), stringify(a).c_str(), 1);
}
catch (const DestringifyError &)
@@ -114,12 +143,21 @@ void ArgsVisitor::visit(IntegerArg & arg)
void ArgsVisitor::visit(EnumArg & arg)
{
- if (! _no)
+ if (! _imp->no)
{
arg.set_specified(true);
- std::string p(get_param(arg));
+
+ std::string p;
+ if ('\0' != _imp->second_char_or_zero)
+ {
+ p = std::string(1, _imp->second_char_or_zero);
+ _imp->second_char_or_zero = '\0';
+ }
+ else
+ p = get_param(arg);
+
arg.set_argument(p);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), p.c_str(), 1);
}
else
@@ -128,14 +166,14 @@ void ArgsVisitor::visit(EnumArg & arg)
void ArgsVisitor::visit(StringSetArg & arg)
{
- if (! _no)
+ if (! _imp->no)
{
arg.set_specified(true);
std::string param = get_param(arg);
arg.add_argument(param);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), join(arg.begin_args(),
arg.end_args(), " ").c_str(), 1);
}
@@ -145,14 +183,14 @@ void ArgsVisitor::visit(StringSetArg & arg)
void ArgsVisitor::visit(StringSequenceArg & arg)
{
- if (! _no)
+ if (! _imp->no)
{
arg.set_specified(true);
std::string param = get_param(arg);
arg.add_argument(param);
- if (! _env_prefix.empty())
+ if (! _imp->env_prefix.empty())
setenv(env_name(arg.long_name()).c_str(), join(arg.begin_args(),
arg.end_args(), " ").c_str(), 1);
}
@@ -163,14 +201,8 @@ void ArgsVisitor::visit(StringSequenceArg & arg)
std::string
ArgsVisitor::env_name(const std::string & long_name) const
{
- std::string result(_env_prefix + "_" + long_name);
+ std::string result(_imp->env_prefix + "_" + long_name);
std::replace(result.begin(), result.end(), '-', '_');
return result;
}
-void
-ArgsVisitor::set_no(const bool n)
-{
- _no = n;
-}
-
diff --git a/paludis/args/args_visitor.hh b/paludis/args/args_visitor.hh
index 18bbcc5..ca2ad7d 100644
--- a/paludis/args/args_visitor.hh
+++ b/paludis/args/args_visitor.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007, 2008, 2009 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh
* Copyright (c) 2006 Stephen Bennett
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -24,6 +24,7 @@
#include <paludis/util/simple_visitor.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/attributes.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/args/args_handler.hh>
#include <string>
@@ -55,24 +56,28 @@ namespace paludis
*
* \ingroup g_args
*/
- class PALUDIS_VISIBLE ArgsVisitor
+ class PALUDIS_VISIBLE ArgsVisitor :
+ private PrivateImplementationPattern<ArgsVisitor>
{
private:
- ArgsHandler::ArgsIterator * _args_index, _args_end;
- std::string _env_prefix;
-
const std::string & get_param(const ArgsOption &);
std::string env_name(const std::string & long_name) const;
- bool _no;
-
public:
/**
* Constructor
+ *
+ * \since 0.47
*/
- ArgsVisitor(ArgsHandler::ArgsIterator *, ArgsHandler::ArgsIterator,
- const std::string & env_prefix = "");
+ ArgsVisitor(
+ ArgsHandler::ArgsIterator *,
+ ArgsHandler::ArgsIterator,
+ const std::string &,
+ char & second_char_or_zero,
+ bool no);
+
+ ~ArgsVisitor();
/// Visit a StringArg.
void visit(StringArg &);
@@ -94,9 +99,6 @@ namespace paludis
/// Visit a StringSequenceArg.
void visit(StringSequenceArg &);
-
- /// Change whether we're visiting a --no- option
- void set_no(const bool);
};
}
}