Accessing arg values at a later stage

Help
max
2006-05-11
2013-05-28
  • max
    max
    2006-05-11

    Is there an easy way to access argument values from the CmdLine after it was parsed, when the is no access to the arguments anymore?

    My code splits the the command line parsing into r steps:
    1.) definition of the command line arguments
    2.) pasring
    3.) Validation

    Somthing like that:

    class ValidatorInterface {

        ValidatorInterface(TCLAP::CmdLine& cmdlp) : { }

        virtual void validate() throw (TCLAP::ArgException) = 0;

    private:
        TCLAP::CmdLine& cmdlp_;

    };

    Actually it would make more sense to add a validator to arguments but for this example code i want to validate one or two arguments in the argument list after it was parsed.

    My questions:
    * how to find the argument in the argument list?
    * how to read the value after i have the right argument?

     
    • Daniel Aarno
      Daniel Aarno
      2006-05-11

      I'm not 100% sure about what the validate function should do but I can give you some general comments that might help.

      1) You can access the argument list through the member function getArgList of CmdLine object.
      2) The CmdLine objecte does NOT copy the arguments but simply keeps a reference to them. This means that the CmdLine object is only valid as long as all the Args added to it is still in scope.
      3) One way to do it would perhaps be to have a std::map in you validator class that keeps a map from the name of the argument to a pointer to that argument and adding all the Args to that map (so that you can find them by name).
      4) You should also have a look at the Vistor interface, which might be an easier way to do things

       
    • max
      max
      2006-05-11

      <quote>
      I'm not 100% sure about what the validate function should do but I can give you some general comments that might help.
      </quote>

      Example for an argument validation: my integer argument is only valid if it is > 0. It should  throw an exception if this is not the case.

      ad 1) yes, but when i have an argument, how do i access the value - unless using dynamic_cast - which is a "bad".

      ad 2) good to know.

      ad 3) yes, but this leads to the problem in 1). Accessing the value will be tricky. I have no idea how a template function could look like to access the value in the argument map.

      Problem with 4) is that the visitor needs a reference to its argument to validate its value. And this reference can't be given to the validator because it does not exit at the time when the validator is created.

       
      • Daniel Aarno
        Daniel Aarno
        2006-05-11

        Ah, a third solution would be the mapping. You would map from names to Arg*s but since each arg has a unique name you would "know" the type and could cast to the correct type without trying all of them. This is a hack of-course, but whatever gets you through your day...

         
    • Daniel Aarno
      Daniel Aarno
      2006-05-11

      OK, now we are getting somewhere. First of all for your example you could simply use an unsigned type for the template argument and everything will happen for you automagically. Given that you want to do something more complicated you could:

      1) Write a new type i.e. an object that overloads operator>> which gets called when the object is matched on the command line and to the validation there. For example I did this with files so that the object checked that the file existed an otherwise throwed an exception. (let me know if you want the code for that and I can send it to you). You would then create a ValueArg<T> where T is your new type.

      2) You could use dynamic cast or typeinfo. However as you point out it's maybe not so nice and the problem stems from using two different programming paradigms, templates and inheretance. If it is just a special case I would say that this in an acceptable solution.

       
    • Mike Smoot
      Mike Smoot
      2006-05-12

      Check out the Constraint interface that is now in CVS.  I think that might provide exactly the kind of validation you're looking for.  Let me know if it doesn't.