home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cmdline.lha / cmdline / src / lib / cmdargs.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  30.4 KB  |  973 lines

  1. //------------------------------------------------------------------------
  2. // ^FILE: cmdargs.h - define the most commonly used argument types
  3. //
  4. // ^DESCRIPTION:
  5. //    This file defines classes for the most commonly used types of
  6. //    command-line arguments.  Most command-line arguments are either
  7. //    boolean-flags, a number, a character, or a string (or a list of
  8. //    numbers or strings).  In each of these cases, the call operator
  9. //    (operator()) of the argument just compiles the value given into
  10. //    some internal value and waits for the programmer to query the
  11. //    value at some later time.
  12. //
  13. //    I call these types of arguments "ArgCompilers". For each of the
  14. //    most common argument types, a corresponding abstract ArgCompiler
  15. //    class is declared.  All that this class does is to add a member
  16. //    function named "compile" to the class.  The "compile()" function
  17. //    looks exactly like the call operator but it takes an additional
  18. //    parameter: a reference to the value to be modified by compiling
  19. //    the argument value.  In all other respects, the "compile()" member
  20. //    function behaves exactly like the call operator.  In fact, most
  21. //    of the call-operator member functions simply call the ArgCompiler's
  22. //    "compile()" member function with the appropriate value and return
  23. //    whatever the compile function returned.
  24. //
  25. //    Once all of these ArgCompilers are declared, it is a simple matter
  26. //    to declare a class that holds a single item, or a list of items,
  27. //    by deriving it from the corresponding ArgCompiler type.
  28. //
  29. //    For derived classes of these ArgCompilers that hold a single item,
  30. //    The derived class implements some operators (such as operator=
  31. //    and an appropriate cast operator) to treat the argument as if it
  32. //    were simply an item (instead of an argument that contains an item).
  33. //    The output operator (ostream & operator<<) is also defined.
  34. //
  35. //    For derived classes of ArgCompilers that hold a list of items,
  36. //    the subscript operator[] is defined in order to treat the argument
  37. //    as if it were simply an array of items and not an argument that
  38. //    contains a list of items.
  39. //
  40. //    *NOTE*
  41. //    ======
  42. //    It is important to remember that each subclass of CmdArg MUST be able
  43. //    to handle NULL as the first argument to the call-operator (and it
  44. //    should NOT be considered an error).  This is because NULL will be
  45. //    passed if the argument takes no value, or if it takes an optional
  46. //    value that was NOT provided on the command-line.  Whenever an
  47. //    argument is correctly specified on the command-line, its call
  48. //    operator is always invoked (regardless of whether or not there
  49. //    is a corresponding value from the command-line).
  50. //
  51. // ^HISTORY:
  52. //    03/25/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  53. //-^^---------------------------------------------------------------------
  54.  
  55. #ifndef _usr_include_cmdargs_h
  56. #define _usr_include_cmdargs_h
  57.  
  58. #include <cmdline.h>
  59.  
  60. //-------------------------------------------------------------- Dummy Argument
  61.  
  62.    // A Dummy argument is one that is used only for its appearance in
  63.    // usage messages. It is completely ignored by the CmdLine object
  64.    // when parsing the command-line.
  65.    //
  66.    // Examples:
  67.    //     CmdArgDummy  dummy1('c', "keyword", "value", "dummy argument # 1");
  68.    //     CmdArgDummy  dummy2("value", "dummy argument # 2");
  69.    //
  70. class CmdArgDummy : public CmdArg {
  71. public:
  72.    CmdArgDummy(char         optchar,
  73.                const char * keyword,
  74.                const char * value,
  75.                const char * description,
  76.                unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  77.       : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  78.  
  79.    CmdArgDummy(char         optchar,
  80.                const char * keyword,
  81.                const char * description,
  82.                unsigned     syntax_flags =CmdArg::isOPT)
  83.       : CmdArg(optchar, keyword, description, syntax_flags) {}
  84.  
  85.    CmdArgDummy(const char * value,
  86.                const char * description,
  87.                unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  88.       : CmdArg(value, description, syntax_flags) {}
  89.  
  90.    CmdArgDummy(const CmdArgDummy & cp) : CmdArg(cp) {}
  91.  
  92.    CmdArgDummy(const CmdArg & cp) : CmdArg(cp) {}
  93.  
  94.    virtual ~CmdArgDummy(void);
  95.  
  96.    virtual  int
  97.    is_dummy(void);   // return non-zero
  98.  
  99.    virtual  int
  100.    operator()(const char * & arg, CmdLine & cmd);  // NO-OP
  101. } ;
  102.  
  103. //-------------------------------------------------------------- Usage Argument
  104.  
  105.    // The sole purpose of a usage argument is to immediately print the
  106.    // program usage (as soon as it is matched) and to exit.
  107.    //
  108.    // There is a default usage argument in every CmdLine object.
  109.    //
  110.    // Example:
  111.    //    CmdArgUsage  usage_arg('?', "help", "print usage and exit");
  112.    //
  113. class  CmdArgUsage : public CmdArg {
  114. public:
  115.    CmdArgUsage(char         optchar,
  116.                const char * keyword,
  117.                const char * description)
  118.       : CmdArg(optchar, keyword, description, CmdArg::isOPT) {}
  119.  
  120.    CmdArgUsage(const CmdArgUsage & cp) : CmdArg(cp) {}
  121.  
  122.    CmdArgUsage(const CmdArg & cp) : CmdArg(cp) {}
  123.  
  124.    virtual ~CmdArgUsage(void);
  125.  
  126.    virtual  int
  127.    operator()(const char * & arg, CmdLine & cmd);
  128. } ;
  129.  
  130. //----------------------------------------------------------- Integer Arguments
  131.  
  132.    // Look under "List Arguments" for a CmdArg that is a list of ints
  133.  
  134.    // CmdArgIntCompiler is the base class for all arguments need to
  135.    // convert the string given on the command-line into an integer.
  136.    //
  137. class  CmdArgIntCompiler : public CmdArg {
  138. public:
  139.    CmdArgIntCompiler(char         optchar,
  140.                      const char * keyword,
  141.                      const char * value,
  142.                      const char * description,
  143.                      unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  144.       : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  145.  
  146.    CmdArgIntCompiler(const char * value,
  147.                      const char * description,
  148.                      unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  149.       : CmdArg(value, description, syntax_flags) {}
  150.  
  151.    CmdArgIntCompiler(const CmdArgIntCompiler & cp) : CmdArg(cp) {}
  152.  
  153.    CmdArgIntCompiler(const CmdArg & cp) : CmdArg(cp) {}
  154.  
  155.    virtual ~CmdArgIntCompiler(void);
  156.  
  157.    virtual  int
  158.    operator()(const char * & arg, CmdLine & cmd) = 0;
  159.  
  160.    int
  161.    compile(const char * & arg, CmdLine & cmd, int & value);
  162. } ;
  163.  
  164.  
  165.    // CmdArgInt - an argument that contains a single integer.
  166.    //
  167.    // The following member functions are provided to treat
  168.    // a CmdArgInt as if it were an integer:
  169.    //
  170.    //    operator=(int);
  171.    //    operator int(void);
  172.    //    operator<<(os, CmdArgInt);
  173.    //
  174.    // The integer value is initialized to zero by the constructor.
  175.    //
  176.    // Examples:
  177.    //     CmdArgInt  count('c', "count", "number", "# of copies to print");
  178.    //     CmdArgInt  nlines("lines", "number of lines to print);
  179.    //
  180.    //     count = 1;
  181.    //     nlines = 0;
  182.    //
  183.    //     if (count > 1) { ... }
  184.    //     cout << "number of lines is " << nlines << endl ;
  185.    //
  186. class  CmdArgInt : public CmdArgIntCompiler {
  187. public:
  188.    CmdArgInt(char         optchar,
  189.              const char * keyword,
  190.              const char * value,
  191.              const char * description,
  192.              unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  193.       : CmdArgIntCompiler(optchar, keyword, value, description, syntax_flags),
  194.         val(0) {}
  195.  
  196.    CmdArgInt(const char * value,
  197.              const char * description,
  198.              unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  199.       : CmdArgIntCompiler(value, description, syntax_flags), val(0) {}
  200.  
  201.    virtual ~CmdArgInt(void);
  202.  
  203.    virtual  int
  204.    operator()(const char * & arg, CmdLine & cmd);
  205.  
  206.    CmdArgInt(const CmdArgInt & cp) : CmdArgIntCompiler(cp), val(cp.val) {}
  207.  
  208.    CmdArgInt(const CmdArg & cp) : CmdArgIntCompiler(cp), val(0) {}
  209.  
  210.    CmdArgInt &
  211.    operator=(const CmdArgInt & cp)  { val = cp.val; return  *this; }
  212.  
  213.    CmdArgInt &
  214.    operator=(int cp)  { val = cp; return  *this; }
  215.  
  216.    operator int(void)  const { return  val; }
  217.  
  218. private:
  219.    int   val;
  220. } ;
  221.  
  222. ostream &
  223. operator<<(ostream & os, const CmdArgInt & int_arg);
  224.  
  225. //---------------------------------------------------- Floating-point Arguments
  226.  
  227.    // Look under "List Arguments" for a CmdArg that is a list of floats
  228.  
  229.    // CmdArgFloatCompiler is the base class for all arguments
  230.    // need to convert the string given on the command-line into
  231.    // a floating-point value.
  232.    //
  233. class  CmdArgFloatCompiler : public CmdArg {
  234. public:
  235.    CmdArgFloatCompiler(char         optchar,
  236.                        const char * keyword,
  237.                        const char * value,
  238.                        const char * description,
  239.                        unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  240.       : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  241.  
  242.    CmdArgFloatCompiler(const char * value,
  243.                        const char * description,
  244.                        unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  245.       : CmdArg(value, description, syntax_flags) {}
  246.  
  247.    CmdArgFloatCompiler(const CmdArgFloatCompiler & cp) : CmdArg(cp) {}
  248.  
  249.    CmdArgFloatCompiler(const CmdArg & cp) : CmdArg(cp) {}
  250.  
  251.    virtual ~CmdArgFloatCompiler(void);
  252.  
  253.    virtual  int
  254.    operator()(const char * & arg, CmdLine & cmd) = 0;
  255.  
  256.    int
  257.    compile(const char * & arg, CmdLine & cmd, float & value);
  258. } ;
  259.  
  260.  
  261.    // CmdArgFloat - an argument that contains a single floating-point value.
  262.    //
  263.    // The following member functions are provided to treat
  264.    // a CmdArgFloat as if it were a float:
  265.    //
  266.    //    operator=(float);
  267.    //    operator float(void);
  268.    //    operator<<(os, CmdArgFloat);
  269.    //
  270.    // The floating-point value is initialized to zero by the constructor.
  271.    //
  272.    // Examples:
  273.    //     CmdArgFloat  major('m', "major", "#", "major radius of ellipse");
  274.    //     CmdArgFloat  minor("minor", "minor radius of ellipse");
  275.    //
  276.    //     major = 2.71828;
  277.    //     minor = 3.14159;
  278.    //
  279.    //     if (minor > major)  {  /* swap major and minor */ }
  280.    //
  281.    //     cout << "major radius is " << major << endl ;
  282.    //
  283. class  CmdArgFloat : public CmdArgFloatCompiler {
  284. public:
  285.    CmdArgFloat(char         optchar,
  286.                const char * keyword,
  287.                const char * value,
  288.                const char * description,
  289.                unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  290.       : CmdArgFloatCompiler(optchar, keyword, value, description, syntax_flags),
  291.         val(0) {}
  292.  
  293.    CmdArgFloat(const char * value,
  294.                const char * description,
  295.                unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  296.       : CmdArgFloatCompiler(value, description, syntax_flags), val(0) {}
  297.  
  298.    virtual ~CmdArgFloat(void);
  299.  
  300.    virtual  int
  301.    operator()(const char * & arg, CmdLine & cmd);
  302.  
  303.    CmdArgFloat(const CmdArgFloat & cp)
  304.       : CmdArgFloatCompiler(cp), val(cp.val) {}
  305.  
  306.    CmdArgFloat(const CmdArg & cp)
  307.       : CmdArgFloatCompiler(cp), val(0) {}
  308.  
  309.    CmdArgFloat &
  310.    operator=(const CmdArgFloat & cp)  { val = cp.val; return  *this; }
  311.  
  312.    CmdArgFloat &
  313.    operator=(float cp)  { val = cp; return  *this; }
  314.  
  315.    operator float(void)  const  { return  val; }
  316.  
  317. private:
  318.    float   val;
  319. } ;
  320.  
  321. ostream &
  322. operator<<(ostream & os, const CmdArgFloat & float_arg);
  323.  
  324.  
  325. //--------------------------------------------------------- Character Arguments
  326.  
  327.    // CmdArgCharCompiler is the base class for all arguments need to
  328.    // convert the string given on the command-line into a character.
  329.    //
  330. class  CmdArgCharCompiler : public CmdArg {
  331. public:
  332.    CmdArgCharCompiler(char         optchar,
  333.                       const char * keyword,
  334.                       const char * value,
  335.                       const char * description,
  336.                       unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  337.       : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  338.  
  339.    CmdArgCharCompiler(const char * value,
  340.                       const char * description,
  341.                       unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  342.       : CmdArg(value, description, syntax_flags) {}
  343.  
  344.    CmdArgCharCompiler(const CmdArgCharCompiler & cp) : CmdArg(cp) {}
  345.  
  346.    CmdArgCharCompiler(const CmdArg & cp) : CmdArg(cp) {}
  347.  
  348.    virtual ~CmdArgCharCompiler(void);
  349.  
  350.    virtual  int
  351.    operator()(const char * & arg, CmdLine & cmd) = 0;
  352.  
  353.    int
  354.    compile(const char * & arg, CmdLine & cmd, char & value);
  355. } ;
  356.  
  357.  
  358.    // CmdArgChar - an argument that contains a single character.
  359.    //
  360.    // The following member functions are provided to treat
  361.    // a CmdArgChar as if it were a character:
  362.    //
  363.    //    operator=(char);
  364.    //    operator char(void);
  365.    //    operator<<(os, CmdArgChar);
  366.    //
  367.    // The character value is initialized to '\0' by the constructor.
  368.    //
  369.    // Examples:
  370.    //     CmdArgChar  ignore('i', "ignore", "character to ignore);
  371.    //     CmdArgChar  sep("field-separator");
  372.    //
  373.    //     ignore = ' ';
  374.    //     sep = ',';
  375.    //
  376.    //     if (sep == '\0') { /* error */ }
  377.    //
  378.    //     cout << "ignore character is '" << ignore << "'" << endl ;
  379.    //
  380. class  CmdArgChar : public CmdArgCharCompiler {
  381. public:
  382.    CmdArgChar(char         optchar,
  383.               const char * keyword,
  384.               const char * value,
  385.               const char * description,
  386.               unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  387.       : CmdArgCharCompiler(optchar, keyword, value, description, syntax_flags),
  388.         val(0) {}
  389.  
  390.    CmdArgChar(const char * value,
  391.               const char * description,
  392.               unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  393.       : CmdArgCharCompiler(value, description, syntax_flags), val(0) {}
  394.  
  395.    virtual ~CmdArgChar(void);
  396.  
  397.    virtual  int
  398.    operator()(const char * & arg, CmdLine & cmd);
  399.  
  400.    CmdArgChar(const CmdArgChar & cp) : CmdArgCharCompiler(cp), val(cp.val) {}
  401.  
  402.    CmdArgChar(const CmdArg & cp) : CmdArgCharCompiler(cp), val(0) {}
  403.  
  404.    CmdArgChar &
  405.    operator=(const CmdArgChar & cp)  { val = cp.val; return  *this; }
  406.  
  407.    CmdArgChar &
  408.    operator=(char cp)  { val = cp; return  *this; }
  409.  
  410.    operator char(void)  const  { return  val; }
  411.  
  412. private:
  413.    char   val;
  414. } ;
  415.  
  416. ostream &
  417. operator<<(ostream & os, const CmdArgChar & char_arg);
  418.  
  419. //------------------------------------------------------------ String Arguments
  420.  
  421.    // Look under "List Arguments" for a CmdArg that is a list of strings
  422.  
  423.    // CmdArgIntCompiler is the base class for all arguments need to
  424.    // convert the string given on the command-line into a string.
  425.    //
  426. class  CmdArgStrCompiler : public CmdArg {
  427. public:
  428.    // We need an internal string type here because sometimes we need
  429.    // to allocate new space for the string, and sometimes we dont.
  430.    // We need a string type that knows how it was allocated and
  431.    // to behave accordingly.
  432.    //
  433.    // Since the programmer, will be seeing our string type instead of
  434.    // a "char *" we need to provide some operators for our string
  435.    // type that make it unnecessary to know the difference between
  436.    // it and a "char *" (in most cases).
  437.    //
  438.    struct  casc_string {
  439.       unsigned     is_alloc : 1 ;
  440.       const char * str ;
  441.  
  442.       casc_string(void) : is_alloc(0), str(0) {}
  443.  
  444.       casc_string(const char * s) : is_alloc(0), str(s) {}
  445.  
  446.       void
  447.       copy(unsigned  is_temporary, const char * s);
  448.  
  449.       casc_string(unsigned  is_temporary, const char * s)
  450.          : is_alloc(0), str(0) { copy(is_temporary, s); }
  451.  
  452.       casc_string(const casc_string & cp)
  453.          : is_alloc(0), str(0) { copy(cp.is_alloc, cp.str); }
  454.  
  455.       casc_string &
  456.       operator=(const casc_string & cp)
  457.          { copy(cp.is_alloc, cp.str); return *this; }
  458.  
  459.       casc_string &
  460.       operator=(const char * cp) { copy(0, cp); return *this; }
  461.  
  462.       operator const char*(void)  const { return  str; }
  463.  
  464.       virtual ~casc_string(void)
  465. #ifdef __gplusplus
  466.          { if (is_alloc)   delete [] (char *) str; }
  467. #endif
  468.       ;
  469.    } ;
  470.  
  471.    CmdArgStrCompiler(char         optchar,
  472.                      const char * keyword,
  473.                      const char * value,
  474.                      const char * description,
  475.                      unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  476.       : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  477.  
  478.    CmdArgStrCompiler(const char * value,
  479.                      const char * description,
  480.                      unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  481.       : CmdArg(value, description, syntax_flags) {}
  482.  
  483.    CmdArgStrCompiler(const CmdArgStrCompiler & cp) : CmdArg(cp) {}
  484.  
  485.    CmdArgStrCompiler(const CmdArg & cp) : CmdArg(cp) {}
  486.  
  487.    virtual ~CmdArgStrCompiler(void);
  488.  
  489.    virtual  int
  490.    operator()(const char * & arg, CmdLine & cmd) = 0;
  491.  
  492.    int
  493.    compile(const char * & arg, CmdLine & cmd, casc_string & value) ;
  494. } ;
  495.  
  496.  
  497.    // CmdArgStr - an argument that holds a single string
  498.    //
  499.    // The following member functions are provided to treat
  500.    // a CmdArgStr as if it were a string:
  501.    //
  502.    //    operator=(char*);
  503.    //    operator char*(void);
  504.    //    operator<<(os, CmdArgStr);
  505.    // 
  506.    // The string value is initialized to NULL by the constructor.
  507.    //
  508.    // Examples:
  509.    //     CmdArgStr  input('i', "input", "filename", "file to read");
  510.    //     CmdArgStr  output("output-file", "file to write);
  511.    //
  512.    //     input = "/usr/input" ;
  513.    //     output = "/usr/output" ;
  514.    //
  515.    //     if (strcmp(input, output) == 0) {
  516.    //        cerr << "input and output are the same file: " << input << endl ;
  517.    //     }
  518.    //
  519. class  CmdArgStr : public CmdArgStrCompiler {
  520. public:
  521.    CmdArgStr(char         optchar,
  522.              const char * keyword,
  523.              const char * value,
  524.              const char * description,
  525.              unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  526.       : CmdArgStrCompiler(optchar, keyword, value, description, syntax_flags),
  527.         val(0) {}
  528.  
  529.    CmdArgStr(const char * value,
  530.              const char * description,
  531.              unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  532.       : CmdArgStrCompiler(value, description, syntax_flags), val(0) {}
  533.  
  534.    virtual ~CmdArgStr(void);
  535.  
  536.    virtual  int
  537.    operator()(const char * & arg, CmdLine & cmd);
  538.  
  539.    CmdArgStr(const CmdArgStr & cp) : CmdArgStrCompiler(cp), val(cp.val) {}
  540.  
  541.    CmdArgStr(const CmdArg & cp) : CmdArgStrCompiler(cp), val(0) {}
  542.  
  543.    CmdArgStr &
  544.    operator=(const CmdArgStr & cp)  { val = cp.val; return  *this; }
  545.  
  546.    CmdArgStr &
  547.    operator=(const CmdArgStrCompiler::casc_string & cp)
  548.       { val = cp; return  *this; }
  549.  
  550.    CmdArgStr &
  551.    operator=(const char * cp)  { val = cp; return  *this; }
  552.  
  553.    operator CmdArgStrCompiler::casc_string(void)  { return  val; }
  554.  
  555.    operator const char*(void)  const { return  val.str; }
  556.  
  557.    // use this for comparing to NULL
  558.    int isNULL(void) const { return (val.str) ? 0 : 1; }
  559.  
  560. private:
  561.    CmdArgStrCompiler::casc_string  val;
  562. } ;
  563.  
  564. ostream &
  565. operator<<(ostream & os, const CmdArgStrCompiler::casc_string & str);
  566.  
  567. ostream &
  568. operator<<(ostream & os, const CmdArgStr & str_arg);
  569.  
  570. //-------------------------------------------------------------- List Arguments
  571.  
  572.    // For each of the list argument types:
  573.    //    The list is initially empty. The only way to add to the list
  574.    //    is with operator(). The number of items in the list may
  575.    //    be obtained by the "count()" member function and a given
  576.    //    item may be obtained by treating the list as an array and
  577.    //    using operator[] to index into the list.
  578.    //
  579.  
  580.  
  581.    // CmdArgIntList - an argument that holds a list of integers
  582.    //
  583.    // Example:
  584.    //     CmdArgIntList ints('i', "ints", "numbers ...", "a list of integers");
  585.    //     CmdArgIntList ints("numbers ...", "a positional list of integers");
  586.    //
  587.    //     for (int i = 0 ; i < ints.count() ; i++) {
  588.    //        cout << "integer #" << i << " is " << ints[i] << endl ;
  589.    //     }
  590.    //
  591. struct CmdArgIntListPrivate;
  592. class  CmdArgIntList : public CmdArgIntCompiler {
  593. public:
  594.    CmdArgIntList(char    optchar,
  595.             const char * keyword,
  596.             const char * value,
  597.             const char * description,
  598.             unsigned   syntax_flags =(CmdArg::isOPTVALREQ + CmdArg::isLIST))
  599.       : CmdArgIntCompiler(optchar, keyword, value, description, syntax_flags),
  600.         val(0) {}
  601.  
  602.    CmdArgIntList(const char * value,
  603.             const char * description,
  604.             unsigned   syntax_flags =(CmdArg::isPOSVALREQ + CmdArg::isLIST))
  605.       : CmdArgIntCompiler(value, description, syntax_flags), val(0) {}
  606.  
  607.    virtual ~CmdArgIntList(void);
  608.  
  609.    virtual  int
  610.    operator()(const char * & arg, CmdLine & cmd);
  611.  
  612.    unsigned
  613.    count(void) const;
  614.  
  615.    int &
  616.    operator[](unsigned  index);
  617.  
  618. private:
  619.    CmdArgIntList(const CmdArgInt & cp);
  620.  
  621.    CmdArgIntList &
  622.    operator=(const CmdArgInt & cp);
  623.  
  624.    CmdArgIntListPrivate * val;
  625. } ;
  626.  
  627.  
  628.    // CmdArgFloatList - an argument that holds a list of floats
  629.    //
  630.    // Example:
  631.    //     CmdArgFloatList flts('f', "flts", "numbers ...", "a list of floats");
  632.    //     CmdArgFloatList flts("numbers ...", "a positional list of floats");
  633.    //
  634.    //     for (int i = 0 ; i < flts.count() ; i++) {
  635.    //        cout << "Float #" << i << " is " << flts[i] << endl ;
  636.    //     }
  637.    //
  638. struct CmdArgFloatListPrivate;
  639. class  CmdArgFloatList : public CmdArgFloatCompiler {
  640. public:
  641.    CmdArgFloatList(char    optchar,
  642.               const char * keyword,
  643.               const char * value,
  644.               const char * description,
  645.               unsigned   syntax_flags =(CmdArg::isOPTVALREQ + CmdArg::isLIST))
  646.       : CmdArgFloatCompiler(optchar, keyword, value, description, syntax_flags),
  647.         val(0) {}
  648.  
  649.    CmdArgFloatList(const char * value,
  650.               const char * description,
  651.               unsigned   syntax_flags =(CmdArg::isPOSVALREQ + CmdArg::isLIST))
  652.       : CmdArgFloatCompiler(value, description, syntax_flags), val(0) {}
  653.  
  654.    virtual ~CmdArgFloatList(void);
  655.  
  656.    virtual  int
  657.    operator()(const char * & arg, CmdLine & cmd);
  658.  
  659.    unsigned
  660.    count(void) const;
  661.  
  662.    float &
  663.    operator[](unsigned  index);
  664.  
  665. private:
  666.    CmdArgFloatList(const CmdArgFloat & cp);
  667.  
  668.    CmdArgFloatList &
  669.    operator=(const CmdArgFloat & cp);
  670.  
  671.    CmdArgFloatListPrivate * val;
  672. } ;
  673.  
  674.  
  675.    // CmdArgStrList - an argument that holds a list of strings
  676.    //
  677.    // Example:
  678.    //     CmdArgStrList strs('s', "strs", "strings ...", "a list of strings");
  679.    //     CmdArgStrList strs("strings ...", "a positional list of strings");
  680.    //
  681.    //     for (int i = 0 ; i < strs.count() ; i++) {
  682.    //        cout << "String #" << i << " is " << strs[i] << endl ;
  683.    //     }
  684.    //
  685. struct CmdArgStrListPrivate;
  686. class  CmdArgStrList : public CmdArgStrCompiler {
  687. public:
  688.    CmdArgStrList(char    optchar,
  689.             const char * keyword,
  690.             const char * value,
  691.             const char * description,
  692.             unsigned   syntax_flags =(CmdArg::isOPTVALREQ + CmdArg::isLIST))
  693.       : CmdArgStrCompiler(optchar, keyword, value, description, syntax_flags),
  694.         val(0) {}
  695.  
  696.    CmdArgStrList(const char * value,
  697.             const char * description,
  698.             unsigned   syntax_flags =(CmdArg::isPOSVALREQ + CmdArg::isLIST))
  699.       : CmdArgStrCompiler(value, description, syntax_flags), val(0) {}
  700.  
  701.    virtual ~CmdArgStrList(void);
  702.  
  703.    virtual  int
  704.    operator()(const char * & arg, CmdLine & cmd);
  705.  
  706.    unsigned
  707.    count(void) const;
  708.  
  709.    CmdArgStrCompiler::casc_string &
  710.    operator[](unsigned  index);
  711.  
  712. private:
  713.    CmdArgStrList(const CmdArgStr & cp);
  714.  
  715.    CmdArgStrList &
  716.    operator=(const CmdArgStr & cp);
  717.  
  718.    CmdArgStrListPrivate * val;
  719. } ;
  720.  
  721. //----------------------------------------------------------- Boolean Arguments
  722.  
  723.    // Boolean arguments are a bit tricky, first of all - we have three
  724.    // different kinds:
  725.    //
  726.    //    1) An argument whose presence SETS a value
  727.    //
  728.    //    2) An argument whose presence UNSETS a value
  729.    //
  730.    //    3) An argument whose presence TOGGLES a value
  731.    //
  732.    // Furthermore, it is not uncommon (especially in VAX/VMS) to have
  733.    // one argument that SETS and value, and another argument that
  734.    // UNSETS the SAME value.
  735.    //
  736.  
  737.    // CmdArgBoolCompiler is a special type of ArgCompiler, not only does
  738.    // its "compile" member function take a reference to the boolean value,
  739.    // but it also needs to know what default-value to use if no explicit
  740.    // value (such as '0', '1', "ON" or "FALSE") was given.
  741.    //
  742. class CmdArgBoolCompiler : public CmdArg {
  743. public:
  744.    CmdArgBoolCompiler(char         optchar,
  745.                       const char * keyword,
  746.                       const char * description,
  747.                       unsigned     syntax_flags =CmdArg::isOPT)
  748.       : CmdArg(optchar, keyword, description, syntax_flags) {}
  749.  
  750.    CmdArgBoolCompiler(const CmdArgBoolCompiler & cp) : CmdArg(cp) {}
  751.  
  752.    CmdArgBoolCompiler(const CmdArg & cp) : CmdArg(cp) {}
  753.  
  754.    virtual ~CmdArgBoolCompiler(void);
  755.  
  756.    virtual  int
  757.    operator()(const char * & arg, CmdLine & cmd) = 0;
  758.  
  759.    int
  760.    compile(const char * & arg,
  761.            CmdLine      & cmd,
  762.            unsigned     & value,
  763.            unsigned       default_value =1);
  764. } ;
  765.  
  766.  
  767.    // CmdArgBool is a boolean ArgCompiler that holds a single
  768.    // boolean value, it has three subclasses:
  769.    //
  770.    //   1) CmdArgSet (which is just an alias for CmdArgBool)
  771.    //      -- This argument SETS a boolean value.
  772.    //         The initial value is 0 (OFF).
  773.    //
  774.    //   2) CmdArgClear
  775.    //      -- This argument CLEARS a boolean value
  776.    //         The initial value is 1 (ON).
  777.    //
  778.    //   3) CmdArgToggle
  779.    //      -- This argument TOGGLES a boolean value
  780.    //         The initial value is 0 (OFF).
  781.    //
  782.    // All of these classes have the following member functions
  783.    // to help make it easier to treat a Boolean Argument as
  784.    // a Boolean Value:
  785.    //
  786.    //   operator=(int);
  787.    //   operator int(void);
  788.    //
  789.    // Examples:
  790.    //    CmdArgBool    xflag('x', "xmode", "turn on xmode);
  791.    //    CmdArgClear   yflag('y', "ymode", "turn on ymode);
  792.    //    CmdArgToggle  zflag('z', "zmode", "turn on zmode);
  793.    //
  794.    //    cout << "xmode is " << (xflag ? "ON" : "OFF") << endl ;
  795.    //
  796. class CmdArgBool : public CmdArgBoolCompiler {
  797. public:
  798.    CmdArgBool(char         optchar,
  799.               const char * keyword,
  800.               const char * description,
  801.               unsigned     syntax_flags =CmdArg::isOPT)
  802.       : CmdArgBoolCompiler(optchar, keyword, description, syntax_flags),
  803.         val(0) {}
  804.  
  805.    CmdArgBool(const CmdArgBool & cp) : CmdArgBoolCompiler(cp), val(cp.val) {}
  806.  
  807.    CmdArgBool(const CmdArg & cp) : CmdArgBoolCompiler(cp), val(0) {}
  808.  
  809.    virtual ~CmdArgBool(void);
  810.  
  811.    CmdArgBool &
  812.    operator=(const CmdArgBool & cp)
  813.       { val = cp.val; return  *this; }
  814.  
  815.    CmdArgBool &
  816.    operator=(int new_value)
  817.       { val = (new_value) ? 1 : 0; return *this; }
  818.  
  819.    operator int(void) const { return  val; }
  820.  
  821.    virtual  int
  822.    operator()(const char * & arg, CmdLine & cmd);
  823.  
  824. protected:
  825.    unsigned  val : 1;
  826. } ;
  827.  
  828. ostream &
  829. operator<<(ostream & os, const CmdArgBool & bool_arg);
  830.  
  831. typedef  CmdArgBool  CmdArgSet ;
  832.  
  833. class CmdArgClear : public CmdArgBool {
  834. public:
  835.    CmdArgClear(char         optchar,
  836.                const char * keyword,
  837.                const char * description,
  838.                unsigned     syntax_flags =CmdArg::isOPT)
  839.       : CmdArgBool(optchar, keyword, description, syntax_flags) { val = 1; }
  840.  
  841.    CmdArgClear(const CmdArgClear & cp) : CmdArgBool(cp) {}
  842.  
  843.    CmdArgClear(const CmdArg & cp) : CmdArgBool(cp) { val = 1; }
  844.  
  845.    virtual ~CmdArgClear(void);
  846.  
  847.    CmdArgClear &
  848.    operator=(const CmdArgClear & cp)
  849.       { val = cp.val; return  *this; }
  850.  
  851.    CmdArgClear &
  852.    operator=(int new_value)
  853.       { val = (new_value) ? 1 : 0; return *this; }
  854.  
  855.    operator int(void) const { return  val; }
  856.  
  857.    virtual  int
  858.    operator()(const char * & arg, CmdLine & cmd);
  859. } ;
  860.  
  861. class CmdArgToggle : public CmdArgBool {
  862. public:
  863.    CmdArgToggle(char         optchar,
  864.                 const char * keyword,
  865.                 const char * description,
  866.                 unsigned     syntax_flags =CmdArg::isOPT)
  867.       : CmdArgBool(optchar, keyword, description, syntax_flags) {}
  868.  
  869.    CmdArgToggle(const CmdArgToggle & cp) : CmdArgBool(cp) {}
  870.  
  871.    CmdArgToggle(const CmdArg & cp) : CmdArgBool(cp) {}
  872.  
  873.    virtual ~CmdArgToggle(void);
  874.  
  875.    CmdArgToggle &
  876.    operator=(const CmdArgToggle & cp)
  877.       { val = cp.val; return  *this; }
  878.  
  879.    CmdArgToggle &
  880.    operator=(int new_value)
  881.       { val = (new_value) ? 1 : 0; return *this; }
  882.  
  883.    operator int(void) const { return  val; }
  884.  
  885.    virtual  int
  886.    operator()(const char * & arg, CmdLine & cmd);
  887. } ;
  888.  
  889.  
  890.    // Now we come to the Reference Boolean arguments, these are boolean
  891.    // arguments that reference the very same value as some other boolean
  892.    // argument. The constructors for Reference Boolean arguments require
  893.    // a reference to the boolean argument whose value they are referencing.
  894.    //
  895.    // The boolean reference classes are as follows:
  896.    //
  897.    //   1) CmdArgBoolRef and CmdArgSetRef
  898.    //      -- SET the boolean value referenced by a CmdArgBool
  899.    //
  900.    //   2) CmdArgClearRef
  901.    //      -- CLEAR the boolean value referenced by a CmdArgBool
  902.    //
  903.    //   3) CmdArgToggleRef
  904.    //      -- TOGGLE the boolean value referenced by a CmdArgBool
  905.    //
  906.    // Examples:
  907.    //    CmdArgBool    xflag('x', "xmode", "turn on xmode");
  908.    //    CmdArgClear   yflag('Y', "noymode", "turn off ymode");
  909.    //    CmdArgToggle  zflag('z', "zmode", "toggle zmode");
  910.    //
  911.    //    CmdArgClearRef x_off(xflag, 'X', "noxmode", "turn off xmode");
  912.    //    CmdArgBoolRef  y_on(yflag, 'Y', "ymode", "turn on ymode");
  913.    //
  914.    //    cout << "xmode is " << (xflag ? "ON" : "OFF") << endl ;
  915.    //
  916. class CmdArgBoolRef : public CmdArg {
  917. public:
  918.    CmdArgBoolRef(CmdArgBool & bool_arg,
  919.                  char         optchar,
  920.                  const char * keyword,
  921.                  const char * description,
  922.                  unsigned     syntax_flags =CmdArg::isOPT)
  923.       : CmdArg(optchar, keyword, description, syntax_flags), ref(bool_arg) {}
  924.  
  925.    virtual  ~CmdArgBoolRef(void);
  926.  
  927.    virtual  int
  928.    operator()(const char * & arg, CmdLine & cmd);
  929.  
  930. protected:
  931.    CmdArgBool & ref;
  932. } ;
  933.  
  934. typedef CmdArgBoolRef  CmdArgSetRef ;
  935.  
  936. class CmdArgClearRef : public CmdArg {
  937. public:
  938.    CmdArgClearRef(CmdArgBool & bool_arg,
  939.                   char         optchar,
  940.                   const char * keyword,
  941.                   const char * description,
  942.                   unsigned     syntax_flags =CmdArg::isOPT)
  943.       : CmdArg(optchar, keyword, description, syntax_flags), ref(bool_arg) {}
  944.  
  945.    virtual  ~CmdArgClearRef(void);
  946.  
  947.    virtual  int
  948.    operator()(const char * & arg, CmdLine & cmd);
  949.  
  950. protected:
  951.    CmdArgBool & ref;
  952. } ;
  953.  
  954. class CmdArgToggleRef : public CmdArg {
  955. public:
  956.    CmdArgToggleRef(CmdArgBool & bool_arg,
  957.                   char         optchar,
  958.                   const char * keyword,
  959.                   const char * description,
  960.                   unsigned     syntax_flags =CmdArg::isOPT)
  961.       : CmdArg(optchar, keyword, description, syntax_flags), ref(bool_arg) {}
  962.  
  963.    virtual  ~CmdArgToggleRef(void);
  964.  
  965.    virtual  int
  966.    operator()(const char * & arg, CmdLine & cmd);
  967.  
  968. protected:
  969.    CmdArgBool & ref;
  970. } ;
  971.  
  972. #endif /* _usr_include_cmdargs_h */
  973.