home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / getlngop / part01 < prev    next >
Encoding:
Text File  |  1993-02-21  |  22.2 KB  |  718 lines

  1. Newsgroups: comp.sources.misc
  2. From: sam@dcs.ed.ac.uk (S Manoharan)
  3. Subject: v35i075:  getlongopt - a C++ class for parsing long options, Part01/01
  4. Message-ID: <1993Feb22.034330.14554@sparky.imd.sterling.com>
  5. X-Md4-Signature: dea4547ac7f0bc643ae83ac4e35a9aa6
  6. Date: Mon, 22 Feb 1993 03:43:30 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: sam@dcs.ed.ac.uk (S Manoharan)
  10. Posting-number: Volume 35, Issue 75
  11. Archive-name: getlongopt/part01
  12. Environment: C++
  13.  
  14. Appended is a neat (!) C++ class for parsing command line options.
  15. Long options are supported; abbreviations are allowed. Parsing of
  16. environment variables is also possible. Good error handling. See
  17. man page and README.cc for details.
  18.  
  19. Share and Enjoy.
  20. ------------------------
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then feed it
  23. # into a shell via "sh file" or similar.  To overwrite existing files,
  24. # type "sh file -c".
  25. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  26. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  27. # Contents:  README.cc GetLongOpt.3 GetLongOpt.h GetLongOpt.cc
  28. #   sample.runs
  29. # Wrapped by mano@arch04 on Sat Jan 30 16:39:32 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. echo If this archive is complete, you will see the following message:
  32. echo '          "shar: End of archive."'
  33. if test -f 'README.cc' -a "${1}" != "-c" ; then 
  34.   echo shar: Will not clobber existing file \"'README.cc'\"
  35. else
  36.   echo shar: Extracting \"'README.cc'\" \(5675 characters\)
  37.   sed "s/^X//" >'README.cc' <<'END_OF_FILE'
  38. X/* $Id: README.cc,v 1.1 1993/01/02 19:11:54 mano Exp mano $ */
  39. X/* S Manoharan. Advanced Computer Research Institute. Lyon. France */
  40. X
  41. X/*
  42. X
  43. XYes. Yet another GetLongOpt. What's special here?
  44. X
  45. XGetLongOpt supports long options. In fact, there is no support for
  46. Xexplicit short options. For example, -a -b *cannot* be shortened
  47. Xto -ab. However, long options can be abbreviated as long as there
  48. Xis no ambiguity. An ambiguity is resolved by using the last option
  49. Xin the sequence of options (we will come to this later).
  50. XIf an option requires a value, then the value should be separated
  51. Xfrom the option either by whitespace  or by a "=".
  52. X
  53. XOther features:
  54. Xo    GetLongOpt can be used to parse options given through environments.
  55. Xo    GetLongOpt provides a usage function to print usage.
  56. Xo    Flags & options with optional or mandatory values are supported.
  57. Xo    The option marker ('-' in Unix) can be customized.
  58. Xo    Parsing of command line returns optind (see getopt(3)).
  59. Xo    Descriptive error messages.
  60. X
  61. XLet's take a walk through the usage. 
  62. X*/
  63. X
  64. X
  65. X#include "GetLongOpt.h"
  66. X#include <iostream.h>
  67. X#include <stdlib.h>
  68. X
  69. Xint debug_index = 0;
  70. X
  71. Xint
  72. Xmain(int argc, char **argv)
  73. X{
  74. X   GetLongOpt option;
  75. X// Constructor for GetLongOpt takes an optional argument: the option
  76. X// marker. If unspecified, this defaults to '-', the standard (?)
  77. X// Unix option marker. For example, a DOS addict may want to have
  78. X// "GetLongOpt option('/');" instead!!
  79. X
  80. X   char *scid = "a.out version 1.0 dated 21.01.1993";
  81. X
  82. X   option.usage("[options and args]");
  83. X
  84. X// GetLongOpt::usage is overloaded. If passed a string "s", it sets the
  85. X// internal usage string to "s". Otherwise it simply prints the
  86. X// command usage. More on it in a while.
  87. X
  88. X   option.enroll("help", GetLongOpt::NoValue,
  89. X      "print this option summary", 0);
  90. X   option.enroll("version", GetLongOpt::NoValue,
  91. X      "print the version", 0);
  92. X   option.enroll("output", GetLongOpt::MandatoryValue,
  93. X      "print output in file $val", "a.out.output");
  94. X   option.enroll("verify", GetLongOpt::NoValue,
  95. X      "verify if ambiguities are resolved as they should be", "");
  96. X#ifdef DEBUG
  97. X   option.enroll("debug", GetLongOpt::MandatoryValue,
  98. X      "set debug level to $val", "0");
  99. X#endif DEBUG
  100. X
  101. X// GetLongOpt::enroll adds option specifications to its internal
  102. X// database. The first argument is the option sting. The second
  103. X// is an enum saying if the option is a flag (GetLongOpt::NoValue),
  104. X// if it requires a mandatory value (GetLongOpt::MandatoryValue) or
  105. X// if it takes an optional value (GetLongOpt::OptionalValue).
  106. X// The third argument is a string giving a brief description of
  107. X// the option. This description will be used by GetLongOpt::usage.
  108. X// GetLongOpt, for usage-printing, uses $val to represent values
  109. X// needed by the options. <$val> is a mandatory value and [$val]
  110. X// is an optional value. The final argument to GetLongOpt::enroll
  111. X// is the default string to be returned if the option is not
  112. X// specified. For flags (options with NoValue), use "" (empty
  113. X// string, or in fact any arbitrary string) for specifying TRUE
  114. X// and 0 (null pointer) to specify FALSE.
  115. X
  116. X// Usage is printed with GetLongOpt::usage. The options and their 
  117. X// descriptions (as specified during enroll) are printed in the
  118. X// order they are enrolled.
  119. X
  120. X   if ( option.parse(getenv("A_OUT"), "A_OUT") < 1 )
  121. X      return -1;
  122. X
  123. X// GetLongOpt::parse is overloaded. It can either parse a string of
  124. X// options (typically given from the environment), or it can parse
  125. X// the command line args (argc, argv). In either case a return
  126. X// value < 1 represents a parse error. Appropriate error messages
  127. X// are printed when errors are seen. GetLongOpt::parse, in its first
  128. X// form, takes two strings: the first one is the string to be
  129. X// parsed and the second one is a string to be prefixed to the
  130. X// parse errors. In ts second form, GetLongOpt::parse returns the
  131. X// the optind (see getopt(3)) if parsing is successful.
  132. X
  133. X   int optind = option.parse(argc, argv);
  134. X   if ( optind < 1 )
  135. X       return -1;
  136. X
  137. X   const char *outfile = option.retrieve("output");
  138. X
  139. X#ifdef DEBUG
  140. X   debug_index = atoi(option.retrieve("debug"));
  141. X#endif DEBUG
  142. X
  143. X   if ( option.retrieve("help") ) {
  144. X      option.usage();
  145. X      return 0;
  146. X   }
  147. X   if ( option.retrieve("version") ) {
  148. X      cout << scid << "\n";
  149. X      return 0;
  150. X   }
  151. X   if ( option.retrieve("verify") ) {
  152. X      cout << "verify turned on by default" << "\n";
  153. X   }
  154. X   else {
  155. X      cout << "verify turned off" << "\n";
  156. X   }
  157. X
  158. X// The values of the options that are enrolled in the database
  159. X// can be retrieved using GetLongOpt::retrieve. This returns a string
  160. X// and this string should be converted to whatever type you want.
  161. X// See atoi, atof, atol etc. I suppose you would do a "parse" before
  162. X// retrieving. Otherwise all you would get are the default values
  163. X// you gave while enrolling!
  164. X// Ambiguities while retrieving (may happen when options are
  165. X// abbreviated) are resolved by taking the matching option that 
  166. X// was enrolled last. For example, -v will expand to -verify.
  167. X
  168. X   
  169. X   for ( ; optind < argc; ++optind ) {
  170. X   } /* process all the arguments here */
  171. X
  172. X   option.retrieve("foo");
  173. X
  174. X// If you try to retrieve something you didn't enroll, you will
  175. X// get a warning message. If you had made a typo somewhere while
  176. X// enrolling or retrieving, now is the time to correct it.
  177. X
  178. X   return 0;
  179. X}
  180. X
  181. X/*
  182. X
  183. XI tested GetLongOpt on gcc 2.3.3 and cfront 2.1 on Sun4s. It worked.
  184. X(Therefore, it works on all C++ compilers and all machines! :-))
  185. X
  186. XS Manoharan                                 Email    : mano@acri.fr
  187. XAdvanced Computer Research Institute        Fax      : +33 72 35 84 10
  188. X1 Boulevard Marius Vivier-Merle             Voice    : +33 72 35 80 44
  189. X69443 Lyon Cedex 03 France            
  190. X
  191. X*/
  192. X
  193. END_OF_FILE
  194.   if test 5675 -ne `wc -c <'README.cc'`; then
  195.     echo shar: \"'README.cc'\" unpacked with wrong size!
  196.   fi
  197.   # end of 'README.cc'
  198. fi
  199. if test -f 'GetLongOpt.3' -a "${1}" != "-c" ; then 
  200.   echo shar: Will not clobber existing file \"'GetLongOpt.3'\"
  201. else
  202.   echo shar: Extracting \"'GetLongOpt.3'\" \(4159 characters\)
  203.   sed "s/^X//" >'GetLongOpt.3' <<'END_OF_FILE'
  204. X.\" @(#)GetLongOpt.3 2.0 12/01/1993
  205. X.TH GETLONGOPT 3 "12 January 1993" "" "C++ LIBRARY CLASSES"
  206. X.UC 4
  207. X.SH NAME
  208. XGetLongOpt - C++ class for parsing command line and strings for options
  209. X.SH SYNOPSIS
  210. X.nf
  211. X.ft B
  212. X.ss 18
  213. X#include <GetLongOpt.h>
  214. X
  215. XGetLongOpt::GetLongOpt(const char optmark = '-');
  216. Xint GetLongOpt::parse(int argc, char * const *argv);
  217. Xint GetLongOpt::parse(char * const str, char * const p);
  218. Xint GetLongOpt::enroll(const char * const opt, const OptType t,
  219. X   const char * const desc, const char * const val);
  220. Xconst char * GetLongOpt::retrieve(const char * const opt) const;
  221. Xvoid GetLongOpt::usage(ostream &outfile = cout) const;
  222. Xvoid GetLongOpt::usage(const char *str);
  223. X.ft
  224. X.fi
  225. X.ss
  226. X
  227. X.SH DESCRIPTION
  228. XGetLongOpt is a C++ class for getting options from the command line
  229. Xand from strings. GetLongOpt supports long options. These options
  230. Xmay be flags or require optional or mandatory values.
  231. XIf an option requires a value, then the value should be separated
  232. Xfrom the option either by whitespace or by a "=". Long options
  233. Xcan be abbreviated. GetLongOpt can also be used to parse options given 
  234. Xthrough environments.
  235. X
  236. XThe constructor for GetLongOpt takes an optional argument: the option
  237. Xmarker. If unspecified, this defaults to '-', the standard (?)
  238. XUnix option marker. For example, a DOS addict may want to 
  239. Xspecify '/' for the option marker!
  240. X
  241. X.I GetLongOpt::enroll
  242. Xadds option specifications to its internal
  243. Xdatabase. The first argument is the option sting. The second
  244. Xis an enum saying if the option is a flag (GetLongOpt::NoValue),
  245. Xif it requires a mandatory value (GetLongOpt::MandatoryValue) or
  246. Xif it takes an optional value (GetLongOpt::OptionalValue).
  247. XThe third argument is a string giving a brief description of
  248. Xthe option. This description will be used by 
  249. X.I GetLongOpt::usage.
  250. XGetLongOpt, for usage-printing, uses $val to represent values
  251. Xneeded by the options. <$val> is a mandatory value and [$val]
  252. Xis an optional value. The final argument to 
  253. X.I GetLongOpt::enroll
  254. Xis the default string to be returned if the option is not
  255. Xspecified. For flags (options with NoValue), use "" (empty
  256. Xstring, or in fact any arbitrary string) for specifying TRUE
  257. Xand 0 (null pointer) to specify FALSE.
  258. X
  259. X.I GetLongOpt::usage
  260. Xis overloaded. If passed a string 
  261. X.I s,
  262. Xit sets the
  263. Xinternal usage string to 
  264. X.I s.
  265. XOtherwise it simply prints the
  266. Xcommand usage. The options and their
  267. Xdescriptions (as specified during enroll) are printed in the
  268. Xorder they are enrolled.
  269. X
  270. X.I GetLongOpt::parse
  271. Xis also overloaded. It can either parse a string of
  272. Xoptions (typically given from the environment), or it can parse
  273. Xthe command line args (argc, argv). In either case a return
  274. Xvalue < 1 represents a parse error. Appropriate error messages
  275. Xare printed when errors are seen. GetLongOpt::parse, in its first
  276. Xform, takes two strings: the first one is the string to be
  277. Xparsed and the second one is a string to be prefixed to the
  278. Xparse errors. In its second form, 
  279. X.I GetLongOpt::parse
  280. Xtakes in argc and argv and returns the
  281. Xthe optind (see getopt(3)) if parsing is successful.
  282. XSuccessful parsing, in either form of
  283. X.I GetLongOpt::parse,
  284. Xupdates the values of the options within the internal database.
  285. X
  286. XThe values of the options that are enrolled in the database
  287. Xcan be retrieved using 
  288. X.I GetLongOpt::retrieve.
  289. XThis returns a string
  290. Xand this string should be converted to whatever type you want.
  291. XSee atoi(3), atof(3), atol(3) etc. I suppose you would do a 
  292. X.I GetLongOpt::parse
  293. Xbefore
  294. Xretrieving. Otherwise all you would get are the default values
  295. Xyou gave while enrolling!
  296. XAmbiguities while retrieving (may happen when options are
  297. Xabbreviated) are resolved by taking the matching option that
  298. Xwas enrolled last.
  299. X
  300. XIf you try to retrieve something you did not enroll, you will
  301. Xget a warning message. This means that you probably had made
  302. Xa typo somewhere while enrolling or retrieving.
  303. X
  304. X.SH BUGS
  305. XThey should be there well-hidden. If you spot one report it.
  306. X
  307. X.SH "SEE ALSO"
  308. Xgetopt(3),
  309. Xgetopts(1),
  310. Xatoi(3), atof(3), atol(3).
  311. X
  312. X.SH AUTHOR
  313. X.nf
  314. XS Manoharan
  315. XAdvanced Computer Research Institute
  316. X1 Boulevard Marius Vivier-Merle
  317. X69443 Lyon Cedex 03 France
  318. X
  319. Xmano@acri.fr
  320. X.fi
  321. X
  322. X.\" end of man page
  323. END_OF_FILE
  324.   if test 4159 -ne `wc -c <'GetLongOpt.3'`; then
  325.     echo shar: \"'GetLongOpt.3'\" unpacked with wrong size!
  326.   fi
  327.   # end of 'GetLongOpt.3'
  328. fi
  329. if test -f 'GetLongOpt.h' -a "${1}" != "-c" ; then 
  330.   echo shar: Will not clobber existing file \"'GetLongOpt.h'\"
  331. else
  332.   echo shar: Extracting \"'GetLongOpt.h'\" \(1478 characters\)
  333.   sed "s/^X//" >'GetLongOpt.h' <<'END_OF_FILE'
  334. X/* $Id: GetLongOpt.h,v 1.1 1993/01/23 14:35:44 mano Exp mano $ */
  335. X/* S Manoharan. Advanced Computer Research Institute. Lyon. France */
  336. X
  337. X#ifndef _GetLongOpt_h_
  338. X#define _GetLongOpt_h_
  339. X
  340. X#include <iostream.h>
  341. X#include <string.h>
  342. X
  343. Xclass GetLongOpt {
  344. Xpublic:
  345. X   enum OptType { 
  346. X      NoValue, OptionalValue, MandatoryValue
  347. X   };
  348. Xprivate:
  349. X   struct Cell {
  350. X      const char *option;    // option name
  351. X      OptType type;        // option type
  352. X      const char *description;    // a description of option
  353. X      const char *value;    // value of option (string)
  354. X      Cell *next;        // pointer to the next cell
  355. X
  356. X      Cell() { option = description = value = 0; next = 0; }
  357. X   };
  358. Xprivate:
  359. X  Cell *table;                // option table
  360. X  const char *ustring;            // usage message
  361. X  char *pname;                // program basename
  362. X  char optmarker;            // option marker
  363. X
  364. X  int enroll_done;            // finished enrolling
  365. X  Cell *last;                // last entry in option table 
  366. X
  367. Xprivate:
  368. X  char *basename(char * const p) const;
  369. X  int setcell(Cell *c, char *valtoken, char *nexttoken, char *p);
  370. Xpublic:
  371. X   GetLongOpt(const char optmark = '-');
  372. X   ~GetLongOpt();
  373. X
  374. X   int parse(int argc, char * const *argv);
  375. X   int parse(char * const str, char * const p);
  376. X
  377. X   int enroll(const char * const opt, const OptType t,
  378. X      const char * const desc, const char * const val);
  379. X   const char *retrieve(const char * const opt) const;
  380. X
  381. X   void usage(ostream &outfile = cout) const;
  382. X   void usage(const char *str)        { ustring = str; }
  383. X};
  384. X
  385. X#endif /* _GetLongOpt_h_ */
  386. END_OF_FILE
  387.   if test 1478 -ne `wc -c <'GetLongOpt.h'`; then
  388.     echo shar: \"'GetLongOpt.h'\" unpacked with wrong size!
  389.   fi
  390.   # end of 'GetLongOpt.h'
  391. fi
  392. if test -f 'GetLongOpt.cc' -a "${1}" != "-c" ; then 
  393.   echo shar: Will not clobber existing file \"'GetLongOpt.cc'\"
  394. else
  395.   echo shar: Extracting \"'GetLongOpt.cc'\" \(6598 characters\)
  396.   sed "s/^X//" >'GetLongOpt.cc' <<'END_OF_FILE'
  397. X/* $Id: GetLongOpt.cc,v 1.1 1993/01/23 14:35:44 mano Exp mano $ */
  398. X/* S Manoharan. Advanced Computer Research Institute. Lyon. France */
  399. X
  400. X#include "GetLongOpt.h"
  401. X
  402. XGetLongOpt::GetLongOpt(const char optmark)
  403. X{
  404. X   table = last = 0;
  405. X   ustring = "[valid options and arguments]";
  406. X   enroll_done = 0;
  407. X   optmarker = optmark;
  408. X}
  409. X
  410. XGetLongOpt::~GetLongOpt()
  411. X{
  412. X   Cell *t = table;
  413. X
  414. X   while ( t ) {
  415. X      Cell *tmp = t;
  416. X      t = t->next;
  417. X      delete tmp;
  418. X   }
  419. X}
  420. X
  421. Xchar *
  422. XGetLongOpt::basename(char * const pname) const
  423. X{
  424. X   char *s;
  425. X
  426. X   s = strrchr(pname, '/');
  427. X   if ( s == 0 ) s = pname;
  428. X   else ++s;
  429. X
  430. X   return s;
  431. X}
  432. X
  433. Xint
  434. XGetLongOpt::enroll(const char * const opt, const OptType t,
  435. Xconst char * const desc, const char * const val)
  436. X{
  437. X   if ( enroll_done ) return 0;
  438. X
  439. X   Cell *c = new Cell;
  440. X   c->option = opt;
  441. X   c->type = t;
  442. X   c->description = desc ? desc : "no description available";
  443. X   c->value = val;
  444. X   c->next = 0;
  445. X
  446. X   if ( last == 0 ) {
  447. X      table = last = c;
  448. X   }
  449. X   else {
  450. X      last->next = c;
  451. X      last = c;
  452. X   }
  453. X
  454. X   return 1;
  455. X}
  456. X
  457. Xconst char *
  458. XGetLongOpt::retrieve(const char * const opt) const
  459. X{
  460. X   Cell *t;
  461. X   for ( t = table; t != 0; t = t->next ) {
  462. X      if ( strcmp(opt, t->option) == 0 )
  463. X     return t->value;
  464. X   }
  465. X   cerr << "GetLongOpt::retrieve - unenrolled option ";
  466. X   cerr << optmarker << opt << "\n";
  467. X   return 0;
  468. X}
  469. X
  470. Xint
  471. XGetLongOpt::parse(int argc, char * const *argv)
  472. X{
  473. X   int optind = 1;
  474. X
  475. X   pname = basename(*argv);
  476. X   enroll_done = 1;
  477. X   if ( argc-- <= 1 ) return optind;
  478. X
  479. X   while ( argc >= 1 ) {
  480. X      char *token = *++argv; --argc;
  481. X
  482. X      if ( token[0] != optmarker || token[1] == optmarker )
  483. X     break;    /* end of options */
  484. X
  485. X      ++optind;
  486. X      char *tmptoken = ++token;
  487. X      while ( *tmptoken && *tmptoken != '=' )
  488. X     ++tmptoken;
  489. X      /* (tmptoken - token) is now equal to the command line option
  490. X     length. */
  491. X
  492. X      Cell *t;
  493. X      enum { NoMatch, ExactMatch, PartialMatch } matchStatus = NoMatch;
  494. X      Cell *pc = 0;    // pointer to the partially-matched cell
  495. X      for ( t = table; t != 0; t = t->next ) {
  496. X     if ( strncmp(t->option, token, (tmptoken - token)) == 0 ) {
  497. X        if ( strlen(t->option) == (tmptoken - token) ) {
  498. X           /* an exact match found */
  499. X           int stat = setcell(t, tmptoken, *(argv+1), pname);
  500. X           if ( stat == -1 ) return -1;
  501. X           else if ( stat == 1 ) {
  502. X          ++argv; --argc; ++optind;
  503. X           }
  504. X           matchStatus = ExactMatch;
  505. X           break;
  506. X        }
  507. X        else {
  508. X           /* partial match found */
  509. X           matchStatus = PartialMatch;
  510. X           pc = t;
  511. X        }
  512. X     } /* end if */
  513. X      } /* end for */
  514. X
  515. X      if ( matchStatus == PartialMatch ) {
  516. X     int stat = setcell(pc, tmptoken, *(argv+1), pname);
  517. X     if ( stat == -1 ) return -1;
  518. X     else if ( stat == 1 ) {
  519. X        ++argv; --argc; ++optind;
  520. X     }
  521. X      }
  522. X      else if ( matchStatus == NoMatch ) {
  523. X     cerr << pname << ": unrecognized option ";
  524. X     cerr << optmarker << strtok(token,"= ") << "\n";
  525. X     return -1;        /* no match */
  526. X      }
  527. X
  528. X   } /* end while */
  529. X
  530. X   return optind;
  531. X}
  532. X
  533. Xint
  534. XGetLongOpt::parse(char * const str, char * const p)
  535. X{
  536. X   enroll_done = 1;
  537. X   char *token = strtok(str, " \t");
  538. X   char *name = p ? p : "GetLongOpt";
  539. X
  540. X   while ( token ) {
  541. X      if ( token[0] != optmarker || token[1] == optmarker ) {
  542. X     cerr << name << ": nonoptions not allowed\n";
  543. X     return -1;    /* end of options */
  544. X      }
  545. X
  546. X      char *ladtoken = 0;    /* lookahead token */
  547. X      char *tmptoken = ++token;
  548. X      while ( *tmptoken && *tmptoken != '=' )
  549. X     ++tmptoken;
  550. X      /* (tmptoken - token) is now equal to the command line option
  551. X     length. */
  552. X
  553. X      Cell *t;
  554. X      enum { NoMatch, ExactMatch, PartialMatch } matchStatus = NoMatch;
  555. X      Cell *pc =0;    // pointer to the partially-matched cell
  556. X      for ( t = table; t != 0; t = t->next ) {
  557. X     if ( strncmp(t->option, token, (tmptoken - token)) == 0 ) {
  558. X        if ( strlen(t->option) == (tmptoken - token) ) {
  559. X           /* an exact match found */
  560. X           ladtoken = strtok(0, " \t");
  561. X           int stat = setcell(t, tmptoken, ladtoken, name);
  562. X           if ( stat == -1 ) return -1;
  563. X           else if ( stat == 1 ) {
  564. X          ladtoken = 0;
  565. X           }
  566. X           matchStatus = ExactMatch;
  567. X           break;
  568. X        }
  569. X        else {
  570. X           /* partial match found */
  571. X           matchStatus = PartialMatch;
  572. X           pc = t;
  573. X        }
  574. X     } /* end if */
  575. X      } /* end for */
  576. X
  577. X      if ( matchStatus == PartialMatch ) {
  578. X     ladtoken = strtok(0, " \t");
  579. X     int stat = setcell(pc, tmptoken, ladtoken, name);
  580. X     if ( stat == -1 ) return -1;
  581. X     else if ( stat == 1 ) {
  582. X        ladtoken = 0;
  583. X     }
  584. X      }
  585. X      else if ( matchStatus == NoMatch ) {
  586. X     cerr << name << ": unrecognized option ";
  587. X     cerr << optmarker << strtok(token,"= ") << "\n";
  588. X     return -1;        /* no match */
  589. X      }
  590. X
  591. X      token = ladtoken ? ladtoken : strtok(0, " \t");
  592. X   } /* end while */
  593. X
  594. X   return 1;
  595. X}
  596. X
  597. X/* ----------------------------------------------------------------
  598. XGetLongOpt::setcell returns
  599. X   -1    if there was an error
  600. X    0    if the nexttoken was not consumed
  601. X    1    if the nexttoken was consumed
  602. X------------------------------------------------------------------- */
  603. X
  604. Xint
  605. XGetLongOpt::setcell(Cell *c, char *valtoken, char *nexttoken, char *name)
  606. X{
  607. X   if ( c == 0 ) return -1;
  608. X
  609. X   switch ( c->type ) {
  610. X   case GetLongOpt::NoValue :
  611. X      if ( *valtoken == '=' ) {
  612. X     cerr << name << ": unsolicited value for flag ";
  613. X     cerr << optmarker << c->option << "\n";
  614. X     return -1;    /* unsolicited value specification */
  615. X      }
  616. X      c->value = (c->value) ? 0 : (char *) ~0;
  617. X      return 0;
  618. X   case GetLongOpt::OptionalValue :
  619. X      if ( *valtoken == '=' ) {
  620. X     c->value = ++valtoken;
  621. X     return 0;
  622. X      }
  623. X      else {
  624. X     if ( nexttoken != 0 && nexttoken[0] != optmarker ) {
  625. X        c->value = nexttoken;
  626. X        return 1;
  627. X     }
  628. X     else return 0;
  629. X      }
  630. X      break;
  631. X   case GetLongOpt::MandatoryValue :
  632. X      if ( *valtoken == '=' ) {
  633. X     c->value = ++valtoken;
  634. X     return 0;
  635. X      }
  636. X      else {
  637. X     if ( nexttoken != 0 && nexttoken[0] != optmarker ) {
  638. X        c->value = nexttoken;
  639. X        return 1;
  640. X     }
  641. X     else {
  642. X        cerr << name << ": mandatory value for ";
  643. X        cerr << optmarker << c->option << " not specified\n";
  644. X        return -1;    /* mandatory value not specified */
  645. X     }
  646. X      }
  647. X      break;
  648. X   default :
  649. X      break;
  650. X   }
  651. X   return -1;
  652. X}
  653. X
  654. Xvoid
  655. XGetLongOpt::usage(ostream &outfile) const
  656. X{
  657. X   Cell *t;
  658. X
  659. X   outfile << "usage: " << pname << " " << ustring << "\n";
  660. X   for ( t = table; t != 0; t = t->next ) {
  661. X      outfile << "\t" << optmarker << t->option;
  662. X      if ( t->type == GetLongOpt::MandatoryValue )
  663. X     outfile << " <$val>";
  664. X      else if ( t->type == GetLongOpt::OptionalValue )
  665. X     outfile << " [$val]";
  666. X      outfile << " (" << t->description << ")\n";
  667. X   }
  668. X   outfile.flush();
  669. X}
  670. X
  671. END_OF_FILE
  672.   if test 6598 -ne `wc -c <'GetLongOpt.cc'`; then
  673.     echo shar: \"'GetLongOpt.cc'\" unpacked with wrong size!
  674.   fi
  675.   # end of 'GetLongOpt.cc'
  676. fi
  677. if test -f 'sample.runs' -a "${1}" != "-c" ; then 
  678.   echo shar: Will not clobber existing file \"'sample.runs'\"
  679. else
  680.   echo shar: Extracting \"'sample.runs'\" \(625 characters\)
  681.   sed "s/^X//" >'sample.runs' <<'END_OF_FILE'
  682. X# a.out
  683. Xverify turned on by default
  684. XGetLongOpt::retrieve - unenrolled option -foo
  685. X# a.out -h
  686. Xusage: a.out [options and args]
  687. X        -help (print this option summary)
  688. X        -version (print the version)
  689. X        -output <$val> (print output in file $val)
  690. X        -verify (verify if ambiguities are resolved as they should be)
  691. X# a.out -hopeless
  692. Xa.out: unrecognized option -hopeless
  693. X# a.out -vers
  694. Xa.out version 1.0 dated 21.01.1993
  695. X# a.out -v   
  696. Xverify turned off
  697. XGetLongOpt::retrieve - unenrolled option -foo
  698. X# a.out -o
  699. Xa.out: mandatory value for -output not specified
  700. X# a.out -v=1  
  701. Xa.out: unsolicited value for flag -verify
  702. END_OF_FILE
  703.   if test 625 -ne `wc -c <'sample.runs'`; then
  704.     echo shar: \"'sample.runs'\" unpacked with wrong size!
  705.   fi
  706.   # end of 'sample.runs'
  707. fi
  708. echo shar: End of archive.
  709. exit 0
  710.  
  711. -- 
  712. S Manoharan                      Bitnet   : sam%dcs.ed@ukacrl.bitnet
  713. Department of Computer Science   Uucp     : sam%dcs.ed@uknet.uucp
  714. University of Edinburgh          Fax      : +44 31 667 7209
  715. Edinburgh EH9 3JZ    UK          Voice    : +44 31 650 5115 (Office)
  716.  
  717. exit 0 # Just in case...
  718.