home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume26 / parseargs / patch09a next >
Text File  |  1991-11-25  |  57KB  |  1,738 lines

  1. Newsgroups: comp.sources.misc
  2. From: Brad Appleton <brad@hcx1.ssd.csd.harris.com>
  3. Subject:  v26i065:  parseargs - functions to parse command line arguments, Patch09a/2
  4. Message-ID: <csm-v26i065=parseargs.203314@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 11ba3c1bdff2402c3ff1fadceddd8d5d
  6. Date: Tue, 26 Nov 1991 02:34:56 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com>
  10. Posting-number: Volume 26, Issue 65
  11. Archive-name: parseargs/patch09a
  12. Environment: UNIX, VMS, MS-DOS, OS/2, Amiga
  13. Patch-To: parseargs: Volume 17, Issue 46-57
  14.  
  15. This is patch09 for parseargs. To apply this patch:
  16.  
  17. 1) cd to your parseargs source directory (which should be at patchlevel 8.
  18.    look at the file patchlevel.h to see which patchlevel you have)
  19.  
  20. 2) Unshar both parts to this patch to create the file PATCH09
  21.  
  22. 3) type "patch -p0 <PATCH09"
  23.  
  24.  
  25. If you dont have all the patches and/or want parseargs in its entirety I will
  26. honor your requests to send it by e-mail.
  27.  
  28. The following is a brief introduction to parseargs for those who are not
  29. already familiar with it:
  30.  
  31.  
  32.  
  33.                                   PARSEARGS
  34.  
  35.                         extracted from Eric Allman's
  36.  
  37.                             NIFTY UTILITY LIBRARY
  38.  
  39.                           Created by Eric P. Allman
  40.                              <eric@Berkeley.EDU>
  41.  
  42.                          Modified by Peter da Silva
  43.                             <peter@Ferranti.COM>
  44.  
  45.                    Modified and Rewritten by Brad Appleton
  46.                           <brad@SSD.CSD.Harris.COM>
  47.  
  48.  
  49.  Welcome to parseargs! Dont let the initial size of this package scare you.
  50.  over 75% of it is English text, and more than 50% of the source is comments.
  51.  
  52.  Parseargs is a set of functions to parse command-line arguments. Unlike
  53.  getopt and its variants, parseargs does more than just split up the
  54.  command-line into some canonical form. Parseargs will actually parse the
  55.  command-line, assigning the appropriate command-line values to the
  56.  corresponding variables, and will verify the command-line syntax (and print
  57.  a usage message if necessary). Furthermore, many features of it's parsing
  58.  behavior are configurable at run-time. Some of these features include the
  59.  following:
  60.  
  61.      o  Prompting the user for missing arguments
  62.      o  Allowing keywords (+count=4) and/or options (-c4)
  63.      o  Checking for default arguments in an environment variable
  64.      o  Ignoring bad syntax instead of terminating
  65.      o  Ignoring upper/lower case on the command-line
  66.      o  Controlling the location of non-positional parameters
  67.      o  Controlling the contents (syntax and verbosity) of usage messages
  68.      o  Having long usage messages piped through a paging program
  69.  
  70.  Parseargs also allows for options that take an optional argument, and
  71.  options that take a (possibly optional) list of one or more arguments.
  72.  In addition, parseargs may be configured at compile-time to parse
  73.  command-lines in accordance with the native command-syntax of any of the
  74.  following operating systems:
  75.  
  76.      o  Unix
  77.      o  VAX/VMS
  78.      o  OS/2
  79.      o  MS-DOS
  80.      o  AmigaDOS
  81.  
  82.  Parseargs consists of a set of C-functions to parse arguments from the
  83.  command-line, from files, from strings, from linked-lists, and from
  84.  string-vectors. Also included is a command-line interface which will parse
  85.  arguments for shell scripts (sh, csh/tcsh/itcsh, ksh, bash, zsh, and rc),
  86.  awk-scripts, and perl-scripts.
  87.  
  88.  The basic structure used by parseargs is the argument-descriptor (sometimes
  89.  called "argdesc" for brevity).  An array/string of argdescs is declared by
  90.  the user to describe the command in question.  The resulting argdesc-array
  91.  is passed to all the parseargs functions and is used to hold all information
  92.  about the command. a sample argdesc-array is shown below.
  93.  
  94.     STARTOFARGS,
  95.     { 'a', ARGVALOPT, argStr,   &area,    "AREAcode : optional area-code" },
  96.     { 'g', ARGLIST,   argStr,   &groups,  "newsGROUPS : groups to test" },
  97.     { 'r', ARGOPT,    argInt,   &count,   "REPcount : repetition factor" },
  98.     { 's', ARGOPT,    argChar,  &sepch,   "SEPchar : field separator" },
  99.     { 'x', ARGOPT,    argBool,  &xflag,   "Xflag : turn on X-mode" },
  100.     { ' ', ARGREQ,    argStr,   &name,    "name : name to use" },
  101.     { ' ', ARGLIST,   argStr,   &args,    "args : any remaining arguments" },
  102.     ENDOFARGS
  103.  
  104.  Once the above array/string is declared it is a simple matter to invoke
  105.  parseargs from C as in the following example:
  106.  
  107.     status = parseargs( argv, argdesc_array );
  108.  
  109.  or from a shell script as in the following example:
  110.  
  111.     echo "$ARGDESC_STR" | parseargs -s sh -- "$0" "$@" >tmp$$
  112.     test  $? = 0  &&  . tmp$$
  113.     /bin/rm -f tmp$$
  114.  
  115.  And before you know it, your command-line had been parsed, all variables 
  116.  have been assigned their corresponding values from the command-line, syntax
  117.  have been verified, and a usage message (if required) has been printed. 
  118.  
  119.  Under UNIX, the command-line syntax (using single character options) for the
  120.  above command would be:
  121.  
  122.     cmdname [-a [<areacode>]] [-g <newsgroups>...] [-r <repcount>]
  123.             [-s <sepchar>] [-x]  <name>  [<args>...]
  124.  
  125.  The UNIX command-line syntax using keywords (or long options) would be:
  126.  
  127.     cmdname [+area [<areacode>]] [+groups <newsgroups>...] [+rep <repcount>]
  128.             [+sep <sepchar>] [+x]  <name>  [<args>...]
  129.  
  130.  The VMS command-line syntax would be the following:
  131.  
  132.     cmdname [/AREA[=<areacode>]] [/GROUPS=<newsgroups>[,<newsgroups>...]]
  133.             [/REP=<repcount>] [/SEP=<sepchar>] [/X]  <name>
  134.             [<args>[,<args>...]]
  135.  
  136.  The MS-DOS and OS/2 command-line syntax would be the following (unless the
  137.  environment variable $SWITCHAR is '-' in which case UNIX syntax is used):
  138.  
  139.     cmdname [/a[=<areacode>]] [/g=<newsgroups>...] [/r=<repcount>]
  140.             [/s=<sepchar>] [/x]  <name>  [<args>...]
  141.  
  142.  The AmigaDOS command-line syntax would be the following:
  143.  
  144.     cmdname [AREA [<areacode>]] [GROUPS <newsgroups>...] [REP <repcount>]
  145.             [SEP <sepchar>] [X]  <name>  [<args>...]
  146.  
  147.  
  148.  Please look at the README files and manpages for more detailed information!
  149. ----
  150. #!/bin/sh
  151. # This is a shell archive (produced by shar 3.49)
  152. # To extract the files from this archive, save it to a file, remove
  153. # everything above the "!/bin/sh" line above, and type "sh file_name".
  154. #
  155. # made 11/26/1991 02:28 UTC by kent@sparky.IMD.Sterling.COM
  156. # Source directory /home/kent/mod/csm/queue/parseargs
  157. #
  158. # existing files will NOT be overwritten unless -c is specified
  159. #
  160. # This is part 1 of a multipart archive                                    
  161. # do not concatenate these parts, unpack them in order with /bin/sh        
  162. #
  163. # This shar contains:
  164. # length  mode       name
  165. # ------ ---------- ------------------------------------------
  166. #  66669 -rw-rw-r-- PATCH09
  167. #
  168. if test -r _shar_seq_.tmp; then
  169.     echo 'Must unpack archives in sequence!'
  170.     echo Please unpack part `cat _shar_seq_.tmp` next
  171.     exit 1
  172. fi
  173. # ============= PATCH09 ==============
  174. if test -f 'PATCH09' -a X"$1" != X"-c"; then
  175.     echo 'x - skipping PATCH09 (File already exists)'
  176.     rm -f _shar_wnt_.tmp
  177. else
  178. > _shar_wnt_.tmp
  179. echo 'x - extracting PATCH09 (Text)'
  180. sed 's/^X//' << 'SHAR_EOF' > 'PATCH09' &&
  181. *** README.OLD    Thu Nov 21 15:16:56 1991
  182. --- README    Thu Nov 21 11:34:11 1991
  183. ***************
  184. *** 784,797 ****
  185. X      USE_TERMCAP  --  Parseargs will use curses/terminfo/termcap when trying
  186. X                       to figure out the size of the screen.
  187. X  
  188. -     UNWRITABLE_STRING_LITERALS
  189. -                  --  This should be used only for compilers and/or machines
  190. -                      that do NOT allow the programmer to modify the contents
  191. -                      of string literals such as "hello, world". If this
  192. -                      constant is #defined, then all modified strings will be
  193. -                      duplicated (using strdup()) before they are changed.
  194. X   IBM-PC VERSION OF parseargs(3)
  195. X   ==============================
  196. X   I also added ibm_args.c for MS-DOS and OS/2.
  197. --- 784,789 ----
  198. ***************
  199. *** 892,898 ****
  200. X   - get parseargs(1) to support arrays for bash
  201. X   - verify that parseargs(1) works for rc, the Plan 9 shell
  202. X   - verify that parseargs(1) works for zsh
  203. -  - verify that parseargs(3) works on VMS systems.
  204. X   - verify that parseargs(3) works on MS-DOS and OS/2 systems.
  205. X  
  206. X  
  207. --- 884,889 ----
  208. ***************
  209. *** 921,929 ****
  210. X   retrieving the value of a symbol), and to Tom Christiansen and Raymond
  211. X   Chen for their help in getting parseargs(1) to work for perl scripts.
  212. X  
  213. !  Thanx also to Gillmer J. Derge, Marco Nijdam, Chris Johnston, & Earl Chew
  214. !  for sending me their bug reports and fixes so that I could incorporate them
  215. !  into the latest patch of parseargs.
  216. X  
  217. X   Lastly, thanks to all those who use and will continue to improve
  218. X   parseargs, all I ask is that you keep me updated of your efforts (so I
  219. --- 912,920 ----
  220. X   retrieving the value of a symbol), and to Tom Christiansen and Raymond
  221. X   Chen for their help in getting parseargs(1) to work for perl scripts.
  222. X  
  223. !  Thanx also to Gillmer J. Derge, Marco Nijdam, Chris Johnston, Earl Chew
  224. !  and Mike Levin for sending me their bug reports and fixes so that I could
  225. !  incorporate them into the latest patch of parseargs.
  226. X  
  227. X   Lastly, thanks to all those who use and will continue to improve
  228. X   parseargs, all I ask is that you keep me updated of your efforts (so I
  229. *** amiga_args.c.OLD    Thu Nov 21 15:17:08 1991
  230. --- amiga_args.c    Mon Nov 18 16:06:49 1991
  231. ***************
  232. *** 6,11 ****
  233. --- 6,15 ----
  234. X  **    vectors and to print AmigaDOS usage messages.
  235. X  **
  236. X  ** ^HISTORY:
  237. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  238. + **    - Use ProgNameLen when accessing ProgName
  239. + **    - Use get_argdesc() to access description
  240. + **
  241. X  **    01/02/91     Brad Appleton     <brad@ssd.csd.harris.com>
  242. X  **    - Added structured block comments
  243. X  **    - Added optional arguments to keywords
  244. ***************
  245. *** 456,463 ****
  246. X        /* get screen size */
  247. X     get_winsize( fileno(stderr), &max_lines, &max_cols );
  248. X  
  249. !    fprintf(fp, "Format: %s", ProgName);
  250. !    ll = strlen( ProgName ) + 8;
  251. X     margin = ll + 1;
  252. X     longest = 0;
  253. X  
  254. --- 460,467 ----
  255. X        /* get screen size */
  256. X     get_winsize( fileno(stderr), &max_lines, &max_cols );
  257. X  
  258. !    fprintf(fp, "Format: %.*s", ProgNameLen, ProgName);
  259. !    ll = ProgNameLen + 8;
  260. X     margin = ll + 1;
  261. X     longest = 0;
  262. X  
  263. ***************
  264. *** 529,534 ****
  265. --- 533,540 ----
  266. X        for ( args = argd ; args ; args = cmd_defargs(args) ) {
  267. X           for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  268. X              argName_t  buf;
  269. +             char  *desc;
  270. +             int  desclen;
  271. X  
  272. X                 /* don't display hidden arguments */
  273. X              if ( ARG_isHIDDEN(ad) )  continue;
  274. ***************
  275. *** 537,543 ****
  276. X  
  277. X              if( !(keywords++) )  fprintf(fp, "Keywords/Arguments:\n");
  278. X              (VOID) fmtarg(ad, buf);
  279. !             indent_para(fp, max_cols, 8, buf, longest+2, arg_description(ad));
  280. X           }/*for each ad */
  281. X        }/* for each argd */
  282. X     }/* for each parm-type */
  283. --- 543,550 ----
  284. X  
  285. X              if( !(keywords++) )  fprintf(fp, "Keywords/Arguments:\n");
  286. X              (VOID) fmtarg(ad, buf);
  287. !             desc = get_argdesc(arg_description(ad), &desclen);
  288. !             indent_para(fp, max_cols, 8, buf, longest+2, desc, desclen);
  289. X           }/*for each ad */
  290. X        }/* for each argd */
  291. X     }/* for each parm-type */
  292. *** arglist.c.OLD    Thu Nov 21 15:17:14 1991
  293. --- arglist.c    Mon Nov 18 16:08:00 1991
  294. ***************
  295. *** 6,11 ****
  296. --- 6,14 ----
  297. X  **    and to delete all items in an arglist.
  298. X  **
  299. X  ** ^HISTORY:
  300. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  301. + **       - Use get_argpfx() when accessing arg_sname().
  302. + **
  303. X  **    01/02/91    Brad Appleton    <brad@ssd.csd.harris.com>
  304. X  **       - Added structured comments
  305. X  **       - Changed arglists to always be kept in FIFO order (hence
  306. ***************
  307. *** 125,131 ****
  308. X     }
  309. X  
  310. X     if ( badalloc ) {
  311. !       usrerr("out of memory saving arg %s", arg_sname(ad));
  312. X        if(copyf) free(cp);
  313. X        return FALSE;
  314. X     }
  315. --- 128,135 ----
  316. X     }
  317. X  
  318. X     if ( badalloc ) {
  319. !       usrerr("out of memory saving arg %.*s", get_argpfx(arg_sname(ad)),
  320. !                                               arg_sname(ad));
  321. X        if(copyf) free(cp);
  322. X        return FALSE;
  323. X     }
  324. *** ibm_args.c.OLD    Thu Nov 21 15:19:57 1991
  325. --- ibm_args.c    Mon Nov 18 16:09:09 1991
  326. ***************
  327. *** 6,11 ****
  328. --- 6,15 ----
  329. X  **    argument vectors and to print MS-DOS and OS/2 usage messages.
  330. X  **
  331. X  ** ^HISTORY:
  332. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  333. + **    - Use ProgNameLen when accessing ProgName
  334. + **    - Use get_argdesc() to access description
  335. + **
  336. X  **    01/02/91     Brad Appleton     <brad@ssd.csd.harris.com>    Created
  337. X  ***^^**********************************************************************/
  338. X  
  339. ***************
  340. *** 699,707 ****
  341. X        /* get screen size */
  342. X     get_winsize( fileno(fp), &max_lines, &max_cols );
  343. X  
  344. !    fprintf(fp, "Usage: %s", ProgName);
  345. X  
  346. !    ll = strlen( ProgName ) + 7;
  347. X     margin = ll + 1;
  348. X     longest = 0;
  349. X  
  350. --- 703,711 ----
  351. X        /* get screen size */
  352. X     get_winsize( fileno(fp), &max_lines, &max_cols );
  353. X  
  354. !    fprintf(fp, "Usage: %.*s", ProgNameLen, ProgName);
  355. X  
  356. !    ll = ProgNameLen + 7;
  357. X     margin = ll + 1;
  358. X     longest = 0;
  359. X  
  360. ***************
  361. *** 777,782 ****
  362. --- 781,788 ----
  363. X        for ( args = argd ; args ; args = cmd_defargs(args) ) {
  364. X           for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  365. X              argName_t  buf;
  366. +             char  *desc;
  367. +             int  desclen;
  368. X  
  369. X                 /* don't display hidden arguments */
  370. X              if ( ARG_isHIDDEN(ad) )  continue;
  371. ***************
  372. *** 785,791 ****
  373. X  
  374. X              if ( !options++ )   fprintf(fp, "Options/Arguments:\n");
  375. X              fmtarg(ad, buf, usage_flags);
  376. !             indent_para( fp, max_cols, 8, buf, longest+2, arg_description(ad) );
  377. X           }/*for each ad */
  378. X        }/* for each argd */
  379. X     }/* for each parm-type */
  380. --- 791,798 ----
  381. X  
  382. X              if ( !options++ )   fprintf(fp, "Options/Arguments:\n");
  383. X              fmtarg(ad, buf, usage_flags);
  384. !             desc = get_argdesc(arg_description(ad), &desclen);
  385. !             indent_para( fp, max_cols, 8, buf, longest+2, desc, desclen );
  386. X           }/*for each ad */
  387. X        }/* for each argd */
  388. X     }/* for each parm-type */
  389. *** parseargs.c.OLD    Thu Nov 21 15:20:11 1991
  390. --- parseargs.c    Mon Nov 18 16:09:34 1991
  391. ***************
  392. *** 80,85 ****
  393. --- 80,88 ----
  394. X  **    - fixed printing of single quotes for perl scripts
  395. X  **    - added -C option for case-insensitivity
  396. X  **    - added hidden -# option to print current version and patchlevel
  397. + **
  398. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  399. + **    - Use ProgNameLen when accessing ProgName
  400. X  ***^^**********************************************************************/
  401. X  
  402. X  #include <stdio.h>
  403. ***************
  404. *** 2215,2220 ****
  405. --- 2218,2224 ----
  406. X     if ( !UsrArgc )   UsrArgd = ARGDESCNULL;
  407. X  
  408. X     ProgName = UsrName;      /* set up program name */
  409. +    ProgNameLen = strlen(ProgName);
  410. X  
  411. X     if ( PrUsage ) {   /* just print usage and exit */
  412. X        usage( UsrArgd );
  413. *** parseargs.h.OLD    Thu Nov 21 15:20:22 1991
  414. --- parseargs.h    Wed Nov 20 11:05:05 1991
  415. ***************
  416. *** 23,28 ****
  417. --- 23,39 ----
  418. X  **
  419. X  ** ^HISTORY:
  420. X  **    12/03/90    Brad Appleton    <brad@ssd.csd.harris.com>
  421. + **    - added ps_NOTCMDLINE state-flag for vms_style
  422. + **
  423. + **    08/27/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  424. + **    - Add ProgNameLen
  425. + **    - Promote ps_flags_t to unsigned short
  426. + **    - Add new states ps_USERNAME, ps_USERPURPOSE, ps_FREENAME,
  427. + **      ps_FREEPURPOSE
  428. + **    - arg_sdesc() now only returns a raw string --- use get_argdesc()
  429. + **      to extract the description from it
  430. + **
  431. + **    12/03/90    Brad Appleton    <brad@ssd.csd.harris.com>
  432. X  **    - Added all the #ifdef stuff
  433. X  **    - Added public and private macros for getting and setting
  434. X  **      the attributes of an argdesc-array and an argdesc
  435. ***************
  436. *** 282,291 ****
  437. X  #define  arg_sname(ad)        ((ad) -> ad_prompt)
  438. X  /*    -- return the string name of an argument.
  439. X  */
  440. ! #define  arg_sdesc(ad)        ( arg_sname(ad) + strlen(arg_sname(ad)) + 1 )
  441. X  /*    -- return the description of an argument. If a description was supplied,
  442. ! **       the ARGDESCRIBED flag will be set and the description will immediately
  443. ! **       follow the NULL byte of the string name.
  444. X  */
  445. X  #define  ARG_isDESCRIBED(ad)  BTEST( arg_flags(ad), ARGDESCRIBED )
  446. X  /*    -- Evaluates to TRUE only if an argument description was provided.
  447. --- 293,302 ----
  448. X  #define  arg_sname(ad)        ((ad) -> ad_prompt)
  449. X  /*    -- return the string name of an argument.
  450. X  */
  451. ! #define  arg_sdesc(ad)        ( arg_sname(ad) )
  452. X  /*    -- return the description of an argument. If a description was supplied,
  453. ! **       the ARGDESCRIBED flag will be set and the description is available
  454. ! **       by calling get_argdesc().
  455. X  */
  456. X  #define  ARG_isDESCRIBED(ad)  BTEST( arg_flags(ad), ARGDESCRIBED )
  457. X  /*    -- Evaluates to TRUE only if an argument description was provided.
  458. ***************
  459. *** 836,843 ****
  460. X  # define  ps_NOFLAGS      0x02  /* opt/kwd parsing in effect? */
  461. X  # define  ps_NOCMDENV     0x04  /* <CMD>_ARGS environment-variable parsed? */
  462. X  # define  ps_NOPARSECNTL  0x08  /* PARSECNTL environment-variable parsed? */
  463. X  
  464. ! typedef unsigned char   ps_flags_t;
  465. X  
  466. X  
  467. X     /*
  468. --- 847,861 ----
  469. X  # define  ps_NOFLAGS      0x02  /* opt/kwd parsing in effect? */
  470. X  # define  ps_NOCMDENV     0x04  /* <CMD>_ARGS environment-variable parsed? */
  471. X  # define  ps_NOPARSECNTL  0x08  /* PARSECNTL environment-variable parsed? */
  472. + # define  ps_USERNAME     0x10    /* user supplied name string */
  473. + # define  ps_FREENAME     0x10    /* free name string space */
  474. + # define  ps_USERPURPOSE  0x20    /* user supplied purpose string */
  475. + # define  ps_FREEPURPOSE  0x20    /* free purpose string space */
  476. + # ifdef vms_style
  477. + #  define  ps_NOTCMDLINE  0x40  /* argv-array is NOT from the command-line */
  478. + # endif
  479. X  
  480. ! typedef unsigned short   ps_flags_t;
  481. X  
  482. X  
  483. X     /*
  484. ***************
  485. *** 1012,1017 ****
  486. --- 1030,1036 ----
  487. X     EXTERN VOID  usage       ARGS(( const ARGDESC * ));
  488. X     EXTERN VOID  init_args   ARGS(( ARGDESC * ));
  489. X     EXTERN CONST char *ProgName;
  490. +    EXTERN int   ProgNameLen;
  491. X  #endif  /* PARSEARGS_NEXTERNS */
  492. X  
  493. X  #endif  /* PARSEARGS_H */
  494. *** patchlevel.h.OLD    Thu Nov 21 15:20:36 1991
  495. --- patchlevel.h    Thu Nov 21 11:32:17 1991
  496. ***************
  497. *** 2,7 ****
  498. --- 2,38 ----
  499. X  ** ^FILE: patchlevel.h - current patchlevel for parseargs
  500. X  **
  501. X  ** ^HISTORY:
  502. + **    08/27/91    Brad Appleton    <brad@ssd.csd.harris.com>
  503. + **    08/27/91    Earl Chew    <cechew@bruce.cs.monash.edu.au>
  504. + **    Patch09
  505. + **    - Added proper support for unwritable strings
  506. + **    - strfuncs.c/strsplit():
  507. + **      Leading, and in particular, trailing space trimming may spin off
  508. + **      the end of the token string. This occurs when the string is empty,
  509. + **      or when it has trailing space.
  510. + **      Out of memory error doesn't call syserr() like the rest of the
  511. + **      routines do.
  512. + **    - xparse.c/parsecntl():
  513. + **      Documentation says that the fourth parameter for pc_ARGFLAGS and
  514. + **      pc_PARSEARGS should be either argMask_t (promoted to int) in the
  515. + **      case of writes, or argMask_t * in the case of reads. The code is 
  516. + **      at odds with the documentation and requires (int *) on reads.
  517. + **      Also, should check for NULL cmd-name before passing it to strdup().
  518. + **    - vms_args.c/is_cmdline():
  519. + **      Mike Level pointed out to me that if lib$get_foreing returns a
  520. + **      zero-length string then the proper actions are not taken. This
  521. + **      has been fixed.
  522. + **    - vms_args.c, parseargs.h, xparse.c
  523. + **      For vms_style I added a new parse-state called ps_NOTCMDLINE.
  524. + **      When this flag is SET, then vms_parse() knows for a fact that
  525. + **      the given argv[] array is NOT from the cmdline so it doesnt even
  526. + **      need to call is_cmdline(). SO Now I just have the proper routines
  527. + **      in xparse.c set this flag before calling vms_parse() (and unset
  528. + **      the flag when they are done).
  529. + **    - vms_args.c/vms_parse():
  530. + **      ARGVALGIVEN was set instead of ARGGIVEN (this was wrong).
  531. + **
  532. + **
  533. X  **    08/15/91    Brad Appleton    <brad@ssd.csd.harris.com>
  534. X  **    Patch08
  535. X  **    - fixed some typos in the comments (SIDE-EFFECTS was misspelled
  536. ***************
  537. *** 101,107 ****
  538. X  
  539. X  #define  VERSION     2
  540. X  #define  REVISION    0
  541. ! #define  PATCHLEVEL  8
  542. X  
  543. X  #ifdef __STDC__
  544. X     static const char
  545. --- 132,138 ----
  546. X  
  547. X  #define  VERSION     2
  548. X  #define  REVISION    0
  549. ! #define  PATCHLEVEL  9
  550. X  
  551. X  #ifdef __STDC__
  552. X     static const char
  553. ***************
  554. *** 108,111 ****
  555. X  #else
  556. X     static char
  557. X  #endif
  558. !    _Ident[] = "@(#)parseargs  2.0  patchlevel 8";
  559. --- 139,142 ----
  560. X  #else
  561. X     static char
  562. X  #endif
  563. !    _Ident[] = "@(#)parseargs  2.0  patchlevel 9";
  564. *** stest.c.OLD    Thu Nov 21 15:20:49 1991
  565. --- stest.c    Wed Nov 20 15:14:47 1991
  566. ***************
  567. *** 246,252 ****
  568. X     static void print_args( const ARGDESC *argd )
  569. X  #endif
  570. X  {
  571. !    int  i, flags;
  572. X     ArgList *ls;
  573. X  
  574. X     printf( "Name = \"%s\", DirName = \"%s\", RepCount = %d,\n",
  575. --- 246,253 ----
  576. X     static void print_args( const ARGDESC *argd )
  577. X  #endif
  578. X  {
  579. !    int  i;
  580. !    argMask_t flags;
  581. X     ArgList *ls;
  582. X  
  583. X     printf( "Name = \"%s\", DirName = \"%s\", RepCount = %d,\n",
  584. *** strfuncs.c.OLD    Thu Nov 21 15:20:55 1991
  585. --- strfuncs.c    Wed Nov 20 10:43:54 1991
  586. ***************
  587. *** 23,28 ****
  588. --- 23,30 ----
  589. X  **       strtrim() -- trim leading and trailing characters in a string
  590. X  **       strsplit() -- split a string up into a vector of tokens
  591. X  **       strjoin() -- join a vector of tokens into a single string
  592. + **       get_argpfx() -- return the length of the first part of the string
  593. + **       get_argdesc() -- return the description (second part) of the string
  594. X  **       get_argname() -- return the aname (argument-name) of an argument
  595. X  **       get_kwdname() -- return the sname (keyword-name) of an argument
  596. X  **       match() -- match two keywords (case insensitive) upto a unique prefix
  597. ***************
  598. *** 30,35 ****
  599. --- 32,47 ----
  600. X  **       indent_para() -- print an indented hanging paragraph
  601. X  **
  602. X  ** ^HISTORY:
  603. + **    08/27/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  604. + **    - add extra length argument to indent_para().
  605. + **    - add FORCE_KWDCASE() macro
  606. + **    - add non-writable strings support to get_argname() and
  607. + **      get_kwdname()
  608. + **    08/27/91    Earl Chew    <cechew@bruce.cs.monash.edu.au>
  609. + **    - add get_argpfx() and get_argdesc() for non-writable strings
  610. + **      support
  611. + **    - allow zero length string for strsplit()
  612. + **
  613. X  **    01/02/91     Brad Appleton     <brad@ssd.csd.harris.com>     Created
  614. X  **    - changed from file misc.c to this name and added all of the strxxx
  615. X  **      functions (plus got rid of some unused functions).
  616. ***************
  617. *** 43,48 ****
  618. --- 55,62 ----
  619. X  #include <ctype.h>
  620. X  #include <useful.h>
  621. X  
  622. + #include "strfuncs.h"
  623. X  EXTERN  VOID   syserr  ARGS((const char *, ...));
  624. X  
  625. X  static CONST char WhiteSpace[] = " \t\n\r\v\f";
  626. ***************
  627. *** 49,58 ****
  628. X  
  629. X  #define c_ARG_SEP '='
  630. X  #if ( defined(unix_style)  ||  defined(ibm_style) )
  631. ! # define  TO_KWDCASE(c)  TOLOWER(c)
  632. X  # define  KWDCASECOPY(dest,src)  strlcpy(dest,src)
  633. X  #else
  634. ! # define  TO_KWDCASE(c)  TOUPPER(c)
  635. X  # define  KWDCASECOPY(dest,src)  strucpy(dest,src)
  636. X  #endif
  637. X  
  638. --- 63,74 ----
  639. X  
  640. X  #define c_ARG_SEP '='
  641. X  #if ( defined(unix_style)  ||  defined(ibm_style) )
  642. ! # define  FORCE_KWDCASE(s)       strlwr(s)
  643. ! # define  TO_KWDCASE(c)          TOLOWER(c)
  644. X  # define  KWDCASECOPY(dest,src)  strlcpy(dest,src)
  645. X  #else
  646. ! # define  FORCE_KWDCASE(s)       strupr(s)
  647. ! # define  TO_KWDCASE(c)          TOUPPER(c)
  648. X  # define  KWDCASECOPY(dest,src)  strucpy(dest,src)
  649. X  #endif
  650. X  
  651. ***************
  652. *** 308,314 ****
  653. X    unsigned len = strlen(str) + 1;
  654. X    char *p = malloc( len * sizeof(char) );
  655. X  
  656. !   if ( !p )  syserr( "Fatal Error -- out of memory" );
  657. X    strcpy(p, str);
  658. X  
  659. X    return p;
  660. --- 324,330 ----
  661. X    unsigned len = strlen(str) + 1;
  662. X    char *p = malloc( len * sizeof(char) );
  663. X  
  664. !   if ( !p )  syserr( "malloc failed in strdup()" );
  665. X    strcpy(p, str);
  666. X  
  667. X    return p;
  668. ***************
  669. *** 582,588 ****
  670. X  **
  671. X  ** ^REQUIREMENTS:
  672. X  **    vec must be non-NULL (it must be a valid address).
  673. ! **    token_str should be non-null and non-empty
  674. X  **
  675. X  ** ^SIDE-EFFECTS:
  676. X  **    All leading and trailing characters from <separators> are removed
  677. --- 598,604 ----
  678. X  **
  679. X  ** ^REQUIREMENTS:
  680. X  **    vec must be non-NULL (it must be a valid address).
  681. ! **    token_str should be non-null
  682. X  **
  683. X  ** ^SIDE-EFFECTS:
  684. X  **    All leading and trailing characters from <separators> are removed
  685. ***************
  686. *** 605,610 ****
  687. --- 621,627 ----
  688. X  **         - advance token_str to point at the next character past the
  689. X  **           rightmost NUL-byte (which should be the start of the next token).
  690. X  **      end-for
  691. + **    - vector[numtokens] = NUL
  692. X  **    - return the number of tokens parsed.
  693. X  ***^^**********************************************************************/
  694. X  #ifdef __ANSI_C__
  695. ***************
  696. *** 614,620 ****
  697. X     register   char c, *pread, *pwrite;
  698. X     int   i, count = 0;
  699. X  
  700. !    if ( !token_str )    return   0;
  701. X        /* if delim-string is NULL, whitespace is used */
  702. X     if ( !separators )   separators = WhiteSpace;
  703. X  
  704. --- 631,637 ----
  705. X     register   char c, *pread, *pwrite;
  706. X     int   i, count = 0;
  707. X  
  708. !    if ( !token_str )    token_str = "";
  709. X        /* if delim-string is NULL, whitespace is used */
  710. X     if ( !separators )   separators = WhiteSpace;
  711. X  
  712. ***************
  713. *** 621,626 ****
  714. --- 638,644 ----
  715. X        /* trim leading separators */
  716. X     pread = token_str;
  717. X     while ( strchr(separators, *pread) )   ++pread;
  718. +    if ( ! *pread )  return  0;
  719. X     token_str = pwrite = pread;
  720. X  
  721. X        /*
  722. ***************
  723. *** 627,653 ****
  724. X        ** make first pass through string, counting # of tokens and
  725. X        ** separating all tokens by a single '\0'
  726. X        */
  727. !    while ( c = *pread++ ) {
  728. X        if ( !strchr(separators, c) )   {
  729. !          *pwrite++ = c;
  730. !       }
  731. !       else {
  732. !          *pwrite++ = '\0';   /* null terminate this token */
  733. !          ++count;                /* update token count */
  734. !          while ( strchr(separators, *pread) )   ++pread;
  735. !       }
  736. !    }/*while*/
  737. !    if ( *(pwrite - 1) )  {
  738. !       ++count;         /* dont forget last token */
  739. !       *pwrite = '\0';   /* null-terminate */
  740. !    }
  741. X  
  742. X        /* allocate space for the caller's vector (remember NULL at the end) */
  743. X     (*vec) = (char **)malloc( (1 + count) * sizeof( char * ) );
  744. !    if ( !*vec ) {
  745. !       fprintf( stderr, "out of memory in strsplit() - aborting\n" );
  746. !       exit( -1 );
  747. !    }
  748. X  
  749. X        /* now go thru token-string again assigning pointers from vector */
  750. X     pread = token_str;
  751. --- 645,669 ----
  752. X        ** make first pass through string, counting # of tokens and
  753. X        ** separating all tokens by a single '\0'
  754. X        */
  755. !    for ( c = *pread++ ; c ; ) {
  756. X        if ( !strchr(separators, c) )   {
  757. !          do {
  758. !             *pwrite++ = c;
  759. !          } while ( (c = *pread++) && !strchr(separators, c) );
  760. !          *pwrite++ = '\0';
  761. !          ++count;
  762. !          do {
  763. !             *pwrite++ = c;
  764. !          } while ( (c = *pread++) && !strchr(separators, c) );
  765. !         *pwrite++ = '\0';
  766. !         ++count;
  767. !       }/*if*/
  768. !       while ( c && strchr(separators, c) )   c = *pread++;
  769. !    }/*for*/
  770. X  
  771. X        /* allocate space for the caller's vector (remember NULL at the end) */
  772. X     (*vec) = (char **)malloc( (1 + count) * sizeof( char * ) );
  773. !    if ( !*vec )  syserr( "malloc failed in strsplit()" );
  774. X  
  775. X        /* now go thru token-string again assigning pointers from vector */
  776. X     pread = token_str;
  777. ***************
  778. *** 748,753 ****
  779. --- 764,912 ----
  780. X  
  781. X  
  782. X  /***************************************************************************
  783. + ** ^FUNCTION: get_argpfx - get the prefix portion of a string
  784. + **
  785. + ** ^SYNOPSIS:
  786. + */
  787. + #ifndef __ANSI_C__
  788. +    int get_argpfx( str )
  789. + /*
  790. + ** ^PARAMETERS:
  791. + */
  792. +    char *str;
  793. + /*    -- the string to parse for a description
  794. + */
  795. + #endif  /* !__ANSI_C__ */
  796. + /* ^DESCRIPTION:
  797. + **    Get_argdesc returns the length of the first portion of the string.
  798. + **
  799. + **    Two "portions" must be either separated by whitespace or the second
  800. + **    portion may be within "(),{},[], or <>" delimiters. The second
  801. + **    portion is assumed to begin with the first alphabetic following
  802. + **    separator.
  803. + **
  804. + ** ^REQUIREMENTS:
  805. + **    str should be non-null and non-empty
  806. + **
  807. + ** ^SIDE-EFFECTS:
  808. + **    None.
  809. + **
  810. + ** ^RETURN-VALUE:
  811. + **    The length of the first portion.
  812. + **
  813. + ** ^ALGORITHM:
  814. + **    - locate the end of the first portion by scanning for whitespace or
  815. + **      balanced delimiters.
  816. + ***^^**********************************************************************/
  817. + #ifdef __ANSI_C__
  818. +    int get_argpfx( const char *str )
  819. + #endif
  820. + {
  821. +    register char  *description;
  822. +    static CONST char  whitespace[]  = " \t\n\r\f\v";
  823. +    static CONST char  beg_portion[] = "(<{[";
  824. +    description = strpbrk( str, whitespace );
  825. +    if ( !description ) {
  826. +        description = strpbrk( str, beg_portion );
  827. +    }
  828. +    return description ? description - str : strlen(str);
  829. + }
  830. + /***************************************************************************
  831. + ** ^FUNCTION: get_argdesc - get the description portion of a string
  832. + **
  833. + ** ^SYNOPSIS:
  834. + */
  835. + #ifndef __ANSI_C__
  836. +    char *get_argdesc( str, len )
  837. + /*
  838. + ** ^PARAMETERS:
  839. + */
  840. +    char *str;
  841. + /*    -- the string to parse for a description
  842. + */
  843. +    int *len;
  844. + /*    -- the pointer to the length
  845. + */
  846. + #endif  /* !__ANSI_C__ */
  847. + /* ^DESCRIPTION:
  848. + **    Get_argdesc returns a pointer to the second portion of the string
  849. + **    and also indicates how long it is.
  850. + **
  851. + **    Two "portions" must be either separated by whitespace or the second
  852. + **    portion may be within "(),{},[], or <>" delimiters. The second
  853. + **    portion is assumed to begin with the first alphabetic following
  854. + **    separator.
  855. + **
  856. + ** ^REQUIREMENTS:
  857. + **    str should be non-null and non-empty
  858. + **
  859. + ** ^SIDE-EFFECTS:
  860. + **    The length of the description is written to *len.
  861. + **
  862. + ** ^RETURN-VALUE:
  863. + **    Address of the description (or NULL if the string has no description).
  864. + **
  865. + ** ^ALGORITHM:
  866. + **    - locate the end of the first portion by scanning for whitespace or
  867. + **      balanced delimiters.
  868. + **    - locate the beginning of the second portion by scanning for the first
  869. + **      alpha-numeric following the end of the first portion.
  870. + **    - return the address of the description.
  871. + ***^^**********************************************************************/
  872. + #ifdef __ANSI_C__
  873. +    char *get_argdesc( const char *str, int *len )
  874. + #endif
  875. + {
  876. +    register char  *description = CHARNULL;
  877. +    BOOL  is_end = FALSE, is_balanced = FALSE;
  878. +    char  *p;
  879. +    static CONST char  whitespace[]  = " \t\n\r\f\v";
  880. +    static CONST char  beg_portion[] = "(<{[";
  881. +    static CONST char  end_portion[] = ")>}]";
  882. +    description = strpbrk( str, whitespace );
  883. +    if ( description ) {
  884. +       is_end = TRUE;
  885. +       while ( isspace(*++description) )  continue;  /* trim leading ' ' */
  886. +       if ( strchr(beg_portion, *description) ) {
  887. +             is_balanced = TRUE;
  888. +             ++description;
  889. +       }
  890. +    }
  891. +    else {
  892. +        description = strpbrk( str, beg_portion );
  893. +        if ( description ) {  /* skip leading '(' */
  894. +           is_end = is_balanced = TRUE;
  895. +           ++description;
  896. +        }
  897. +    }
  898. +    if ( !description ) {
  899. +       *len = 0;
  900. +    }
  901. +    else {
  902. +       if ( is_balanced ) {  /* remove trailing ')' */
  903. +          p = description + (strlen( description ) - 1);
  904. +          if ( !strchr(end_portion, *p) )  ++p;
  905. +          *len = p - description;
  906. +       }
  907. +       else {
  908. +          while ( !isalnum(*description) )  ++description;
  909. +          *len = strlen( description );
  910. +       }
  911. +    }
  912. +    return  description;
  913. + }
  914. + /***************************************************************************
  915. X  ** ^FUNCTION: get_argname - return the aname (argument-name) of an argument
  916. X  **
  917. X  ** ^SYNOPSIS:
  918. ***************
  919. *** 787,803 ****
  920. X     char *get_argname( const char *s, char *buf )
  921. X  #endif
  922. X  {
  923. !    register CONST char *p1 = s, *p2;
  924. X  
  925. X        /* see if sname and aname are separated by c_ARG_SEP
  926. X        ** <buf> must be large enough to hold the result!
  927. X        */
  928. !    p2 = strchr( p1, c_ARG_SEP );
  929. !    if ( p2 ) {
  930. !       strlcpy( buf, ++p2 );
  931. X     }
  932. X     else {
  933. !       strlcpy(buf, s);
  934. X     }
  935. X     return   buf;
  936. X  }
  937. --- 946,969 ----
  938. X     char *get_argname( const char *s, char *buf )
  939. X  #endif
  940. X  {
  941. !    register CONST char *p2;
  942. !    int len;
  943. X  
  944. X        /* see if sname and aname are separated by c_ARG_SEP
  945. X        ** <buf> must be large enough to hold the result!
  946. X        */
  947. !    len = get_argpfx(s);
  948. !    p2 = strchr( s, c_ARG_SEP );
  949. !    if ( p2 && p2 < &s[len]) {
  950. !       ++p2;
  951. !       strncpy( buf, p2, len-(p2-s) );
  952. !       buf[len-(p2-s)] = 0;
  953. !       strlwr(buf);
  954. X     }
  955. X     else {
  956. !       strncpy( buf, s, len );
  957. !       buf[len] = 0;
  958. !       strlwr(buf);
  959. X     }
  960. X     return   buf;
  961. X  }
  962. ***************
  963. *** 849,871 ****
  964. X  #endif
  965. X  {
  966. X     register char *p1 = (char *)s, *p2, ch;
  967. X     BOOL caps = FALSE;
  968. X  
  969. X     if ( !p1 )  return  CHARNULL;
  970. X  
  971. X        /* see if sname and aname are separated by c_ARG_SEP */
  972. X     p2 = strchr( p1, c_ARG_SEP );
  973. !    if ( p2 ) {
  974. !       ch = *p2;
  975. !       *p2 = '\0';
  976. !       KWDCASECOPY( buf, p1 );
  977. !       *p2 = ch;
  978. X        return  buf;
  979. X     }
  980. X  
  981. X        /* copy string into buffer and convert it to desired case */
  982. X        /* <buf> must be large enough to hold the result! */
  983. !    for ( p2 = buf; *p1 ; p1++ ) {
  984. X        if ( isupper(*p1) ) {
  985. X           if ( !caps ) {
  986. X              caps = TRUE;
  987. --- 1015,1038 ----
  988. X  #endif
  989. X  {
  990. X     register char *p1 = (char *)s, *p2, ch;
  991. +    int len;
  992. X     BOOL caps = FALSE;
  993. X  
  994. X     if ( !p1 )  return  CHARNULL;
  995. X  
  996. X        /* see if sname and aname are separated by c_ARG_SEP */
  997. +    len = get_argpfx( p1 );
  998. X     p2 = strchr( p1, c_ARG_SEP );
  999. !    if ( p2 && p2 < &p1[len]) {
  1000. !       strncpy( buf, p1, p2-p1);
  1001. !       buf[p2-p1] = 0;
  1002. !       FORCE_KWDCASE(buf);
  1003. X        return  buf;
  1004. X     }
  1005. X  
  1006. X        /* copy string into buffer and convert it to desired case */
  1007. X        /* <buf> must be large enough to hold the result! */
  1008. !    for ( p2 = buf; *p1 && len != 0; p1++, len-- ) {
  1009. X        if ( isupper(*p1) ) {
  1010. X           if ( !caps ) {
  1011. X              caps = TRUE;
  1012. ***************
  1013. *** 1145,1151 ****
  1014. X  ** ^SYNOPSIS:
  1015. X  */
  1016. X  #ifndef __ANSI_C__
  1017. !    VOID indent_para(fp, maxcols, margin, title, indent, text)
  1018. X  /*
  1019. X  ** ^PARAMETERS:
  1020. X  */
  1021. --- 1312,1318 ----
  1022. X  ** ^SYNOPSIS:
  1023. X  */
  1024. X  #ifndef __ANSI_C__
  1025. !    VOID indent_para(fp, maxcols, margin, title, indent, text, textlen)
  1026. X  /*
  1027. X  ** ^PARAMETERS:
  1028. X  */
  1029. ***************
  1030. *** 1167,1172 ****
  1031. --- 1334,1342 ----
  1032. X     char *text;
  1033. X  /*    -- the body of the paragraph
  1034. X  */
  1035. +    int textlen;
  1036. + /*    -- the length of the body of the paragraph
  1037. + */
  1038. X  #endif  /* !__ANSI_C__ */
  1039. X  
  1040. X  /* ^DESCRIPTION:
  1041. ***************
  1042. *** 1193,1204 ****
  1043. X  ***^^**********************************************************************/
  1044. X  #ifdef __ANSI_C__
  1045. X     void indent_para( FILE *fp, int maxcols, int margin,
  1046. !                      const char *title, int indent, const char *text )
  1047. X  #endif
  1048. X  {
  1049. X     register int idx = 0;
  1050. X     BOOL first_line = TRUE;
  1051. -    int  text_len = strlen(text);
  1052. X     char ch;
  1053. X  
  1054. X     /* print the title */
  1055. --- 1363,1374 ----
  1056. X  ***^^**********************************************************************/
  1057. X  #ifdef __ANSI_C__
  1058. X     void indent_para( FILE *fp, int maxcols, int margin,
  1059. !                      const char *title, int indent, const char *text,
  1060. !                      int textlen )
  1061. X  #endif
  1062. X  {
  1063. X     register int idx = 0;
  1064. X     BOOL first_line = TRUE;
  1065. X     char ch;
  1066. X  
  1067. X     /* print the title */
  1068. ***************
  1069. *** 1206,1241 ****
  1070. X  
  1071. X     idx = maxcols - margin - indent;
  1072. X  
  1073. !    if ( text_len <= idx )
  1074. !       fprintf(fp, "%s\n", text);
  1075. X     else
  1076. X        do {
  1077. X                 /* backup to end of previous word */
  1078. X           while (idx  &&  !isspace(text[idx]))  --idx;
  1079. X           while (idx  &&  isspace(text[idx]))   --idx;
  1080. X  
  1081. X              /* print leading whitespace */
  1082. X           if (!first_line)
  1083. X              fprintf(fp, "%*s%-*s", margin, "", indent, "");
  1084. X  
  1085. !          ch = text[ ++idx ];
  1086. !          *((char *)text + idx) = '\0';
  1087. !          fprintf(fp, "%s\n", text);
  1088. !          *((char *)text + idx) = ch;
  1089. X           first_line = FALSE;
  1090. X           text = &(text[idx+1]);
  1091. !          text_len -= (idx+1);
  1092. X  
  1093. X           while (isspace(*text)) {  /* goto next word */
  1094. X              ++text;
  1095. !             --text_len;
  1096. X           }
  1097. X  
  1098. X           idx = maxcols - margin - indent;
  1099. X  
  1100. !          if ( text_len <= idx )  /* print-last line */
  1101. !             fprintf(fp, "%*s%-*s%s\n", margin, "", indent, "", text);
  1102. !       } while ( text_len > idx );
  1103. X  }
  1104. X  
  1105. X  
  1106. --- 1376,1410 ----
  1107. X  
  1108. X     idx = maxcols - margin - indent;
  1109. X  
  1110. !    if ( textlen <= idx )
  1111. !       fprintf(fp, "%.*s\n", textlen, text);
  1112. X     else
  1113. X        do {
  1114. X                 /* backup to end of previous word */
  1115. X           while (idx  &&  !isspace(text[idx]))  --idx;
  1116. X           while (idx  &&  isspace(text[idx]))   --idx;
  1117. +          idx++;
  1118. X  
  1119. X              /* print leading whitespace */
  1120. X           if (!first_line)
  1121. X              fprintf(fp, "%*s%-*s", margin, "", indent, "");
  1122. X  
  1123. !          fprintf(fp, "%.*s\n", idx, text);
  1124. X           first_line = FALSE;
  1125. X           text = &(text[idx+1]);
  1126. !          textlen -= (idx+1);
  1127. X  
  1128. X           while (isspace(*text)) {  /* goto next word */
  1129. X              ++text;
  1130. !             --textlen;
  1131. X           }
  1132. X  
  1133. X           idx = maxcols - margin - indent;
  1134. X  
  1135. !          if ( textlen <= idx )  /* print-last line */
  1136. !             fprintf(fp, "%*s%-*s%.*s\n", margin, "", indent, "", textlen, text);
  1137. !       } while ( textlen > idx );
  1138. X  }
  1139. X  
  1140. X  
  1141. *** strfuncs.h.OLD    Thu Nov 21 15:21:03 1991
  1142. --- strfuncs.h    Mon Nov 18 16:19:25 1991
  1143. ***************
  1144. *** 5,10 ****
  1145. --- 5,14 ----
  1146. X  **    External declarations for the functions implemented in strfuncs.c
  1147. X  **
  1148. X  ** ^HISTORY:
  1149. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  1150. + **    - Add extra argument to indent_para()
  1151. + **    - Add new prototypes for get_argdesc() and get_argpfx()
  1152. + **
  1153. X  **    01/07/91    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1154. X  ***^^**********************************************************************/
  1155. X  
  1156. ***************
  1157. *** 35,43 ****
  1158. X  
  1159. X  EXTERN  char  *get_argname  ARGS(( const char *, char * ));
  1160. X  EXTERN  char  *get_kwdname  ARGS(( const char *, char * ));
  1161. X  EXTERN  int    match        ARGS(( const char *, const char * ));
  1162. X  EXTERN  char  *basename     ARGS(( char * ));
  1163. X  EXTERN  VOID   indent_para  ARGS(( FILE *, int, int,
  1164. !                                    const char *, int, const char * ));
  1165. X  
  1166. X  #endif
  1167. --- 39,49 ----
  1168. X  
  1169. X  EXTERN  char  *get_argname  ARGS(( const char *, char * ));
  1170. X  EXTERN  char  *get_kwdname  ARGS(( const char *, char * ));
  1171. + EXTERN  char  *get_argdesc  ARGS(( const char *, int * ));
  1172. + EXTERN  int    get_argpfx   ARGS(( const char * ));
  1173. X  EXTERN  int    match        ARGS(( const char *, const char * ));
  1174. X  EXTERN  char  *basename     ARGS(( char * ));
  1175. X  EXTERN  VOID   indent_para  ARGS(( FILE *, int, int,
  1176. !                                    const char *, int, const char *, int ));
  1177. X  
  1178. X  #endif
  1179. *** syserr.c.OLD    Thu Nov 21 15:21:10 1991
  1180. --- syserr.c    Mon Nov 18 16:19:57 1991
  1181. ***************
  1182. *** 10,15 ****
  1183. --- 10,18 ----
  1184. X  **       eprintf() --  print to stderr and return
  1185. X  **
  1186. X  ** ^HISTORY:
  1187. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  1188. + **    - Use ProgNameLen when accessing ProgName
  1189. + **
  1190. X  **    01/02/91    Brad Appleton    <brad@ssd.csd.harris.com>
  1191. X  **       - Changed to use varargs/stdargs
  1192. X  **       - Added structured comment blocks
  1193. ***************
  1194. *** 28,33 ****
  1195. --- 31,37 ----
  1196. X  VERSIONID("$Header: syserr.c,v 2.0 89/12/24 00:56:31 eric Exp $");
  1197. X  
  1198. X  extern  char *ProgName;
  1199. + extern  int ProgNameLen;
  1200. X  EXTERN  int   vfprintf  ARGS((FILE *, const char *, va_list));
  1201. X  
  1202. X  
  1203. ***************
  1204. *** 75,81 ****
  1205. X     int save_err;
  1206. X  
  1207. X     save_err = errno;
  1208. !    if (ProgName  &&  *ProgName)  fprintf(stderr, "%s: ", ProgName);
  1209. X  
  1210. X     (VOID) vfprintf(stderr, format, ap);
  1211. X  
  1212. --- 79,86 ----
  1213. X     int save_err;
  1214. X  
  1215. X     save_err = errno;
  1216. !    if (ProgName  &&  *ProgName)
  1217. !       fprintf(stderr, "%.*s: ", ProgNameLen, ProgName);
  1218. X  
  1219. X     (VOID) vfprintf(stderr, format, ap);
  1220. X  
  1221. *** unix_args.c.OLD    Thu Nov 21 15:21:49 1991
  1222. --- unix_args.c    Mon Nov 18 16:20:49 1991
  1223. ***************
  1224. *** 6,11 ****
  1225. --- 6,15 ----
  1226. X  **    vectors and to print Unix usage messages.
  1227. X  **
  1228. X  ** ^HISTORY:
  1229. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  1230. + **    - Use ProgNameLen when accessing ProgName
  1231. + **    - Use get_argdesc() to access description
  1232. + **
  1233. X  **    01/02/91     Brad Appleton     <brad@ssd.csd.harris.com>
  1234. X  **    - Added structured block comments
  1235. X  **    - Added optional arguments to keywords and options
  1236. ***************
  1237. *** 615,623 ****
  1238. X        /* get screen size */
  1239. X     get_winsize( fileno(fp), &max_lines, &max_cols );
  1240. X  
  1241. !    fprintf(fp, "Usage: %s", ProgName);
  1242. X  
  1243. !    ll = strlen( ProgName ) + 7;
  1244. X     margin = ll + 1;
  1245. X     longest = 0;
  1246. X  
  1247. --- 619,627 ----
  1248. X        /* get screen size */
  1249. X     get_winsize( fileno(fp), &max_lines, &max_cols );
  1250. X  
  1251. !    fprintf(fp, "Usage: %.*s", ProgNameLen, ProgName);
  1252. X  
  1253. !    ll = ProgNameLen + 7;
  1254. X     margin = ll + 1;
  1255. X     longest = 0;
  1256. X  
  1257. ***************
  1258. *** 693,698 ****
  1259. --- 697,704 ----
  1260. X        for ( args = argd ; args ; args = cmd_defargs(args) ) {
  1261. X           for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  1262. X              argName_t  buf;
  1263. +             char  *desc;
  1264. +             int  desclen;
  1265. X  
  1266. X                 /* don't display hidden arguments */
  1267. X              if ( ARG_isHIDDEN(ad) )  continue;
  1268. ***************
  1269. *** 701,707 ****
  1270. X  
  1271. X              if ( !options++ )   fprintf(fp, "Options/Arguments:\n");
  1272. X              fmtarg(ad, buf, usage_flags);
  1273. !             indent_para( fp, max_cols, 8, buf, longest+2, arg_description(ad) );
  1274. X           }/*for each ad */
  1275. X        }/* for each argd */
  1276. X     }/* for each parm-type */
  1277. --- 707,714 ----
  1278. X  
  1279. X              if ( !options++ )   fprintf(fp, "Options/Arguments:\n");
  1280. X              fmtarg(ad, buf, usage_flags);
  1281. !             desc = get_argdesc(arg_description(ad), &desclen);
  1282. !             indent_para( fp, max_cols, 8, buf, longest+2, desc, desclen );
  1283. X           }/*for each ad */
  1284. X        }/* for each argd */
  1285. X     }/* for each parm-type */
  1286. *** unix_man.c.OLD    Thu Nov 21 15:21:57 1991
  1287. --- unix_man.c    Mon Nov 18 16:23:09 1991
  1288. ***************
  1289. *** 7,12 ****
  1290. --- 7,16 ----
  1291. X  **    The template is formatted for {n|t}roff using the -man macros.
  1292. X  **
  1293. X  ** ^HISTORY:
  1294. + **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  1295. + **    - Use ProgNameLen when accessing ProgName
  1296. + **    - Use get_argpfx() to access names
  1297. + **
  1298. X  **    01/02/91     Brad Appleton     <brad@ssd.csd.harris.com>     Created
  1299. X  ***^^**********************************************************************/
  1300. X  
  1301. ***************
  1302. *** 24,30 ****
  1303. X  #define MAXCOLS  65
  1304. X  #define VAL(str)           ((str) ? str : "")
  1305. X  #define COMMENT            printf(".\\\"-----------------------------------\n")
  1306. ! #define TH(title,section)  printf(".TH %s %d\n", title, section )
  1307. X  #define SH(title)          printf(".SH %s\n", title )
  1308. X  #define TP(cols,title)     printf(".TP %d\n%s\n", cols, title )
  1309. X  #define PP                 printf(".PP\n" )
  1310. --- 28,34 ----
  1311. X  #define MAXCOLS  65
  1312. X  #define VAL(str)           ((str) ? str : "")
  1313. X  #define COMMENT            printf(".\\\"-----------------------------------\n")
  1314. ! #define TH(title,len,section)  printf(".TH %.*s %d\n", len, title, section )
  1315. X  #define SH(title)          printf(".SH %s\n", title )
  1316. X  #define TP(cols,title)     printf(".TP %d\n%s\n", cols, title )
  1317. X  #define PP                 printf(".PP\n" )
  1318. ***************
  1319. *** 165,171 ****
  1320. X     register CONST ARGDESC *ad, *args, *cmd;
  1321. X     argName_t  name;
  1322. X     CONST char *program, *purpose, *description;
  1323. !    int   len, maxlen, positionals;
  1324. X  
  1325. X        /* allow null argument descriptor */
  1326. X     if ( !argd )  return;
  1327. --- 169,175 ----
  1328. X     register CONST ARGDESC *ad, *args, *cmd;
  1329. X     argName_t  name;
  1330. X     CONST char *program, *purpose, *description;
  1331. !    int   len, maxlen, positionals, namelen, programlen, purposelen;
  1332. X  
  1333. X        /* allow null argument descriptor */
  1334. X     if ( !argd )  return;
  1335. ***************
  1336. *** 173,187 ****
  1337. X     if ( !CMD_isINIT(argd) )   init_args( (ARGDESC *)argd );
  1338. X     cmd = argd;
  1339. X  
  1340. !    (VOID) strcpy( name, cmd_name(cmd) );
  1341. X     if ( cmd_name(cmd) ) {
  1342. X        program = cmd_name(cmd);
  1343. X     }
  1344. X     else if ( cmd_argv0(cmd) ) {
  1345. X        program = cmd_argv0(cmd);
  1346. X     }
  1347. X  
  1348. X     purpose = cmd_purpose(cmd);
  1349. X     description = cmd_description(cmd);
  1350. X  
  1351. X     printf(".\\\"---------- TO PRINT, USE: {n,t}roff -man file ----------\n");
  1352. --- 177,213 ----
  1353. X     if ( !CMD_isINIT(argd) )   init_args( (ARGDESC *)argd );
  1354. X     cmd = argd;
  1355. X  
  1356. !    name[0] = 0;
  1357. !    namelen = 0;
  1358. X     if ( cmd_name(cmd) ) {
  1359. +       (VOID) strcpy( name, cmd_name(cmd) );
  1360. +       if ( !BTEST(cmd_state(cmd), ps_USERNAME|ps_FREENAME) ) {
  1361. +          namelen = get_argpfx( name );
  1362. +          name[namelen] = 0;
  1363. +       }
  1364. +       else {
  1365. +          namelen = strlen( cmd_name(cmd) );
  1366. +       }
  1367. +    }
  1368. +    program = 0;
  1369. +    programlen = 0;
  1370. +    if ( cmd_name(cmd) ) {
  1371. X        program = cmd_name(cmd);
  1372. +       programlen = namelen;
  1373. X     }
  1374. X     else if ( cmd_argv0(cmd) ) {
  1375. X        program = cmd_argv0(cmd);
  1376. +       programlen = strlen(program);
  1377. X     }
  1378. X  
  1379. X     purpose = cmd_purpose(cmd);
  1380. +    if ( !BTEST(cmd_state(cmd), ps_USERPURPOSE|ps_FREEPURPOSE) && purpose ) {
  1381. +       purpose = get_argdesc(purpose, &purposelen);
  1382. +    }
  1383. +    else {
  1384. +      purposelen = strlen(VAL(purpose));
  1385. +    }
  1386. X     description = cmd_description(cmd);
  1387. X  
  1388. X     printf(".\\\"---------- TO PRINT, USE: {n,t}roff -man file ----------\n");
  1389. ***************
  1390. *** 190,203 ****
  1391. X  
  1392. X     COMMENT;
  1393. X  #ifdef SVR4
  1394. !    TH( name, 1 );
  1395. X  #else
  1396. !    TH( strupr(name), 1 );
  1397. X  #endif
  1398. X  
  1399. X     COMMENT;
  1400. X     SH( "NAME" );
  1401. !    printf( "%s \\- %s\n", VAL(program), VAL(purpose) );
  1402. X  
  1403. X     COMMENT;
  1404. X     SH( "SYNOPSIS" );
  1405. --- 216,229 ----
  1406. X  
  1407. X     COMMENT;
  1408. X  #ifdef SVR4
  1409. !    TH( name, namelen, 1 );
  1410. X  #else
  1411. !    TH( strupr(name), namelen, 1 );
  1412. X  #endif
  1413. X  
  1414. X     COMMENT;
  1415. X     SH( "NAME" );
  1416. !    printf( "%s \\- %.*s\n", VAL(program), purposelen, VAL(purpose) );
  1417. X  
  1418. X     COMMENT;
  1419. X     SH( "SYNOPSIS" );
  1420. ***************
  1421. *** 204,212 ****
  1422. X  
  1423. X     len = strlen( program ) + 1;
  1424. X  #ifdef SVR4
  1425. !    sprintf( name, "\\f4%s\\fP", program );
  1426. X  #else
  1427. !    sprintf( name, "\\fB%s\\fP", program );
  1428. X  #endif
  1429. X     TP( len, name );
  1430. X  
  1431. --- 230,238 ----
  1432. X  
  1433. X     len = strlen( program ) + 1;
  1434. X  #ifdef SVR4
  1435. !    sprintf( name, "\\f4%.*s\\fP", programlen, program );
  1436. X  #else
  1437. !    sprintf( name, "\\fB%.*s\\fP", programlen, program );
  1438. X  #endif
  1439. X     TP( len, name );
  1440. X  
  1441. ***************
  1442. *** 246,251 ****
  1443. --- 272,279 ----
  1444. X        for ( args = argd ; args ; args = cmd_defargs(args) ) {
  1445. X           for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  1446. X              argName_t  buf;
  1447. +             char  *desc;
  1448. +             int  desclen;
  1449. X  
  1450. X                 /* don't display hidden arguments */
  1451. X              if ( ARG_isHIDDEN(ad) )  continue;
  1452. ***************
  1453. *** 254,260 ****
  1454. X  
  1455. X              (VOID) fmtarg( ad, buf );
  1456. X              TP( maxlen + 2, buf );
  1457. !             indent_para(stdout, MAXCOLS, 0, "", 0, arg_description(ad) );
  1458. X           }/*for each ad */
  1459. X        }/* for each argd */
  1460. X     }/* for each parm-type */
  1461. --- 282,289 ----
  1462. X  
  1463. X              (VOID) fmtarg( ad, buf );
  1464. X              TP( maxlen + 2, buf );
  1465. !             desc = get_argdesc(arg_description(ad), &desclen);
  1466. !             indent_para(stdout, MAXCOLS, 0, "", 0, desc, desclen );
  1467. X           }/*for each ad */
  1468. X        }/* for each argd */
  1469. X     }/* for each parm-type */
  1470. *** useful.h.OLD    Thu Nov 21 15:22:05 1991
  1471. --- useful.h    Mon Nov 18 16:23:49 1991
  1472. ***************
  1473. *** 255,262 ****
  1474. X     EXTERN  char  *strpbrk   ARGS(( const char *, const char * ));
  1475. X     EXTERN  int    strspn    ARGS(( const char *, const char * ));
  1476. X     EXTERN  int    strcspn   ARGS(( const char *, const char * ));
  1477. !    EXTERN  char  *strtok    ARGS(( char *, char * ));
  1478. !    EXTERN  char  *strdup    ARGS(( const char * ));
  1479. X     
  1480. X  # else
  1481. X  #  define strchr(s,c)   index(s,c)
  1482. --- 255,261 ----
  1483. X     EXTERN  char  *strpbrk   ARGS(( const char *, const char * ));
  1484. X     EXTERN  int    strspn    ARGS(( const char *, const char * ));
  1485. X     EXTERN  int    strcspn   ARGS(( const char *, const char * ));
  1486. !    EXTERN  char  *strtok    ARGS(( char *, const char * ));
  1487. X     
  1488. X  # else
  1489. X  #  define strchr(s,c)   index(s,c)
  1490. ***************
  1491. *** 294,299 ****
  1492. --- 293,299 ----
  1493. X  
  1494. X  #if ( !defined(__ANSI_C__)  &&  !defined(_SIZE_T_DEFINED) )
  1495. X  # if (defined(sun) && defined(BSD))
  1496. + #  include <sys/types.h>
  1497. X  #  if (!defined (__sys_stdtypes_h))
  1498. X      /* size_t is also defined in <sys/stdtypes.h> in SunOS 4.1 */
  1499. X      typedef int size_t;
  1500. *** vms_args.c.OLD    Thu Nov 21 15:22:11 1991
  1501. --- vms_args.c    Thu Nov 21 15:16:13 1991
  1502. ***************
  1503. *** 6,11 ****
  1504. --- 6,22 ----
  1505. X  **    vectors and to print VMS/DCL usage messages.
  1506. X  **
  1507. X  ** ^HISTORY:
  1508. + **    11/21/91    Brad Appleton    <brad@ssd.csd.harris.com>
  1509. + **    - added Mike Levins fix to is_cmdline() to check for 0 length
  1510. + **      returned by lib$get_foreign.
  1511. + **    - added check of ps_NOTCMDLINE state-flag before calling is_cmdline()
  1512. + **    - fixed problem in vms_parse() where ARGVALGIVEN was getting set in
  1513. + **      place of ARGGIVEN.
  1514. + **
  1515. + **    08/27/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  1516. + **    - Use ProgNameLen when accessing ProgName
  1517. + **    - Use get_argdesc() to access description
  1518. + **
  1519. X  **    12/03/90    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1520. X  ***^^**********************************************************************/
  1521. X  
  1522. ***************
  1523. *** 127,137 ****
  1524. X     static BOOL is_cmdline( const char *argv[], char **result )
  1525. X  #endif
  1526. X  {
  1527. X     unsigned long int stat;
  1528. X     unsigned short int len;
  1529. !    register CONST char *aptr, *sptr, *avstr;
  1530. !    static char str[ MAXCMDLINE ] = "" ;
  1531. ! #ifdef vms
  1532. X     $DESCRIPTOR(str_d, str);
  1533. X  #endif
  1534. X  
  1535. --- 138,150 ----
  1536. X     static BOOL is_cmdline( const char *argv[], char **result )
  1537. X  #endif
  1538. X  {
  1539. +    register CONST char *avstr;
  1540. + #ifdef vms
  1541. X     unsigned long int stat;
  1542. X     unsigned short int len;
  1543. !    register CONST char *aptr, *sptr;
  1544. !    static char str[ MAXCMDLINE ];
  1545. !    static BOOL got_cmd_line = FALSE;
  1546. X     $DESCRIPTOR(str_d, str);
  1547. X  #endif
  1548. X  
  1549. ***************
  1550. *** 144,155 ****
  1551. X  
  1552. X  #else
  1553. X        /* get the original command-line */
  1554. !    if ( !*str ) {
  1555. X        stat = lib$get_foreign( &str_d, VNULL, &len, VNULL );
  1556. X        str[len] = '\0';
  1557. X        if (! (stat & 1))  exit( stat );
  1558. X     }
  1559. X  
  1560. X        /* compare the two */
  1561. X     for ( aptr = avstr, sptr = str ; *aptr && *sptr ; sptr++ ) {
  1562. X        if ( toupper(*sptr) == toupper(*aptr) ) {
  1563. --- 157,175 ----
  1564. X  
  1565. X  #else
  1566. X        /* get the original command-line */
  1567. !    if ( ! got_cmd_line ) {
  1568. X        stat = lib$get_foreign( &str_d, VNULL, &len, VNULL );
  1569. X        str[len] = '\0';
  1570. +       got_cmd_line = TRUE;
  1571. X        if (! (stat & 1))  exit( stat );
  1572. X     }
  1573. X  
  1574. +       /* if we didnt have a command-line, dont bother comparing */
  1575. +    if ( !*str ) {
  1576. +       *result = (char *)avstr;
  1577. +       return  FALSE;
  1578. +    }
  1579. X        /* compare the two */
  1580. X     for ( aptr = avstr, sptr = str ; *aptr && *sptr ; sptr++ ) {
  1581. X        if ( toupper(*sptr) == toupper(*aptr) ) {
  1582. ***************
  1583. *** 596,602 ****
  1584. X  
  1585. X     if ( !argv || !*argv )  return  parse_error;
  1586. X  
  1587. !    (VOID) is_cmdline( (CONST char **)argv, &avstr );
  1588. X     BSET( cmd_flags(cmd), pa_COPYF );
  1589. X     (VOID) dcl_strxlat( avstr );
  1590. X     if ( !avstr || !*avstr )  return  parse_error;
  1591. --- 616,624 ----
  1592. X  
  1593. X     if ( !argv || !*argv )  return  parse_error;
  1594. X  
  1595. !    if ( !BTEST(cmd_state(cmd), ps_NOTCMDLINE) ) {
  1596. !       (VOID) is_cmdline( (CONST char **)argv, &avstr );
  1597. !    }
  1598. X     BSET( cmd_flags(cmd), pa_COPYF );
  1599. X     (VOID) dcl_strxlat( avstr );
  1600. X     if ( !avstr || !*avstr )  return  parse_error;
  1601. ***************
  1602. *** 680,686 ****
  1603. X              /* now get the real value */
  1604. X           if ( !s || !(*s) ) {
  1605. X              if ( ARG_isVALOPTIONAL(ad) ) {
  1606. !                BSET( arg_flags(ad), ARGVALGIVEN );
  1607. X              }
  1608. X              else {
  1609. X                 (VOID) get_kwdname( arg_sname(ad), keyword );
  1610. --- 702,708 ----
  1611. X              /* now get the real value */
  1612. X           if ( !s || !(*s) ) {
  1613. X              if ( ARG_isVALOPTIONAL(ad) ) {
  1614. !                BSET( arg_flags(ad), ARGGIVEN );
  1615. X              }
  1616. X              else {
  1617. X                 (VOID) get_kwdname( arg_sname(ad), keyword );
  1618. ***************
  1619. *** 942,950 ****
  1620. X        : stderr;
  1621. X  
  1622. X        /* allow null argument descriptor */
  1623. !    fprintf(fp, "Format: %s", ProgName);
  1624. X  
  1625. !    ll = strlen( ProgName ) + 8;
  1626. X     margin = ll + 1;
  1627. X     longest = 0;
  1628. X  
  1629. --- 964,972 ----
  1630. X        : stderr;
  1631. X  
  1632. X        /* allow null argument descriptor */
  1633. !    fprintf(fp, "Format: %.*s", ProgNameLen, ProgName);
  1634. X  
  1635. !    ll = ProgNameLen + 8;
  1636. X     margin = ll + 1;
  1637. X     longest = 0;
  1638. X  
  1639. ***************
  1640. *** 1020,1025 ****
  1641. --- 1042,1049 ----
  1642. X        for ( args = argd ; args ; args = cmd_defargs(args) ) {
  1643. X           for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  1644. X              argName_t  buf;
  1645. +         char  *desc;
  1646. +         int  desclen;
  1647. X  
  1648. X                 /* don't display hidden arguments */
  1649. X              if ( ARG_isHIDDEN(ad) )  continue;
  1650. ***************
  1651. *** 1028,1034 ****
  1652. X  
  1653. X              if ( !qualifiers++ )  fprintf(fp, "Qualifiers/Parameters:\n");
  1654. X              (VOID) fmtarg(ad, buf);
  1655. !             indent_para(fp, max_cols, 8, buf, longest+2, arg_description(ad) );
  1656. X           }/*for each ad */
  1657. X        }/* for each argd */
  1658. X     }/* for each parm-type */
  1659. --- 1052,1059 ----
  1660. X  
  1661. X              if ( !qualifiers++ )  fprintf(fp, "Qualifiers/Parameters:\n");
  1662. X              (VOID) fmtarg(ad, buf);
  1663. !         desc = get_argdesc(arg_description(ad), &desclen);
  1664. !             indent_para(fp, max_cols, 8, buf, longest+2, desc, desclen );
  1665. X           }/*for each ad */
  1666. X        }/* for each argd */
  1667. X     }/* for each parm-type */
  1668. *** xparse.c.OLD    Thu Nov 21 15:22:30 1991
  1669. --- xparse.c    Wed Nov 20 11:07:39 1991
  1670. ***************
  1671. *** 98,103 ****
  1672. --- 98,112 ----
  1673. X  **      previous parse-flags should not be reset until AFTER required
  1674. X  **      arguments are checked for, otherwise we may forget to prompt
  1675. X  **      for them if $PARSECNTL asked us to do so.
  1676. + **
  1677. + **    08/27/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  1678. + **    - split out get_description().
  1679. + **    - add ProgNameLen
  1680. + **    - support for non-writable strings
  1681. + **    - allow sparseargs() to parse empty strings like parseargs()
  1682. + **
  1683. + **    04/03/91     Brad Appleton     <brad@ssd.csd.harris.com>
  1684. + **    - changed vms_style stuff to use ps_NOTCMDLINE
  1685. X  ***^^**********************************************************************/
  1686. X  
  1687. X  #include <stdio.h>
  1688. ***************
  1689. *** 170,176 ****
  1690. X  
  1691. X  
  1692. X  /***************************************************************************
  1693. ! ** ^GLOBAL-VARIABLE: ProgName
  1694. X  **
  1695. X  ** ^VISIBILITY:
  1696. X  **    external global (visible to functions in all files)
  1697. --- 179,185 ----
  1698. X  
  1699. X  
  1700. X  /***************************************************************************
  1701. ! ** ^GLOBAL-VARIABLE: ProgName, ProgNameLen
  1702. X  **
  1703. X  ** ^VISIBILITY:
  1704. X  **    external global (visible to functions in all files)
  1705. ***************
  1706. *** 179,186 ****
  1707. --- 188,197 ----
  1708. SHAR_EOF
  1709. true || echo 'restore of PATCH09 failed'
  1710. fi
  1711. echo 'End of  part 1'
  1712. echo 'File PATCH09 is continued in part 2'
  1713. echo 2 > _shar_seq_.tmp
  1714. exit 0
  1715. exit 0 # Just in case...
  1716. -- 
  1717. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1718. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1719. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1720. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1721.