|
- // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
-
- /******************************************************************************
- *
- * file: SwitchArg.h
- *
- * Copyright (c) 2003, Michael E. Smoot .
- * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
- * Copyright (c) 2017, Google LLC
- * All rights reserved.
- *
- * See the file COPYING in the top directory of this distribution for
- * more information.
- *
- * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- *****************************************************************************/
-
- #ifndef TCLAP_SWITCH_ARG_H
- #define TCLAP_SWITCH_ARG_H
-
- #include <string>
- #include <vector>
-
- #include <tclap/Arg.h>
-
- namespace TCLAP
- {
-
- /**
- * A simple switch argument. If the switch is set on the command line, then
- * the getValue method will return the opposite of the default value for the
- * switch.
- */
- class SwitchArg : public Arg
- {
- protected:
- /**
- * The value of the switch.
- */
- bool _value;
-
- /**
- * Used to support the reset() method so that ValueArg can be
- * reset to their constructed value.
- */
- bool _default;
-
- public:
- /**
- * SwitchArg constructor.
- * \param flag - The one character flag that identifies this
- * argument on the command line.
- * \param name - A one word name for the argument. Can be
- * used as a long flag on the command line.
- * \param desc - A description of what the argument is for or
- * does.
- * \param def - The default value for this Switch.
- * \param v - An optional visitor. You probably should not
- * use this unless you have a very good reason.
- */
- SwitchArg(const std::string& flag, const std::string& name, const std::string& desc, bool def = false, Visitor* v = NULL);
-
- /**
- * SwitchArg constructor.
- * \param flag - The one character flag that identifies this
- * argument on the command line.
- * \param name - A one word name for the argument. Can be
- * used as a long flag on the command line.
- * \param desc - A description of what the argument is for or
- * does.
- * \param parser - A CmdLine parser object to add this Arg to
- * \param def - The default value for this Switch.
- * \param v - An optional visitor. You probably should not
- * use this unless you have a very good reason.
- */
- SwitchArg(const std::string& flag, const std::string& name, const std::string& desc, CmdLineInterface& parser, bool def = false, Visitor* v = NULL);
-
- /**
- * Handles the processing of the argument.
- * This re-implements the Arg version of this method to set the
- * _value of the argument appropriately.
- * \param i - Pointer the the current argument in the list.
- * \param args - Mutable list of strings. Passed
- * in from main().
- */
- virtual bool processArg(int* i, std::vector<std::string>& args);
-
- /**
- * Checks a string to see if any of the chars in the string
- * match the flag for this Switch.
- */
- bool combinedSwitchesMatch(std::string& combined);
-
- /**
- * Returns bool, whether or not the switch has been set.
- */
- bool getValue() const
- {
- return _value;
- }
-
- /**
- * A SwitchArg can be used as a boolean, indicating
- * whether or not the switch has been set. This is the
- * same as calling getValue()
- */
- operator bool() const
- {
- return _value;
- }
-
- virtual void reset();
-
- private:
- /**
- * Checks to see if we've found the last match in
- * a combined string.
- */
- bool lastCombined(std::string& combined);
-
- /**
- * Does the common processing of processArg.
- */
- void commonProcessing();
- };
-
- //////////////////////////////////////////////////////////////////////
- // BEGIN SwitchArg.cpp
- //////////////////////////////////////////////////////////////////////
- inline SwitchArg::SwitchArg(const std::string& flag, const std::string& name, const std::string& desc, bool default_val, Visitor* v) :
- Arg(flag, name, desc, false, false, v),
- _value(default_val),
- _default(default_val)
- {
- }
-
- inline SwitchArg::SwitchArg(const std::string& flag, const std::string& name, const std::string& desc, CmdLineInterface& parser, bool default_val, Visitor* v) :
- Arg(flag, name, desc, false, false, v),
- _value(default_val),
- _default(default_val)
- {
- parser.add(this);
- }
-
- inline bool SwitchArg::lastCombined(std::string& combinedSwitches)
- {
- for (unsigned int i = 1; i < combinedSwitches.length(); i++)
- if (combinedSwitches[i] != Arg::blankChar())
- return false;
-
- return true;
- }
-
- inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches)
- {
- // make sure this is actually a combined switch
- if (combinedSwitches.length() > 0 &&
- combinedSwitches[0] != Arg::flagStartString()[0])
- return false;
-
- // make sure it isn't a long name
- if (combinedSwitches.substr(0, Arg::nameStartString().length()) ==
- Arg::nameStartString())
- return false;
-
- // make sure the delimiter isn't in the string
- if (combinedSwitches.find_first_of(Arg::delimiter()) != std::string::npos)
- return false;
-
- // ok, we're not specifying a ValueArg, so we know that we have
- // a combined switch list.
- for (unsigned int i = 1; i < combinedSwitches.length(); i++)
- if (_flag.length() > 0 &&
- combinedSwitches[i] == _flag[0] &&
- _flag[0] != Arg::flagStartString()[0])
- {
- // update the combined switches so this one is no longer present
- // this is necessary so that no unlabeled args are matched
- // later in the processing.
- // combinedSwitches.erase(i,1);
- combinedSwitches[i] = Arg::blankChar();
- return true;
- }
-
- // none of the switches passed in the list match.
- return false;
- }
-
- inline void SwitchArg::commonProcessing()
- {
- if (_xorSet)
- throw(CmdLineParseException(
- "Mutually exclusive argument already set!", toString()
- ));
-
- if (_alreadySet)
- throw(CmdLineParseException("Argument already set!", toString()));
-
- _alreadySet = true;
-
- if (_value == true)
- _value = false;
- else
- _value = true;
-
- _checkWithVisitor();
- }
-
- inline bool SwitchArg::processArg(int* i, std::vector<std::string>& args)
- {
- if (_ignoreable && Arg::ignoreRest())
- return false;
-
- // if the whole string matches the flag or name string
- if (argMatches(args[*i]))
- {
- commonProcessing();
-
- return true;
- }
- // if a substring matches the flag as part of a combination
- else if (combinedSwitchesMatch(args[*i]))
- {
- // check again to ensure we don't misinterpret
- // this as a MultiSwitchArg
- if (combinedSwitchesMatch(args[*i]))
- throw(CmdLineParseException("Argument already set!", toString()));
-
- commonProcessing();
-
- // We only want to return true if we've found the last combined
- // match in the string, otherwise we return true so that other
- // switches in the combination will have a chance to match.
- return lastCombined(args[*i]);
- }
- else
- return false;
- }
-
- inline void SwitchArg::reset()
- {
- Arg::reset();
- _value = _default;
- }
- //////////////////////////////////////////////////////////////////////
- // End SwitchArg.cpp
- //////////////////////////////////////////////////////////////////////
-
- } // namespace TCLAP
-
- #endif
|