home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / cmdline / part07 < prev    next >
Encoding:
Text File  |  1992-07-26  |  60.4 KB  |  1,852 lines

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