#ifndef PROG_ARG_H #define PROG_ARG_H #include #include #include #include namespace icl{ /// initialization of the ProgArg-Environment \ingroup PA /** The UCLUtils/ProgArg tool provides a more convenient access to executables arguments, given via "nArgs" and "ppcArg" in the main function.

What?

Consider a default main(int n, char **ppc) - application. If the programs arguments have to be evaluated to affect the program flow, you have to take care about many things: - define what arguments you will need / which are allowed - parsing the list of arguments - parsing sub-arguments as "-grabber pwc" - converting the string-arguments in correct data types as in "-size 640 480" - printing error messages and usage if - denied arguments were given the program - an argument go not the correct count of sub-arguments - list and explain possible arguments - ...

ProgArg - a more convenient approach!

The following example, also available in ICLUtils/examples/progargdemo, shows the advantages of using the ProgArg environment: \code #include using namespace icl; int main(int n, char **ppc){ pa_explain("-size", "image size\n" "first param = width (one of 160, 320 or 640)\n" "second param = height one of (120, 240 or 480)"); pa_explain("-format","image format\none of:\n- formatRGB\n- formatGray\n- formatHLS"); pa_explain("-channels","count of image channels\none of {1,2,3,4}"); pa_explain("-fast","enables the \"fast\"-mode which does everything\nmuch faster!"); pa_init(n,ppc,"-size(2) -format(1) -channels(1) -fast"); printf("programs name is %s \n",pa_progname().c_str()); printf("argcount is %d \n",pa_argcount()); if(pa_defined("-size")){ printf("given size was %d %d \n",pa_subarg("-size",0),pa_subarg("-size",1)); } if(pa_defined("-format")){ printf("given format was %s \n",pa_subarg("-format",0)); } if(pa_defined("-fast")){ printf("enabling fast (whatever this will effect!?) \n"); } for(unsigned int i=0;i(i)); } return 0; } \endcode The following outputs are possible.
  gordonfreeman\@blackmesa:~/projects/ICL/ICLUtils/examples> ./progargdemo -size 640 480 -channels 3 -format rgb -fast
  programs name is ./progargdemo
  argcount is 8
  given size was 640 480
  given format was rgb
  arg 0 was -size
  arg 1 was 640
  arg 2 was 480
  arg 3 was -channels
  arg 4 was 3
  arg 5 was -format
  arg 6 was rgb
  arg 7 was -fast

  but
 
  gordonfreeman\@blackmesa:~/projects/ICL/ICLUtils/examples> ./progargdemo -size 640 480 -slow
  error: nothing known about arg -slow [index=3]
  usage: progargdemo [ARGS] 
        allowed ARGS are:
        -channels(1) : count of image channels
                       one of {1,2,3,4}
        -fast : enables the "fast"-mode which does everything
                much faster!
        -format(1) : image format
                     one of:
                     - formatRGB
                     - formatGray
                     - formatHLS
        -size(2) : image size
                   first param = width (one of 160, 320 or 640)
                   second param = height one of (120, 240 or 480)
        --help : show this usage
  

pa_init

This function must be called before any other ProgArg function is available. The function knows two different modes: - if "allowedArgs" is given, actual program arguments are checked for being compatible to the argument definition (given with "allowedArgs"). - if not, all params are valid, and the developer has to take care himself about tackling params. @param nArgs argument count received in the main function @param ppcArg argument vector received in the main function @param allowedArgs optional definition of the allowed arguments with the following syntax: [ARG<(\#SUBARGS)>]. E.g. "-size(2) -input-file(1) -fast". More details in the example above! @param skipUnknownArgs if set to true, unknown args are just skipped, otherwise, the "usage" is shown, and the programm is aborted using exit(-1) */ void pa_init(int nArgs, char **ppcArg, std::string allowedArgs="", bool skipUnknownArgs=false); /// returns the program name as it was written to start the program \ingroup PA /** e.g. "./myprogram" */ const std::string &pa_progname(); /// this function can be used to explain arguents \ingroup PA /** e.g. if you call pa_init(n,ppc,"-s(1)"), the "-s" arg is not explained enogh propably. To do this, just call: \code pa_explain("-s","sets up the current image size"); \endcode and the following usage will help to understand programm args better:
      usage: 
      
NOTE: pa_explain(..) must be called BEFORE pa_init() is called !! @param argname name of the argument to explain @param explanation explanation for argname */ void pa_explain(const std::string &argname, const std::string &explanation); /// returns the count of parameters actually given \ingroup PA unsigned int pa_argcount(); /// writes the error message followed by a usage definition \ingroup PA /** the usage is only defined, if "allowedArgs" was set in pa_init */ void pa_usage(const std::string &errorMessage=""); /// returns weather a certain argument was actually given \ingroup PA bool pa_defined(const std::string ¶m); /// returns list of args not defined in pa_defined and not subargs of those /** only available if pa_init was called with skipUnknownArgs*/ const std::vector &pa_dangling_args(); /// internal utility function const std::string &pa_arg_internal(unsigned int index) throw (ICLException); /// internal utility function const std::string &pa_subarg_internal(const std::string ¶m, unsigned int idx) throw (ICLException); /// access to the actually given program arguments \ingroup PA /** Note: Arguments are received as double and than parsed using the std::istream-operator-based icl::parse-template function. */ template inline T pa_arg(unsigned int index) throw (ICLException){ return parse(pa_arg_internal(index)); } /// access to sub arguments with a given default value \ingroup PA /** If the given argument "param" was not actually given, the default argument is returned without an additional warning message. Possible types T are: - string (std::string) - int - uint - bool - char - uchar - float - double */ template inline T pa_subarg(const std::string ¶m, unsigned int index, T defaultValue) throw (ICLException){ try{ return parse(pa_subarg_internal(param,index)); }catch(...){} return defaultValue; } } #endif