9

Say I have an executable (running on mac, win, and linux)

 a.out [-a] [-b] [-r -i <file> -o <file> -t <double> -n <int> ]

where an argument in [ ] means that it is optional. However, if the last argument -r is set then -i,-o,-t, and -n have to be supplied, too.

There are lots of good C++-libraries out there to parse command-line arguments, e.g. gflags (http://code.google.com/p/gflags/), tclap (http://tclap.sourceforge.net/), simpleopt(http://code.jellycan.com/simpleopt/), boost.program_options (http://www.boost.org/doc/libs/1_52_0/doc/html/program_options.html), etc. But I wondered if there is one that lets me encode these conditional relationships between arguments directly, w/o manually coding error handling

if ( argR.isSet() && ( ! argI.isSet() || ! argO.isSet() || ... ) ) ...

and manually setting up the --help.

The library tclap allows to XOR arguments, e.g. either -a or -b is allowed but not both. So, in that terminology an AND for arguments would be nice.

Does anybody know a versatile, light-weight, and cross-platform library that can do that?

nils
  • 2,424
  • 1
  • 17
  • 31
  • [Here](http://www.boost.org/libs/program_options/example/real.cpp) is the example from Boost.Program_options that deals with conflicting and dependent options. –  Jan 21 '13 at 07:57

4 Answers4

2

You could two passes over the arguments; If -r is in the options you reset the parser and start over with the new mandatory options added.


You could also look into how the TCLAP XorHandler works, and create your own AndHandler.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Yes, I have tried that but then you still have to code the help-screen yourself (which is not a problem, but would be nice to have). Adding the AndHandler would be a good option, I guess. – nils Dec 19 '12 at 16:00
  • @Nick The help-screen needs special handling anyway. One thing I like about Boost program-options is that it doesn't show the help screen itself, but you have to provide your own `--help` option and check for that and print the help yourself. This way you can just add the special options and print it all in one go. – Some programmer dude Dec 19 '12 at 16:19
0

You could change the argument syntax so that -r takes four values in a row.

DSimon
  • 3,280
  • 2
  • 21
  • 24
  • 2
    This would be rather confusing, though, as that's not how arguments generally work –  Dec 19 '12 at 15:57
  • True, however, they could be different data types. As far as I know, the libraries mentioned in the question handle multi-arguments (only) as one type. – nils Dec 19 '12 at 16:03
0

I have part of the TCLAP snippet of code lying around that seems to fit the error handling portion that you're looking for, however it doesn't match exactly what you're looking for:

# include "tclap/CmdLine.h"

namespace TCLAP {

class RequiredDependentArgException : public ArgException {
public:
  /**
   * Constructor.
   * \param text - The text of the exception.
   * \param parentArg - The text identifying the parent argument source
   * \param dependentArg - The text identifying the required dependent argument
   * of the exception.
   */
  RequiredDependentArgException(
    const TCLAP::Arg& parentArg,
    const TCLAP::Arg& requiredArg)
  : ArgException(
    std::string( "Required argument ") +
    requiredArg.toString() +
    std::string(" missing when the ") +
    parentArg.toString() +
    std::string(" flag is specified."),
    requiredArg.toString())
  { }
};

} // namespace TCLAP

And then make use of the new exception after TCLAP::CmdLine::parse has been called:

if (someArg.isSet() && !conditionallyRequiredArg.isSet()) {
  throw(TCLAP::RequiredDependentArgException(someArg, conditionallyRequiredArg));
}

I remember looking in to extending and adding an additional class that would handle this logic, but then I realized the only thing I was actually looking for was nice error reporting because the logic wasn't entirely straightforward and couldn't be easily condensed (at least, not in a way that was useful to the next poor guy who came along). A contrived scenario dissuaded me from pursuing it further, something to the effect of, "if A is true, B must be set but C can't be set if D is of value N." Expressing such things in native C++ is the way to go, especially when it comes time to do very strict argument checks at CLI arg parse time.

For truly pathological cases and requirements, create a state machine using something like Boost.MSM (Multi-State Machine). HTH.

Sean
  • 9,888
  • 4
  • 40
  • 43
-1

do you want to parse a command line?you can use simpleopt,it can be used as followings:downLoad simpleopt from: https://code.google.com/archive/p/simpleopt/downloads

test: int _tmain(int argc, TCHAR * argv[]) argv can be:1.txt 2.txt *.cpp

350740378
  • 11
  • 1