tclap  1.4.0
SwitchArg.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: SwitchArg.h
6  *
7  * Copyright (c) 2003, Michael E. Smoot .
8  * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
9  * Copyright (c) 2017, Google LLC
10  * All rights reserved.
11  *
12  * See the file COPYING in the top directory of this distribution for
13  * more information.
14  *
15  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  *****************************************************************************/
24 
25 #ifndef TCLAP_SWITCH_ARG_H
26 #define TCLAP_SWITCH_ARG_H
27 
28 #include <tclap/Arg.h>
29 
30 #include <string>
31 #include <vector>
32 
33 namespace TCLAP {
34 
40 class SwitchArg : public Arg {
41 protected:
45  bool _value;
46 
51  bool _default;
52 
53 public:
66  SwitchArg(const std::string &flag, const std::string &name,
67  const std::string &desc, bool def = false, Visitor *v = NULL);
68 
82  SwitchArg(const std::string &flag, const std::string &name,
83  const std::string &desc, ArgContainer &parser, bool def = false,
84  Visitor *v = NULL);
85 
94  virtual bool processArg(int *i, std::vector<std::string> &args);
95 
100  bool combinedSwitchesMatch(std::string &combined);
101 
105  bool getValue() const { return _value; }
106 
112  operator bool() const { return _value; }
113 
114  virtual void reset();
115 
116 private:
121  bool lastCombined(std::string &combined);
122 
126  void commonProcessing();
127 };
128 
130 // BEGIN SwitchArg.cpp
132 inline SwitchArg::SwitchArg(const std::string &flag, const std::string &name,
133  const std::string &desc, bool default_val,
134  Visitor *v)
135  : Arg(flag, name, desc, false, false, v),
136  _value(default_val),
137  _default(default_val) {}
138 
139 inline SwitchArg::SwitchArg(const std::string &flag, const std::string &name,
140  const std::string &desc, ArgContainer &parser,
141  bool default_val, Visitor *v)
142  : Arg(flag, name, desc, false, false, v),
143  _value(default_val),
144  _default(default_val) {
145  parser.add(this);
146 }
147 
148 inline bool SwitchArg::lastCombined(std::string &combinedSwitches) {
149  for (unsigned int i = 1; i < combinedSwitches.length(); i++)
150  if (combinedSwitches[i] != Arg::blankChar()) return false;
151 
152  return true;
153 }
154 
155 inline bool SwitchArg::combinedSwitchesMatch(std::string &combinedSwitches) {
156  // make sure this is actually a combined switch
157  if (combinedSwitches.length() > 0 &&
158  combinedSwitches[0] != Arg::flagStartString()[0])
159  return false;
160 
161  // make sure it isn't a long name
162  if (combinedSwitches.substr(0, Arg::nameStartString().length()) ==
164  return false;
165 
166  // make sure the delimiter isn't in the string
167  if (combinedSwitches.find_first_of(Arg::delimiter()) != std::string::npos)
168  return false;
169 
170  // ok, we're not specifying a ValueArg, so we know that we have
171  // a combined switch list.
172  for (unsigned int i = 1; i < combinedSwitches.length(); i++) {
173  if (_flag.length() > 0 && combinedSwitches[i] == _flag[0] &&
174  _flag[0] != Arg::flagStartString()[0]) {
175  // update the combined switches so this one is no longer
176  // present this is necessary so that no unlabeled args are
177  // matched later in the processing.
178  // combinedSwitches.erase(i,1);
179  _setBy = Arg::flagStartString() + combinedSwitches[i];
180  combinedSwitches[i] = Arg::blankChar();
181  return true;
182  }
183  }
184 
185  // none of the switches passed in the list match.
186  return false;
187 }
188 
189 inline void SwitchArg::commonProcessing() {
190  if (_alreadySet)
191  throw(CmdLineParseException("Argument already set!", toString()));
192 
193  _alreadySet = true;
194 
195  if (_value == true)
196  _value = false;
197  else
198  _value = true;
199 
201 }
202 
203 inline bool SwitchArg::processArg(int *i, std::vector<std::string> &args) {
204  if (argMatches(args[*i])) {
205  // The whole string matches the flag or name string
206  _setBy = args[*i];
207  commonProcessing();
208 
209  return true;
210  } else if (combinedSwitchesMatch(args[*i])) {
211  // A substring matches the flag as part of a combination
212  // check again to ensure we don't misinterpret
213  // this as a MultiSwitchArg
214  if (combinedSwitchesMatch(args[*i]))
215  throw(CmdLineParseException("Argument already set!", toString()));
216 
217  commonProcessing();
218 
219  // We only want to return true if we've found the last combined
220  // match in the string, otherwise we return true so that other
221  // switches in the combination will have a chance to match.
222  return lastCombined(args[*i]);
223  }
224 
225  return false;
226 }
227 
228 inline void SwitchArg::reset() {
229  Arg::reset();
230  _value = _default;
231 }
232 
233 } // namespace TCLAP
234 
235 #endif // TCLAP_SWITCH_ARG_H
bool getValue() const
Returns bool, whether or not the switch has been set.
Definition: SwitchArg.h:105
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:535
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:122
virtual ArgContainer & add(Arg &a)=0
Adds an argument.
bool combinedSwitchesMatch(std::string &combined)
Checks a string to see if any of the chars in the string match the flag for this Switch.
Definition: SwitchArg.h:155
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:53
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: ArgException.h:129
A simple switch argument.
Definition: SwitchArg.h:40
virtual void reset()
Clears the Arg object and allows it to be reused by new command lines.
Definition: Arg.h:595
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:186
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: SwitchArg.h:203
bool _value
The value of the switch.
Definition: SwitchArg.h:45
bool _default
Used to support the reset() method so that ValueArg can be reset to their constructed value...
Definition: SwitchArg.h:51
void _checkWithVisitor() const
Performs the special handling described by the Visitor.
Definition: Arg.h:553
static const std::string nameStartString()
Definition: Arg.h:220
Interface that allows adding an Arg to a "container".
Definition: ArgContainer.h:39
A base class that defines the interface for visitors.
Definition: Visitor.h:32
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:543
virtual void reset()
Clears the Arg object and allows it to be reused by new command lines.
Definition: SwitchArg.h:228
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition: Arg.h:192
SwitchArg(const std::string &flag, const std::string &name, const std::string &desc, bool def=false, Visitor *v=NULL)
SwitchArg constructor.
Definition: SwitchArg.h:132
std::string _flag
The single char flag used to identify the argument.
Definition: Arg.h:83
Definition: Arg.h:46
std::string _setBy
Indicates the value specified to set this flag (like -a or –all).
Definition: Arg.h:126
static const std::string flagStartString()
Definition: Arg.h:211