home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / cmdline / patch01b / PATCH01.B
Encoding:
Text File  |  1993-04-04  |  30.8 KB  |  988 lines

  1. *** src/lib/cmdline.h.OLD    Fri Mar 26 10:50:26 1993
  2. --- src/lib/cmdline.h    Tue Mar 23 17:02:47 1993
  3. ***************
  4. *** 9,14 ****
  5. --- 9,21 ----
  6.   //
  7.   // ^HISTORY:
  8.   //    03/19/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  9. + //
  10. + //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  11. + //    - Added arg_sequence field to CmdArg
  12. + //    - Added cmd_nargs_parsed field to CmdLine
  13. + //    - Added cmd_description field to CmdLine
  14. + //    - Added exit_handler() and quit() member-functions to CmdLine
  15. + //    - Added ALLOW_PLUS to list of CmdLine configuration flags
  16.   //-^^---------------------------------------------------------------------
  17.   
  18.   #ifndef _usr_include_cmdline_h
  19. ***************
  20. *** 68,78 ****
  21. --- 75,93 ----
  22.         isLIST      = 0x20,  // argument is a list
  23.         isPOS       = 0x40,  // argument is positional
  24.         isHIDDEN    = 0x80,  // argument is not to be printed in usage
  25. + #ifndef __gplusplus
  26.         isVALTAKEN  = (isVALREQ | isVALOPT),    // argument takes a value
  27.         isOPTVALOPT = (isOPT | isVALOPT),
  28.         isOPTVALREQ = (isOPT | isVALREQ),
  29.         isPOSVALOPT = (isPOS | isVALOPT),
  30.         isPOSVALREQ = (isPOS | isVALREQ),
  31. + #else
  32. +       isVALTAKEN  = 0x06,     // g++ doesnt seem to recognize enums that
  33. +       isOPTVALOPT = 0x02,     // are defined in terms of previous values
  34. +       isOPTVALREQ = 0x04,     // so I have to hard code the values instead.
  35. +       isPOSVALOPT = 0x42,     //
  36. +       isPOSVALREQ = 0x44,     // If this ever changes -- remove this stuff!
  37. + #endif
  38.      } ;
  39.   
  40.        // Flags that say how the argument was specied on the command-line
  41. ***************
  42. *** 204,209 ****
  43. --- 219,234 ----
  44.      unsigned
  45.      flags(void) const  { return  arg_flags; }
  46.   
  47. +       // Get the sequence number corresponding to the last
  48. +       // time this argument was matched on the command-line.
  49. +       //
  50. +       // If this argument was not matched, the sequence number
  51. +       // will be zero, otherwise it will be 'N' where the last
  52. +       // time this argument was matched, it was the 'N'th argument
  53. +       // encountered.
  54. +    unsigned
  55. +    sequence(void) const { return arg_sequence; }
  56.         // Get the character (short-option) name of this argument.
  57.         // Returns '\0' if there isnt one.
  58.      char
  59. ***************
  60. *** 248,253 ****
  61. --- 273,281 ----
  62.      void
  63.      clear(unsigned flags =~0)  { arg_flags &= ~flags; }
  64.   
  65. +       // set sequence number
  66. +    void
  67. +    sequence(unsigned  num) { arg_sequence = num; }
  68.   
  69.      // Private data members
  70.   
  71. ***************
  72. *** 256,261 ****
  73. --- 284,291 ----
  74.      unsigned     arg_flags : 8 ;
  75.      unsigned     arg_syntax : 8 ;
  76.   
  77. +    unsigned     arg_sequence;
  78.      char         arg_char_name;
  79.      const char * arg_keyword_name;
  80.      const char * arg_value_name;
  81. ***************
  82. *** 309,314 ****
  83. --- 339,345 ----
  84.      virtual const char *
  85.      operator()(void);
  86.   
  87. +       // is_temporary returns 0 for CmdArgvIter
  88.      virtual int
  89.      is_temporary(void) const;
  90.   
  91. ***************
  92. *** 361,366 ****
  93. --- 392,398 ----
  94.      void
  95.      delimiters(const char * new_delimiters)  { seps = new_delimiters; }
  96.   
  97. +       // is_temporary returns 1 for CmdStrTokIter
  98.      virtual int
  99.      is_temporary(void) const;
  100.   
  101. ***************
  102. *** 387,392 ****
  103. --- 419,432 ----
  104.      //
  105.   class  CmdIstreamIter : public CmdLineArgIter {
  106.   public:
  107. +    static const unsigned  MAX_LINE_LEN ;
  108. + #ifdef vms
  109. +    enum { c_COMMENT = '!' } ;
  110. + #else
  111. +    enum { c_COMMENT = '#' } ;
  112. + #endif
  113.      CmdIstreamIter(istream & input);
  114.   
  115.      virtual ~CmdIstreamIter(void);
  116. ***************
  117. *** 394,399 ****
  118. --- 434,440 ----
  119.      virtual const char *
  120.      operator()(void);
  121.   
  122. +       // is_temporary returns 1 for CmdIstreamIter
  123.      virtual int
  124.      is_temporary(void) const;
  125.   
  126. ***************
  127. *** 420,426 ****
  128.      enum CmdFlags {
  129.         ANY_CASE_OPTS = 0x001, // Ignore character-case for short-options
  130.         PROMPT_USER   = 0x002, // Prompt the user for missing required args
  131. !       NO_ABORT      = 0x004, // Dont exit upon syntax error
  132.         OPTS_FIRST    = 0x008, // No options after positional parameters
  133.         OPTS_ONLY     = 0x010, // Dont accept short-options
  134.         KWDS_ONLY     = 0x020, // Dont accept long-options
  135. --- 461,467 ----
  136.      enum CmdFlags {
  137.         ANY_CASE_OPTS = 0x001, // Ignore character-case for short-options
  138.         PROMPT_USER   = 0x002, // Prompt the user for missing required args
  139. !       NO_ABORT      = 0x004, // Dont quit upon syntax error
  140.         OPTS_FIRST    = 0x008, // No options after positional parameters
  141.         OPTS_ONLY     = 0x010, // Dont accept short-options
  142.         KWDS_ONLY     = 0x020, // Dont accept long-options
  143. ***************
  144. *** 431,436 ****
  145. --- 472,479 ----
  146.                                   // when we see an unmatched option,
  147.                                   // we will try to see if it matches
  148.                                   // a keyword (and vice-versa).
  149. +       ALLOW_PLUS    = 0x200, // Allow "+" (as well as "--") as a prefix
  150. +                                 // indicating long-options.
  151.      } ;
  152.   
  153.         // Flags to convey parsing-status
  154. ***************
  155. *** 477,482 ****
  156. --- 520,535 ----
  157.      void
  158.      name(const char * progname);
  159.   
  160. +       // Get the command description.
  161. +    const char *
  162. +    description(void)  const  { return  cmd_description; }
  163. +       // Specify a command description.
  164. +    void
  165. +    description(const char * the_description) {
  166. +       cmd_description = the_description;
  167. +    }
  168.         // Append an argument
  169.      CmdLine &
  170.      append(CmdArg * cmdarg);
  171. ***************
  172. *** 615,620 ****
  173. --- 668,708 ----
  174.      epilogue(void) ;
  175.   
  176.      //
  177. +    // Find out the number of arguments parsed so far
  178. +    //
  179. +    unsigned
  180. +    nargs_parsed(void) const { return cmd_nargs_parsed; }
  181. +    //
  182. +    // Exception handling (well -- not really)
  183. +    //
  184. +    typedef  void (* quit_func_t)(int);
  185. +       // When a fatal error is encounteredi or when parsing needs to
  186. +       // terminate immediately, the quit() member function is called.
  187. +       // If the programmer has used quit_handler() to setup his own
  188. +       // handler-function, that that function is called; otherwise
  189. +       // exit() is called with the given status.
  190. +       // 
  191. +    void
  192. +    quit(int status);
  193. +       // Set the quit-handler. The quit-handler is a pointer to
  194. +       // a function that has no return value and takes a single
  195. +       // integer parameter.
  196. +       //
  197. +    void
  198. +    quit_handler(quit_func_t  quit_func) { cmd_quit_handler = quit_func ; }
  199. +       // Get the current quit-handler (returns NULL if there isnt one)
  200. +       //
  201. +    quit_func_t
  202. +    quit_handler(void) const { return  cmd_quit_handler; }
  203. +    //
  204.      // Retrieve a specific argument
  205.      //
  206.   
  207. ***************
  208. *** 704,713 ****
  209. --- 792,804 ----
  210.      unsigned          cmd_state  : 8 ;
  211.      unsigned          cmd_flags  : 16 ;
  212.      unsigned          cmd_status : 16 ;
  213. +    unsigned          cmd_nargs_parsed ;
  214.      const char      * cmd_name ;
  215. +    const char      * cmd_description ;
  216.      CmdArg          * cmd_matched_arg ;
  217.      CmdArgListList  * cmd_args ;
  218.      ostream         * cmd_err ;
  219. +    quit_func_t       cmd_quit_handler ;
  220.   
  221.         // Disallow copying and assignment
  222.      CmdLine(const CmdLine & );
  223. *** src/lib/cmdtest.c.OLD    Fri Mar 26 10:50:31 1993
  224. --- src/lib/cmdtest.c    Wed Mar  3 14:11:57 1993
  225. ***************
  226. *** 6,11 ****
  227. --- 6,14 ----
  228.   //
  229.   // ^HISTORY:
  230.   //    03/18/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  231. + //
  232. + //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  233. + //    - Attached a description to the command.
  234.   //-^^---------------------------------------------------------------------
  235.   
  236.   #include <stdlib.h>
  237. ***************
  238. *** 74,79 ****
  239. --- 77,84 ----
  240.   
  241.            case 'g' : new_flags |= CmdLine::NO_GUESSING;    break;
  242.   
  243. +          case '+' : new_flags |= CmdLine::ALLOW_PLUS;     break;
  244.            default  : break;
  245.         } //switch
  246.      } //for
  247. ***************
  248. *** 100,105 ****
  249. --- 105,111 ----
  250.      't' = Temporary-args\n\
  251.      'q' = Quiet!\n\
  252.      'g' = no-Guessing\n\
  253. +    '+' = allow-plus\n\
  254.   This-is-a-very-long-line-containing-no-whitespace-\
  255.   characters-and-I-just-want-to-see-if-it-gets-\
  256.   formatted-appropriately!"
  257. ***************
  258. *** 200,207 ****
  259. --- 206,219 ----
  260.                   & name,
  261.                   & files,
  262.                   NULL);
  263.      CmdArgvIter  argv_iter(--argc, ++argv);
  264.   
  265. +    cmd.description(
  266. + "This program is intended to statically and dynamically test \
  267. + the CmdLine(3C++) class library."
  268. +    );
  269.      cout << "Test of " << CmdLine::ident() << endl ;
  270.   
  271.      xflag = 0;
  272. ***************
  273. *** 226,232 ****
  274.      int  parse_cin = infile;
  275.   
  276.      // Parse arguments from a string
  277. !    if (str) {
  278.         CmdStrTokIter  tok_iter(str);
  279.   
  280.         xflag = 0;
  281. --- 238,244 ----
  282.      int  parse_cin = infile;
  283.   
  284.      // Parse arguments from a string
  285. !    if (! str.isNULL()) {
  286.         CmdStrTokIter  tok_iter(str);
  287.   
  288.         xflag = 0;
  289. *** src/lib/dump.c.OLD    Fri Mar 26 10:50:35 1993
  290. --- src/lib/dump.c    Mon Mar  1 11:01:33 1993
  291. ***************
  292. *** 8,13 ****
  293. --- 8,18 ----
  294.   //
  295.   // ^HISTORY:
  296.   //    04/01/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  297. + //
  298. + //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  299. + //    - Added arg_sequence field to CmdArg
  300. + //    - Added cmd_nargs_parsed field to CmdLine
  301. + //    - Added cmd_description field to CmdLine
  302.   //-^^---------------------------------------------------------------------
  303.   
  304.   #include  "cmdline.h"
  305. ***************
  306. *** 295,300 ****
  307. --- 300,307 ----
  308.      ::indent(os, level + 1) << "flags=" ;
  309.      dump_arg_flags(os, arg_flags) << "\n";
  310.   
  311. +    ::indent(os, level + 1) << "sequence=" << arg_sequence << "\n";
  312.      ::indent(os, level) << "}" << endl;
  313.   #endif
  314.   }
  315. ***************
  316. *** 309,314 ****
  317. --- 316,323 ----
  318.   
  319.      ::indent(os, level + 1) << "name=\"" << cmd_name << "\"\n";
  320.   
  321. +    ::indent(os, level + 1) << "description=\"" << cmd_description << "\"\n";
  322.      ::indent(os, level + 1) << "flags=" ;
  323.      dump_cmd_flags(os, cmd_flags) << "\n";
  324.   
  325. ***************
  326. *** 327,332 ****
  327. --- 336,344 ----
  328.      } else {
  329.         os << "matched_arg=" << (void *)cmd_matched_arg << "\n";
  330.      }
  331. +    ::indent(os, level + 1) << "# valid-args-parsed="
  332. +                            << cmd_nargs_parsed << "\n" ;
  333.   
  334.      ::indent(os, level) << "}" << endl;
  335.   #endif
  336. *** src/lib/parse.c.OLD    Fri Mar 26 10:50:41 1993
  337. --- src/lib/parse.c    Wed Mar  3 10:02:21 1993
  338. ***************
  339. *** 10,15 ****
  340. --- 10,19 ----
  341.   //
  342.   // ^HISTORY:
  343.   //    12/05/91    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  344. + //
  345. + //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  346. + //    - Added cmd_nargs_parsed field to CmdLine
  347. + //    - Added exit_handler() and quit() member-functions to CmdLine
  348.   //-^^---------------------------------------------------------------------
  349.   
  350.   #include <stdlib.h>
  351. ***************
  352. *** 58,63 ****
  353. --- 62,68 ----
  354.      cmd_parse_state = cmd_START_STATE ;
  355.      cmd_state = 0 ;
  356.      cmd_status = NO_ERROR ;
  357. +    cmd_nargs_parsed = 0 ;
  358.   
  359.      // reset parse-specific attributes for each argument
  360.      CmdArgListListIter  list_iter(cmd_args);
  361. ***************
  362. *** 94,100 ****
  363.   //
  364.   //    Prints a usage message if there were syntax error.
  365.   //
  366. ! //    Terminates program execution by calling ::exit(e_SYNTAX) if
  367.   //    (NO_ABORT is NOT set and the command-status is NOT NO_ERROR).
  368.   //
  369.   // ^RETURN-VALUE:
  370. --- 99,105 ----
  371.   //
  372.   //    Prints a usage message if there were syntax error.
  373.   //
  374. ! //    Terminates program execution by calling quit(e_SYNTAX) if
  375.   //    (NO_ABORT is NOT set and the command-status is NOT NO_ERROR).
  376.   //
  377.   // ^RETURN-VALUE:
  378. ***************
  379. *** 121,130 ****
  380.      // print usage if necessary
  381.      if (cmd_status & ARG_MISSING) {
  382.         usage();
  383. !       ::exit(e_SYNTAX);
  384.      } else if (cmd_status && (! (cmd_flags & NO_ABORT))) {
  385.         usage();
  386. !       ::exit(e_SYNTAX);
  387.      }
  388.   
  389.      return  cmd_status ;
  390. --- 126,135 ----
  391.      // print usage if necessary
  392.      if (cmd_status & ARG_MISSING) {
  393.         usage();
  394. !       quit(e_SYNTAX);
  395.      } else if (cmd_status && (! (cmd_flags & NO_ABORT))) {
  396.         usage();
  397. !       quit(e_SYNTAX);
  398.      }
  399.   
  400.      return  cmd_status ;
  401. *** src/lib/patchlevel.c.OLD    Fri Mar 26 10:50:46 1993
  402. --- src/lib/patchlevel.c    Wed Mar  3 14:41:41 1993
  403. ***************
  404. *** 9,14 ****
  405. --- 9,17 ----
  406.   //
  407.   // ^HISTORY:
  408.   //    04/03/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  409. + //
  410. + //    03/03/93    Brad Appleton    <brad@ssd.csd.harris.com>
  411. + //    - Modified for patch 1
  412.   //-^^---------------------------------------------------------------------
  413.   
  414.   #include "cmdline.h"
  415. ***************
  416. *** 21,33 ****
  417.      // file that makes up this version of the project.
  418.      //
  419.   static const char ident[] =
  420. !    "@(#)SMS  task: cmdline-1.00" ;
  421.   
  422.   
  423.      // Release and patchlevel information
  424.   #define  CMDLINE_RELEASE     1
  425. ! #define  CMDLINE_PATCHLEVEL  0
  426. ! #define  CMDLINE_IDENT       "@(#)CmdLine    1.00"
  427.   
  428.   unsigned
  429.   CmdLine::release(void)  { return  CMDLINE_RELEASE; }
  430. --- 24,36 ----
  431.      // file that makes up this version of the project.
  432.      //
  433.   static const char ident[] =
  434. !    "@(#)SMS  task: cmdline-1.01" ;
  435.   
  436.   
  437.      // Release and patchlevel information
  438.   #define  CMDLINE_RELEASE     1
  439. ! #define  CMDLINE_PATCHLEVEL  1
  440. ! #define  CMDLINE_IDENT       "@(#)CmdLine    1.01"
  441.   
  442.   unsigned
  443.   CmdLine::release(void)  { return  CMDLINE_RELEASE; }
  444. *** src/lib/private.c.OLD    Fri Mar 26 10:50:51 1993
  445. --- src/lib/private.c    Wed Mar  3 10:03:01 1993
  446. ***************
  447. *** 15,20 ****
  448. --- 15,23 ----
  449.   //
  450.   // ^HISTORY:
  451.   //    01/09/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  452. + //
  453. + //    03/03/93    Brad Appleton    <brad@ssd.csd.harris.com>
  454. + //    - Added exit_handler() and quit() member-functions to CmdLine
  455.   //-^^---------------------------------------------------------------------
  456.   
  457.   #include <iostream.h>
  458. ***************
  459. *** 96,102 ****
  460.   //    with the argument "cmdarg".
  461.   //
  462.   // ^ALGORITHM:
  463. ! //    - if this is a cmdargUsage argument then print usage and call exit(3C)
  464.   //    - call the operator() of "cmdarg" and save the result.
  465.   //    - if the above call returned SUCCESS then set the GIVEN and VALGIVEN
  466.   //      flags of the argument.
  467. --- 99,105 ----
  468.   //    with the argument "cmdarg".
  469.   //
  470.   // ^ALGORITHM:
  471. ! //    - if this is a cmdargUsage argument then print usage and call quit()
  472.   //    - call the operator() of "cmdarg" and save the result.
  473.   //    - if the above call returned SUCCESS then set the GIVEN and VALGIVEN
  474.   //      flags of the argument.
  475. ***************
  476. *** 107,119 ****
  477.   int
  478.   CmdLine::handle_arg(CmdArg * cmdarg, const char * & arg)
  479.   {
  480. !    int  bad_val ;
  481.   
  482.      // call the argument compiler
  483.      const char * save_arg = arg ;  // just in case someone forgets to set it
  484. !    bad_val = (*cmdarg)(arg, *this);
  485.      if (! bad_val) {
  486.         cmdarg->set(CmdArg::GIVEN) ;
  487.         if (arg != save_arg) {
  488.            cmdarg->set(CmdArg::VALGIVEN) ;
  489.         }
  490. --- 110,123 ----
  491.   int
  492.   CmdLine::handle_arg(CmdArg * cmdarg, const char * & arg)
  493.   {
  494. !    ++cmd_nargs_parsed;  // update the number of parsed args
  495.   
  496.      // call the argument compiler
  497.      const char * save_arg = arg ;  // just in case someone forgets to set it
  498. !    int  bad_val = (*cmdarg)(arg, *this);
  499.      if (! bad_val) {
  500.         cmdarg->set(CmdArg::GIVEN) ;
  501. +       cmdarg->sequence(cmd_nargs_parsed) ;
  502.         if (arg != save_arg) {
  503.            cmdarg->set(CmdArg::VALGIVEN) ;
  504.         }
  505. ***************
  506. *** 397,403 ****
  507.   //
  508.   // ^SIDE-EFFECTS:
  509.   //    - modifies the status of "cmd".
  510. ! //    - terminates execution by calling exit(3C) if cmd_NOABORT is NOT
  511.   //      set and a required argument (that was not properly supplied by
  512.   //      the user) is not given.
  513.   //    - prints on stderr if an argument is missing and cmd_QUIET is NOT set.
  514. --- 401,407 ----
  515.   //
  516.   // ^SIDE-EFFECTS:
  517.   //    - modifies the status of "cmd".
  518. ! //    - terminates execution by calling quit() if cmd_NOABORT is NOT
  519.   //      set and a required argument (that was not properly supplied by
  520.   //      the user) is not given.
  521.   //    - prints on stderr if an argument is missing and cmd_QUIET is NOT set.
  522. *** src/lib/states.h.OLD    Fri Mar 26 10:50:57 1993
  523. --- src/lib/states.h    Mon Feb 22 14:24:12 1993
  524. ***************
  525. *** 56,69 ****
  526. --- 56,81 ----
  527.      cmd_TOK_REQUIRED = 0x01,  // is the "wanted" token required?
  528.   
  529.      cmd_WANT_VAL     = 0x02,  // are we expecting a value?
  530. + #ifndef __gplusplus
  531.      cmd_NEED_VAL     = (cmd_WANT_VAL | cmd_TOK_REQUIRED),
  532. + #else
  533. +    cmd_NEED_VAL     = 0x03,
  534. + #endif
  535.   
  536.   #ifdef vms_style
  537.      cmd_WANT_VALSEP  = 0x04,  // are we expecting ':' or '='
  538. + # ifndef __gplusplus
  539.      cmd_NEED_VALSEP  = (cmd_WANT_VALSEP | cmd_TOK_REQUIRED),
  540. + # else
  541. +    cmd_NEED_VALSEP  = 0x05,
  542. + # endif
  543.   
  544.      cmd_WANT_LISTSEP = 0x08,  // are we expecting ',' or '+'
  545. + # ifndef __gplusplus
  546.      cmd_NEED_LISTSEP = (cmd_WANT_LISTSEP | cmd_TOK_REQUIRED),
  547. + # else
  548. +    cmd_NEED_LISTSEP = 0x09,
  549. + # endif
  550.   #endif
  551.   } ;
  552.   
  553. *** src/lib/unix.c.OLD    Fri Mar 26 10:51:03 1993
  554. --- src/lib/unix.c    Wed Mar  3 14:20:20 1993
  555. ***************
  556. *** 16,21 ****
  557. --- 16,24 ----
  558.   //
  559.   // ^HISTORY:
  560.   //    01/09/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  561. + //
  562. + //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  563. + //    - Added ALLOW_PLUS to list of CmdLine configuration flags
  564.   //-^^---------------------------------------------------------------------
  565.   
  566.   #include <iostream.h>
  567. ***************
  568. *** 27,34 ****
  569.   #include "cmdline.h"
  570.   #include "states.h"
  571.   
  572. !   // Prefix string used for short options
  573. ! static const char OPT_PFX[] = "-" ;
  574.   
  575.     // Function to tell us if an argument looks like an option
  576.   inline static int
  577. --- 30,38 ----
  578.   #include "cmdline.h"
  579.   #include "states.h"
  580.   
  581. ! //
  582. ! // Some Helper function for getting and recognizing prefixes
  583. ! //
  584.   
  585.     // Function to tell us if an argument looks like an option
  586.   inline static int
  587. ***************
  588. *** 36,60 ****
  589.      return  ((*(s) == '-') && ((*((s)+1) != '-')) && ((*((s)+1) != '\0'))) ;
  590.   }
  591.   
  592. !   // Need a prefix string for a long-option and a function to tell us
  593. !   // if an argument looks like a long-option as well.
  594. !   //
  595. ! #ifdef  USE_PLUS
  596. !    static const char KWD_PFX[] = "+" ;
  597.   
  598. -    inline static int
  599. -    isKEYWORD(const char *s) {
  600. -       return   ((*(s) == '+') && ((*((s)+1) != '\0'))) ;
  601. -    }
  602. - #else
  603. -    static const char KWD_PFX[] = "--" ;
  604.   
  605. !    inline static int
  606. !    isKEYWORD(const char *s) {
  607. !       return  ((*(s) == '-') && (*((s)+1) == '-')  && (*((s)+2) != '\0')) ;
  608. !    }
  609. ! #endif
  610.   
  611.      // Need to know when an argument means "end-of-options"
  612.   inline static int
  613.   isENDOPTIONS(const char *s) {
  614. --- 40,64 ----
  615.      return  ((*(s) == '-') && ((*((s)+1) != '-')) && ((*((s)+1) != '\0'))) ;
  616.   }
  617.   
  618. !    // Function to return the option-prefix
  619. ! inline static const char *
  620. ! OptionPrefix(void) { return  "-" ; }
  621.   
  622.   
  623. !    // Function to tell us if an argument looks like a long-option.
  624. !    //
  625. !    // NOTE: allowing "+" does not preclude the use of "--"
  626. !    //
  627. ! inline static int
  628. ! isKEYWORD(const char *s, int allow_plus) {
  629. !    return  (((*(s) == '-') && (*((s)+1) == '-')  && (*((s)+2) != '\0')) ||
  630. !             (allow_plus && (*(s) == '+') && ((*((s)+1) != '\0')))) ;
  631. ! }
  632.   
  633. +    // Function to return the long-option prefix
  634. + inline static const char *
  635. + KeywordPrefix(int allow_plus) { return  (allow_plus) ? "+" : "--" ; }
  636.      // Need to know when an argument means "end-of-options"
  637.   inline static int
  638.   isENDOPTIONS(const char *s) {
  639. ***************
  640. *** 61,67 ****
  641. --- 65,75 ----
  642.      return  ((*(s) == '-') && (*((s)+1) == '-')  && (*((s)+2) == '\0')) ;
  643.   }
  644.   
  645. +    // Function to return the "end-of-options" string
  646. + inline static const char *
  647. + EndOptions(void) { return "--" ; }
  648.   
  649.   //-------
  650.   // ^FUNCTION: CmdLine::parse_option - parse a Unix option
  651.   //
  652. ***************
  653. *** 140,146 ****
  654.               }
  655.            }
  656.            if (! (cmd_flags & QUIET)) {
  657. !             error() << "unknown option \"" << OPT_PFX << char(*arg)
  658.                       << "\"." << endl ;
  659.            }
  660.            rc |= BAD_OPTION ;
  661. --- 148,154 ----
  662.               }
  663.            }
  664.            if (! (cmd_flags & QUIET)) {
  665. !             error() << "unknown option \"" << OptionPrefix() << char(*arg)
  666.                       << "\"." << endl ;
  667.            }
  668.            rc |= BAD_OPTION ;
  669. ***************
  670. *** 164,170 ****
  671.               if (cmdarg->syntax() & CmdArg::isVALREQ) {
  672.                  if (! (cmd_flags & QUIET)) {
  673.                     error() << "value required in same argument for "
  674. !                           << OPT_PFX << char(cmdarg->char_name())
  675.                             << " option." << endl;
  676.                  }
  677.                  rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
  678. --- 172,178 ----
  679.               if (cmdarg->syntax() & CmdArg::isVALREQ) {
  680.                  if (! (cmd_flags & QUIET)) {
  681.                     error() << "value required in same argument for "
  682. !                           << OptionPrefix() << char(cmdarg->char_name())
  683.                             << " option." << endl;
  684.                  }
  685.                  rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
  686. ***************
  687. *** 204,210 ****
  688.             (cmdarg->syntax() & CmdArg::isVALSEP)) {
  689.            if (! (cmd_flags & QUIET)) {
  690.               error() << "value required in separate argument for "
  691. !                     << OPT_PFX << char(cmdarg->char_name())
  692.                       << " option." << endl;
  693.            }
  694.            rc |= (VAL_MISSING | VAL_NOTSEP) ;
  695. --- 212,218 ----
  696.             (cmdarg->syntax() & CmdArg::isVALSEP)) {
  697.            if (! (cmd_flags & QUIET)) {
  698.               error() << "value required in separate argument for "
  699. !                     << OptionPrefix() << char(cmdarg->char_name())
  700.                       << " option." << endl;
  701.            }
  702.            rc |= (VAL_MISSING | VAL_NOTSEP) ;
  703. ***************
  704. *** 285,290 ****
  705. --- 293,300 ----
  706.      int  ambiguous = 0, len = -1, bad_val;
  707.      const char * val = NULL ;
  708.   
  709. +    int  plus = (cmd_flags & ALLOW_PLUS) ;  // Can we use "+"?
  710.      // see if we left an argument dangling without a value
  711.      ck_need_val() ;
  712.   
  713. ***************
  714. *** 312,318 ****
  715.         }
  716.         if (! (cmd_flags & QUIET)) {
  717.            error() << ((ambiguous) ? "ambiguous" : "unknown") << " option "
  718. !                  << "\"" << ((cmd_flags & KWDS_ONLY) ? OPT_PFX : KWD_PFX)
  719.                    << arg << "\"." << endl ;
  720.         }
  721.         rc |= ((ambiguous) ? KWD_AMBIGUOUS : BAD_KEYWORD) ;
  722. --- 322,329 ----
  723.         }
  724.         if (! (cmd_flags & QUIET)) {
  725.            error() << ((ambiguous) ? "ambiguous" : "unknown") << " option "
  726. !                  << "\"" << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
  727. !                                                      : KeywordPrefix(plus))
  728.                    << arg << "\"." << endl ;
  729.         }
  730.         rc |= ((ambiguous) ? KWD_AMBIGUOUS : BAD_KEYWORD) ;
  731. ***************
  732. *** 334,340 ****
  733.            if (cmdarg->syntax() & CmdArg::isVALREQ) {
  734.               if (! (cmd_flags & QUIET)) {
  735.                  error() << "value required in same argument for "
  736. !                        << ((cmd_flags & KWDS_ONLY) ? OPT_PFX : KWD_PFX)
  737.                          << cmdarg->keyword_name() << " option." << endl;
  738.               }
  739.               rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
  740. --- 345,352 ----
  741.            if (cmdarg->syntax() & CmdArg::isVALREQ) {
  742.               if (! (cmd_flags & QUIET)) {
  743.                  error() << "value required in same argument for "
  744. !                        << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
  745. !                                                    : KeywordPrefix(plus))
  746.                          << cmdarg->keyword_name() << " option." << endl;
  747.               }
  748.               rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
  749. ***************
  750. *** 374,380 ****
  751.          (cmdarg->syntax() & CmdArg::isVALSEP)) {
  752.         if (! (cmd_flags & QUIET)) {
  753.            error() << "value required in separate argument for "
  754. !                  << ((cmd_flags & KWDS_ONLY) ? OPT_PFX : KWD_PFX)
  755.                    << cmdarg->keyword_name() << " option." << endl;
  756.         }
  757.         rc |= (VAL_MISSING | VAL_NOTSEP) ;
  758. --- 386,393 ----
  759.          (cmdarg->syntax() & CmdArg::isVALSEP)) {
  760.         if (! (cmd_flags & QUIET)) {
  761.            error() << "value required in separate argument for "
  762. !                  << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
  763. !                                              : KeywordPrefix(plus))
  764.                    << cmdarg->keyword_name() << " option." << endl;
  765.         }
  766.         rc |= (VAL_MISSING | VAL_NOTSEP) ;
  767. ***************
  768. *** 544,549 ****
  769. --- 557,564 ----
  770.   {
  771.      if (arg == NULL)  return  cmd_status ;
  772.   
  773. +    int  plus = (cmd_flags & ALLOW_PLUS) ;  // Can we use "+"?
  774.      if (cmd_parse_state & cmd_TOK_REQUIRED) {
  775.         // If a required value is expected, then this argument MUST be
  776.         // the value (even if it looks like an option
  777. ***************
  778. *** 559,570 ****
  779.            cmd_status |=  parse_option(arg) ;
  780.         }
  781.      } else if ((! (cmd_flags & OPTS_ONLY))
  782. !               && isKEYWORD(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
  783.         cmd_state |= cmd_KEYWORDS_USED ;
  784. !       ++arg ;  // skip over '+' keyword prefix
  785. ! #ifndef USE_PLUS
  786. !       ++arg ;  // skip over '--' keyword prefix
  787. ! #endif
  788.         cmd_status |= parse_keyword(arg) ;
  789.      } else if (isENDOPTIONS(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
  790.         cmd_state |= cmd_END_OF_OPTIONS ;
  791. --- 574,586 ----
  792.            cmd_status |=  parse_option(arg) ;
  793.         }
  794.      } else if ((! (cmd_flags & OPTS_ONLY))
  795. !               && isKEYWORD(arg, plus) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
  796.         cmd_state |= cmd_KEYWORDS_USED ;
  797. !       if (*arg == '+') {
  798. !          ++arg ;  // skip over '+' keyword prefix
  799. !       } else {
  800. !          arg += 2 ;  // skip over '--' keyword prefix
  801. !       }
  802.         cmd_status |= parse_keyword(arg) ;
  803.      } else if (isENDOPTIONS(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
  804.         cmd_state |= cmd_END_OF_OPTIONS ;
  805. ***************
  806. *** 611,624 ****
  807.   ostream &
  808.   CmdLine::arg_error(const char * error_str, const CmdArg * cmdarg) const
  809.   {
  810.      ostream & os = error() << error_str << char(' ') ;
  811.   
  812.      if (cmdarg->flags() & CmdArg::GIVEN) {
  813.          if (cmdarg->flags() & CmdArg::KEYWORD) {
  814. !           os << ((cmd_flags & KWDS_ONLY) ? OPT_PFX : KWD_PFX)
  815.                << cmdarg->keyword_name() << " option" ;
  816.          } else if (cmdarg->flags() & CmdArg::OPTION) {
  817. !           os << OPT_PFX << (char)cmdarg->char_name() << " option" ;
  818.          } else {
  819.             os << cmdarg->value_name() << " argument" ;
  820.          }
  821. --- 627,643 ----
  822.   ostream &
  823.   CmdLine::arg_error(const char * error_str, const CmdArg * cmdarg) const
  824.   {
  825. +    int  plus = (cmd_flags & ALLOW_PLUS) ;  // Can we use "+"?
  826.      ostream & os = error() << error_str << char(' ') ;
  827.   
  828.      if (cmdarg->flags() & CmdArg::GIVEN) {
  829.          if (cmdarg->flags() & CmdArg::KEYWORD) {
  830. !           os << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
  831. !                                          : KeywordPrefix(plus))
  832.                << cmdarg->keyword_name() << " option" ;
  833.          } else if (cmdarg->flags() & CmdArg::OPTION) {
  834. !           os << OptionPrefix() << (char)cmdarg->char_name() << " option" ;
  835.          } else {
  836.             os << cmdarg->value_name() << " argument" ;
  837.          }
  838. ***************
  839. *** 627,635 ****
  840.             os << cmdarg->value_name() << " argument" ;
  841.          } else {
  842.             if (cmd_flags & KWDS_ONLY) {
  843. !              os << OPT_PFX << cmdarg->keyword_name() << " option" ;
  844.             } else {
  845. !              os << OPT_PFX << (char)cmdarg->char_name() << " option" ;
  846.             }
  847.          }
  848.      }
  849. --- 646,654 ----
  850.             os << cmdarg->value_name() << " argument" ;
  851.          } else {
  852.             if (cmd_flags & KWDS_ONLY) {
  853. !              os << OptionPrefix() << cmdarg->keyword_name() << " option" ;
  854.             } else {
  855. !              os << OptionPrefix() << (char)cmdarg->char_name() << " option" ;
  856.             }
  857.          }
  858.      }
  859. ***************
  860. *** 686,691 ****
  861. --- 705,711 ----
  862.      ostrstream  oss(buf, bufsize);
  863.      *buf = '\0';
  864.   
  865. +    int  plus = (cmd_flags & ALLOW_PLUS) ;  // Can we use "+"?
  866.      char optchar = cmdarg->char_name();
  867.      const char * keyword = cmdarg->keyword_name();
  868.   
  869. ***************
  870. *** 723,734 ****
  871.          (cmdarg->syntax() & CmdArg::isVALSTICKY))
  872.      {
  873.         if (cmdarg->syntax() & CmdArg::isVALOPT) {
  874. !          oss << OPT_PFX << char(optchar) << char('[') << cmdarg->value_name()
  875. !              << "]|" << KWD_PFX << keyword << "[=" << cmdarg->value_name()
  876. !              << char(']') ;
  877.         } else {
  878. !          oss << OPT_PFX << optchar << cmdarg->value_name() << char('|')
  879. !              << KWD_PFX << keyword << char('=') << cmdarg->value_name() ;
  880.         }
  881.         if ((level == VERBOSE_USAGE) && (cmdarg->syntax() & CmdArg::isLIST)) {
  882.            oss << " ..." ;
  883. --- 743,755 ----
  884.          (cmdarg->syntax() & CmdArg::isVALSTICKY))
  885.      {
  886.         if (cmdarg->syntax() & CmdArg::isVALOPT) {
  887. !          oss << OptionPrefix() << char(optchar) << char('[')
  888. !              << cmdarg->value_name() << "]|" << KeywordPrefix(plus)
  889. !              << keyword << "[=" << cmdarg->value_name() << char(']') ;
  890.         } else {
  891. !          oss << OptionPrefix() << optchar << cmdarg->value_name()
  892. !              << char('|') << KeywordPrefix(plus) << keyword << char('=')
  893. !              << cmdarg->value_name() ;
  894.         }
  895.         if ((level == VERBOSE_USAGE) && (cmdarg->syntax() & CmdArg::isLIST)) {
  896.            oss << " ..." ;
  897. ***************
  898. *** 743,758 ****
  899.      if (! (cmdarg->syntax() & CmdArg::isPOS)) {
  900.         switch(syntax) {
  901.            case cmd_OPTS_ONLY :
  902. !             oss << OPT_PFX << char(optchar) ;
  903.               break ;
  904.   
  905.            case cmd_KWDS_ONLY :
  906. !             oss << ((cmd_flags & KWDS_ONLY) ? OPT_PFX : KWD_PFX) << keyword ;
  907.               break ;
  908.   
  909.            case cmd_BOTH :
  910. !             oss << OPT_PFX << char(optchar) << char('|')
  911. !                 << KWD_PFX << keyword ;
  912.               break ;
  913.   
  914.            default :
  915. --- 764,780 ----
  916.      if (! (cmdarg->syntax() & CmdArg::isPOS)) {
  917.         switch(syntax) {
  918.            case cmd_OPTS_ONLY :
  919. !             oss << OptionPrefix() << char(optchar) ;
  920.               break ;
  921.   
  922.            case cmd_KWDS_ONLY :
  923. !             oss << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
  924. !                                             : KeywordPrefix(plus)) << keyword ;
  925.               break ;
  926.   
  927.            case cmd_BOTH :
  928. !             oss << OptionPrefix() << char(optchar) << char('|')
  929. !                 << KeywordPrefix(plus) << keyword ;
  930.               break ;
  931.   
  932.            default :
  933. *** src/lib/usage.c.OLD    Fri Mar 26 10:51:13 1993
  934. --- src/lib/usage.c    Mon Mar  1 10:48:48 1993
  935. ***************
  936. *** 8,13 ****
  937. --- 8,16 ----
  938.   //
  939.   // ^HISTORY:
  940.   //    01/09/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  941. + //
  942. + //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  943. + //    - Added cmd_description field to CmdLine
  944.   //-^^---------------------------------------------------------------------
  945.   
  946.   #include <iostream.h>
  947. ***************
  948. *** 304,309 ****
  949. --- 307,319 ----
  950.      // now print argument descriptions
  951.      os << "\n" ;
  952.      print_descriptions(cmd_syntax, os, max_cols, longest) ;
  953. +    // now print the command-description if there is one
  954. +    if (cmd_description && *cmd_description) {
  955. +       os << "\nDescription:" << endl;
  956. +       strindent(os, max_cols, 8, "", 0, cmd_description);
  957. +    }
  958.      return  os;
  959.   }
  960.   
  961.