home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume17 / parseargs / part08 < prev    next >
Encoding:
Internet Message Format  |  1991-03-18  |  61.3 KB

  1. From: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i053:  parseargs - functions to parse command line arguments, Part08/12
  4. Message-ID: <1991Mar18.155647.2119@sparky.IMD.Sterling.COM>
  5. Date: 18 Mar 91 15:56:47 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 7c204e50 6df81a05 9d8110ce 317d0fad
  8.  
  9. Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com>
  10. Posting-number: Volume 17, Issue 53
  11. Archive-name: parseargs/part08
  12.  
  13. This is part 8 of parseargs
  14.  
  15. #!/bin/sh
  16. # this is Part.08 (part 8 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file parseargs/parseargs1.txt continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 8; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping parseargs/parseargs1.txt'
  34. else
  35. echo 'x - continuing file parseargs/parseargs1.txt'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'parseargs/parseargs1.txt' &&
  37. X     or    characters following a newline may be lost, in any
  38. X     variables that are    set by parseargs.
  39. X
  40. X     Parseargs(1) is subject to    the same caveats as parseargs(3).
  41. X     Refer to the CAVEATS section of the parseargs(3) manual
  42. X     page(s) for more information.
  43. X
  44. AUTHOR
  45. X     Brad Appleton  (brad@ssd.csd.harris.com)
  46. X     Harris Computer Systems, Fort Lauderdale, FL USA
  47. X
  48. X
  49. X
  50. X
  51. X
  52. X
  53. X
  54. X
  55. X
  56. X
  57. X
  58. X
  59. X
  60. Page 15
  61. X
  62. X
  63. X
  64. SHAR_EOF
  65. echo 'File parseargs/parseargs1.txt is complete' &&
  66. chmod 0664 parseargs/parseargs1.txt ||
  67. echo 'restore of parseargs/parseargs1.txt failed'
  68. Wc_c="`wc -c < 'parseargs/parseargs1.txt'`"
  69. test 33378 -eq "$Wc_c" ||
  70.     echo 'parseargs/parseargs1.txt: original size 33378, current size' "$Wc_c"
  71. rm -f _shar_wnt_.tmp
  72. fi
  73. # ============= parseargs/parseargs3.txt ==============
  74. if test -f 'parseargs/parseargs3.txt' -a X"$1" != X"-c"; then
  75.     echo 'x - skipping parseargs/parseargs3.txt (File already exists)'
  76.     rm -f _shar_wnt_.tmp
  77. else
  78. > _shar_wnt_.tmp
  79. echo 'x - extracting parseargs/parseargs3.txt (Text)'
  80. sed 's/^X//' << 'SHAR_EOF' > 'parseargs/parseargs3.txt' &&
  81. X
  82. X
  83. X
  84. PARSEARGS(3)                         PARSEARGS(3)
  85. X
  86. X
  87. X
  88. NAME
  89. X     parseargs,    usage -    parse command line argument vectors
  90. X
  91. SYNOPSIS
  92. X     #include <parseargs.h>
  93. X
  94. X     int  parseargs(  char *argv[],  ARGDESC *argd  )
  95. X     int  fparseargs(  FILE *fp,  ARGDESC *argd     )
  96. X     int  lparseargs(  ArgList *argls,    ARGDESC    *argd  )
  97. X     int  sparseargs(  char *str,  ARGDESC *argd  )
  98. X     int  vparseargs(  ARGDESC *argd,  ...  )
  99. X     void  usage(  const ARGDESC *argd    )
  100. X
  101. DESCRIPTION
  102. X     Given a vector of string-valued arguments such as that
  103. X     passed to main and    a vector describing the    possible argu-
  104. X     ments, parseargs matches actual arguments to possible argu-
  105. X     ments, converts values to the desired type, and diagnoses
  106. X     problems such as missing arguments, extra arguments, and
  107. X     argument values that are syntactically incorrect.
  108. X
  109. X     Given a readable input stream and an argdesc array, fpar-
  110. X     seargs will parse arguments in a file in much the same
  111. X     manner as parseargs.  A maximum-line length of 255    charac-
  112. X     ters is imposed.  NO ``escaping'' of any kind is performed.
  113. X     Comments of a limited form    are permitted: if the first non-
  114. X     whitespace    character on a line is a '#' (or '!' for VMS)
  115. X     then that entire line is considered a comment and is
  116. X     ignored.  If a value is provided for an argument that is NOT
  117. X     a list or a vector, then the value    MUST be    on the same line
  118. X     as    the argument (in other words, ``-v val'' is fine but
  119. X     ``-v\nval'' is a not).
  120. X
  121. X     Given an ArgList and an argdesc array, lparseargs will parse
  122. X     arguments in a file in much the same manner as parseargs.
  123. X
  124. X     Given a single string and an argdesc array, sparseargs will
  125. X     parse arguments from a string in much the same manner as
  126. X     parseargs.     Sparseargs will split the given string    up into    a
  127. X     vector of whitespace separated tokens and then attempt to
  128. X     parse the resultant vector    as if it were given as argv[] on
  129. X     the command-line.    NO special treatment is    given to charac-
  130. X     ters such as single-quotes, double-quotes,    or anything else.
  131. X     Sparseargs    will always assume that    any whitespace characters
  132. X     are intended as argument separators.
  133. X
  134. X
  135. X     Vparseargs    takes an argdesc array,    the number of arguments
  136. X     to    parse, and a (possibly NULL terminated)    list of
  137. X     argument-strings and parses them in much the same manner as
  138. X     parseargs.     Unlike    sparseargs, vparseargs assumes that all
  139. X     parameters    are already split up into tokens, hence    any
  140. X
  141. X
  142. X
  143. Page 1
  144. X
  145. X
  146. X
  147. X
  148. X
  149. X
  150. PARSEARGS(3)                         PARSEARGS(3)
  151. X
  152. X
  153. X
  154. X     whitespace    characters contained in    any of the string-
  155. X     parameters    are used as is (and will be considered a part of
  156. X     an    argument name or value).
  157. X
  158. X
  159. X     Given an argdesc array, usage will    print the usage    for the
  160. X     given command in the format specified by the user's
  161. X     USAGECNTL environment variable.
  162. X
  163. THE ARGUMENT STRUCTURE
  164. X     The basic type used by the    parseargs library is the argument
  165. X     descriptor    (or "argdesc" for short). An ARGDESC structure is
  166. X     used to describe a    command-line argument. Each command line
  167. X     argument contains various fields which need to be set and/or
  168. X     queried by    the programmer.     The individual    fields of an
  169. X     ARGDESC structure are desribed below:
  170. X
  171. X     char  ad_name;
  172. X      This is a single character which corresponds to the
  173. X      option-letter    (case-sensitive) from the command-line
  174. X      that matches the argument described by this structure.
  175. X      Positional-arguments are denoted by putting a    a space
  176. X      character in this field.
  177. X
  178. X     argMask_t    ad_flags;
  179. X      This field contains the various bitflags that    describe
  180. X      the semantics    of this    argument. See the ARGUMENT FLAGS
  181. X      section for more information on the possible combina-
  182. X      tions    of bitmasks for    this field.
  183. X
  184. X     argTypePtr_t  ad_type;
  185. X      This field is    a pointer to a type conversion function
  186. X      (such    as the ones provided in    argtype(3). The    type
  187. X      conversion function is responsible for verifying the
  188. X      validity of the argument, allocating any necessary
  189. X      storage for its internal representation, and converting
  190. X      the command-line argument into its required internal
  191. X      form.    The type conversion function used may be one of
  192. X      the pre-defined argtype(3) functions.    The function is
  193. X      given    three parameters: The first is a pointer to the
  194. X      ARGDESC struct in question, the second is the    string-
  195. X      value    (if any) supplied on the command-line, and the
  196. X      third    is a boolean value that    is TRUE    only if    the
  197. X      second parameter points to temporary storage (and hence
  198. X      may need to be copied).  In the case of parseargs(1)
  199. X      this field must correspond to    the name of one    of the
  200. X      argument type    functions described in argtype(3).
  201. X
  202. X     ARBPTR  ad_valp;
  203. X      This field is    a generic pointer to the storage used to
  204. X      represent the    internal value of the command-line argu-
  205. X      ment.    It may be a pointer to a number, a boolean value,
  206. X
  207. X
  208. X
  209. Page 2
  210. X
  211. X
  212. X
  213. X
  214. X
  215. X
  216. PARSEARGS(3)                         PARSEARGS(3)
  217. X
  218. X
  219. X
  220. X      a string, a list, or anything    else for which there
  221. X      exists a corresponding arg-type function to use in the
  222. X      ad_type field. In the    case of    of parseargs(1)    this
  223. X      field    must be    the name of the    corresponding shell vari-
  224. X      able which eventually    hold the value of the argument
  225. X      given    on the command-line.
  226. X
  227. X     const char     *ad_prompt;
  228. X      This field contains the long-name of the argument and
  229. X      an optional description (the description must    be
  230. X      separated from the long-name by at least one whitespace
  231. X      characters and may optionally    be enclosed in a set of
  232. X      balanced delimiters (such as parentheses, curly-braces,
  233. X      square-brackets, or angle-brackets. If the long-name
  234. X      contains any uppercase characters, then the substring
  235. X      of long-name consisting of all uppercase characters is
  236. X      used as the argument name and    the entire long-name is
  237. X      used as the name of the argument-value (if a value my
  238. X      be supplied).    The long-name may be matched by    supplying
  239. X      a unique prefix of either the    argument name or the
  240. X      argument-value name.
  241. X
  242. DEFINING ARGDESC ARRAYS
  243. X     When defining an argdesc array, the first item in the list
  244. X     should be the item    STARTOFARGS. Normal arguments (defined by
  245. X     the programmer) may then be specified as documented in this
  246. X     manual.  The list of arguments is terminated using
  247. X     ENDOFARGS.
  248. X
  249. X     For example, consider the description:
  250. X       int  RepCount =       2;
  251. X       BOOL Verbose = FALSE;
  252. X       char *InFile;
  253. X       char *OutFile =       CHARNULL;
  254. X       BOOL XRated =  FALSE;
  255. X       struct namelist *Files =    NULL;
  256. X
  257. X       ARGDESC Args[] =
  258. X       {
  259. X     STARTOFARGS,
  260. X     'c', ARGOPT,     argInt,  __ &RepCount,    "REPcount {# of    repetitions}",
  261. X     'v', ARGOPT,     argBool, __ &Verbose,    "Verbose {set verbose mode}",
  262. X     ' ', ARGREQ,     argStr,  __ &InFile,    "INPUTfile {input file}",
  263. X     ' ', ARGOPT,     argStr,  __ &OutFile,    "OUTPUTfile {output file}",
  264. X     'X', ARGHIDDEN, argBool, __ &XRated,    "XratedMODE {naughty stuff!}",
  265. X     ' ', ARGOPT|ARGLIST, argStr, __ &Files, "File {files to be read}",
  266. X     ENDOFARGS
  267. X       };
  268. X
  269. X     This describes a program accepting    up to three flag argu-
  270. X     ments and one or two positional arguments,    plus a list of
  271. X     additional    file arguments.     Only the first    positional
  272. X
  273. X
  274. X
  275. Page 3
  276. X
  277. X
  278. X
  279. X
  280. X
  281. X
  282. PARSEARGS(3)                         PARSEARGS(3)
  283. X
  284. X
  285. X
  286. X     argument is required.  The    possible flags (in UNIX) are:
  287. X
  288. X     -c    count  An integer repetition count.  This defaults to
  289. X           two.
  290. X
  291. X     -v           A Boolean ``verbose'' flag.  It defaults    to FALSE.
  292. X
  293. X     -X           A Boolean ``X Rated'' flag.  This is not    printed
  294. X           in the usage message.
  295. X
  296. X     The two positional    arguments are both strings, as is the
  297. X     final list.  In AmigaDOS, the options would be REP    count, V,
  298. X     and XMODE.     In VAX/VMS, the qualifiers would be /REP=count,
  299. X     /V, and /XMODE.
  300. X
  301. ARGUMENT FLAGS
  302. X     These are the possible bitmasks that may be turned    ON or OFF
  303. X     in    the ad_flags field of an ARGDESC structure.
  304. X
  305. X     ARGOPT
  306. X      This flag is actually    a dummy    flag (i.e. it is the
  307. X      default). This flag specifies    that the command-line
  308. X      argument is optional (need not appear    on the command-
  309. X      line). It is only needed if no other flags are used to
  310. X      define the given argument.  If other flags are given
  311. X      and ARGREQ is    NOT one    of them, then ARGOPT is    always
  312. X      assumed.
  313. X
  314. X     ARGREQ
  315. X      The associated command argument is required on the
  316. X      command-line.
  317. X
  318. X     ARGPOS
  319. X      The associated command argument is positonal.    The
  320. X      difference between using this    flag to    indicate a posi-
  321. X      tional argument and between using a blank in the
  322. X      ad_name field    to indicate a positional arguments is the
  323. X      following: If    this flag is set but the ad_name of the
  324. X      argument is non-blank, then this argument may    be
  325. X      matched either positionally or by keyword. If    the
  326. X      ad_name field    is blank, then this argument may only be
  327. X      matched positionally.
  328. X
  329. X     ARGNOVAL
  330. X      The associated command argument takes    no value (as in
  331. X      "-x value"); Its mere    presence (or lack thereof) on the
  332. X      command-line is sufficient to    determine the necessary
  333. X      action(s) to take (as    in "-x").  Boolean argument types
  334. X      and Pseudo-argument types automatically default to ARG-
  335. X      NOVAL.
  336. X
  337. X     ARGVALOPT
  338. X
  339. X
  340. X
  341. Page 4
  342. X
  343. X
  344. X
  345. X
  346. X
  347. X
  348. PARSEARGS(3)                         PARSEARGS(3)
  349. X
  350. X
  351. X
  352. X      This flag is used to indicate    that the command-line
  353. X      argument takes a value (as in    "-s string" or
  354. X      "/str=string") but that the value to this command-line
  355. X      argument is NOT required (hence simply "-s" or "/str"
  356. X      is also permissable).
  357. X
  358. X     ARGVALREQ
  359. X      Another "dummy" flag.    Unless ARGNOVAL    or ARGVALOPT is
  360. X      specified, ARGVALREQ is always assumed. This flag indi-
  361. X      cates    that the value to a command-line argument is
  362. X      required (hence "-s string" is okay but just "-s" is
  363. X      not).
  364. X
  365. X     ARGHIDDEN
  366. X      Don't    display    this argument in usage messages    but still
  367. X      attempt to match it against strings given on the
  368. X      command-line.
  369. X
  370. X     ARGLIST
  371. X      A variable number of values are used for this    argument
  372. X      (and hence may use more than one or two argv elements
  373. X      from the command-line    as in "-l val1 val2 ..."). The
  374. X      list of values must be stored    in an ArgList structure
  375. X      (NOT a vector    structure), an the corresponding
  376. X      argument-type    function should    be one of the listXxxx
  377. X      functions.
  378. X
  379. X     ARGVEC
  380. X      A variable number of values are used for this    argument
  381. X      (and hence may use more than one or two argv elements
  382. X      from the command-line    as in in "-v val1 val2 ..."). The
  383. X      list of values must be stored    in a vector structure
  384. X      (NOT an ArgList structure).
  385. X
  386. X     The following bitmasks may    also be    present, but, unlike the
  387. X     above masks which must be specified by the    programmer at
  388. X     initialization time, the following    masks must only    be read
  389. X     (never set) by the    programmer. They may be    queried    by using
  390. X     the pc_ARGFLAGS function code and the mode    pc_READ    with par-
  391. X     secntl(3).
  392. X
  393. X     ARGGIVEN
  394. X      The argument WAS given on the    command-line.
  395. X
  396. X     ARGVALGIVEN
  397. X      The value for    this argument was given    on the command-
  398. X      line.
  399. X
  400. X     ARGVALSEP
  401. X      The value to this argument was supplied in a separate
  402. X      argv element from the    argument itself    (as in "-x value"
  403. X      as opposed to    "-xvalue").
  404. X
  405. X
  406. X
  407. Page 5
  408. X
  409. X
  410. X
  411. X
  412. X
  413. X
  414. PARSEARGS(3)                         PARSEARGS(3)
  415. X
  416. X
  417. X
  418. X     ARGKEYWORD
  419. X      This argument    was matched as a keyword (long-form) on
  420. X      the command-line and not as a    single character.
  421. X
  422. X     ARGDESCRIBED
  423. X      This argument    was given a description    by the programmer
  424. X      at initialization.
  425. X
  426. X     ARGCOPYF
  427. X      This flag is only used for lists and vectors (mul-
  428. X      tivalued arguments) and is used on a per-item    basis. If
  429. X      it is    set, it    means that the corresponding value in the
  430. X      vector/list required space to    be allocated (such as the
  431. X      duplication of a temporary string).
  432. X
  433. ARGDESC    MACROS
  434. X     The following macros are used to extract and query    the
  435. X     attributes    of a pointer to    a preprocessed arg-descriptor:
  436. X
  437. X     arg_cname(ad)
  438. X      Return the single-character name of an argument.
  439. X
  440. X     arg_flags(ad)
  441. X      Return the argument flags of an argument.  The flags
  442. X      themselves may be manipulated    using the BTEST, BSET,
  443. X      and BCLEAR macros defined in <useful.h>.
  444. X
  445. X     arg_type(ad)
  446. X      Return the pointer to    the value-translation-routine of
  447. X      an argument.
  448. X
  449. X     arg_valp(ad)
  450. X      Return the pointer to    the value of this argument.
  451. X
  452. X     arg_sname(ad)
  453. X      Return the string name of an argument.
  454. X
  455. X     arg_sdesc(ad)
  456. X      Return the description of an argument. If a description
  457. X      was supplied,    the ARGDESCRIBED flag will be set and the
  458. X      description will immediately follow the terminating NUL
  459. X      byte of the string name.
  460. X
  461. X     ARG_isDESCRIBED(ad)
  462. X      Evaluates to TRUE only if an argument    description was
  463. X      provided.
  464. X
  465. X     arg_description(ad)
  466. X      Return the description string    (or an empty string if no
  467. X      description was given) for this argument.
  468. X
  469. X     ARG_isPOSITIONAL(ad)
  470. X
  471. X
  472. X
  473. Page 6
  474. X
  475. X
  476. X
  477. X
  478. X
  479. X
  480. PARSEARGS(3)                         PARSEARGS(3)
  481. X
  482. X
  483. X
  484. X      Evaluates to TRUE if this argument may be positionally
  485. X      matched.
  486. X
  487. X     ARG_isPOSONLY(ad)
  488. X      Evaluates to TRUE if this argument may only be posi-
  489. X      tionally matched.
  490. X
  491. X     ARG_isLIST(ad)
  492. X      Evaluates to TRUE if this argument is    an arglist.
  493. X
  494. X     ARG_isVEC(ad)
  495. X      Evaluates to TRUE if this argument is    a vector.
  496. X
  497. X     ARG_isMULTIVAL(ad)
  498. X      Evaluates to TRUE if this argument is    an arglist or a
  499. X      vector.
  500. X
  501. X     ARG_isVALTAKEN(ad)
  502. X      Evaluates to TRUE if this argument does NOT take a
  503. X      value.
  504. X
  505. X     ARG_isGIVEN(ad)
  506. X      Evaluates to TRUE if this argument was given on the
  507. X      command-line.
  508. X
  509. X     ARG_isVALGIVEN(ad)
  510. X      Evaluates to TRUE if the argument value was given on
  511. X      the command-line.
  512. X
  513. X     ARG_isREQUIRED(ad)
  514. X      Evaluates to TRUE if this argument is    required.
  515. X
  516. X     ARG_isVALOPTIONAL(ad)
  517. X      Evaluates to TRUE if the argument value is optional.
  518. X
  519. X     ARG_isVALSEPARATE(ad)
  520. X      Evaluates to TRUE if the argument value is optional.
  521. X
  522. X     ARG_isHIDDEN(ad)
  523. X      Evaluates to TRUE if this argument is    omitted    from
  524. X      usage    messages.
  525. X
  526. CMD MACROS
  527. X     Parseargs.h defines a set of macros to allow a more "self
  528. X     documenting" approach to declaring    argument-descriptor
  529. X     arrays. The "old-style" is    still accepted (but if used it is
  530. X     recommended that the STARTOFARGS macro is used in conjunc-
  531. X     tion with ENDOFARGS).  An example use of these macros
  532. X     (which, with one exception, all begin with    ``CMD'') follows:
  533. X      #include <parseargs.h>
  534. X
  535. X      static BOOL bflag = FALSE;
  536. X
  537. X
  538. X
  539. Page 7
  540. X
  541. X
  542. X
  543. X
  544. X
  545. X
  546. PARSEARGS(3)                         PARSEARGS(3)
  547. X
  548. X
  549. X
  550. X      static char *arg1 = CHARNULL;
  551. X      static char *arg2 = CHARNULL;
  552. X
  553. X      static
  554. X         CMD_OBJECT
  555. X        MyCmd
  556. X
  557. X         CMD_NAME
  558. X        "mycmd -- one line statement of    purpose"
  559. X
  560. X         CMD_DESCRIPTION
  561. X        "Mycmd will try    really really hard to run without errors \
  562. X      and do whatever the heck it is supposed to do. If (God forbid) \
  563. X      something should actually go wrong it    will say so."
  564. X
  565. X         CMD_ARGUMENTS
  566. X        'H', ARGOPT, argUsage, __ NULL,
  567. X        "Help -- display usage and quit",
  568. X
  569. X        'b', ARGOPT, argSBool, __ &bflag,
  570. X        "bflag -- turn on `b'-mode (whatever that is)",
  571. X
  572. X        ' ', ARGREQ, argStr, __    &arg1,
  573. X        "arg1 -- first argument    to this    spiffy program",
  574. X
  575. X        ' ', ARGOPT, argStr, __    &arg2,
  576. X        "arg2 -- optional second argument to this spiffy program",
  577. X
  578. X        END_ARGUMENTS
  579. X         CMD_END
  580. X
  581. X      main(    int argc, char *argv[] )
  582. X      {
  583. X         (void) parseargs( argv, MyCmd );
  584. X         (void) dostuff();
  585. X         exit( 0 );
  586. X      }
  587. X
  588. DEFAULT    ARGUMENT DESCRIPTOR
  589. X     Each argdesc-array    has an initial default argument    list
  590. X     (which may    be reset using the pc_DEFARGS function code with
  591. X     parsecntl). This initial default argument-list contains `?'
  592. X     and `H' which may be used as single character keywords to
  593. X     display command-usage for all command-line    styles.     Simi-
  594. X     larly, ``?'', ``H'', and ``Help'' may be used as long-
  595. X     keywords to display command-usage for all command-line
  596. X     styles.  In Addition, for VMS style commands, the qualifiers
  597. X     /INPUT=file, /OUTPUT=file,    and /ERROR=file, may be    used to
  598. X     redirect stdin, stdout, and stderr    (respectively) to a file.
  599. X     For AmigaDOS style    commands, the keyword ``ENDKWDS'' may be
  600. X     used to disable parsing for any more keywords on the
  601. X     command-line.
  602. X
  603. X
  604. X
  605. Page 8
  606. X
  607. X
  608. X
  609. X
  610. X
  611. X
  612. PARSEARGS(3)                         PARSEARGS(3)
  613. X
  614. X
  615. X
  616. SUPPLYING DEFAULT ARGUMENTS
  617. X     Programs that use parseargs may be    given default arguments
  618. X     under UNIX    and PCs    through    the use    of environment variables
  619. X     (symbols are used for VMS systems). If a  C-program or
  620. X     shell-script uses parseargs to implement a    command    named
  621. X     ``cmd'' then the environment variable ``CMD_ARGS''    will be
  622. X     parsed for    any "default" arguments    before the command-line
  623. X     is    parsed.     The command-line will over-ride any options that
  624. X     are specified in this environment variable    (except    that
  625. X     ARGLISTs and ARGVECs set in ``CMD_ARGS'' will be appended
  626. X     from the command-line
  627. X
  628. X     It    is important to    note that the contents of the
  629. X     ``CMD_ARGS'' environment variable are NOT expanded    by the
  630. X     shell and hence any special characters (such as quotes or
  631. X     back-slashes) will    NOT be escaped or removed by parseargs.
  632. X     Furthermore, it will not be possible to try and use a tab,
  633. X     space, or newline character in the    environment variable as
  634. X     anything other than an argument separator.
  635. X
  636. X     Lastly, parts of an option    specification in ``CMD_ARGS'' may
  637. X     NOT be continued on the command-line. As an example, if -f
  638. X     requires an argument and CMD_ARGS="-f", then the command-
  639. X     line "cmd    bah" will NOT assign "bah" as the argument to -f
  640. X     but will instead complain about a missing argument    for -f.
  641. X     Similarly,    if -l takes a list of arguments    and CMD_ARGS="-l
  642. X     item1 item2", then    the command-line "cmd  bah", will NOT
  643. X     assign "bah" to the end of    the list containing "item1" and
  644. X     "item2" but will instead treat "bah" as the first positional
  645. X     parameter on the command-line.
  646. X
  647. PARSING    BEHAVIOR
  648. X     The programmer may    control    parsing    behavior through the use
  649. X     of    parsecntl(3).  The user    may set    his (or    her) own desired
  650. X     parsing behavior through the use of the ``PARSECNTL''
  651. X     environment variable.  By indicating any number of    flags
  652. X     (possibly negated)    the user will directly modify the
  653. X     behavior of the parseargs library.    Flags may be combined by
  654. X     placing a `+' or `|' character in between flags. A    switch is
  655. X     negated by    immediately preceding it with a    `!' or `-' char-
  656. X     acter.  The possible ``flags'' are    given by the following
  657. X     table. Flags are case-insensitive.
  658. X
  659. X     Prompt
  660. X      Prompt the user for any missing arguments that are
  661. X      required on the command-line.    No special escaping or
  662. X      quoting is performed on the user input. Required argu-
  663. X      ments    that expect a list of values will be repeatedly
  664. X      prompted for (one item per line) until a blank line
  665. X      (followed by a carriage return) is entered.
  666. X
  667. X     Ignore
  668. X
  669. X
  670. X
  671. Page 9
  672. X
  673. X
  674. X
  675. X
  676. X
  677. X
  678. PARSEARGS(3)                         PARSEARGS(3)
  679. X
  680. X
  681. X
  682. X      Ignore any unrecognized or improperly    specified
  683. X      command-line arguments and continue execution    of the
  684. X      program. Normally, if    an argument is unmatched (or is
  685. X      improperly specified), a usage message is printed pro-
  686. X      gram execution is terminated.
  687. X
  688. X     OptsOnly
  689. X      Under    UNIX, setting this flag    will disable the parsing
  690. X      of long-option syntax. This will cause all arguments
  691. X      starting with    '+' to always be treated as a positional
  692. X      parameter (instead of    a long-option).
  693. X
  694. X     KwdsOnly
  695. X      Under    UNIX, setting this flag    disables the parsing of
  696. X      single-character options.  This will cause all argu-
  697. X      ments    starting with '-' to always be treated as a posi-
  698. X      tional parameter (instead of an option).
  699. X
  700. X     LoptsOnly
  701. X      Same as KwdsOnly.
  702. X
  703. X     Flags1st
  704. X      Setting this flag causes the parseargs library to force
  705. X      any and all non-positional arguments to be specified
  706. X      before any positional    ones.  As an example, under UNIX,
  707. X      if this flag is SET then parseargs will consider the
  708. X      command line "cmd -x arg" to consist of one option and
  709. X      one positional argument; however the command line "cmd
  710. X      arg -x" would    be considered to consist of two    posi-
  711. X      tional arguments (the    -x option will be unmatched).
  712. X
  713. X      If this flag is UNSET, then both of the previous exam-
  714. X      ples are considered to consist of one    option and one
  715. X      positional argument.
  716. X
  717. X     CaseIgnore
  718. X      Setting this flag cause character-case to be ignored
  719. X      when attempting to match single-character argument
  720. X      names    (i.e. causes "-i" and "-I" will    be considered
  721. X      equivalent).
  722. X
  723. X     If    the environment    variable ``PARSECNTL'' is empty    or unde-
  724. X     fined, then parsing behavior set by the programmer    is used.
  725. X     If    the programmer has not explicitly used parsecntl(3) to
  726. X     modify the    parsing    behavior will be ``!Prompt + !Ignore''
  727. X     for Unix MS-DOS, OS/2, and    AmigaDOS systems, and ``Prompt''
  728. X     for VMS systems.
  729. X
  730. USAGE MESSAGES
  731. X     Through the use of    an environment variable    (or a VMS sym-
  732. X     bol), the user may    control    the syntax and the verbosity of
  733. X     the command-usage messages    that are printed by parseargs.
  734. X
  735. X
  736. X
  737. Page 10
  738. X
  739. X
  740. X
  741. X
  742. X
  743. X
  744. PARSEARGS(3)                         PARSEARGS(3)
  745. X
  746. X
  747. X
  748. X     The desired level of verbosity may    be set by defining the
  749. X     environment variable ``USAGECNTL" to be a combination of
  750. X     strings (case insensitive). The value of each string con-
  751. X     trols one of three    different ``modes'' of behavior    in the
  752. X     displaying    of usage messages:  The    first ``mode'' is ``ver-
  753. X     bose'' mode, which    controls whether or not    a detailed
  754. X     description of each argument should accompany the usual
  755. X     command-line sysnopsis. If    verbose    mode is    ``off'', then
  756. X     only a command-line synopsis is printed (this is also ref-
  757. X     ferred to as ``terse'' mode). The other two ``modes'' con-
  758. X     trol the displaying of option syntax and long-option syntax.
  759. X     A mode may    be explicitly disabled by preceding its
  760. X     corresponding string with the `!'    character. The ``modes''
  761. X     which correspond to the possible values of    the ``USAGECNTL''
  762. X     environment variable are given by the following table.
  763. X
  764. X     Quiet
  765. X      No usage message of any kind is displayed.
  766. X
  767. X     Silent
  768. X      Same as Quiet.
  769. X
  770. X     Paged
  771. X      The usage message is piped to    a pager. The pager used
  772. X      is named by the ``USAGE_PAGER'' environment variable.
  773. X      If this variable is unset or empty (or is not    the name
  774. X      of an    executable program) then the pager named by the
  775. X      ``PAGER'' environment    variable us used.  If this vari-
  776. X      able is unset    or empty (or is    not the    name of    an exe-
  777. X      cutable program) then    /usr/ucb/more is used.
  778. X
  779. X     Description
  780. X      The command description is printed.
  781. X
  782. X     Terse
  783. X      Terse    mode, just print command-line synopsis.
  784. X
  785. X     Verbose
  786. X      Verbose mode,    print descriptions for each argument
  787. X
  788. X     Options
  789. X      Option syntax    is displayed.
  790. X
  791. X     LongOpts
  792. X      Long-option syntax is    displayed.
  793. X
  794. X     KeyWords
  795. X      Same as LongOpts.
  796. X
  797. X
  798. X     If    the environment    variable ``USAGECNTL'' is empty    or unde-
  799. X     fined, then the default usage level (which    is presently
  800. X
  801. X
  802. X
  803. Page 11
  804. X
  805. X
  806. X
  807. X
  808. X
  809. X
  810. PARSEARGS(3)                         PARSEARGS(3)
  811. X
  812. X
  813. X
  814. X     ``Verbose + Options'') will be used.
  815. X
  816. MULTI-VALUED ARGUMENTS
  817. X     Parseargs supports    two different types of multi-valued argu-
  818. X     ments: linked-lists and vectors. The linked-lists are called
  819. X     argument lists (or    arg-lists) and are specified by    supplying
  820. X     the ARGLIST flag along with an associated listXxxx
  821. X     argument-translation routine. The value associated    with an
  822. X     arg-list should be    a list structure of type ArgList. The
  823. X     include file <parseargs.h>    defines    four macros for    manipu-
  824. X     lating ArgList structures:     ARGLISTNULL, L_NEXT, L_STRING,
  825. X     and L_FLAGS.
  826. X
  827. X     ARGLISTNULL is simply the NULL argument-list pointer.
  828. X     L_NEXT and    L_STRING each take a pointer to    a non-NULL
  829. X     ArgList structure.    L_NEXT returns the address of the next
  830. X     item in the list and L_STRING returns the string-value of
  831. X     the current list-item.  L_FLAGS return the    arg-flags for a
  832. X     given item    in the list. With non-multivalued, only    the flags
  833. X     in    the argument descriptor    are needed; lists and vectors
  834. X     however need a set    of flags for each item they contain. Once
  835. X     an    arg-list has been created, it may be deallocated using
  836. X     the function listFree. ListFree takes two parameters, the
  837. X     first of which is the address of the first    item in    the arg-
  838. X     list, and the second of which is a    boolean    value that is
  839. X     TRUE only if each value pointed to    by each    item should also
  840. X     be    deallocated.
  841. X
  842. X     An    alternative to argument-lists is argument vectors (or
  843. X     arg-vectors).  Arg-vectors    use the    ARGVEC flag instead of
  844. X     the ARGLIST flag and do not require a special listXxxx func-
  845. X     tion for each vector-type.     Each of the argXxxx functions is
  846. X     responsible for handling vectors of its type (although some
  847. X     argXxx functions such as the boolean types    do not support
  848. X     vectors). An arg-vector is    a structure which contains a
  849. X     count, an array of    elements (i.e. an argc/argv pair), and an
  850. X     array of flags, one for each element of argv. There are two
  851. X     macros in defined in <parseargs.h>    which are used for arg-
  852. X     vectors. ARGVEC_T may be used to declare a    vector structure
  853. X     or    a vector type; ARGVEC_EMPTY may    be used    to initialize the
  854. X     structure.     It is strongly    recommended that ARGVEC_T be used
  855. X     to    declare    vector types in    a typedef statement (particularly
  856. X     if    one is using function prototypes) but for those    who
  857. X     insist, it    may be used to directly    declare    a  structure.
  858. X     String-vectors will always    have an    extra NULL-pointer at the
  859. X     end such that:
  860. X
  861. X      ( StrVec.array[ StrVec.count ] == (char *)NULL )
  862. X
  863. X     is    always true, and character-vectors will    always have an
  864. X     extra NUL-character at the    end such that:
  865. X
  866. X
  867. X
  868. X
  869. Page 12
  870. X
  871. X
  872. X
  873. X
  874. X
  875. X
  876. PARSEARGS(3)                         PARSEARGS(3)
  877. X
  878. X
  879. X
  880. X      ( CharVec.array[ CharVec.count ] == '\0' )
  881. X
  882. X     is    always true. Integer and floating point    vectors    contain
  883. X     no    extra "null" elements.
  884. X
  885. X     Once created, arg-vectors may be deallocated by calling the
  886. X     macro vecFree or the macro    vecDeepFree and    passing    it the
  887. X     arg-vector    structure. The differemce between these    two mac-
  888. X     ros is that the latter will also free each    item in    the vec-
  889. X     tor that required space to    be allocated (at the expense of
  890. X     traversing    the vector).  At this writing, the only    prede-
  891. X     fined argument-types that would benefit from vecDeepFree is
  892. X     argStr vectors.
  893. X
  894. X     An    example    use of arg-lists, and of arg-vectors follows:
  895. X
  896. X      #include <parseargs.h>
  897. X
  898. X      typedef ARGVEC_T(char    *) strvec_t;
  899. X
  900. X      static ArgList  *StringList =    ARGLISTNULL;
  901. X      static strvec_t  StringVec = ARGVEC_EMPTY(char *);
  902. X      static ARGVEC_T(int)    NumberVec = ARGVEC_EMPTY(int);
  903. X
  904. X      static
  905. X        CMD_OBJECT    Args
  906. X        CMD_NAME    "foo --    do whatever foo    does"
  907. X        CMD_DESCRIPTION  "put a brief paragraph here"
  908. X        CMD_ARGUMENTS
  909. X           'l', ARGLIST, listStr, __ &StrList, "LiSt {list of strings}",
  910. X           's', ARGVEC,  argStr,  __ &StrVec,  "STRing {vector of strings}",
  911. X           'i', ARGVEC,  argInt,  __ &NumVec,  "NUMber {vector of numbers}",
  912. X           END_ARGUMENTS
  913. X        CMD_END
  914. X
  915. X      main(    int argc, char *argv[] )
  916. X      {
  917. X         int i, *ls;
  918. X
  919. X         if    ( parseargs(argv, Args)    )  syserr( "parseargs failed" );
  920. X
  921. X         for ( ls =    StrList, i=1 ; ls ; ls = L_NEXT(ls), i++ )
  922. X        printf(    "List item %d=%s, flags=%x\n",
  923. X            i, L_STRING(ls), L_FLAGS(ls) );
  924. X
  925. X         for ( i = 0 ; i < StrVec.count ; i++ )
  926. X        printf(    "String[%d]=%s,    flags=%x\n",
  927. X            i, StrVec.array[i], StrVec.flags[i] );
  928. X
  929. X         for ( i = 0 ; i < NumVec.count ; i++ )
  930. X        printf(    "Number[%d]=%s,    flags=%x\n",
  931. X            i, NumVec.array[i], NumVec.flags[i] );
  932. X
  933. X
  934. X
  935. Page 13
  936. X
  937. X
  938. X
  939. X
  940. X
  941. X
  942. PARSEARGS(3)                         PARSEARGS(3)
  943. X
  944. X
  945. X
  946. X         listFree( StrList );
  947. X         StrList = ARGLISTNULL;
  948. X
  949. X         vecDeepFree( StrVec, char * );
  950. X         vecFree( NumVec, int );
  951. X
  952. X         exit( 0 );
  953. X      }
  954. X
  955. X
  956. ARGUMENT TYPE FUNCTIONS
  957. X     The argument types    recognized by parseargs    can be extended
  958. X     by    adding new type    functions.  Argument type functions are
  959. X     declared as:
  960. X
  961. X      BOOL    argXxx(     ARGDESC *ad,  char *vp,  BOOL copyf  )
  962. X
  963. X     The argd argument points to the descriptor    for the    argument
  964. X     being converted.  Its main    use is to find the location in
  965. X     which to store the    converted value, located in
  966. X     argd->ad_valp.  The string    value to be converted is passed
  967. X     in    argp (which will be NULL if the    ARGNOVAL flag was set for
  968. X     the corresponding entry in    the arg-descriptor table).  The
  969. X     copyf flag    is TRUE    if the argp string value must be copied
  970. X     when saved.  Most non-string types    are copied implicitly
  971. X     (for example, integer arguments are stored    in binary form,
  972. X     so    the original string value need not be saved), so this
  973. X     argument can usually be ignored.  Put simply, this    flag is
  974. X     TRUE when argp points to a    temporary buffer area.
  975. X
  976. X     If    the type function successfully converts    the value, and
  977. X     uses the entire value, it should return TRUE.  If the type
  978. X     function successfully converts the    value, and uses    only N
  979. X     characters    of the value, it should    return -N.  Otherwise, it
  980. X     should print a message using usrerr(3) and    return FALSE.
  981. X     This message should be of the form    "invalid xxxx option
  982. X     'yyyy' for    Zzzz", where xxxx is the type of the option, yyyy
  983. X     is    the string passed in vp, and zzzz is the name (taken from
  984. X     ad->ad_prompt).  The argXxxx function is responsible for
  985. X     detecting if the given argument descriptor    is an ARGVEC
  986. X     argument and for taking the appropriate action.
  987. X
  988. X     For example, a type function that took a filename and stored
  989. X     an    open file pointer might    be coded as:
  990. X
  991. X      #define REALLOC(ptr,size)  ((! ptr) ?    malloc(size) : realloc(ptr, size))
  992. X      typedef ARGVEC_T(FILE    *)  FILEvec_t;
  993. X
  994. X      BOOL    argReadFile(  ARGDESC *ad,  char *vp,  BOOL copyf  )
  995. X      {
  996. X           register    FILE *fp;
  997. X           fp = fopen(vp, "r");
  998. X
  999. X
  1000. X
  1001. Page 14
  1002. X
  1003. X
  1004. X
  1005. X
  1006. X
  1007. X
  1008. PARSEARGS(3)                         PARSEARGS(3)
  1009. X
  1010. X
  1011. X
  1012. X           if ( ! fp ) {
  1013. X            usrerr("cannot open    '%s' for reading", vp);
  1014. X            return (FALSE);
  1015. X           }
  1016. X           if ( BTEST(arg_flags(ad), ARGVEC) ) {
  1017. X            FILEvec_t  *vec = (FILEvec_t *) arg_valp(ad);
  1018. X            size_t  size  = (1 + vec->count) * (sizeof (FILE *));
  1019. X
  1020. X            vec->array = (FILE **) REALLOC(vec->array, size);
  1021. X            if ( ! vec->array )
  1022. X             syserr( "(m|re)alloc failed in    argReadFile" );
  1023. X            vec->flags = (FILE **) REALLOC(vec->flags, size);
  1024. X            if ( ! vec->flags )
  1025. X             syserr( "(m|re)alloc failed in    argReadFile" );
  1026. X
  1027. X            vec->flags[    vec->count ] = arg_flags(ad);
  1028. X            vec->array[    (vec->count)++ ] = fp;
  1029. X           }
  1030. X           else
  1031. X            *(FILE *) arg_valp(ad) = fp;
  1032. X           return (TRUE);
  1033. X      }
  1034. X
  1035. LONG OPTIONS
  1036. X     Under UNIX, Parseargs also    allows for long    options    in addi-
  1037. X     tion to single character options. Long options are    denoted
  1038. X     by    a `+' character    (which may be changed using keywordpre-
  1039. X     fix). The keyword that is used is the first word in the
  1040. X     prompt field of an    argument descriptor entry.  Long options
  1041. X     are case insensitive! An argument to a long option    may be
  1042. X     separated from the    long option by an equal    sign (`=') or by
  1043. X     one or more whitespace characters.     Thus, if an entry looks
  1044. X     like:
  1045. X
  1046. X     then ``-c4'', ``+repcount=4'', ``+count=4'', ``+rep-
  1047. X     count 4'',    and ``+count 4'' will all have the same    effect.
  1048. X
  1049. X     The long option names for ``-?'' in the default argument
  1050. X     descriptor    are ``+help'' and ``+?'' (respectively). In addi-
  1051. X     tion, ``++'' or ``+endopts'' may be used to indicate the end
  1052. X     of    options    so that    all remaining arguments    will be    inter-
  1053. X     preted as positional parameters (even if one begins with a
  1054. X     `+' or a `-').
  1055. X
  1056. X     Under VAX/VMS and AmigaDOS, single-character options are not
  1057. X     used and the ``long'' name    (in the    prompt field of    an argu-
  1058. X     ment descriptor) is always    used to    match for possible argu-
  1059. X     ments (or keywords, or qualifiers).
  1060. X
  1061. X     For all supported operating systems, a long option    may be
  1062. X     matched in    one of two ways: it may    match all uppercase char-
  1063. X     acters in the prompt field, or it may match all characters
  1064. X
  1065. X
  1066. X
  1067. Page 15
  1068. X
  1069. X
  1070. X
  1071. X
  1072. X
  1073. X
  1074. PARSEARGS(3)                         PARSEARGS(3)
  1075. X
  1076. X
  1077. X
  1078. X     in    the prompt field (as in    ``+count=4'' and ``+rep-
  1079. X     count=4'').
  1080. X
  1081. X     Under UNIX    and VAX/VMS, only the number of    characters
  1082. X     required to uniquely identify the desired argument    are
  1083. X     needed, but at least two characters must be given (unless
  1084. X     the prompt    field is itself    less than two characters long).
  1085. X     This means    that using the above example, that ``+rep=4'' and
  1086. X     ``+cou=4''    would also work    but ``+c=4'' would NOT (in other
  1087. X     words, if you only    want to    use one    character, use ``-c4''
  1088. X     instead).
  1089. X
  1090. X     Under VAX/VMS, the    possibilities using the    above example
  1091. X     would be:    ``/REPCOUNT=4'', ``/COUNT=4'', ``/REP=4'', and
  1092. X     ``/COU=4'',
  1093. X
  1094. X     Under AmigaDOS, no    ``shortened'' keywords are accepted and
  1095. X     the possibilities using the above example would be:  ``REP-
  1096. X     COUNT 4'',    and ``COUNT 4''
  1097. X
  1098. RETURN VALUE
  1099. X     The functions in the parseargs library will return    a value
  1100. X     of    zero upon succesful completion.    They may however, return
  1101. X     any of the    following status codes (which are defined in
  1102. X     <parseargs.h>):
  1103. X
  1104. X     pe_SYSTEM
  1105. X      A system error occurred. The global variable errno may
  1106. X      indicate the problem (then again, it may not).
  1107. X
  1108. X     pe_SUCCESS
  1109. X      Success, no errors encountered (zero is returned).
  1110. X
  1111. X     pe_SYNTAX
  1112. X      A command-line syntax    error was encountered
  1113. X
  1114. X     pe_DEFARGS
  1115. X      An attempt (using parsecntl) was made    to change the
  1116. X      default arg-search list of a command to point    to an
  1117. X      argdesc-array    which already has the given command on
  1118. X      its default arg-search list (which would cause an
  1119. X      infinite loop    when attempting    to match an unknown
  1120. X      command-line argument).
  1121. X
  1122. X     pe_NOMATCH
  1123. X      Unable to match the named argument. This occurs when
  1124. X      the argument keyword name passed to parsecntl    (using
  1125. X      the pc_ARGFLAGS functions code) was found in the given
  1126. X      argdesc-array    or in its default-list.
  1127. X
  1128. X     pe_BADMODE
  1129. X      Bad mode for given command in    parsecntl. This    occurs
  1130. X
  1131. X
  1132. X
  1133. Page 16
  1134. X
  1135. X
  1136. X
  1137. X
  1138. X
  1139. X
  1140. PARSEARGS(3)                         PARSEARGS(3)
  1141. X
  1142. X
  1143. X
  1144. X      when pc_WRITE    or pc_RDWR mode    is passed to parsecntl in
  1145. X      conjunction with the pc_ARGFLAGS functions code.  Par-
  1146. X      secntl will not modify existing arguments.
  1147. X
  1148. X     pe_BADCNTL
  1149. X      Bad command for parsecntl. This occurs if an unknown
  1150. X      function-code    was passed to parsecntl.
  1151. X
  1152. SEE ALSO
  1153. X     argtype(3), parseargs(1), syserr(3)
  1154. X     The ``C Advisor'' column in UNIX Review Vol. 7 No.    11.
  1155. X
  1156. CAVEATS
  1157. X     Because of    the way    argument parsing is implemented    under
  1158. X     UNIX, MS-DOS, and OS/2, option arguments which contain a
  1159. X     leading dash (`-')    (or whatever the option    prefix character
  1160. X     is    defined    to be) may not be specified as a separate argu-
  1161. X     ment on the command line, it must be part of the same argu-
  1162. X     ment. That    is to say that if a program has    a -f option that
  1163. X     requires a    string argument, then the following:
  1164. X      -f-arg
  1165. X
  1166. X     will properly assign the string ``-arg'' to the option
  1167. X     whereas the following:
  1168. X      -f -arg
  1169. X
  1170. X     will be interpreted by parseargs as two option strings: the
  1171. X     first of which (``-f'') is    missing    a required argument and
  1172. X     the second    of which (``-arg'') will most likely be    flagged
  1173. X     as    an invalid option.
  1174. X
  1175. X     Similarly,    if the user requires an    ARGLIST    option to take
  1176. X     multiple arguments    with leading dashes then the following
  1177. X     method must be used: It is    a ``feature'' of parseargs that
  1178. X     ARGLIST arguments are always appended to the current list of
  1179. X     arguments for the given option. Thus, if ``-f'' is    an option
  1180. X     taking a list of arguments, then the following are    all
  1181. X     equivalent:
  1182. X      -farg1 arg2
  1183. X
  1184. X      -f arg1 arg2
  1185. X      -farg1 -farg2
  1186. X
  1187. X      -f arg1 -f arg2
  1188. X     Hence multiple ``leading dash'' arguments may specified as
  1189. X     follows:
  1190. X
  1191. X      -f-dash_arg1 -f-dash_arg2  ...
  1192. X
  1193. BUGS
  1194. X     When a non-multivalued argument appears more than once on
  1195. X     the command-line then only    the last value supplied    is used.
  1196. X
  1197. X
  1198. X
  1199. Page 17
  1200. X
  1201. X
  1202. X
  1203. X
  1204. X
  1205. X
  1206. PARSEARGS(3)                         PARSEARGS(3)
  1207. X
  1208. X
  1209. X
  1210. X     A problem occurs however in the following scenario: suppose
  1211. X     `-s' is an    option that takes an optional string argument (nd
  1212. X     suppose `-x' is some boolean flag). Then if the following
  1213. X     command-line is issued:
  1214. X
  1215. X      command  -s string  -x  -s
  1216. X
  1217. X     then, the argument    flags will properly correspond to the
  1218. X     second instance of    the `-s' option    (namely    ARGGIVEN will be
  1219. X     set but ARGVALGIVEN will be unset)    but the    value associated
  1220. X     with the option will be ``string''    (because the first
  1221. X     instance overwrote    the default).  Because of this,    it may be
  1222. X     safest to reassign    the default value if ARGGIVEN is set but
  1223. X     ARGVALGIVEN is unset.
  1224. X
  1225. AUTHOR
  1226. X     Eric Allman, University of    California, Berkeley
  1227. X
  1228. MODIFICATIONS
  1229. X     Modified to accept    a vector of arguments, better error mes-
  1230. X     sages, Unix keyword matching, and AmigaDOS    version    by Peter
  1231. X     da    Silva.
  1232. X
  1233. X     Rewritten by Brad Appleton.  Parseargs(1);    functions par-
  1234. X     secntl, sparseargs, fparseargs, lparseargs, and vparseargs;
  1235. X     argument types argUsage, argDummy,    argUBool, and argTBool;
  1236. X     argument flags ARGPOS, ARGVALOPT, ARGVALREQ, ARGVALGIVEN,
  1237. X     ARGNOVAL, and ARGVEC; and VAX/VMS version and IBM-PC version
  1238. X     by    Brad Appleton
  1239. X
  1240. X
  1241. X
  1242. X
  1243. X
  1244. X
  1245. X
  1246. X
  1247. X
  1248. X
  1249. X
  1250. X
  1251. X
  1252. X
  1253. X
  1254. X
  1255. X
  1256. X
  1257. X
  1258. X
  1259. X
  1260. X
  1261. X
  1262. X
  1263. X
  1264. X
  1265. Page 18
  1266. X
  1267. X
  1268. X
  1269. SHAR_EOF
  1270. chmod 0664 parseargs/parseargs3.txt ||
  1271. echo 'restore of parseargs/parseargs3.txt failed'
  1272. Wc_c="`wc -c < 'parseargs/parseargs3.txt'`"
  1273. test 37108 -eq "$Wc_c" ||
  1274.     echo 'parseargs/parseargs3.txt: original size 37108, current size' "$Wc_c"
  1275. rm -f _shar_wnt_.tmp
  1276. fi
  1277. # ============= parseargs/parsecntl3.txt ==============
  1278. if test -f 'parseargs/parsecntl3.txt' -a X"$1" != X"-c"; then
  1279.     echo 'x - skipping parseargs/parsecntl3.txt (File already exists)'
  1280.     rm -f _shar_wnt_.tmp
  1281. else
  1282. > _shar_wnt_.tmp
  1283. echo 'x - extracting parseargs/parsecntl3.txt (Text)'
  1284. sed 's/^X//' << 'SHAR_EOF' > 'parseargs/parsecntl3.txt' &&
  1285. X
  1286. X
  1287. X
  1288. PARSECNTL(3)                         PARSECNTL(3)
  1289. X
  1290. X
  1291. X
  1292. NAME
  1293. X     parsecntl - get and set attributes    of an argument descriptor
  1294. X     array
  1295. X
  1296. SYNOPSIS
  1297. X     #include <parseargs.h>
  1298. X
  1299. X     int  parsecntl( ARGDESC argd[],  parsecntl_t func,     parsemode_t mode,  ...    )
  1300. X
  1301. X
  1302. DESCRIPTION
  1303. X     Parsecntl will read and/or    write the desired attributes of
  1304. X     the given command-object. The attributes to be operated upon
  1305. X     are specified by the second parameter to parsecntl. The
  1306. X     desired mode (read, write,    or both) are specified by the
  1307. X     third parameter to    parsecntl. If the operation to be per-
  1308. X     formed is pc_ARGFLAGS, then the fourth argument to    parsecntl
  1309. X     should be the keyword name    of the argument    whose flags are
  1310. X     to    be retrieved.  The last    parameter to parsecntl is always
  1311. X     the object    to contain the attribute(s) to be read/written.
  1312. X     If    the attribute(s) are to    be read    (regardless of whether or
  1313. X     not they are also being changed) then the last argument
  1314. X     should be a pointer to an object, otherwise the last argu-
  1315. X     ment should be the    object itself.
  1316. X
  1317. X     If    mode is    pc_READ, then the desired attributes are copied
  1318. X     into the object pointed to    by the last parameter. If the
  1319. X     mode is pc_WRITE, then the    attributes from    the last parame-
  1320. X     ter are copied to the command- object. If mode is pc_RDWR,
  1321. X     then the attributes pointed to by the last    parameter are
  1322. X     copied to the command-object, and then the    previous value of
  1323. X     these attributes (before they were    overwritten) is    copied
  1324. X     into the object pointed to    by the last parameter.
  1325. X
  1326. X     If    cntl is    pc_ARGFLAGS, then the only valid mode is pc_READ.
  1327. X     All other attributes may be written or read by parsecntl.
  1328. X
  1329. FUNCTION CODES
  1330. X     Each of the following function codes specifies an attribute
  1331. X     that is to    be manipulated by parsecntl.  The function code
  1332. X     is    the second parameter to    parsecntl. With    the exception of
  1333. X     pc_ARGFLAGS, each of the function codes corresponds to a
  1334. X     call to parsecntl using four parameters ( pc_ARGFLAGS uses    5
  1335. X     parameters). In each case,    the last parameter is either the
  1336. X     address of    a buffer to write the attribute    to, or the actual
  1337. X     buffer to read the    attribute from (depending upon the mode    -
  1338. X     the third parameter to parsecntl).
  1339. X
  1340. X     pc_PARSEFLAGS
  1341. X      This function    code is    used to    read and/or modify the
  1342. X      existing parsing parsing behavior. The fourth    parameter
  1343. X      to parsecntl should be a combination of pc_XXXX
  1344. X
  1345. X
  1346. X
  1347. Page 1
  1348. X
  1349. X
  1350. X
  1351. X
  1352. X
  1353. X
  1354. PARSECNTL(3)                         PARSECNTL(3)
  1355. X
  1356. X
  1357. X
  1358. X      bitmasks if the parse-flags are only being written,
  1359. X      otherwise it should be a pointer to an argMask_t vari-
  1360. X      able.
  1361. X
  1362. X     pc_ARGFLAGS
  1363. X      This function    code may only be used to read the
  1364. X      argument-flags of a named argument. It is an error to
  1365. X      specify a mode that attempts to write    the argument-
  1366. X      flags    with this function code. The fourth parameter to
  1367. X      parsecntl should be the keyword name of the argument
  1368. X      whose    flags are to be    read. The fifth    (and final) argu-
  1369. X      ment should be a pointer to the argMask_t variable
  1370. X      which    will receive the resulting argument-flags.
  1371. X
  1372. X     pc_DEFARGS
  1373. X      This function    code is    used to    query or modify    the
  1374. X      current default argument-descriptor list for the given
  1375. X      command. The fourth parameter    to parsecntl should be
  1376. X      the argument-descriptor array    to assign as the new
  1377. X      default-list (or the address of an argdesc-array if the
  1378. X      default list is being    retrieved).
  1379. X
  1380. X      If a given option/qualifier does not appear to match
  1381. X      any items in the argdesc-array, a  default argdesc-
  1382. X      array    is then    searched to match the option. If it is
  1383. X      STILL    unmatched then it is flagged as    such. The
  1384. X      default-argdesc array    is automatically used by all
  1385. X      programmer-defined argdesc-array but may be unset or
  1386. X      reset    using the pc_DEFARGS function of parsecntl. In
  1387. X      such a  manner, a  programmer    could specify a    different
  1388. X      set of default-arguments to search for. Furthermore,
  1389. X      default argdesc-arrays may also be assigned default
  1390. X      argdesc-arrays, thus allowing    the programmer to define
  1391. X      a whole search-list of default argdesc-arrays    for a
  1392. X      given    command.
  1393. X
  1394. X      This could prove useful in a situation where a set of
  1395. X      commands have    a few common-options and differ    in their
  1396. X      remaining ones. If the same main() were used for each
  1397. X      command, then    main could define one common argdesc-
  1398. X      array    and then a set of argdesc-arrays for each com-
  1399. X      mand.    Main could then    figure out which argdesc-array to
  1400. X      used based on    the name in argv[0], and set its default
  1401. X      argdesc-array    to be the common argdesc-array,    as in the
  1402. X      following:
  1403. X
  1404. X      #include <parseargs.h>
  1405. X           .
  1406. X           .  variable declarations
  1407. X           .
  1408. X
  1409. X      static ARGDESC common_args[] = {
  1410. X
  1411. X
  1412. X
  1413. Page 2
  1414. X
  1415. X
  1416. X
  1417. X
  1418. X
  1419. X
  1420. PARSECNTL(3)                         PARSECNTL(3)
  1421. X
  1422. X
  1423. X
  1424. X         STARTOFARGS,
  1425. X         { 'L', ARGOPT, argBool, __    &lflag,    "list (list the    items)"    },
  1426. X         { 'I', ARGOPT, argStr, __ &item, "item (item to use)" },
  1427. X         ENDOFARGS
  1428. X      };
  1429. X
  1430. X      static ARGDESC cmd1_args[] = {
  1431. X         STARTOFARGS,
  1432. X         { 's', ARGOPT, argBool, __    &sflag,    "S (set    S)" },
  1433. X         { 't', ARGOPT, argBool, __    &tflag,    "T (set    T)" },
  1434. X         ENDOFARGS
  1435. X      };
  1436. X
  1437. X      static ARGDESC cmd2_args[] = {
  1438. X         STARTOFARGS,
  1439. X         { 'x', ARGOPT, argBool, __    &xflag,    "X (set    X)" },
  1440. X         { 'y', ARGOPT, argBool, __    &yflag,    "Y (set    Y)" },
  1441. X         ENDOFARGS
  1442. X      };
  1443. X
  1444. X      main(    int argc, char *argv[] )
  1445. X      {
  1446. X         ARGDESC *cmd = cmd1_args;
  1447. X         int  rc;
  1448. X
  1449. X         if    ( strcmp(*argv,    "cmd2")    == 0 )
  1450. X        cmd = cmd2_args;
  1451. X
  1452. X         rc    = parsecntl( cmd, pc_DEFARGS, pc_WRITE,    common_args );
  1453. X         if    ( rc !=    pe_SUCCESS )
  1454. X        syserr(    "unable    to set default args" );
  1455. X
  1456. X         rc    = parseargs( argv, cmd );
  1457. X        .
  1458. X        .
  1459. X        .
  1460. X      }
  1461. X
  1462. X      Note that in the above call to parsecntl(3), that zero
  1463. X      will be returned upon    success    and non-zero upon
  1464. X      failure. If pe_DEFARGS is returned, then cmd is already
  1465. X      on common_args's list    of defaults (and would result in
  1466. X      an infinite loop while parsing).
  1467. X
  1468. X     pc_NAME
  1469. X
  1470. X     pc_PURPOSE
  1471. X
  1472. X     pc_DESCRIPTION
  1473. X      Each of these    last three function codes are used to
  1474. X      modify or query the name, purpose, or    description asso-
  1475. X      ciated with a    command. The fourth parameter to
  1476. X
  1477. X
  1478. X
  1479. Page 3
  1480. X
  1481. X
  1482. X
  1483. X
  1484. X
  1485. X
  1486. PARSECNTL(3)                         PARSECNTL(3)
  1487. X
  1488. X
  1489. X
  1490. X      parsecntl should be the new string to    use (or    the
  1491. X      address of the string, a char** variable, to recieve
  1492. X      the current value).
  1493. X
  1494. PARSE MODES
  1495. X     Parsecntl may be used to read current command attributes,
  1496. X     write (assign) new    command    attributes, or both. The mode
  1497. X     argument to parsecntl determines the which    of these three
  1498. X     alternatives are desired. If the programmer merely    wishes to
  1499. X     assign new    attributes, then invoking parsecntl in pc_WRITE
  1500. X     mode and passing the new attributes will do the job. If the
  1501. X     programmer    wishes simply to query attributes, then    invoking
  1502. X     parsecntl in pc_READ mode and passing a pointer to    the
  1503. X     desired object in which to    write the attribute settings will
  1504. X     suffice.
  1505. X
  1506. X     If    the programmer wishes to assign    new attributes and at the
  1507. X     same time find out    what the attributes were before    making
  1508. X     the assignment, then programmer must invoke parsecntl for
  1509. X     pc_RDWR mode and pass a pointer to    the object containing the
  1510. X     new attribute settings; When parsecntl returns, then (assum-
  1511. X     ing it returns 0) the desired attributes will have    been
  1512. X     assigned and the object that contained the    new attribute
  1513. X     settings will now contain the attribute settings that were
  1514. X     in    effect before parsecntl    was invoked.
  1515. X
  1516. PARSE FLAGS
  1517. X     The following bitmasks may    be combined in order to    modify
  1518. X     the behavior of the parseargs library. The    parse flags for    a
  1519. X     given may be set through the use of the parsecntl(3) func-
  1520. X     tion.
  1521. X
  1522. X     pa_PROMPT
  1523. X      Prompt the user for any missing arguments that are
  1524. X      required on the command-line.    No special escaping or
  1525. X      quoting is performed on the user input. Required argu-
  1526. X      ments    that expect a list of values will be repeatedly
  1527. X      prompted for (one item per line) until a blank line
  1528. X      (followed by a carriage return) is entered.
  1529. X
  1530. X     pa_IGNORE
  1531. X      Ignore any unrecognized or improperly    specified
  1532. X      command-line arguments and continue execution    of the
  1533. X      program. Normally, if    an argument is unmatched (or is
  1534. X      improperly specified), a usage message is printed pro-
  1535. X      gram execution is terminated.
  1536. X
  1537. X     pa_OPTSONLY
  1538. X      Under    UNIX, setting this flag    will disable the parsing
  1539. X      of long-option syntax. This will cause all arguments
  1540. X      starting with    `+' to always be treated as a positional
  1541. X      parameter (instead of    a long-option).
  1542. X
  1543. X
  1544. X
  1545. Page 4
  1546. X
  1547. X
  1548. X
  1549. X
  1550. X
  1551. X
  1552. PARSECNTL(3)                         PARSECNTL(3)
  1553. X
  1554. X
  1555. X
  1556. X     pa_KWDSONLY
  1557. X      Under    UNIX, setting this flag    disables the parsing of
  1558. X      single-character options.  This will cause all argu-
  1559. X      ments    starting with `-' to always be treated as a posi-
  1560. X      tional parameter (instead of an option).
  1561. X
  1562. X     pa_FLAGS1ST
  1563. X      Setting this flag causes the parseargs library to force
  1564. X      any and all non-positional arguments to be specified
  1565. X      before any positional    ones.  As an example, under UNIX,
  1566. X      if this flag is SET then parseargs will consider the
  1567. X      command line "cmd -x arg" to consist of one option and
  1568. X      one positional argument; however the command line "cmd
  1569. X      arg -x" would    be considered to consist of two    posi-
  1570. X      tional arguments (the    -x option will be unmatched).
  1571. X
  1572. X      If this flag is UNSET, then both of the previous exam-
  1573. X      ples are considered to consist of one    option and one
  1574. X      positional argument.
  1575. X
  1576. X     pa_ANYCASE
  1577. X      Setting this flag will cause character-case to be
  1578. X      ignored when attempting to match single-character argu-
  1579. X      ment names (i.e. causes "-i" and "-I"    will be    con-
  1580. X      sidered equivalent).
  1581. X
  1582. X     pa_ARGV0
  1583. X      Normally, the    parseargs library will assume that the
  1584. X      first    argument on the    command-line is    the name of the
  1585. X      command. Setting this    flag tells parseargs that this is
  1586. X      NOT the case and that    the very first argument    on the
  1587. X      command-line is a bona-fide argument to the command.
  1588. X
  1589. X     pa_NOCHECK
  1590. X      Setting this flag will prevent parseargs from    checking
  1591. X      for any required arguments that were not given on the
  1592. X      command-line.    This is    useful when more than one call to
  1593. X      the parseargs    library    is needed to parse all the
  1594. X      command-line arguments (which    could occur if the
  1595. X      command-line argument    came from a file or from two
  1596. X      argv-vectors).
  1597. X
  1598. X      Keeping this flag on until the final set of arguments
  1599. X      is parsed will cause parseargs to not    check for missing
  1600. X      arguments until the last set of arguments has    been
  1601. X      parsed (by the final call to *parseargs).
  1602. X
  1603. X     pa_CONTINUE
  1604. X      Setting this flag will cause subsequent calls    to the
  1605. X      parseargs library to NOT reset the current command-
  1606. X      state. Hence,    all arguments will not be initially set
  1607. X      to "NOT GIVEN" and other (normal) initializations are
  1608. X
  1609. X
  1610. X
  1611. Page 5
  1612. X
  1613. X
  1614. X
  1615. X
  1616. X
  1617. X
  1618. PARSECNTL(3)                         PARSECNTL(3)
  1619. X
  1620. X
  1621. X
  1622. X      not be performed.  This is useful in conjunction with
  1623. X      the pa_NOCHECK flag when more    than one call to par-
  1624. X      seargs is required to    parse all the command arguments.
  1625. X      In this scenario, pa_CONTINUE    should be unset    (the
  1626. X      default setting) for the very    first call to parseargs,
  1627. X      but should then be set before    any subsequent calls to
  1628. X      parseargs are    made.
  1629. X
  1630. X     pa_NOCMDENV
  1631. X      Setting this flag prevents parseargs from checking the
  1632. X      CMD-NAME_ARGS    environment variable (or symbol) for any
  1633. X      user-defined default command arguments.
  1634. X
  1635. X     pa_COPYF
  1636. X      When this flag is OFF    (the default), a value of FALSE
  1637. X      is provided as the copyf argument to all the arg-type
  1638. X      (argXxxxx) functions when an argument    is matched. Set-
  1639. X      ting this flag will cause a value of TRUE to be pro-
  1640. X      vided    as the copyf argument to all the arg-type
  1641. X      (argXxxxx) functions when an argument    is matched.
  1642. X
  1643. ARGUMENT FLAGS
  1644. X     These are the possible bitmasks that may be turned    ON or OFF
  1645. X     in    the ad_flags field of an ARGDESC structure.
  1646. X
  1647. X     ARGOPT
  1648. X      This flag is actually    a dummy    flag (i.e. it is the
  1649. X      default). This flag specifies    that the command-line
  1650. X      argument is optional (need not appear    on the command-
  1651. X      line). It is only needed if no other flags are used to
  1652. X      define the given argument.  If other flags are given
  1653. X      and ARGREQ is    NOT one    of them, then ARGOPT is    always
  1654. X      assumed.
  1655. X
  1656. X     ARGREQ
  1657. X      The associated command argument is required on the
  1658. X      command-line.
  1659. X
  1660. X     ARGPOS
  1661. X      The associated command argument is positonal.    The
  1662. X      difference between using this    flag to    indicate a posi-
  1663. X      tional argument and between using a blank in the
  1664. X      ad_name field    to indicate a positional arguments is the
  1665. X      following: If    this flag is set but the ad_name of the
  1666. X      argument is non-blank, then this argument may    be
  1667. X      matched either positionally or by keyword. If    the
  1668. X      ad_name field    is blank, then this argument may only be
  1669. X      matched positionally.
  1670. X
  1671. X     ARGNOVAL
  1672. X      The associated command argument takes    no value (as in
  1673. X      "-x value"); Its mere    presence (or lack thereof) on the
  1674. X
  1675. X
  1676. X
  1677. Page 6
  1678. X
  1679. X
  1680. X
  1681. X
  1682. X
  1683. X
  1684. PARSECNTL(3)                         PARSECNTL(3)
  1685. X
  1686. X
  1687. X
  1688. X      command-line is sufficient to    determine the necessary
  1689. X      action(s) to take (as    in "-x").  Boolean argument types
  1690. X      and Pseudo-argument types automatically default to ARG-
  1691. X      NOVAL.
  1692. X
  1693. X     ARGVALOPT
  1694. X      This flag is used to indicate    that the command-line
  1695. X      argument takes a value (as in    "-s string" or
  1696. X      "/str=string") but that the value to this command-line
  1697. X      argument is NOT required (hence simply "-s" or "/str"
  1698. X      is also permissable).
  1699. X
  1700. X     ARGVALREQ
  1701. X      Another "dummy" flag.    Unless ARGNOVAL    or ARGVALOPT is
  1702. X      specified, ARGVALREQ is always assumed. This flag indi-
  1703. X      cates    that the value to a command-line argument is
  1704. X      required (hence "-s string" is okay but just "-s" is
  1705. X      not).
  1706. X
  1707. X     ARGHIDDEN
  1708. X      Don't    display    this argument in usage messages    but still
  1709. X      attempt to match it against strings given on the
  1710. X      command-line.
  1711. X
  1712. X     ARGLIST
  1713. X      A variable number of values are used for this    argument
  1714. X      (and hence may use more than one or two argv elements
  1715. X      from the command-line    as in "-l val1 val2 ..."). The
  1716. X      list of values must be stored    in an ArgList structure
  1717. X      (NOT a vector    structure), an the corresponding
  1718. X      argument-type    function should    be one of the listXxxx
  1719. X      functions.
  1720. X
  1721. X     ARGVEC
  1722. X      A variable number of values are used for this    argument
  1723. X      (and hence may use more than one or two argv elements
  1724. X      from the command-line    as in in "-v val1 val2 ..."). The
  1725. X      list of values must be stored    in a vector structure
  1726. X      (NOT an ArgList structure).
  1727. X
  1728. X     The following bitmasks may    also be    present, but, unlike the
  1729. X     above masks which must be specified by the    programmer at
  1730. X     initialization time, the following    masks must only    be read
  1731. X     (never set) by the    programmer. They may be    queried    by using
  1732. X     the pc_ARGFLAGS function code and the mode    pc_READ    with par-
  1733. X     secntl(3).
  1734. X
  1735. X     ARGGIVEN
  1736. X      The argument WAS given on the    command-line.
  1737. X
  1738. X     ARGVALGIVEN
  1739. X      The value for    this argument was given    on the command-
  1740. X
  1741. X
  1742. X
  1743. Page 7
  1744. X
  1745. X
  1746. X
  1747. X
  1748. X
  1749. X
  1750. PARSECNTL(3)                         PARSECNTL(3)
  1751. X
  1752. X
  1753. X
  1754. X      line.
  1755. X
  1756. X     ARGVALSEP
  1757. X      The value to this argument was supplied in a separate
  1758. X      argv element from the    argument itself    (as in "-x value"
  1759. X      as opposed to    "-xvalue").
  1760. X
  1761. X     ARGKEYWORD
  1762. X      This argument    was matched as a keyword (long-form) on
  1763. X      the command-line and not as a    single character.
  1764. X
  1765. X     ARGDESCRIBED
  1766. X      This argument    was given a description    by the programmer
  1767. X      at initialization.
  1768. X
  1769. X     ARGCOPYF
  1770. X      This flag is only used for lists and vectors (mul-
  1771. X      tivalued arguments) and is used on a per-item    basis. If
  1772. X      it is    set, it    means that the corresponding value in the
  1773. X      vector/list required space to    be allocated (such as the
  1774. X      duplication of a temporary string).
  1775. X
  1776. RETURN VALUE
  1777. X     The functions in the parseargs library will return    a value
  1778. X     of    zero upon succesful completion.    They may however, return
  1779. X     any of the    following status codes (which are defined in
  1780. X     <parseargs.h>):
  1781. X
  1782. X     pe_SYSTEM
  1783. X      A system error occurred. The global variable errno may
  1784. X      indicate the problem (then again, it may not).
  1785. X
  1786. X     pe_SUCCESS
  1787. X      Success, no errors encountered (zero is returned).
  1788. X
  1789. X     pe_SYNTAX
  1790. X      A command-line syntax    error was encountered
  1791. X
  1792. X     pe_DEFARGS
  1793. X      An attempt (using parsecntl) was made    to change the
  1794. X      default arg-search list of a command to point    to an
  1795. X      argdesc-array    which already has the given command on
  1796. X      its default arg-search list (which would cause an
  1797. X      infinite loop    when attempting    to match an unknown
  1798. X      command-line argument).
  1799. X
  1800. X     pe_NOMATCH
  1801. X      Unable to match the named argument. This occurs when
  1802. X      the argument keyword name passed to parsecntl    (using
  1803. X      the pc_ARGFLAGS functions code) was found in the given
  1804. X      argdesc-array    or in its default-list.
  1805. X
  1806. X
  1807. X
  1808. X
  1809. Page 8
  1810. X
  1811. X
  1812. X
  1813. X
  1814. X
  1815. X
  1816. PARSECNTL(3)                         PARSECNTL(3)
  1817. X
  1818. X
  1819. X
  1820. X     pe_BADMODE
  1821. X      Bad mode for given command in    parsecntl. This    occurs
  1822. X      when pc_WRITE    or pc_RDWR mode    is passed to parsecntl in
  1823. X      conjunction with the pc_ARGFLAGS functions code.  Par-
  1824. X      secntl will not modify existing arguments.
  1825. X
  1826. X     pe_BADCNTL
  1827. X      Bad command for parsecntl. This occurs if an unknown
  1828. X      function-code    was passed to parsecntl.
  1829. X
  1830. SEE ALSO
  1831. X     argtype(3),
  1832. X     parseargs(3),
  1833. X     parseargs(1)
  1834. X
  1835. AUTHOR
  1836. X     Brad Appleton  (brad@ssd.csd.harris.com)
  1837. X     Harris Computer Systems, Fort Lauderdale, FL USA
  1838. X
  1839. X
  1840. X
  1841. X
  1842. X
  1843. X
  1844. X
  1845. X
  1846. X
  1847. X
  1848. X
  1849. X
  1850. X
  1851. X
  1852. X
  1853. X
  1854. X
  1855. X
  1856. X
  1857. X
  1858. X
  1859. X
  1860. X
  1861. X
  1862. X
  1863. X
  1864. X
  1865. X
  1866. X
  1867. X
  1868. X
  1869. X
  1870. X
  1871. X
  1872. X
  1873. X
  1874. X
  1875. Page 9
  1876. X
  1877. X
  1878. X
  1879. SHAR_EOF
  1880. chmod 0664 parseargs/parsecntl3.txt ||
  1881. echo 'restore of parseargs/parsecntl3.txt failed'
  1882. Wc_c="`wc -c < 'parseargs/parsecntl3.txt'`"
  1883. test 17278 -eq "$Wc_c" ||
  1884.     echo 'parseargs/parsecntl3.txt: original size 17278, current size' "$Wc_c"
  1885. rm -f _shar_wnt_.tmp
  1886. fi
  1887. # ============= parseargs/pgopen.c ==============
  1888. if test -f 'parseargs/pgopen.c' -a X"$1" != X"-c"; then
  1889.     echo 'x - skipping parseargs/pgopen.c (File already exists)'
  1890.     rm -f _shar_wnt_.tmp
  1891. else
  1892. > _shar_wnt_.tmp
  1893. echo 'x - extracting parseargs/pgopen.c (Text)'
  1894. sed 's/^X//' << 'SHAR_EOF' > 'parseargs/pgopen.c' &&
  1895. /*************************************************************************
  1896. ** ^FILE: pgopen.c - pipe output to a pager for Unix Systems.
  1897. **
  1898. ** ^DESCRIPTION:
  1899. **    The functions in this file implement a minimal paging system
  1900. **    using popen() & pclose() to invoke a specified paging program.
  1901. **
  1902. **    The following public functions are defined:
  1903. **
  1904. **       FILE *pgopen( FILE *fp, const char *pager_cmd )
  1905. **           -- attempt to open the pager, return the corresponding
  1906. **              file-pointer to write to (which will be <fp> if
  1907. **              popen(3S) fails).
  1908. **
  1909. **       int pgclose( FILE *pager_fp )
  1910. **           -- close the pager stream, return 0 on success
  1911. **
  1912. **       int pgactive( const FILE *pager_fp )
  1913. **           -- return TRUE if the pager is open.
  1914. **
  1915. ** ^HISTORY:
  1916. **    12/03/90     Brad Appleton     <brad@ssd.csd.harris.com>     Created
  1917. ***^^**********************************************************************/
  1918. X
  1919. #ifdef  USE_PAGER
  1920. X
  1921. X
  1922. #include <stdio.h>
  1923. #include <signal.h>
  1924. #include <setjmp.h>
  1925. #include <useful.h>
  1926. X
  1927. /* get #defines for access() call */
  1928. #include <sys/file.h>
  1929. #ifndef X_OK
  1930. #  define X_OK  0x01
  1931. #endif
  1932. X
  1933. /*
  1934. **  Implement a state machine that tries first to use a pager
  1935. **  specified by the user, then as a second choice, /usr/ucb/more,
  1936. **  if all else fails use the given file-pointer (which we assume to
  1937. **  be writable)
  1938. **
  1939. **  The following defines the state machine.
  1940. **
  1941. */
  1942. X
  1943. typedef enum  {
  1944. X   PG_CLOSED,  /* pager not-yet-open */
  1945. X   PG_NONE,    /* No pager used */
  1946. X   PG_ENV,     /* the given pager name (or $PAGER) was used */
  1947. X   PG_DFLT,    /* default pager (more) used */
  1948. X   PG_FILE     /* file-pointer used */
  1949. }  pager_t;
  1950. X
  1951. #define  DEFAULT_PAGER   "/usr/ucb/more"
  1952. X
  1953. #ifndef TRUE
  1954. #  define  TRUE  1
  1955. #endif
  1956. #ifndef FALSE
  1957. #  define  FALSE 0
  1958. #endif
  1959. X
  1960. #define MAX_NAME_LEN  512
  1961. #define isTERMINAL(fd)   ( isatty(fd) ) ? TRUE : (errno = 0, FALSE)
  1962. X
  1963. extern  char *strcpy();
  1964. extern  int   strcmp();
  1965. extern  int   access();
  1966. extern  int   isatty();
  1967. extern  int   wait();
  1968. extern  int   sleep();
  1969. X
  1970. extern  int  errno;
  1971. X
  1972. static void  pg_error();       /* broken-pipe exception handler */
  1973. static jmp_buf pg_recover;     /* jump-buffer for exception handler */
  1974. static pager_t  pg_pathname();
  1975. X
  1976. static pager_t  Pager_Type = PG_CLOSED;
  1977. static FILE    *Pager_FP = (FILE *)NULL;
  1978. X
  1979. X
  1980. /***************************************************************************
  1981. ** ^FUNCTION: pgactive - query pager status
  1982. **
  1983. ** ^SYNOPSIS:
  1984. */
  1985. #ifndef __ANSI_C__
  1986. X   int pgactive( pager_fp )
  1987. /*
  1988. ** ^PARAMETERS:
  1989. */
  1990. X   FILE *pager_fp;
  1991. /*    -- the file-pointer returned by pgopen()
  1992. */
  1993. #endif  /* !__ANSI_C__ */
  1994. X
  1995. /* ^DESCRIPTION:
  1996. **    Pgactive indicates whether or not the given file-pointer is in
  1997. **    use by the paging system.
  1998. **
  1999. ** ^REQUIREMENTS:
  2000. **    pgopen() must first be called in order to obtain a valid
  2001. SHAR_EOF
  2002. true || echo 'restore of parseargs/pgopen.c failed'
  2003. fi
  2004. echo 'End of  part 8'
  2005. echo 'File parseargs/pgopen.c is continued in part 9'
  2006. echo 9 > _shar_seq_.tmp
  2007. exit 0
  2008. exit 0 # Just in case...
  2009. -- 
  2010. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2011. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2012. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2013. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2014.