home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / sources / misc / 3778 < prev    next >
Encoding:
Text File  |  1992-07-26  |  60.6 KB  |  1,859 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
  4. Subject:  v31i054:  cmdline - C++ Library for parsing command-line arguments, Part07/07
  5. Message-ID: <1992Jul27.020933.29895@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: b6f56ee0f7111828ee70cfe954cf4419
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Reply-To: brad@travis.csd.harris.com
  10. Organization: Harris Computer Systems
  11. References: <csm-v31i047=cmdline.205609@sparky.IMD.Sterling.COM>
  12. Date: Mon, 27 Jul 1992 02:09:33 GMT
  13. Approved: kent@sparky.imd.sterling.com
  14. Lines: 1843
  15.  
  16. Submitted-by: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
  17. Posting-number: Volume 31, Issue 54
  18. Archive-name: cmdline/part07
  19. Environment: C++
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then unpack
  23. # it by saving it into a file and typing "sh file".  To overwrite existing
  24. # files, type "sh file -c".  You can also feed this as standard input via
  25. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  26. # will see the following message at the end:
  27. #        "End of archive 7 (of 7)."
  28. # Contents:  src/lib/cmdargs.h src/lib/cmdline.h
  29. # Wrapped by brad@hcx1 on Mon Jul 20 10:41:33 1992
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'src/lib/cmdargs.h' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'src/lib/cmdargs.h'\"
  33. else
  34. echo shar: Extracting \"'src/lib/cmdargs.h'\" \(30824 characters\)
  35. sed "s/^X//" >'src/lib/cmdargs.h' <<'END_OF_FILE'
  36. X//------------------------------------------------------------------------
  37. X// ^FILE: cmdargs.h - define the most commonly used argument types
  38. X//
  39. X// ^DESCRIPTION:
  40. X//    This file defines classes for the most commonly used types of
  41. X//    command-line arguments.  Most command-line arguments are either
  42. X//    boolean-flags, a number, a character, or a string (or a list of
  43. X//    numbers or strings).  In each of these cases, the call operator
  44. X//    (operator()) of the argument just compiles the value given into
  45. X//    some internal value and waits for the programmer to query the
  46. X//    value at some later time.
  47. X//
  48. X//    I call these types of arguments "ArgCompilers". For each of the
  49. X//    most common argument types, a corresponding abstract ArgCompiler
  50. X//    class is declared.  All that this class does is to add a member
  51. X//    function named "compile" to the class.  The "compile()" function
  52. X//    looks exactly like the call operator but it takes an additional
  53. X//    parameter: a reference to the value to be modified by compiling
  54. X//    the argument value.  In all other respects, the "compile()" member
  55. X//    function behaves exactly like the call operator.  In fact, most
  56. X//    of the call-operator member functions simply call the ArgCompiler's
  57. X//    "compile()" member function with the appropriate value and return
  58. X//    whatever the compile function returned.
  59. X//
  60. X//    Once all of these ArgCompilers are declared, it is a simple matter
  61. X//    to declare a class that holds a single item, or a list of items,
  62. X//    by deriving it from the corresponding ArgCompiler type.
  63. X//
  64. X//    For derived classes of these ArgCompilers that hold a single item,
  65. X//    The derived class implements some operators (such as operator=
  66. X//    and an appropriate cast operator) to treat the argument as if it
  67. X//    were simply an item (instead of an argument that contains an item).
  68. X//    The output operator (ostream & operator<<) is also defined.
  69. X//
  70. X//    For derived classes of ArgCompilers that hold a list of items,
  71. X//    the subscript operator[] is defined in order to treat the argument
  72. X//    as if it were simply an array of items and not an argument that
  73. X//    contains a list of items.
  74. X//
  75. X//    *NOTE*
  76. X//    ======
  77. X//    It is important to remember that each subclass of CmdArg MUST be able
  78. X//    to handle NULL as the first argument to the call-operator (and it
  79. X//    should NOT be considered an error).  This is because NULL will be
  80. X//    passed if the argument takes no value, or if it takes an optional
  81. X//    value that was NOT provided on the command-line.  Whenever an
  82. X//    argument is correctly specified on the command-line, its call
  83. X//    operator is always invoked (regardless of whether or not there
  84. X//    is a corresponding value from the command-line).
  85. X//
  86. X// ^HISTORY:
  87. X//    03/25/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  88. X//-^^---------------------------------------------------------------------
  89. X
  90. X#ifndef _usr_include_cmdargs_h
  91. X#define _usr_include_cmdargs_h
  92. X
  93. X#include <cmdline.h>
  94. X
  95. X//-------------------------------------------------------------- Dummy Argument
  96. X
  97. X   // A Dummy argument is one that is used only for its appearance in
  98. X   // usage messages. It is completely ignored by the CmdLine object
  99. X   // when parsing the command-line.
  100. X   //
  101. X   // Examples:
  102. X   //     CmdArgDummy  dummy1('c', "keyword", "value", "dummy argument # 1");
  103. X   //     CmdArgDummy  dummy2("value", "dummy argument # 2");
  104. X   //
  105. Xclass CmdArgDummy : public CmdArg {
  106. Xpublic:
  107. X   CmdArgDummy(char         optchar,
  108. X               const char * keyword,
  109. X               const char * value,
  110. X               const char * description,
  111. X               unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  112. X      : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  113. X
  114. X   CmdArgDummy(char         optchar,
  115. X               const char * keyword,
  116. X               const char * description,
  117. X               unsigned     syntax_flags =CmdArg::isOPT)
  118. X      : CmdArg(optchar, keyword, description, syntax_flags) {}
  119. X
  120. X   CmdArgDummy(const char * value,
  121. X               const char * description,
  122. X               unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  123. X      : CmdArg(value, description, syntax_flags) {}
  124. X
  125. X   CmdArgDummy(const CmdArgDummy & cp) : CmdArg(cp) {}
  126. X
  127. X   CmdArgDummy(const CmdArg & cp) : CmdArg(cp) {}
  128. X
  129. X   virtual ~CmdArgDummy(void);
  130. X
  131. X   virtual  int
  132. X   is_dummy(void);   // return non-zero
  133. X
  134. X   virtual  int
  135. X   operator()(const char * & arg, CmdLine & cmd);  // NO-OP
  136. X} ;
  137. X
  138. X//-------------------------------------------------------------- Usage Argument
  139. X
  140. X   // The sole purpose of a usage argument is to immediately print the
  141. X   // program usage (as soon as it is matched) and to exit.
  142. X   //
  143. X   // There is a default usage argument in every CmdLine object.
  144. X   //
  145. X   // Example:
  146. X   //    CmdArgUsage  usage_arg('?', "help", "print usage and exit");
  147. X   //
  148. Xclass  CmdArgUsage : public CmdArg {
  149. Xpublic:
  150. X   CmdArgUsage(char         optchar,
  151. X               const char * keyword,
  152. X               const char * description)
  153. X      : CmdArg(optchar, keyword, description, CmdArg::isOPT) {}
  154. X
  155. X   CmdArgUsage(const CmdArgUsage & cp) : CmdArg(cp) {}
  156. X
  157. X   CmdArgUsage(const CmdArg & cp) : CmdArg(cp) {}
  158. X
  159. X   virtual ~CmdArgUsage(void);
  160. X
  161. X   virtual  int
  162. X   operator()(const char * & arg, CmdLine & cmd);
  163. X} ;
  164. X
  165. X//----------------------------------------------------------- Integer Arguments
  166. X
  167. X   // Look under "List Arguments" for a CmdArg that is a list of ints
  168. X
  169. X   // CmdArgIntCompiler is the base class for all arguments need to
  170. X   // convert the string given on the command-line into an integer.
  171. X   //
  172. Xclass  CmdArgIntCompiler : public CmdArg {
  173. Xpublic:
  174. X   CmdArgIntCompiler(char         optchar,
  175. X                     const char * keyword,
  176. X                     const char * value,
  177. X                     const char * description,
  178. X                     unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  179. X      : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  180. X
  181. X   CmdArgIntCompiler(const char * value,
  182. X                     const char * description,
  183. X                     unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  184. X      : CmdArg(value, description, syntax_flags) {}
  185. X
  186. X   CmdArgIntCompiler(const CmdArgIntCompiler & cp) : CmdArg(cp) {}
  187. X
  188. X   CmdArgIntCompiler(const CmdArg & cp) : CmdArg(cp) {}
  189. X
  190. X   virtual ~CmdArgIntCompiler(void);
  191. X
  192. X   virtual  int
  193. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  194. X
  195. X   int
  196. X   compile(const char * & arg, CmdLine & cmd, int & value);
  197. X} ;
  198. X
  199. X
  200. X   // CmdArgInt - an argument that contains a single integer.
  201. X   //
  202. X   // The following member functions are provided to treat
  203. X   // a CmdArgInt as if it were an integer:
  204. X   //
  205. X   //    operator=(int);
  206. X   //    operator int(void);
  207. X   //    operator<<(os, CmdArgInt);
  208. X   //
  209. X   // The integer value is initialized to zero by the constructor.
  210. X   //
  211. X   // Examples:
  212. X   //     CmdArgInt  count('c', "count", "number", "# of copies to print");
  213. X   //     CmdArgInt  nlines("lines", "number of lines to print);
  214. X   //
  215. X   //     count = 1;
  216. X   //     nlines = 0;
  217. X   //
  218. X   //     if (count > 1) { ... }
  219. X   //     cout << "number of lines is " << nlines << endl ;
  220. X   //
  221. Xclass  CmdArgInt : public CmdArgIntCompiler {
  222. Xpublic:
  223. X   CmdArgInt(char         optchar,
  224. X             const char * keyword,
  225. X             const char * value,
  226. X             const char * description,
  227. X             unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  228. X      : CmdArgIntCompiler(optchar, keyword, value, description, syntax_flags),
  229. X        val(0) {}
  230. X
  231. X   CmdArgInt(const char * value,
  232. X             const char * description,
  233. X             unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  234. X      : CmdArgIntCompiler(value, description, syntax_flags), val(0) {}
  235. X
  236. X   virtual ~CmdArgInt(void);
  237. X
  238. X   virtual  int
  239. X   operator()(const char * & arg, CmdLine & cmd);
  240. X
  241. X   CmdArgInt(const CmdArgInt & cp) : CmdArgIntCompiler(cp), val(cp.val) {}
  242. X
  243. X   CmdArgInt(const CmdArg & cp) : CmdArgIntCompiler(cp), val(0) {}
  244. X
  245. X   CmdArgInt &
  246. X   operator=(const CmdArgInt & cp)  { val = cp.val; return  *this; }
  247. X
  248. X   CmdArgInt &
  249. X   operator=(int cp)  { val = cp; return  *this; }
  250. X
  251. X   operator int(void)  const { return  val; }
  252. X
  253. Xprivate:
  254. X   int   val;
  255. X} ;
  256. X
  257. Xostream &
  258. Xoperator<<(ostream & os, const CmdArgInt & int_arg);
  259. X
  260. X//---------------------------------------------------- Floating-point Arguments
  261. X
  262. X   // Look under "List Arguments" for a CmdArg that is a list of floats
  263. X
  264. X   // CmdArgFloatCompiler is the base class for all arguments
  265. X   // need to convert the string given on the command-line into
  266. X   // a floating-point value.
  267. X   //
  268. Xclass  CmdArgFloatCompiler : public CmdArg {
  269. Xpublic:
  270. X   CmdArgFloatCompiler(char         optchar,
  271. X                       const char * keyword,
  272. X                       const char * value,
  273. X                       const char * description,
  274. X                       unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  275. X      : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  276. X
  277. X   CmdArgFloatCompiler(const char * value,
  278. X                       const char * description,
  279. X                       unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  280. X      : CmdArg(value, description, syntax_flags) {}
  281. X
  282. X   CmdArgFloatCompiler(const CmdArgFloatCompiler & cp) : CmdArg(cp) {}
  283. X
  284. X   CmdArgFloatCompiler(const CmdArg & cp) : CmdArg(cp) {}
  285. X
  286. X   virtual ~CmdArgFloatCompiler(void);
  287. X
  288. X   virtual  int
  289. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  290. X
  291. X   int
  292. X   compile(const char * & arg, CmdLine & cmd, float & value);
  293. X} ;
  294. X
  295. X
  296. X   // CmdArgFloat - an argument that contains a single floating-point value.
  297. X   //
  298. X   // The following member functions are provided to treat
  299. X   // a CmdArgFloat as if it were a float:
  300. X   //
  301. X   //    operator=(float);
  302. X   //    operator float(void);
  303. X   //    operator<<(os, CmdArgFloat);
  304. X   //
  305. X   // The floating-point value is initialized to zero by the constructor.
  306. X   //
  307. X   // Examples:
  308. X   //     CmdArgFloat  major('m', "major", "#", "major radius of ellipse");
  309. X   //     CmdArgFloat  minor("minor", "minor radius of ellipse");
  310. X   //
  311. X   //     major = 2.71828;
  312. X   //     minor = 3.14159;
  313. X   //
  314. X   //     if (minor > major)  {  /* swap major and minor */ }
  315. X   //
  316. X   //     cout << "major radius is " << major << endl ;
  317. X   //
  318. Xclass  CmdArgFloat : public CmdArgFloatCompiler {
  319. Xpublic:
  320. X   CmdArgFloat(char         optchar,
  321. X               const char * keyword,
  322. X               const char * value,
  323. X               const char * description,
  324. X               unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  325. X      : CmdArgFloatCompiler(optchar, keyword, value, description, syntax_flags),
  326. X        val(0) {}
  327. X
  328. X   CmdArgFloat(const char * value,
  329. X               const char * description,
  330. X               unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  331. X      : CmdArgFloatCompiler(value, description, syntax_flags), val(0) {}
  332. X
  333. X   virtual ~CmdArgFloat(void);
  334. X
  335. X   virtual  int
  336. X   operator()(const char * & arg, CmdLine & cmd);
  337. X
  338. X   CmdArgFloat(const CmdArgFloat & cp)
  339. X      : CmdArgFloatCompiler(cp), val(cp.val) {}
  340. X
  341. X   CmdArgFloat(const CmdArg & cp)
  342. X      : CmdArgFloatCompiler(cp), val(0) {}
  343. X
  344. X   CmdArgFloat &
  345. X   operator=(const CmdArgFloat & cp)  { val = cp.val; return  *this; }
  346. X
  347. X   CmdArgFloat &
  348. X   operator=(float cp)  { val = cp; return  *this; }
  349. X
  350. X   operator float(void)  const  { return  val; }
  351. X
  352. Xprivate:
  353. X   float   val;
  354. X} ;
  355. X
  356. Xostream &
  357. Xoperator<<(ostream & os, const CmdArgFloat & float_arg);
  358. X
  359. X
  360. X//--------------------------------------------------------- Character Arguments
  361. X
  362. X   // CmdArgCharCompiler is the base class for all arguments need to
  363. X   // convert the string given on the command-line into a character.
  364. X   //
  365. Xclass  CmdArgCharCompiler : public CmdArg {
  366. Xpublic:
  367. X   CmdArgCharCompiler(char         optchar,
  368. X                      const char * keyword,
  369. X                      const char * value,
  370. X                      const char * description,
  371. X                      unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  372. X      : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  373. X
  374. X   CmdArgCharCompiler(const char * value,
  375. X                      const char * description,
  376. X                      unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  377. X      : CmdArg(value, description, syntax_flags) {}
  378. X
  379. X   CmdArgCharCompiler(const CmdArgCharCompiler & cp) : CmdArg(cp) {}
  380. X
  381. X   CmdArgCharCompiler(const CmdArg & cp) : CmdArg(cp) {}
  382. X
  383. X   virtual ~CmdArgCharCompiler(void);
  384. X
  385. X   virtual  int
  386. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  387. X
  388. X   int
  389. X   compile(const char * & arg, CmdLine & cmd, char & value);
  390. X} ;
  391. X
  392. X
  393. X   // CmdArgChar - an argument that contains a single character.
  394. X   //
  395. X   // The following member functions are provided to treat
  396. X   // a CmdArgChar as if it were a character:
  397. X   //
  398. X   //    operator=(char);
  399. X   //    operator char(void);
  400. X   //    operator<<(os, CmdArgChar);
  401. X   //
  402. X   // The character value is initialized to '\0' by the constructor.
  403. X   //
  404. X   // Examples:
  405. X   //     CmdArgChar  ignore('i', "ignore", "character to ignore);
  406. X   //     CmdArgChar  sep("field-separator");
  407. X   //
  408. X   //     ignore = ' ';
  409. X   //     sep = ',';
  410. X   //
  411. X   //     if (sep == '\0') { /* error */ }
  412. X   //
  413. X   //     cout << "ignore character is '" << ignore << "'" << endl ;
  414. X   //
  415. Xclass  CmdArgChar : public CmdArgCharCompiler {
  416. Xpublic:
  417. X   CmdArgChar(char         optchar,
  418. X              const char * keyword,
  419. X              const char * value,
  420. X              const char * description,
  421. X              unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  422. X      : CmdArgCharCompiler(optchar, keyword, value, description, syntax_flags),
  423. X        val(0) {}
  424. X
  425. X   CmdArgChar(const char * value,
  426. X              const char * description,
  427. X              unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  428. X      : CmdArgCharCompiler(value, description, syntax_flags), val(0) {}
  429. X
  430. X   virtual ~CmdArgChar(void);
  431. X
  432. X   virtual  int
  433. X   operator()(const char * & arg, CmdLine & cmd);
  434. X
  435. X   CmdArgChar(const CmdArgChar & cp) : CmdArgCharCompiler(cp), val(cp.val) {}
  436. X
  437. X   CmdArgChar(const CmdArg & cp) : CmdArgCharCompiler(cp), val(0) {}
  438. X
  439. X   CmdArgChar &
  440. X   operator=(const CmdArgChar & cp)  { val = cp.val; return  *this; }
  441. X
  442. X   CmdArgChar &
  443. X   operator=(char cp)  { val = cp; return  *this; }
  444. X
  445. X   operator char(void)  const  { return  val; }
  446. X
  447. Xprivate:
  448. X   char   val;
  449. X} ;
  450. X
  451. Xostream &
  452. Xoperator<<(ostream & os, const CmdArgChar & char_arg);
  453. X
  454. X//------------------------------------------------------------ String Arguments
  455. X
  456. X   // Look under "List Arguments" for a CmdArg that is a list of strings
  457. X
  458. X   // CmdArgIntCompiler is the base class for all arguments need to
  459. X   // convert the string given on the command-line into a string.
  460. X   //
  461. Xclass  CmdArgStrCompiler : public CmdArg {
  462. Xpublic:
  463. X   // We need an internal string type here because sometimes we need
  464. X   // to allocate new space for the string, and sometimes we dont.
  465. X   // We need a string type that knows how it was allocated and
  466. X   // to behave accordingly.
  467. X   //
  468. X   // Since the programmer, will be seeing our string type instead of
  469. X   // a "char *" we need to provide some operators for our string
  470. X   // type that make it unnecessary to know the difference between
  471. X   // it and a "char *" (in most cases).
  472. X   //
  473. X   struct  string {
  474. X      unsigned     is_alloc : 1 ;
  475. X      const char * str ;
  476. X
  477. X      string(void) : is_alloc(0), str(0) {}
  478. X
  479. X      string(const char * s) : is_alloc(0), str(s) {}
  480. X
  481. X      void
  482. X      copy(unsigned  is_temporary, const char * s);
  483. X
  484. X      string(unsigned  is_temporary, const char * s)
  485. X         : is_alloc(0), str(0) { copy(is_temporary, s); }
  486. X
  487. X      string(const string & cp)
  488. X         : is_alloc(0), str(0) { copy(cp.is_alloc, cp.str); }
  489. X
  490. X      string &
  491. X      operator=(const string & cp)
  492. X         { copy(cp.is_alloc, cp.str); return *this; }
  493. X
  494. X      string &
  495. X      operator=(const char * cp) { copy(0, cp); return *this; }
  496. X
  497. X      operator const char*(void)  const { return  str; }
  498. X
  499. X      virtual ~string(void);
  500. X   } ;
  501. X
  502. X   CmdArgStrCompiler(char         optchar,
  503. X                     const char * keyword,
  504. X                     const char * value,
  505. X                     const char * description,
  506. X                     unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  507. X      : CmdArg(optchar, keyword, value, description, syntax_flags) {}
  508. X
  509. X   CmdArgStrCompiler(const char * value,
  510. X                     const char * description,
  511. X                     unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  512. X      : CmdArg(value, description, syntax_flags) {}
  513. X
  514. X   CmdArgStrCompiler(const CmdArgStrCompiler & cp) : CmdArg(cp) {}
  515. X
  516. X   CmdArgStrCompiler(const CmdArg & cp) : CmdArg(cp) {}
  517. X
  518. X   virtual ~CmdArgStrCompiler(void);
  519. X
  520. X   virtual  int
  521. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  522. X
  523. X   int
  524. X   compile(const char * & arg, CmdLine & cmd, string & value) ;
  525. X} ;
  526. X
  527. X
  528. X   // CmdArgStr - an argument that holds a single string
  529. X   //
  530. X   // The following member functions are provided to treat
  531. X   // a CmdArgStr as if it were a string:
  532. X   //
  533. X   //    operator=(char*);
  534. X   //    operator char*(void);
  535. X   //    operator<<(os, CmdArgStr);
  536. X   // 
  537. X   // The string value is initialized to NULL by the constructor.
  538. X   //
  539. X   // Examples:
  540. X   //     CmdArgStr  input('i', "input", "filename", "file to read");
  541. X   //     CmdArgStr  output("output-file", "file to write);
  542. X   //
  543. X   //     input = "/usr/input" ;
  544. X   //     output = "/usr/output" ;
  545. X   //
  546. X   //     if (strcmp(input, output) == 0) {
  547. X   //        cerr << "input and output are the same file: " << input << endl ;
  548. X   //     }
  549. X   //
  550. Xclass  CmdArgStr : public CmdArgStrCompiler {
  551. Xpublic:
  552. X   CmdArgStr(char         optchar,
  553. X             const char * keyword,
  554. X             const char * value,
  555. X             const char * description,
  556. X             unsigned     syntax_flags =CmdArg::isOPTVALREQ)
  557. X      : CmdArgStrCompiler(optchar, keyword, value, description, syntax_flags),
  558. X        val(0) {}
  559. X
  560. X   CmdArgStr(const char * value,
  561. X             const char * description,
  562. X             unsigned     syntax_flags =CmdArg::isPOSVALREQ)
  563. X      : CmdArgStrCompiler(value, description, syntax_flags), val(0) {}
  564. X
  565. X   virtual ~CmdArgStr(void);
  566. X
  567. X   virtual  int
  568. X   operator()(const char * & arg, CmdLine & cmd);
  569. X
  570. X   CmdArgStr(const CmdArgStr & cp) : CmdArgStrCompiler(cp), val(cp.val) {}
  571. X
  572. X   CmdArgStr(const CmdArg & cp) : CmdArgStrCompiler(cp), val(0) {}
  573. X
  574. X   CmdArgStr &
  575. X   operator=(const CmdArgStr & cp)  { val = cp.val; return  *this; }
  576. X
  577. X   CmdArgStr &
  578. X   operator=(const CmdArgStrCompiler::string & cp)
  579. X      { val = cp; return  *this; }
  580. X
  581. X   CmdArgStr &
  582. X   operator=(const char * cp)  { val = cp; return  *this; }
  583. X
  584. X   operator CmdArgStrCompiler::string(void)  { return  val; }
  585. X
  586. X   operator const char*(void)  const { return  val.str; }
  587. X
  588. Xprivate:
  589. X   CmdArgStrCompiler::string  val;
  590. X} ;
  591. X
  592. Xostream &
  593. Xoperator<<(ostream & os, const CmdArgStrCompiler::string & str);
  594. X
  595. Xostream &
  596. Xoperator<<(ostream & os, const CmdArgStr & str_arg);
  597. X
  598. X//-------------------------------------------------------------- List Arguments
  599. X
  600. X   // For each of the list argument types:
  601. X   //    The list is initially empty. The only way to add to the list
  602. X   //    is with operator(). The number of items in the list may
  603. X   //    be obtained by the "count()" member function and a given
  604. X   //    item may be obtained by treating the list as an array and
  605. X   //    using operator[] to index into the list.
  606. X   //
  607. X
  608. X
  609. X   // CmdArgIntList - an argument that holds a list of integers
  610. X   //
  611. X   // Example:
  612. X   //     CmdArgIntList ints('i', "ints", "numbers ...", "a list of integers");
  613. X   //     CmdArgIntList ints("numbers ...", "a positional list of integers");
  614. X   //
  615. X   //     for (int i = 0 ; i < ints.count() ; i++) {
  616. X   //        cout << "integer #" << i << " is " << ints[i] << endl ;
  617. X   //     }
  618. X   //
  619. Xstruct CmdArgIntListPrivate;
  620. Xclass  CmdArgIntList : public CmdArgIntCompiler {
  621. Xpublic:
  622. X   CmdArgIntList(char    optchar,
  623. X            const char * keyword,
  624. X            const char * value,
  625. X            const char * description,
  626. X            unsigned   syntax_flags =(CmdArg::isOPTVALREQ + CmdArg::isLIST))
  627. X      : CmdArgIntCompiler(optchar, keyword, value, description, syntax_flags),
  628. X        val(0) {}
  629. X
  630. X   CmdArgIntList(const char * value,
  631. X            const char * description,
  632. X            unsigned   syntax_flags =(CmdArg::isPOSVALREQ + CmdArg::isLIST))
  633. X      : CmdArgIntCompiler(value, description, syntax_flags), val(0) {}
  634. X
  635. X   virtual ~CmdArgIntList(void);
  636. X
  637. X   virtual  int
  638. X   operator()(const char * & arg, CmdLine & cmd);
  639. X
  640. X   unsigned
  641. X   count(void) const;
  642. X
  643. X   int &
  644. X   operator[](unsigned  index);
  645. X
  646. Xprivate:
  647. X   CmdArgIntList(const CmdArgInt & cp);
  648. X
  649. X   CmdArgIntList &
  650. X   operator=(const CmdArgInt & cp);
  651. X
  652. X   CmdArgIntListPrivate * val;
  653. X} ;
  654. X
  655. X
  656. X   // CmdArgFloatList - an argument that holds a list of floats
  657. X   //
  658. X   // Example:
  659. X   //     CmdArgFloatList flts('f', "flts", "numbers ...", "a list of floats");
  660. X   //     CmdArgFloatList flts("numbers ...", "a positional list of floats");
  661. X   //
  662. X   //     for (int i = 0 ; i < flts.count() ; i++) {
  663. X   //        cout << "Float #" << i << " is " << flts[i] << endl ;
  664. X   //     }
  665. X   //
  666. Xstruct CmdArgFloatListPrivate;
  667. Xclass  CmdArgFloatList : public CmdArgFloatCompiler {
  668. Xpublic:
  669. X   CmdArgFloatList(char    optchar,
  670. X              const char * keyword,
  671. X              const char * value,
  672. X              const char * description,
  673. X              unsigned   syntax_flags =(CmdArg::isOPTVALREQ + CmdArg::isLIST))
  674. X      : CmdArgFloatCompiler(optchar, keyword, value, description, syntax_flags),
  675. X        val(0) {}
  676. X
  677. X   CmdArgFloatList(const char * value,
  678. X              const char * description,
  679. X              unsigned   syntax_flags =(CmdArg::isPOSVALREQ + CmdArg::isLIST))
  680. X      : CmdArgFloatCompiler(value, description, syntax_flags), val(0) {}
  681. X
  682. X   virtual ~CmdArgFloatList(void);
  683. X
  684. X   virtual  int
  685. X   operator()(const char * & arg, CmdLine & cmd);
  686. X
  687. X   unsigned
  688. X   count(void) const;
  689. X
  690. X   float &
  691. X   operator[](unsigned  index);
  692. X
  693. Xprivate:
  694. X   CmdArgFloatList(const CmdArgFloat & cp);
  695. X
  696. X   CmdArgFloatList &
  697. X   operator=(const CmdArgFloat & cp);
  698. X
  699. X   CmdArgFloatListPrivate * val;
  700. X} ;
  701. X
  702. X
  703. X   // CmdArgStrList - an argument that holds a list of strings
  704. X   //
  705. X   // Example:
  706. X   //     CmdArgStrList strs('s', "strs", "strings ...", "a list of strings");
  707. X   //     CmdArgStrList strs("strings ...", "a positional list of strings");
  708. X   //
  709. X   //     for (int i = 0 ; i < strs.count() ; i++) {
  710. X   //        cout << "String #" << i << " is " << strs[i] << endl ;
  711. X   //     }
  712. X   //
  713. Xstruct CmdArgStrListPrivate;
  714. Xclass  CmdArgStrList : public CmdArgStrCompiler {
  715. Xpublic:
  716. X   CmdArgStrList(char    optchar,
  717. X            const char * keyword,
  718. X            const char * value,
  719. X            const char * description,
  720. X            unsigned   syntax_flags =(CmdArg::isOPTVALREQ + CmdArg::isLIST))
  721. X      : CmdArgStrCompiler(optchar, keyword, value, description, syntax_flags),
  722. X        val(0) {}
  723. X
  724. X   CmdArgStrList(const char * value,
  725. X            const char * description,
  726. X            unsigned   syntax_flags =(CmdArg::isPOSVALREQ + CmdArg::isLIST))
  727. X      : CmdArgStrCompiler(value, description, syntax_flags), val(0) {}
  728. X
  729. X   virtual ~CmdArgStrList(void);
  730. X
  731. X   virtual  int
  732. X   operator()(const char * & arg, CmdLine & cmd);
  733. X
  734. X   unsigned
  735. X   count(void) const;
  736. X
  737. X   CmdArgStrCompiler::string &
  738. X   operator[](unsigned  index);
  739. X
  740. Xprivate:
  741. X   CmdArgStrList(const CmdArgStr & cp);
  742. X
  743. X   CmdArgStrList &
  744. X   operator=(const CmdArgStr & cp);
  745. X
  746. X   CmdArgStrListPrivate * val;
  747. X} ;
  748. X
  749. X//----------------------------------------------------------- Boolean Arguments
  750. X
  751. X   // Boolean arguments are a bit tricky, first of all - we have three
  752. X   // different kinds:
  753. X   //
  754. X   //    1) An argument whose presence SETS a value
  755. X   //
  756. X   //    2) An argument whose presence UNSETS a value
  757. X   //
  758. X   //    3) An argument whose presence TOGGLES a value
  759. X   //
  760. X   // Furthermore, it is not uncommon (especially in VAX/VMS) to have
  761. X   // one argument that SETS and value, and another argument that
  762. X   // UNSETS the SAME value.
  763. X   //
  764. X
  765. X   // CmdArgBoolCompiler is a special type of ArgCompiler, not only does
  766. X   // its "compile" member function take a reference to the boolean value,
  767. X   // but it also needs to know what default-value to use if no explicit
  768. X   // value (such as '0', '1', "ON" or "FALSE") was given.
  769. X   //
  770. Xclass CmdArgBoolCompiler : public CmdArg {
  771. Xpublic:
  772. X   CmdArgBoolCompiler(char         optchar,
  773. X                      const char * keyword,
  774. X                      const char * description,
  775. X                      unsigned     syntax_flags =CmdArg::isOPT)
  776. X      : CmdArg(optchar, keyword, description, syntax_flags) {}
  777. X
  778. X   CmdArgBoolCompiler(const CmdArgBoolCompiler & cp) : CmdArg(cp) {}
  779. X
  780. X   CmdArgBoolCompiler(const CmdArg & cp) : CmdArg(cp) {}
  781. X
  782. X   virtual ~CmdArgBoolCompiler(void);
  783. X
  784. X   virtual  int
  785. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  786. X
  787. X   int
  788. X   compile(const char * & arg,
  789. X           CmdLine      & cmd,
  790. X           unsigned     & value,
  791. X           unsigned       default_value =1);
  792. X} ;
  793. X
  794. X
  795. X   // CmdArgBool is a boolean ArgCompiler that holds a single
  796. X   // boolean value, it has three subclasses:
  797. X   //
  798. X   //   1) CmdArgSet (which is just an alias for CmdArgBool)
  799. X   //      -- This argument SETS a boolean value.
  800. X   //         The initial value is 0 (OFF).
  801. X   //
  802. X   //   2) CmdArgClear
  803. X   //      -- This argument CLEARS a boolean value
  804. X   //         The initial value is 1 (ON).
  805. X   //
  806. X   //   3) CmdArgToggle
  807. X   //      -- This argument TOGGLES a boolean value
  808. X   //         The initial value is 0 (OFF).
  809. X   //
  810. X   // All of these classes have the following member functions
  811. X   // to help make it easier to treat a Boolean Argument as
  812. X   // a Boolean Value:
  813. X   //
  814. X   //   operator=(int);
  815. X   //   operator int(void);
  816. X   //
  817. X   // Examples:
  818. X   //    CmdArgBool    xflag('x', "xmode", "turn on xmode);
  819. X   //    CmdArgClear   yflag('y', "ymode", "turn on ymode);
  820. X   //    CmdArgToggle  zflag('z', "zmode", "turn on zmode);
  821. X   //
  822. X   //    cout << "xmode is " << (xflag ? "ON" : "OFF") << endl ;
  823. X   //
  824. Xclass CmdArgBool : public CmdArgBoolCompiler {
  825. Xpublic:
  826. X   CmdArgBool(char         optchar,
  827. X              const char * keyword,
  828. X              const char * description,
  829. X              unsigned     syntax_flags =CmdArg::isOPT)
  830. X      : CmdArgBoolCompiler(optchar, keyword, description, syntax_flags),
  831. X        val(0) {}
  832. X
  833. X   CmdArgBool(const CmdArgBool & cp) : CmdArgBoolCompiler(cp), val(cp.val) {}
  834. X
  835. X   CmdArgBool(const CmdArg & cp) : CmdArgBoolCompiler(cp), val(0) {}
  836. X
  837. X   virtual ~CmdArgBool(void);
  838. X
  839. X   CmdArgBool &
  840. X   operator=(const CmdArgBool & cp)
  841. X      { val = cp.val; return  *this; }
  842. X
  843. X   CmdArgBool &
  844. X   operator=(int new_value)
  845. X      { val = (new_value) ? 1 : 0; return *this; }
  846. X
  847. X   operator int(void) const { return  val; }
  848. X
  849. X   virtual  int
  850. X   operator()(const char * & arg, CmdLine & cmd);
  851. X
  852. Xprotected:
  853. X   unsigned  val : 1;
  854. X} ;
  855. X
  856. Xostream &
  857. Xoperator<<(ostream & os, const CmdArgBool & bool_arg);
  858. X
  859. Xtypedef  CmdArgBool  CmdArgSet ;
  860. X
  861. Xclass CmdArgClear : public CmdArgBool {
  862. Xpublic:
  863. X   CmdArgClear(char         optchar,
  864. X               const char * keyword,
  865. X               const char * description,
  866. X               unsigned     syntax_flags =CmdArg::isOPT)
  867. X      : CmdArgBool(optchar, keyword, description, syntax_flags) { val = 1; }
  868. X
  869. X   CmdArgClear(const CmdArgClear & cp) : CmdArgBool(cp) {}
  870. X
  871. X   CmdArgClear(const CmdArg & cp) : CmdArgBool(cp) { val = 1; }
  872. X
  873. X   virtual ~CmdArgClear(void);
  874. X
  875. X   CmdArgClear &
  876. X   operator=(const CmdArgClear & cp)
  877. X      { val = cp.val; return  *this; }
  878. X
  879. X   CmdArgClear &
  880. X   operator=(int new_value)
  881. X      { val = (new_value) ? 1 : 0; return *this; }
  882. X
  883. X   operator int(void) const { return  val; }
  884. X
  885. X   virtual  int
  886. X   operator()(const char * & arg, CmdLine & cmd);
  887. X} ;
  888. X
  889. Xclass CmdArgToggle : public CmdArgBool {
  890. Xpublic:
  891. X   CmdArgToggle(char         optchar,
  892. X                const char * keyword,
  893. X                const char * description,
  894. X                unsigned     syntax_flags =CmdArg::isOPT)
  895. X      : CmdArgBool(optchar, keyword, description, syntax_flags) {}
  896. X
  897. X   CmdArgToggle(const CmdArgToggle & cp) : CmdArgBool(cp) {}
  898. X
  899. X   CmdArgToggle(const CmdArg & cp) : CmdArgBool(cp) {}
  900. X
  901. X   virtual ~CmdArgToggle(void);
  902. X
  903. X   CmdArgToggle &
  904. X   operator=(const CmdArgToggle & cp)
  905. X      { val = cp.val; return  *this; }
  906. X
  907. X   CmdArgToggle &
  908. X   operator=(int new_value)
  909. X      { val = (new_value) ? 1 : 0; return *this; }
  910. X
  911. X   operator int(void) const { return  val; }
  912. X
  913. X   virtual  int
  914. X   operator()(const char * & arg, CmdLine & cmd);
  915. X} ;
  916. X
  917. X
  918. X   // Now we come to the Reference Boolean arguments, these are boolean
  919. X   // arguments that reference the very same value as some other boolean
  920. X   // argument. The constructors for Reference Boolean arguments require
  921. X   // a reference to the boolean argument whose value they are referencing.
  922. X   //
  923. X   // The boolean reference classes are as follows:
  924. X   //
  925. X   //   1) CmdArgBoolRef and CmdArgSetRef
  926. X   //      -- SET the boolean value referenced by a CmdArgBool
  927. X   //
  928. X   //   2) CmdArgClearRef
  929. X   //      -- CLEAR the boolean value referenced by a CmdArgBool
  930. X   //
  931. X   //   3) CmdArgToggleRef
  932. X   //      -- TOGGLE the boolean value referenced by a CmdArgBool
  933. X   //
  934. X   // Examples:
  935. X   //    CmdArgBool    xflag('x', "xmode", "turn on xmode");
  936. X   //    CmdArgClear   yflag('Y', "noymode", "turn off ymode");
  937. X   //    CmdArgToggle  zflag('z', "zmode", "toggle zmode");
  938. X   //
  939. X   //    CmdArgClearRef x_off(xflag, 'X', "noxmode", "turn off xmode");
  940. X   //    CmdArgBoolRef  y_on(yflag, 'Y', "ymode", "turn on ymode");
  941. X   //
  942. X   //    cout << "xmode is " << (xflag ? "ON" : "OFF") << endl ;
  943. X   //
  944. Xclass CmdArgBoolRef : public CmdArg {
  945. Xpublic:
  946. X   CmdArgBoolRef(CmdArgBool & bool_arg,
  947. X                 char         optchar,
  948. X                 const char * keyword,
  949. X                 const char * description,
  950. X                 unsigned     syntax_flags =CmdArg::isOPT)
  951. X      : CmdArg(optchar, keyword, description, syntax_flags), ref(bool_arg) {}
  952. X
  953. X   virtual  ~CmdArgBoolRef(void);
  954. X
  955. X   virtual  int
  956. X   operator()(const char * & arg, CmdLine & cmd);
  957. X
  958. Xprotected:
  959. X   CmdArgBool & ref;
  960. X} ;
  961. X
  962. Xtypedef CmdArgBoolRef  CmdArgSetRef ;
  963. X
  964. Xclass CmdArgClearRef : public CmdArg {
  965. Xpublic:
  966. X   CmdArgClearRef(CmdArgBool & bool_arg,
  967. X                  char         optchar,
  968. X                  const char * keyword,
  969. X                  const char * description,
  970. X                  unsigned     syntax_flags =CmdArg::isOPT)
  971. X      : CmdArg(optchar, keyword, description, syntax_flags), ref(bool_arg) {}
  972. X
  973. X   virtual  ~CmdArgClearRef(void);
  974. X
  975. X   virtual  int
  976. X   operator()(const char * & arg, CmdLine & cmd);
  977. X
  978. Xprotected:
  979. X   CmdArgBool & ref;
  980. X} ;
  981. X
  982. Xclass CmdArgToggleRef : public CmdArg {
  983. Xpublic:
  984. X   CmdArgToggleRef(CmdArgBool & bool_arg,
  985. X                  char         optchar,
  986. X                  const char * keyword,
  987. X                  const char * description,
  988. X                  unsigned     syntax_flags =CmdArg::isOPT)
  989. X      : CmdArg(optchar, keyword, description, syntax_flags), ref(bool_arg) {}
  990. X
  991. X   virtual  ~CmdArgToggleRef(void);
  992. X
  993. X   virtual  int
  994. X   operator()(const char * & arg, CmdLine & cmd);
  995. X
  996. Xprotected:
  997. X   CmdArgBool & ref;
  998. X} ;
  999. X
  1000. X#endif /* _usr_include_cmdargs_h */
  1001. END_OF_FILE
  1002. if test 30824 -ne `wc -c <'src/lib/cmdargs.h'`; then
  1003.     echo shar: \"'src/lib/cmdargs.h'\" unpacked with wrong size!
  1004. fi
  1005. # end of 'src/lib/cmdargs.h'
  1006. fi
  1007. if test -f 'src/lib/cmdline.h' -a "${1}" != "-c" ; then 
  1008.   echo shar: Will not clobber existing file \"'src/lib/cmdline.h'\"
  1009. else
  1010. echo shar: Extracting \"'src/lib/cmdline.h'\" \(26959 characters\)
  1011. sed "s/^X//" >'src/lib/cmdline.h' <<'END_OF_FILE'
  1012. X//------------------------------------------------------------------------
  1013. X// ^FILE: cmdline.h - declare the basic classes used in the CmdLine library
  1014. X//
  1015. X// ^DESCRIPTION:
  1016. X//    This file declares the three basic classes used in the CmdLine library.
  1017. X//    These three classes are "CmdArg" (a command-argument object),
  1018. X//    "CmdLineArgIter" (an object to iterate over a set of arguments),
  1019. X//    and "CmdLine" (the command-line object itself).
  1020. X//
  1021. X// ^HISTORY:
  1022. X//    03/19/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1023. X//-^^---------------------------------------------------------------------
  1024. X
  1025. X#ifndef _usr_include_cmdline_h
  1026. X#define _usr_include_cmdline_h
  1027. X
  1028. Xclass  ostream ;
  1029. Xclass  istream ;
  1030. Xclass  CmdLine ;
  1031. Xclass  CmdArgListIter ;
  1032. Xclass  CmdArgListList ;
  1033. X
  1034. X//-----------------------------------------------------------------------------
  1035. X
  1036. X   // A CmdArg is an abstract command-line argument.
  1037. X   // At this level (being the base class), all a command argument
  1038. X   // contains is the "interface" (on the command-line) of the
  1039. X   // argument, and some information (after the command-line has
  1040. X   // been parsed) that says "how" the argument appeared (if it did).
  1041. X   //
  1042. X   // The interface of a CmdArg consists of 6 things:
  1043. X   //    1) a character name
  1044. X   //    2) a keyword name
  1045. X   //    3) a value name (if the argument takes a value)
  1046. X   //    4) an argument description
  1047. X   //    5) a set of flags describing the syntax of the argument.
  1048. X   //    6) a set of flags to record how (and if) the argument
  1049. X   //         appeared on the command-line.
  1050. X   //
  1051. X   // When constructing a CmdArg, the most common syntax-flags can be
  1052. X   // inferred from the syntax used in the argument description,
  1053. X   // and the argument value name.  If the first non-white character
  1054. X   // of the argument description is ';', then the argument is considered
  1055. X   // to be "secret" and is NOT printed in usage messages.
  1056. X   //
  1057. X   // When specifiying a value, one may enclose the value name between
  1058. X   // '[' and ']' to indicate the value is optional. Also, one may follow
  1059. X   // the actual value name with "..." to indicate that the value corresponds
  1060. X   // to a LIST of values.
  1061. X   //
  1062. X   // Hence, the only time you really need to explicitly specify any syntax
  1063. X   // flags is when you want a value to be "strictly sticky" or "strictly
  1064. X   // separate"  and/or you want an argument to be able to be matched both
  1065. X   // positionally AND by (long or short) keyword.
  1066. X   //
  1067. Xclass  CmdArg {
  1068. Xpublic:
  1069. X   friend class CmdLine ;
  1070. X
  1071. X      // Flags that define the argument syntax
  1072. X   enum  CmdArgSyntax {
  1073. X      isOPT       = 0x00,  // argument is optional
  1074. X      isREQ       = 0x01,  // argument is required
  1075. X      isVALOPT    = 0x02,  // argument value is optional
  1076. X      isVALREQ    = 0x04,  // argument value is required
  1077. X      isVALSEP    = 0x08,  // argument value must be in a separate token
  1078. X      isVALSTICKY = 0x10,  // argument value must be in the same token
  1079. X      isLIST      = 0x20,  // argument is a list
  1080. X      isPOS       = 0x40,  // argument is positional
  1081. X      isHIDDEN    = 0x80,  // argument is not to be printed in usage
  1082. X      isVALTAKEN  = (isVALREQ | isVALOPT),    // argument takes a value
  1083. X      isOPTVALOPT = (isOPT | isVALOPT),
  1084. X      isOPTVALREQ = (isOPT | isVALREQ),
  1085. X      isPOSVALOPT = (isPOS | isVALOPT),
  1086. X      isPOSVALREQ = (isPOS | isVALREQ),
  1087. X   } ;
  1088. X
  1089. X     // Flags that say how the argument was specied on the command-line
  1090. X   enum  CmdArgFlags {
  1091. X      GIVEN      = 0x01,  // argument was given
  1092. X      VALGIVEN   = 0x02,  // argument value was given
  1093. X      OPTION     = 0x04,  // item was matched as an option
  1094. X      KEYWORD    = 0x08,  // item was matched as a keyword
  1095. X      POSITIONAL = 0x10,  // item was matched as a positional argument
  1096. X      VALSEP     = 0x20,  // value was in a separate token
  1097. X   } ;
  1098. X
  1099. X      // Create an option that takes a value.
  1100. X      //
  1101. X      // The default flags are to assume that the argument is optional
  1102. X      // and that the value is required.
  1103. X      //
  1104. X      // Some examples:
  1105. X      //
  1106. X      //    CmdArg('c', "count", "number", "specify the # of copies to use);
  1107. X      //
  1108. X      //    CmdArg('d', "debug", "[level]". "turn on debugging and optionally"
  1109. X      //                                    "specify the debug level");
  1110. X      //
  1111. X      //    CmdArg('l', "list", "items ...", "specify a list of items.");
  1112. X      //
  1113. X   CmdArg(char         optchar,
  1114. X          const char * keyword,
  1115. X          const char * value,
  1116. X          const char * description,
  1117. X          unsigned     syntax_flags =isOPTVALREQ);
  1118. X
  1119. X      // Create an option that takes no value.
  1120. X      //
  1121. X      // The default flags are to assume that the argument is optional.
  1122. X      //
  1123. X      // Some examples:
  1124. X      //
  1125. X      //    CmdArg('m', "mode", "turn on this mode");
  1126. X      //
  1127. X   CmdArg(char         optchar,
  1128. X          const char * keyword,
  1129. X          const char * description,
  1130. X          unsigned     syntax_flags =isOPT);
  1131. X
  1132. X      // Create a positional argument.
  1133. X      //
  1134. X      // The default flags are to assume that the argument is positional
  1135. X      // and that the argument value is required.
  1136. X      //
  1137. X      // Some examples:
  1138. X      //
  1139. X      //    CmdArg("file", "file to read");
  1140. X      //
  1141. X      //    CmdArg("[file]", "optional file to read");
  1142. X      //
  1143. X      //    CmdArg("file ...", "list of files to read");
  1144. X      //
  1145. X      //    CmdArg("[file ...]", "optional list of files to read");
  1146. X      //
  1147. X   CmdArg(const char * value,
  1148. X          const char * description,
  1149. X          unsigned     syntax_flags =isPOSVALREQ);
  1150. X
  1151. X
  1152. X   CmdArg(const CmdArg & cp);
  1153. X
  1154. X   virtual ~CmdArg(void);
  1155. X
  1156. X      // over-ride this function to return a non-zero value if you
  1157. X      // wish the argument to be ignored (except for usage messages).
  1158. X      //
  1159. X   virtual  int
  1160. X   is_dummy(void);
  1161. X
  1162. X      // Here is the "primary" function that makes everything work ...
  1163. X      //
  1164. X      // Whenever we actually "match" an argument on the command-line,
  1165. X      // we need to tell the argument it was matched (and how), and
  1166. X      // give it the string value (if there is one) to associate with it.
  1167. X      //
  1168. X      // At this point, the argument object is then responsible for
  1169. X      // performing whatever "magic" is to be done. This might be going
  1170. X      // off and reading a file, performing some other actions, or just
  1171. X      // "compiling" the argument into some internal value (specified
  1172. X      // by the derived class) to be queried at a later time.
  1173. X      //
  1174. X      // The parameters to this function are as follows:
  1175. X      //
  1176. X      //   PARAMETER 1: arg
  1177. X      //      The string value on the command-line to associate with this
  1178. X      //      argument. If this argument does not take a value, or the
  1179. X      //      value is optional and was NOT supplied, then NULL is passed.
  1180. X      //      This parameter is a reference parameter and before returning,
  1181. X      //      "arg" should either be set to NULL (to indicate that the entire
  1182. X      //      argument was used) or should point to the first unused character
  1183. X      //      of "arg".
  1184. X      //
  1185. X      //   PARAMETER 2: cmd
  1186. X      //      A reference to the command-line object that is currently being
  1187. X      //      parsed.  There are parts of this object that may be helpful in
  1188. X      //      determining what to do. In particular, we may want to look at
  1189. X      //      the "flags" of the command.  If the QUIET flag is set, then
  1190. X      //      this routine should suppress the printing of any error messages.
  1191. X      //      If the TEMP flag is set, then "arg" (the first parameter) points
  1192. X      //      to storage that may not be around for much longer and we may
  1193. X      //      want to make a copy of it.
  1194. X      //
  1195. X      // Before, this function is called, the CmdLine object that is parsing
  1196. X      // the arguments has already set the "flags()" of this argument to tell
  1197. X      // us how we appeared on the command-line this time around (were we
  1198. X      // specified as an option or positionally? Is "arg" in a separate argv[]
  1199. X      // element?).
  1200. X      //
  1201. X      // After we have done our "magic" and set the reference parameter
  1202. X      // "arg", this function should return a value of 0 if everything
  1203. X      // is A-OK and "arg" was a correctly specified value for this type of
  1204. X      // of argument. If something went wrong (like a syntax error in "arg"),
  1205. X      // then we should return a non-zero value.
  1206. X      //
  1207. X   virtual  int
  1208. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  1209. X
  1210. X      // Retrieve the syntax flags for this argument.
  1211. X   unsigned
  1212. X   syntax(void) const  { return  arg_syntax; }
  1213. X
  1214. X      // Get the flags that say how this argument was specified.
  1215. X   unsigned
  1216. X   flags(void) const  { return  arg_flags; }
  1217. X
  1218. X      // Get the character (short-option) name of this argument.
  1219. X      // Returns '\0' if there isnt one.
  1220. X   char
  1221. X   char_name(void) const  { return  arg_char_name; }
  1222. X
  1223. X      // Get the keyword (long-option) name of this argument
  1224. X      // Returns NULL if there isnt one.
  1225. X   const char *
  1226. X   keyword_name(void) const  { return  arg_keyword_name; }
  1227. X
  1228. X      // Get the value name of this argument.
  1229. X      // Returns NULL if this argument takes no value.
  1230. X   const char *
  1231. X   value_name(void) const  { return  arg_value_name; }
  1232. X
  1233. X      // Get the description (help-message) of this argument.
  1234. X   const char *
  1235. X   description(void) const  { return  arg_description; }
  1236. X
  1237. X      // If we were compiled for dubugging, then dump this argument
  1238. X   virtual  void
  1239. X   dump(ostream & os, unsigned level =0) const;
  1240. X
  1241. Xprivate:
  1242. X   // Member functions for internal use
  1243. X
  1244. X   void
  1245. X   adjust_syntax(void);
  1246. X
  1247. X   void
  1248. X   parse_description(void);
  1249. X
  1250. X   void
  1251. X   parse_value(void);
  1252. X
  1253. X   void
  1254. X   flags(unsigned newflags)  { arg_flags = newflags; }
  1255. X
  1256. X   void
  1257. X   set(unsigned flags)  { arg_flags |= flags; }
  1258. X
  1259. X   void
  1260. X   clear(unsigned flags =~0)  { arg_flags &= ~flags; }
  1261. X
  1262. X
  1263. X   // Private data members
  1264. X
  1265. X   unsigned     alloc_value_name : 1 ;
  1266. X
  1267. X   unsigned     arg_flags : 8 ;
  1268. X   unsigned     arg_syntax : 8 ;
  1269. X
  1270. X   char         arg_char_name;
  1271. X   const char * arg_keyword_name;
  1272. X   const char * arg_value_name;
  1273. X   const char * arg_description;
  1274. X} ;
  1275. X
  1276. X//-----------------------------------------------------------------------------
  1277. X
  1278. X   // In order to parse arguments, we need to have an input source where
  1279. X   // the arguments are coming from.  CmdLineArgIter is an abstract
  1280. X   // iterator class for cycling through all the command-line arguments
  1281. X   // from an arbitrary input source.
  1282. X   //
  1283. Xclass  CmdLineArgIter {
  1284. Xpublic:
  1285. X   CmdLineArgIter(void);
  1286. X
  1287. X   virtual ~CmdLineArgIter(void);
  1288. X
  1289. X      // Return the current argument and advance to the next one.
  1290. X      // Returns NULL if we are already at the end of the arguments
  1291. X      //
  1292. X   virtual const char *
  1293. X   operator()(void) = 0;
  1294. X
  1295. X      // Are the args returned by operator() pointing to temporary storage?
  1296. X   virtual int
  1297. X   is_temporary(void) const = 0;
  1298. X
  1299. Xprivate:
  1300. X   CmdLineArgIter(const CmdLineArgIter &) ;
  1301. X
  1302. X   CmdLineArgIter &
  1303. X   operator=(const CmdLineArgIter &) ;
  1304. X} ;
  1305. X
  1306. X
  1307. X   // CmdArgvIter is a class used to iterate through command arguments
  1308. X   // that come from an array of strings (like argv[] from main()).
  1309. X   //
  1310. Xclass  CmdArgvIter : public CmdLineArgIter {
  1311. Xpublic:
  1312. X   CmdArgvIter(int argc, const char * const argv[])
  1313. X      : count(argc), array(argv), index(0) {}
  1314. X
  1315. X   CmdArgvIter(const char * const argv[])
  1316. X      : array(argv), index(0), count(-1) {}
  1317. X
  1318. X   virtual ~CmdArgvIter(void);
  1319. X
  1320. X   virtual const char *
  1321. X   operator()(void);
  1322. X
  1323. X   virtual int
  1324. X   is_temporary(void) const;
  1325. X
  1326. X      // Restart using a different string array.
  1327. X   void
  1328. X   reset(int argc, const char * const argv[])
  1329. X      { count = argc; array = argv; index = 0; }
  1330. X
  1331. X   void
  1332. X   reset(const char * const argv[])
  1333. X      { array = argv; index = 0; count = -1; }
  1334. X
  1335. Xprivate:
  1336. X   CmdArgvIter(const CmdArgvIter &) ;
  1337. X
  1338. X   CmdArgvIter &
  1339. X   operator=(const CmdArgvIter &) ;
  1340. X
  1341. X   int   count;
  1342. X   int   index;
  1343. X   const char * const *  array;
  1344. X} ;
  1345. X
  1346. X
  1347. X   // CmdStrTok iterator is a class for iterating over arguments that
  1348. X   // are specified in a string of tokens that are delimited by a
  1349. X   // particular set of characters.  The strtok(3C) library function
  1350. X   // is used to extract tokens from the string.
  1351. X   //
  1352. X   // If NULL is given as the delimiter-set, then whitespace is assumed.
  1353. X   //
  1354. Xclass  CmdStrTokIter : public CmdLineArgIter {
  1355. Xpublic:
  1356. X   CmdStrTokIter(const char * tokens, const char * delimiters =0);
  1357. X
  1358. X   virtual ~CmdStrTokIter(void);
  1359. X
  1360. X   virtual const char *
  1361. X   operator()(void);
  1362. X
  1363. X      // Reset using a new token-string and delimiter set.
  1364. X   void
  1365. X   reset(const char * tokens, const char * delimiters =0);
  1366. X
  1367. X      // Get the current delimiter set
  1368. X   const char *
  1369. X   delimiters(void) const { return  seps; }
  1370. X
  1371. X      // Change the current delimiter set
  1372. X   void
  1373. X   delimiters(const char * new_delimiters)  { seps = new_delimiters; }
  1374. X
  1375. X   virtual int
  1376. X   is_temporary(void) const;
  1377. X
  1378. Xprivate:
  1379. X   CmdStrTokIter(const CmdStrTokIter &) ;
  1380. X
  1381. X   CmdStrTokIter &
  1382. X   operator=(const CmdStrTokIter &) ;
  1383. X
  1384. X   char       * tokstr;
  1385. X   const char * seps;
  1386. X   const char * token;
  1387. X} ;
  1388. X
  1389. X
  1390. X   // CmdIstreamIter is a class for iterating over arguments that come
  1391. X   // from an input stream. Each line of the input stream is considered
  1392. X   // to be a set of white-space separated tokens. If the the first
  1393. X   // non-white character on a line is '#' ('!' for VMS systems) then
  1394. X   // the line is considered a comment and is ignored.
  1395. X   //
  1396. X   // *Note:: If a line is more than 1022 characters in length then we
  1397. X   // treat it as if it were several lines of length 1022 or less.
  1398. X   //
  1399. Xclass  CmdIstreamIter : public CmdLineArgIter {
  1400. Xpublic:
  1401. X   CmdIstreamIter(istream & input);
  1402. X
  1403. X   virtual ~CmdIstreamIter(void);
  1404. X
  1405. X   virtual const char *
  1406. X   operator()(void);
  1407. X
  1408. X   virtual int
  1409. X   is_temporary(void) const;
  1410. X
  1411. Xprivate:
  1412. X   istream & is ;
  1413. X   CmdStrTokIter * tok_iter ;
  1414. X} ;
  1415. X
  1416. X//-----------------------------------------------------------------------------
  1417. X
  1418. X   // Here is the class that represents a command-line object. A command
  1419. X   // line object is a parsing machine (with machine states), whose parsing
  1420. X   // behavior may be configured at run-time by specifying various CmdFlags
  1421. X   // (defined below). A command-line object also contains a command-name
  1422. X   // and a list of CmdArg objects that correspond to the various arguments
  1423. X   // that are allowed to occur on the command line.
  1424. X   //
  1425. Xclass  CmdLine {
  1426. Xpublic:
  1427. X   friend class CmdLineCmdArgIter;
  1428. X
  1429. X      // Flags that define parsing behavior
  1430. X      //   The default flags (for Unix) are OPTS_FIRST.
  1431. X   enum CmdFlags {
  1432. X      ANY_CASE_OPTS = 0x001, // Ignore character-case for short-options
  1433. X      PROMPT_USER   = 0x002, // Prompt the user for missing required args
  1434. X      NO_ABORT      = 0x004, // Dont exit upon syntax error
  1435. X      OPTS_FIRST    = 0x008, // No options after positional parameters
  1436. X      OPTS_ONLY     = 0x010, // Dont accept short-options
  1437. X      KWDS_ONLY     = 0x020, // Dont accept long-options
  1438. X      TEMP          = 0x040, // Assume all arg-strings are temporary
  1439. X      QUIET         = 0x080, // Dont print syntax error messages
  1440. X      NO_GUESSING   = 0x100, // Dont guess if cant match an option. 
  1441. X                                // Unless this flag is given, then
  1442. X                                // when we see an unmatched option,
  1443. X                                // we will try to see if it matches
  1444. X                                // a keyword (and vice-versa).
  1445. X   } ;
  1446. X
  1447. X      // Flags to convey parsing-status
  1448. X   enum CmdStatus {
  1449. X      NO_ERROR      = 0x000,  // No problems
  1450. X      ARG_MISSING   = 0x001,  // A required argument was not specified
  1451. X      VAL_MISSING   = 0x002,  // A required argument value was not specified
  1452. X      VAL_NOTSTICKY = 0x004,  // Value needs to be in same token
  1453. X      VAL_NOTSEP    = 0x008,  // Value needs to be in separate token
  1454. X      KWD_AMBIGUOUS = 0x010,  // An ambiguous keyword prefix was specified
  1455. X      BAD_OPTION    = 0x020,  // An invalid option was specified
  1456. X      BAD_KEYWORD   = 0x040,  // An invalid keyword was specified
  1457. X      BAD_VALUE     = 0x080,  // An invalid value was specified for an arg
  1458. X      TOO_MANY_ARGS = 0x100,  // Too many positional args were specified
  1459. X   } ;
  1460. X
  1461. X      // Contructors and Destructors ...
  1462. X      //
  1463. X      //   It is not necessary to supply a command-name at construction
  1464. X      //   time, but one SHOULD be specified before parsing a command-line
  1465. X      //   or printing a usage message.
  1466. X      //
  1467. X      //   Similarly, CmdArgs are not required at construction time and may
  1468. X      //   even be added on the fly. All desired arguments should be added
  1469. X      //   before any parsing happens and before printing usage.
  1470. X      //
  1471. X      //   The order in which CmdArgs are added to a CmdLine is important
  1472. X      //   because for positional parameters, this specifies the order in
  1473. X      //   which they are expected to appear on the command-line.
  1474. X      //
  1475. X   CmdLine(const char * name =0);
  1476. X
  1477. X   CmdLine(const char * name, CmdArg * ...);   // last arg should be NULL
  1478. X
  1479. X   CmdLine(CmdArg * cmdarg, CmdArg * ...);     // last arg should be NULL
  1480. X
  1481. X   virtual ~CmdLine(void);
  1482. X
  1483. X      // Get the command name.
  1484. X   const char *
  1485. X   name(void)  const  { return  cmd_name; }
  1486. X
  1487. X      // Specify a command name.
  1488. X   void
  1489. X   name(const char * progname);
  1490. X
  1491. X      // Append an argument
  1492. X   CmdLine &
  1493. X   append(CmdArg * cmdarg);
  1494. X
  1495. X   CmdLine &
  1496. X   append(CmdArg & cmdarg)  { return  append(& cmdarg); }
  1497. X
  1498. X      // The insertion operator (operator<<) is merely a convenient
  1499. X      // shorthand for the append() member function.
  1500. X      //
  1501. X   CmdLine &
  1502. X   operator<<(CmdArg * cmdarg)  { return  append(cmdarg) ; }
  1503. X
  1504. X   CmdLine &
  1505. X   operator<<(CmdArg & cmdarg)  { return  append(& cmdarg) ; }
  1506. X
  1507. X   //
  1508. X   // Messages and Status
  1509. X   //
  1510. X
  1511. X      // Specify the verboseness of usage messages
  1512. X   enum CmdUsageLevel {
  1513. X      NO_USAGE      = 0,  // Dont print usage at all.
  1514. X      TERSE_USAGE   = 1,  // Just print command-line syntax.
  1515. X      VERBOSE_USAGE = 2,  // Print command-line syntax & argument-descriptions.
  1516. X      DEFAULT_USAGE = 3,  // Read the $USAGE_LEVEL environment variable for
  1517. X                             // the usage-level: 0=none, 1=terse, 2=verbose.
  1518. X                             // if $USAGE_LEVEL is empty or is not 0, 1, or 2
  1519. X                             // then VERBOSE_USAGE is used.
  1520. X   } ;
  1521. X
  1522. X      // Print usage on the given output stream using the given verboseness
  1523. X   ostream &
  1524. X   usage(ostream & os, CmdUsageLevel level =DEFAULT_USAGE) const ;
  1525. X
  1526. X      // Print usage on the CmdLine's error-outstream
  1527. X   ostream &
  1528. X   usage(CmdUsageLevel level =DEFAULT_USAGE) const ;
  1529. X
  1530. X      // Obtain the current status of the command. The status will be
  1531. X      // zero if everything is alright; otherwise it will correspond
  1532. X      // to a combination of CmdStatus bitmasks telling us precisely
  1533. X      // what went wrong.
  1534. X      //
  1535. X   unsigned
  1536. X   status(void)  const  { return  cmd_status; }
  1537. X
  1538. X      // Print an error message prefix on the error output stream
  1539. X      // associated with this command. The prefix printed is the
  1540. X      // basename of the command followed by a ':'.
  1541. X      //
  1542. X      // Hence error messages associated with this command may be
  1543. X      // printed as follows:
  1544. X      //
  1545. X      //    my_cmd.error() << "This is what went wrong!" << endl;
  1546. X      //
  1547. X      // If NOPRINT is given as a parameter, then nothing
  1548. X      // is printed.
  1549. X      //
  1550. X   enum { NOPRINT = 0, PRINT = 1 } ;
  1551. X
  1552. X   ostream &
  1553. X   error(int  print =PRINT) const;
  1554. X
  1555. X      // If the QUIET-flag is not set, then we need to know where
  1556. X      // to print any error messages (the default is cerr).
  1557. X      //
  1558. X      // Use this member function to specify the desired output stream
  1559. X      // for error messages.
  1560. X      //
  1561. X   void
  1562. X   error(ostream & os) { cmd_err = &os; }
  1563. X
  1564. X   //
  1565. X   // Get & set the command-parsing-flags
  1566. X   //
  1567. X
  1568. X      // Get the current set of command-flags
  1569. X   unsigned
  1570. X   flags(void) const  { return  cmd_flags; }
  1571. X
  1572. X      // Specify a new set of command-flags
  1573. X   void
  1574. X   flags(unsigned newflags)  { cmd_flags = newflags; }
  1575. X
  1576. X      // Set only the given command-flags
  1577. X   void
  1578. X   set(unsigned flags)  { cmd_flags |= flags; }
  1579. X
  1580. X      // Clear only the given command-flags
  1581. X   void
  1582. X   clear(unsigned flags =~0)  { cmd_flags &= ~flags; }
  1583. X
  1584. X   //
  1585. X   // We are somewhat flexible in the way we parse arguments.
  1586. X   // Before any parsing can occur, some preprocessing needs to
  1587. X   // be done. After we have parsed all the arguments, some
  1588. X   // post-processing needs to be done.  If you use the "parse()"
  1589. X   // member function, then this pre- and post- processing is
  1590. X   // automatically performed for you UNLESS you specify a second
  1591. X   // parameter of NO_PROCESSING.  If you have arguments that are
  1592. X   // coming from more then one input source, you will have to
  1593. X   // manually activate pre-processing (by calling prologue()),
  1594. X   // then parse all your arguments (using parse() with NO_PROCESSING
  1595. X   // and/or using arg_parse()), and then manually activate
  1596. X   // post-processing (by calling epilogue()).
  1597. X   //
  1598. X
  1599. X      // Parse a set of arguments (pre- and post- processing is
  1600. X      // automatically performed UNLESS "NO_PROCESSING" is given
  1601. X      // as the second argument).
  1602. X      //
  1603. X      // Return the resultant command status.
  1604. X      //
  1605. X   enum { NO_PROCESSING = 0, AUTO_PROCESSING = 1 } ;
  1606. X
  1607. X   unsigned
  1608. X   parse(CmdLineArgIter & arg_iter, int  processing =AUTO_PROCESSING) ;
  1609. X
  1610. X      // Perform the necessary pre-processing.
  1611. X      // Return the resultant command status.
  1612. X      //
  1613. X   unsigned
  1614. X   prologue(void) ;
  1615. X
  1616. X      // Parse a single argument (pre- and post- processing is
  1617. X      // NOT performed).
  1618. X      //
  1619. X   unsigned
  1620. X   parse_arg(const char * arg) ;
  1621. X
  1622. X      // Perform the necessary post-processing.
  1623. X      // Return the resultant command status.
  1624. X      //
  1625. X   unsigned
  1626. X   epilogue(void) ;
  1627. X
  1628. X   //
  1629. X   // Retrieve a specific argument
  1630. X   //
  1631. X
  1632. X      // Retrieve an argument based on its character-name.
  1633. X      // Returns NULL if no argument matches the given character.
  1634. X      //
  1635. X   CmdArg *
  1636. X   operator[](char optchar) const { return  opt_match(optchar); }
  1637. X
  1638. X      // Retrieve an argument based on its keyword-name.
  1639. X      // (if an argument has no keyword-name then we try to match its
  1640. X      // value name instead).
  1641. X      //
  1642. X      // Returns NULL if no argument matches the given keyword or
  1643. X      // the keyword is ambiguous.
  1644. X      //
  1645. X   CmdArg *
  1646. X   operator[](const char * keyword) const
  1647. X      { int ambig = 0;  return  kwd_match(keyword, -1, ambig, 1); }
  1648. X
  1649. X   //
  1650. X   // Version specific information
  1651. X   //
  1652. X
  1653. X      // get the release number
  1654. X   static  unsigned
  1655. X   release(void);
  1656. X
  1657. X      // get the patchlevel number
  1658. X   static  unsigned
  1659. X   patchlevel(void);
  1660. X
  1661. X      // get the SCCS identifier string
  1662. X   static  const char *
  1663. X   ident(void);
  1664. X
  1665. X   //
  1666. X   // These next few functions are used internally but are general
  1667. X   // enough in purpose as to possibly be useful to others.
  1668. X   //
  1669. X
  1670. X      // return type for an attempted keyword match
  1671. X   enum strmatch_t { str_NONE, str_PARTIAL, str_EXACT } ;
  1672. X
  1673. X      // Try to match "attempt" against "src", if len is 0 then
  1674. X      // only the first "len" characters are compared.
  1675. X      //
  1676. X      // Returns str_EXACT for an exact-match str_PARTIAL for a
  1677. X      // partial-match, and str_NONE otherwise.
  1678. X      //
  1679. X   static  strmatch_t
  1680. X   strmatch(const char * src, const char * attempt, unsigned  len =0);
  1681. X
  1682. X      // Print a hanging indented paragraph on an outstream. Long lines
  1683. X      // are broken at word boundaries and are warpped to line up with
  1684. X      // the rest of the paragraph.  The format looks like the following
  1685. X      // (text starts on a new line is the strlen(title) >= indent):
  1686. X      //
  1687. X      // <------------------------- maxcols ------------------------------->
  1688. X      // <--- margin ---><--- indent --->
  1689. X      //                 title           This is the first sentence.  This
  1690. X      //                                 is the second sentence. etc ...
  1691. X      //
  1692. X   static  void
  1693. X   strindent(ostream    & os,
  1694. X             unsigned     maxcols,
  1695. X             unsigned     margin,
  1696. X             const char * title,
  1697. X             unsigned     indent,
  1698. X             const char * text);
  1699. X
  1700. X   //
  1701. X   // Debugging stuff ...
  1702. X   //
  1703. X
  1704. X      // If we were compiled for dubugging, then dump this command
  1705. X   virtual  void
  1706. X   dump(ostream & os, unsigned level =0) const;
  1707. X
  1708. X      // If we were compiled for dubugging, then dump the argument list
  1709. X   virtual  void
  1710. X   dump_args(ostream & os, unsigned level =0) const;
  1711. X
  1712. Xprivate:
  1713. X      // Private data members
  1714. X   unsigned          cmd_parse_state : 8 ;
  1715. X   unsigned          cmd_state  : 8 ;
  1716. X   unsigned          cmd_flags  : 16 ;
  1717. X   unsigned          cmd_status : 16 ;
  1718. X   const char      * cmd_name ;
  1719. X   CmdArg          * cmd_matched_arg ;
  1720. X   CmdArgListList  * cmd_args ;
  1721. X   ostream         * cmd_err ;
  1722. X
  1723. X      // Disallow copying and assignment
  1724. X   CmdLine(const CmdLine & );
  1725. X
  1726. X   CmdLine &
  1727. X   operator=(const CmdLine & );
  1728. X
  1729. X   //
  1730. X   // Member functions for internal use
  1731. X   //
  1732. X
  1733. X      // Specify the command syntax to use for usage messages
  1734. X   enum CmdLineSyntax { cmd_OPTS_ONLY = 0, cmd_KWDS_ONLY = 1, cmd_BOTH = 2 } ;
  1735. X
  1736. X   int
  1737. X   handle_arg(CmdArg * cmdarg, const char * & arg);
  1738. X
  1739. X   void
  1740. X   ck_need_val(void);
  1741. X
  1742. X   CmdLineSyntax
  1743. X   syntax(void) const;
  1744. X
  1745. X   unsigned
  1746. X   prompt_user(CmdArg * cmdarg);
  1747. X
  1748. X   unsigned
  1749. X   missing_args(void);
  1750. X
  1751. X   CmdArg *
  1752. X   opt_match(char optchar) const;
  1753. X
  1754. X   CmdArg *
  1755. X   kwd_match(const char * kwd,
  1756. X             int          len,
  1757. X             int &        is_ambiguous,
  1758. X             int          match_value =0) const;
  1759. X
  1760. X   CmdArg *
  1761. X   pos_match(void) const;
  1762. X
  1763. X   unsigned
  1764. X   parse_option(const char * arg);
  1765. X
  1766. X   unsigned
  1767. X   parse_keyword(const char * arg);
  1768. X
  1769. X   unsigned
  1770. X   parse_value(const char * arg);
  1771. X
  1772. X   ostream &
  1773. X   arg_error(const char * error_str, const CmdArg * cmdarg) const;
  1774. X
  1775. X   unsigned
  1776. X   fmt_arg(const CmdArg * cmdarg,
  1777. X           char         * buf,
  1778. X           unsigned       bufsize,
  1779. X           CmdLineSyntax  syntax,
  1780. X           CmdUsageLevel  level) const;
  1781. X
  1782. X   static  CmdUsageLevel
  1783. X   get_usage_level(void);
  1784. X
  1785. X   unsigned
  1786. X   print_synopsis(CmdLineSyntax syntax,
  1787. X                  ostream     & os,
  1788. X                  int           cols) const;
  1789. X
  1790. X   void
  1791. X   print_descriptions(CmdLineSyntax   syntax,
  1792. X                      ostream       & os,
  1793. X                      int             cols,
  1794. X                      unsigned        longest) const;
  1795. X
  1796. X} ;
  1797. X
  1798. X
  1799. X   // "os << cmd" is equivalent to "cmd.usage(os)"
  1800. Xinline ostream &
  1801. Xoperator <<(ostream & os, CmdLine & cmd)  { return  cmd.usage(os); }
  1802. X
  1803. X
  1804. X//-----------------------------------------------------------------------------
  1805. X
  1806. X   // We want to provide the user with a means to iterate over all the
  1807. X   // arguments in the argument list of a command-line.  We will provide
  1808. X   // a class named "CmdLineCmdArgIter" to do this.
  1809. X
  1810. Xclass  CmdLineCmdArgIter {
  1811. Xpublic:
  1812. X   CmdLineCmdArgIter(CmdLine & cmd);
  1813. X
  1814. X   CmdLineCmdArgIter(CmdLine * cmd);
  1815. X
  1816. X   virtual ~CmdLineCmdArgIter(void);
  1817. X
  1818. X      // Return the current argument and advance to the next one.
  1819. X      // Returns NULL if we are already at the end of the list.
  1820. X      //
  1821. X   CmdArg *
  1822. X   operator()(void);
  1823. X
  1824. Xprivate:
  1825. X   CmdLineCmdArgIter(const CmdLineCmdArgIter &);
  1826. X
  1827. X   CmdLineCmdArgIter &
  1828. X   operator=(const CmdLineCmdArgIter &);
  1829. X
  1830. X   CmdArgListIter * iter;
  1831. X} ;
  1832. X
  1833. X#endif /* _usr_include_cmdline_h */
  1834. END_OF_FILE
  1835. if test 26959 -ne `wc -c <'src/lib/cmdline.h'`; then
  1836.     echo shar: \"'src/lib/cmdline.h'\" unpacked with wrong size!
  1837. fi
  1838. # end of 'src/lib/cmdline.h'
  1839. fi
  1840. echo shar: End of archive 7 \(of 7\).
  1841. cp /dev/null ark7isdone
  1842. MISSING=""
  1843. for I in 1 2 3 4 5 6 7 ; do
  1844.     if test ! -f ark${I}isdone ; then
  1845.     MISSING="${MISSING} ${I}"
  1846.     fi
  1847. done
  1848. if test "${MISSING}" = "" ; then
  1849.     echo You have unpacked all 7 archives.
  1850.     rm -f ark[1-9]isdone
  1851. else
  1852.     echo You still need to unpack the following archives:
  1853.     echo "        " ${MISSING}
  1854. fi
  1855. ##  End of shell archive.
  1856. exit 0
  1857.  
  1858. exit 0 # Just in case...
  1859.