home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume26
/
parseargs
/
patch09a
next >
Wrap
Text File
|
1991-11-25
|
57KB
|
1,738 lines
Newsgroups: comp.sources.misc
From: Brad Appleton <brad@hcx1.ssd.csd.harris.com>
Subject: v26i065: parseargs - functions to parse command line arguments, Patch09a/2
Message-ID: <csm-v26i065=parseargs.203314@sparky.IMD.Sterling.COM>
X-Md4-Signature: 11ba3c1bdff2402c3ff1fadceddd8d5d
Date: Tue, 26 Nov 1991 02:34:56 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com>
Posting-number: Volume 26, Issue 65
Archive-name: parseargs/patch09a
Environment: UNIX, VMS, MS-DOS, OS/2, Amiga
Patch-To: parseargs: Volume 17, Issue 46-57
This is patch09 for parseargs. To apply this patch:
1) cd to your parseargs source directory (which should be at patchlevel 8.
look at the file patchlevel.h to see which patchlevel you have)
2) Unshar both parts to this patch to create the file PATCH09
3) type "patch -p0 <PATCH09"
If you dont have all the patches and/or want parseargs in its entirety I will
honor your requests to send it by e-mail.
The following is a brief introduction to parseargs for those who are not
already familiar with it:
PARSEARGS
extracted from Eric Allman's
NIFTY UTILITY LIBRARY
Created by Eric P. Allman
<eric@Berkeley.EDU>
Modified by Peter da Silva
<peter@Ferranti.COM>
Modified and Rewritten by Brad Appleton
<brad@SSD.CSD.Harris.COM>
Welcome to parseargs! Dont let the initial size of this package scare you.
over 75% of it is English text, and more than 50% of the source is comments.
Parseargs is a set of functions to parse command-line arguments. Unlike
getopt and its variants, parseargs does more than just split up the
command-line into some canonical form. Parseargs will actually parse the
command-line, assigning the appropriate command-line values to the
corresponding variables, and will verify the command-line syntax (and print
a usage message if necessary). Furthermore, many features of it's parsing
behavior are configurable at run-time. Some of these features include the
following:
o Prompting the user for missing arguments
o Allowing keywords (+count=4) and/or options (-c4)
o Checking for default arguments in an environment variable
o Ignoring bad syntax instead of terminating
o Ignoring upper/lower case on the command-line
o Controlling the location of non-positional parameters
o Controlling the contents (syntax and verbosity) of usage messages
o Having long usage messages piped through a paging program
Parseargs also allows for options that take an optional argument, and
options that take a (possibly optional) list of one or more arguments.
In addition, parseargs may be configured at compile-time to parse
command-lines in accordance with the native command-syntax of any of the
following operating systems:
o Unix
o VAX/VMS
o OS/2
o MS-DOS
o AmigaDOS
Parseargs consists of a set of C-functions to parse arguments from the
command-line, from files, from strings, from linked-lists, and from
string-vectors. Also included is a command-line interface which will parse
arguments for shell scripts (sh, csh/tcsh/itcsh, ksh, bash, zsh, and rc),
awk-scripts, and perl-scripts.
The basic structure used by parseargs is the argument-descriptor (sometimes
called "argdesc" for brevity). An array/string of argdescs is declared by
the user to describe the command in question. The resulting argdesc-array
is passed to all the parseargs functions and is used to hold all information
about the command. a sample argdesc-array is shown below.
STARTOFARGS,
{ 'a', ARGVALOPT, argStr, &area, "AREAcode : optional area-code" },
{ 'g', ARGLIST, argStr, &groups, "newsGROUPS : groups to test" },
{ 'r', ARGOPT, argInt, &count, "REPcount : repetition factor" },
{ 's', ARGOPT, argChar, &sepch, "SEPchar : field separator" },
{ 'x', ARGOPT, argBool, &xflag, "Xflag : turn on X-mode" },
{ ' ', ARGREQ, argStr, &name, "name : name to use" },
{ ' ', ARGLIST, argStr, &args, "args : any remaining arguments" },
ENDOFARGS
Once the above array/string is declared it is a simple matter to invoke
parseargs from C as in the following example:
status = parseargs( argv, argdesc_array );
or from a shell script as in the following example:
echo "$ARGDESC_STR" | parseargs -s sh -- "$0" "$@" >tmp$$
test $? = 0 && . tmp$$
/bin/rm -f tmp$$
And before you know it, your command-line had been parsed, all variables
have been assigned their corresponding values from the command-line, syntax
have been verified, and a usage message (if required) has been printed.
Under UNIX, the command-line syntax (using single character options) for the
above command would be:
cmdname [-a [<areacode>]] [-g <newsgroups>...] [-r <repcount>]
[-s <sepchar>] [-x] <name> [<args>...]
The UNIX command-line syntax using keywords (or long options) would be:
cmdname [+area [<areacode>]] [+groups <newsgroups>...] [+rep <repcount>]
[+sep <sepchar>] [+x] <name> [<args>...]
The VMS command-line syntax would be the following:
cmdname [/AREA[=<areacode>]] [/GROUPS=<newsgroups>[,<newsgroups>...]]
[/REP=<repcount>] [/SEP=<sepchar>] [/X] <name>
[<args>[,<args>...]]
The MS-DOS and OS/2 command-line syntax would be the following (unless the
environment variable $SWITCHAR is '-' in which case UNIX syntax is used):
cmdname [/a[=<areacode>]] [/g=<newsgroups>...] [/r=<repcount>]
[/s=<sepchar>] [/x] <name> [<args>...]
The AmigaDOS command-line syntax would be the following:
cmdname [AREA [<areacode>]] [GROUPS <newsgroups>...] [REP <repcount>]
[SEP <sepchar>] [X] <name> [<args>...]
Please look at the README files and manpages for more detailed information!
----
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 11/26/1991 02:28 UTC by kent@sparky.IMD.Sterling.COM
# Source directory /home/kent/mod/csm/queue/parseargs
#
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 66669 -rw-rw-r-- PATCH09
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= PATCH09 ==============
if test -f 'PATCH09' -a X"$1" != X"-c"; then
echo 'x - skipping PATCH09 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting PATCH09 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'PATCH09' &&
*** README.OLD Thu Nov 21 15:16:56 1991
--- README Thu Nov 21 11:34:11 1991
***************
*** 784,797 ****
X USE_TERMCAP -- Parseargs will use curses/terminfo/termcap when trying
X to figure out the size of the screen.
X
- UNWRITABLE_STRING_LITERALS
- -- This should be used only for compilers and/or machines
- that do NOT allow the programmer to modify the contents
- of string literals such as "hello, world". If this
- constant is #defined, then all modified strings will be
- duplicated (using strdup()) before they are changed.
-
-
X IBM-PC VERSION OF parseargs(3)
X ==============================
X I also added ibm_args.c for MS-DOS and OS/2.
--- 784,789 ----
***************
*** 892,898 ****
X - get parseargs(1) to support arrays for bash
X - verify that parseargs(1) works for rc, the Plan 9 shell
X - verify that parseargs(1) works for zsh
- - verify that parseargs(3) works on VMS systems.
X - verify that parseargs(3) works on MS-DOS and OS/2 systems.
X
X
--- 884,889 ----
***************
*** 921,929 ****
X retrieving the value of a symbol), and to Tom Christiansen and Raymond
X Chen for their help in getting parseargs(1) to work for perl scripts.
X
! Thanx also to Gillmer J. Derge, Marco Nijdam, Chris Johnston, & Earl Chew
! for sending me their bug reports and fixes so that I could incorporate them
! into the latest patch of parseargs.
X
X Lastly, thanks to all those who use and will continue to improve
X parseargs, all I ask is that you keep me updated of your efforts (so I
--- 912,920 ----
X retrieving the value of a symbol), and to Tom Christiansen and Raymond
X Chen for their help in getting parseargs(1) to work for perl scripts.
X
! Thanx also to Gillmer J. Derge, Marco Nijdam, Chris Johnston, Earl Chew
! and Mike Levin for sending me their bug reports and fixes so that I could
! incorporate them into the latest patch of parseargs.
X
X Lastly, thanks to all those who use and will continue to improve
X parseargs, all I ask is that you keep me updated of your efforts (so I
*** amiga_args.c.OLD Thu Nov 21 15:17:08 1991
--- amiga_args.c Mon Nov 18 16:06:49 1991
***************
*** 6,11 ****
--- 6,15 ----
X ** vectors and to print AmigaDOS usage messages.
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
+ ** - Use get_argdesc() to access description
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com>
X ** - Added structured block comments
X ** - Added optional arguments to keywords
***************
*** 456,463 ****
X /* get screen size */
X get_winsize( fileno(stderr), &max_lines, &max_cols );
X
! fprintf(fp, "Format: %s", ProgName);
! ll = strlen( ProgName ) + 8;
X margin = ll + 1;
X longest = 0;
X
--- 460,467 ----
X /* get screen size */
X get_winsize( fileno(stderr), &max_lines, &max_cols );
X
! fprintf(fp, "Format: %.*s", ProgNameLen, ProgName);
! ll = ProgNameLen + 8;
X margin = ll + 1;
X longest = 0;
X
***************
*** 529,534 ****
--- 533,540 ----
X for ( args = argd ; args ; args = cmd_defargs(args) ) {
X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
X argName_t buf;
+ char *desc;
+ int desclen;
X
X /* don't display hidden arguments */
X if ( ARG_isHIDDEN(ad) ) continue;
***************
*** 537,543 ****
X
X if( !(keywords++) ) fprintf(fp, "Keywords/Arguments:\n");
X (VOID) fmtarg(ad, buf);
! indent_para(fp, max_cols, 8, buf, longest+2, arg_description(ad));
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
--- 543,550 ----
X
X if( !(keywords++) ) fprintf(fp, "Keywords/Arguments:\n");
X (VOID) fmtarg(ad, buf);
! desc = get_argdesc(arg_description(ad), &desclen);
! indent_para(fp, max_cols, 8, buf, longest+2, desc, desclen);
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
*** arglist.c.OLD Thu Nov 21 15:17:14 1991
--- arglist.c Mon Nov 18 16:08:00 1991
***************
*** 6,11 ****
--- 6,14 ----
X ** and to delete all items in an arglist.
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use get_argpfx() when accessing arg_sname().
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com>
X ** - Added structured comments
X ** - Changed arglists to always be kept in FIFO order (hence
***************
*** 125,131 ****
X }
X
X if ( badalloc ) {
! usrerr("out of memory saving arg %s", arg_sname(ad));
X if(copyf) free(cp);
X return FALSE;
X }
--- 128,135 ----
X }
X
X if ( badalloc ) {
! usrerr("out of memory saving arg %.*s", get_argpfx(arg_sname(ad)),
! arg_sname(ad));
X if(copyf) free(cp);
X return FALSE;
X }
*** ibm_args.c.OLD Thu Nov 21 15:19:57 1991
--- ibm_args.c Mon Nov 18 16:09:09 1991
***************
*** 6,11 ****
--- 6,15 ----
X ** argument vectors and to print MS-DOS and OS/2 usage messages.
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
+ ** - Use get_argdesc() to access description
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com> Created
X ***^^**********************************************************************/
X
***************
*** 699,707 ****
X /* get screen size */
X get_winsize( fileno(fp), &max_lines, &max_cols );
X
! fprintf(fp, "Usage: %s", ProgName);
X
! ll = strlen( ProgName ) + 7;
X margin = ll + 1;
X longest = 0;
X
--- 703,711 ----
X /* get screen size */
X get_winsize( fileno(fp), &max_lines, &max_cols );
X
! fprintf(fp, "Usage: %.*s", ProgNameLen, ProgName);
X
! ll = ProgNameLen + 7;
X margin = ll + 1;
X longest = 0;
X
***************
*** 777,782 ****
--- 781,788 ----
X for ( args = argd ; args ; args = cmd_defargs(args) ) {
X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
X argName_t buf;
+ char *desc;
+ int desclen;
X
X /* don't display hidden arguments */
X if ( ARG_isHIDDEN(ad) ) continue;
***************
*** 785,791 ****
X
X if ( !options++ ) fprintf(fp, "Options/Arguments:\n");
X fmtarg(ad, buf, usage_flags);
! indent_para( fp, max_cols, 8, buf, longest+2, arg_description(ad) );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
--- 791,798 ----
X
X if ( !options++ ) fprintf(fp, "Options/Arguments:\n");
X fmtarg(ad, buf, usage_flags);
! desc = get_argdesc(arg_description(ad), &desclen);
! indent_para( fp, max_cols, 8, buf, longest+2, desc, desclen );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
*** parseargs.c.OLD Thu Nov 21 15:20:11 1991
--- parseargs.c Mon Nov 18 16:09:34 1991
***************
*** 80,85 ****
--- 80,88 ----
X ** - fixed printing of single quotes for perl scripts
X ** - added -C option for case-insensitivity
X ** - added hidden -# option to print current version and patchlevel
+ **
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
X ***^^**********************************************************************/
X
X #include <stdio.h>
***************
*** 2215,2220 ****
--- 2218,2224 ----
X if ( !UsrArgc ) UsrArgd = ARGDESCNULL;
X
X ProgName = UsrName; /* set up program name */
+ ProgNameLen = strlen(ProgName);
X
X if ( PrUsage ) { /* just print usage and exit */
X usage( UsrArgd );
*** parseargs.h.OLD Thu Nov 21 15:20:22 1991
--- parseargs.h Wed Nov 20 11:05:05 1991
***************
*** 23,28 ****
--- 23,39 ----
X **
X ** ^HISTORY:
X ** 12/03/90 Brad Appleton <brad@ssd.csd.harris.com>
+ ** - added ps_NOTCMDLINE state-flag for vms_style
+ **
+ ** 08/27/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Add ProgNameLen
+ ** - Promote ps_flags_t to unsigned short
+ ** - Add new states ps_USERNAME, ps_USERPURPOSE, ps_FREENAME,
+ ** ps_FREEPURPOSE
+ ** - arg_sdesc() now only returns a raw string --- use get_argdesc()
+ ** to extract the description from it
+ **
+ ** 12/03/90 Brad Appleton <brad@ssd.csd.harris.com>
X ** - Added all the #ifdef stuff
X ** - Added public and private macros for getting and setting
X ** the attributes of an argdesc-array and an argdesc
***************
*** 282,291 ****
X #define arg_sname(ad) ((ad) -> ad_prompt)
X /* -- return the string name of an argument.
X */
! #define arg_sdesc(ad) ( arg_sname(ad) + strlen(arg_sname(ad)) + 1 )
X /* -- return the description of an argument. If a description was supplied,
! ** the ARGDESCRIBED flag will be set and the description will immediately
! ** follow the NULL byte of the string name.
X */
X #define ARG_isDESCRIBED(ad) BTEST( arg_flags(ad), ARGDESCRIBED )
X /* -- Evaluates to TRUE only if an argument description was provided.
--- 293,302 ----
X #define arg_sname(ad) ((ad) -> ad_prompt)
X /* -- return the string name of an argument.
X */
! #define arg_sdesc(ad) ( arg_sname(ad) )
X /* -- return the description of an argument. If a description was supplied,
! ** the ARGDESCRIBED flag will be set and the description is available
! ** by calling get_argdesc().
X */
X #define ARG_isDESCRIBED(ad) BTEST( arg_flags(ad), ARGDESCRIBED )
X /* -- Evaluates to TRUE only if an argument description was provided.
***************
*** 836,843 ****
X # define ps_NOFLAGS 0x02 /* opt/kwd parsing in effect? */
X # define ps_NOCMDENV 0x04 /* <CMD>_ARGS environment-variable parsed? */
X # define ps_NOPARSECNTL 0x08 /* PARSECNTL environment-variable parsed? */
X
! typedef unsigned char ps_flags_t;
X
X
X /*
--- 847,861 ----
X # define ps_NOFLAGS 0x02 /* opt/kwd parsing in effect? */
X # define ps_NOCMDENV 0x04 /* <CMD>_ARGS environment-variable parsed? */
X # define ps_NOPARSECNTL 0x08 /* PARSECNTL environment-variable parsed? */
+ # define ps_USERNAME 0x10 /* user supplied name string */
+ # define ps_FREENAME 0x10 /* free name string space */
+ # define ps_USERPURPOSE 0x20 /* user supplied purpose string */
+ # define ps_FREEPURPOSE 0x20 /* free purpose string space */
+ # ifdef vms_style
+ # define ps_NOTCMDLINE 0x40 /* argv-array is NOT from the command-line */
+ # endif
X
! typedef unsigned short ps_flags_t;
X
X
X /*
***************
*** 1012,1017 ****
--- 1030,1036 ----
X EXTERN VOID usage ARGS(( const ARGDESC * ));
X EXTERN VOID init_args ARGS(( ARGDESC * ));
X EXTERN CONST char *ProgName;
+ EXTERN int ProgNameLen;
X #endif /* PARSEARGS_NEXTERNS */
X
X #endif /* PARSEARGS_H */
*** patchlevel.h.OLD Thu Nov 21 15:20:36 1991
--- patchlevel.h Thu Nov 21 11:32:17 1991
***************
*** 2,7 ****
--- 2,38 ----
X ** ^FILE: patchlevel.h - current patchlevel for parseargs
X **
X ** ^HISTORY:
+ ** 08/27/91 Brad Appleton <brad@ssd.csd.harris.com>
+ ** 08/27/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** Patch09
+ ** - Added proper support for unwritable strings
+ ** - strfuncs.c/strsplit():
+ ** Leading, and in particular, trailing space trimming may spin off
+ ** the end of the token string. This occurs when the string is empty,
+ ** or when it has trailing space.
+ ** Out of memory error doesn't call syserr() like the rest of the
+ ** routines do.
+ ** - xparse.c/parsecntl():
+ ** Documentation says that the fourth parameter for pc_ARGFLAGS and
+ ** pc_PARSEARGS should be either argMask_t (promoted to int) in the
+ ** case of writes, or argMask_t * in the case of reads. The code is
+ ** at odds with the documentation and requires (int *) on reads.
+ ** Also, should check for NULL cmd-name before passing it to strdup().
+ ** - vms_args.c/is_cmdline():
+ ** Mike Level pointed out to me that if lib$get_foreing returns a
+ ** zero-length string then the proper actions are not taken. This
+ ** has been fixed.
+ ** - vms_args.c, parseargs.h, xparse.c
+ ** For vms_style I added a new parse-state called ps_NOTCMDLINE.
+ ** When this flag is SET, then vms_parse() knows for a fact that
+ ** the given argv[] array is NOT from the cmdline so it doesnt even
+ ** need to call is_cmdline(). SO Now I just have the proper routines
+ ** in xparse.c set this flag before calling vms_parse() (and unset
+ ** the flag when they are done).
+ ** - vms_args.c/vms_parse():
+ ** ARGVALGIVEN was set instead of ARGGIVEN (this was wrong).
+ **
+ **
X ** 08/15/91 Brad Appleton <brad@ssd.csd.harris.com>
X ** Patch08
X ** - fixed some typos in the comments (SIDE-EFFECTS was misspelled
***************
*** 101,107 ****
X
X #define VERSION 2
X #define REVISION 0
! #define PATCHLEVEL 8
X
X #ifdef __STDC__
X static const char
--- 132,138 ----
X
X #define VERSION 2
X #define REVISION 0
! #define PATCHLEVEL 9
X
X #ifdef __STDC__
X static const char
***************
*** 108,111 ****
X #else
X static char
X #endif
! _Ident[] = "@(#)parseargs 2.0 patchlevel 8";
--- 139,142 ----
X #else
X static char
X #endif
! _Ident[] = "@(#)parseargs 2.0 patchlevel 9";
*** stest.c.OLD Thu Nov 21 15:20:49 1991
--- stest.c Wed Nov 20 15:14:47 1991
***************
*** 246,252 ****
X static void print_args( const ARGDESC *argd )
X #endif
X {
! int i, flags;
X ArgList *ls;
X
X printf( "Name = \"%s\", DirName = \"%s\", RepCount = %d,\n",
--- 246,253 ----
X static void print_args( const ARGDESC *argd )
X #endif
X {
! int i;
! argMask_t flags;
X ArgList *ls;
X
X printf( "Name = \"%s\", DirName = \"%s\", RepCount = %d,\n",
*** strfuncs.c.OLD Thu Nov 21 15:20:55 1991
--- strfuncs.c Wed Nov 20 10:43:54 1991
***************
*** 23,28 ****
--- 23,30 ----
X ** strtrim() -- trim leading and trailing characters in a string
X ** strsplit() -- split a string up into a vector of tokens
X ** strjoin() -- join a vector of tokens into a single string
+ ** get_argpfx() -- return the length of the first part of the string
+ ** get_argdesc() -- return the description (second part) of the string
X ** get_argname() -- return the aname (argument-name) of an argument
X ** get_kwdname() -- return the sname (keyword-name) of an argument
X ** match() -- match two keywords (case insensitive) upto a unique prefix
***************
*** 30,35 ****
--- 32,47 ----
X ** indent_para() -- print an indented hanging paragraph
X **
X ** ^HISTORY:
+ ** 08/27/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - add extra length argument to indent_para().
+ ** - add FORCE_KWDCASE() macro
+ ** - add non-writable strings support to get_argname() and
+ ** get_kwdname()
+ ** 08/27/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - add get_argpfx() and get_argdesc() for non-writable strings
+ ** support
+ ** - allow zero length string for strsplit()
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com> Created
X ** - changed from file misc.c to this name and added all of the strxxx
X ** functions (plus got rid of some unused functions).
***************
*** 43,48 ****
--- 55,62 ----
X #include <ctype.h>
X #include <useful.h>
X
+ #include "strfuncs.h"
+
X EXTERN VOID syserr ARGS((const char *, ...));
X
X static CONST char WhiteSpace[] = " \t\n\r\v\f";
***************
*** 49,58 ****
X
X #define c_ARG_SEP '='
X #if ( defined(unix_style) || defined(ibm_style) )
! # define TO_KWDCASE(c) TOLOWER(c)
X # define KWDCASECOPY(dest,src) strlcpy(dest,src)
X #else
! # define TO_KWDCASE(c) TOUPPER(c)
X # define KWDCASECOPY(dest,src) strucpy(dest,src)
X #endif
X
--- 63,74 ----
X
X #define c_ARG_SEP '='
X #if ( defined(unix_style) || defined(ibm_style) )
! # define FORCE_KWDCASE(s) strlwr(s)
! # define TO_KWDCASE(c) TOLOWER(c)
X # define KWDCASECOPY(dest,src) strlcpy(dest,src)
X #else
! # define FORCE_KWDCASE(s) strupr(s)
! # define TO_KWDCASE(c) TOUPPER(c)
X # define KWDCASECOPY(dest,src) strucpy(dest,src)
X #endif
X
***************
*** 308,314 ****
X unsigned len = strlen(str) + 1;
X char *p = malloc( len * sizeof(char) );
X
! if ( !p ) syserr( "Fatal Error -- out of memory" );
X strcpy(p, str);
X
X return p;
--- 324,330 ----
X unsigned len = strlen(str) + 1;
X char *p = malloc( len * sizeof(char) );
X
! if ( !p ) syserr( "malloc failed in strdup()" );
X strcpy(p, str);
X
X return p;
***************
*** 582,588 ****
X **
X ** ^REQUIREMENTS:
X ** vec must be non-NULL (it must be a valid address).
! ** token_str should be non-null and non-empty
X **
X ** ^SIDE-EFFECTS:
X ** All leading and trailing characters from <separators> are removed
--- 598,604 ----
X **
X ** ^REQUIREMENTS:
X ** vec must be non-NULL (it must be a valid address).
! ** token_str should be non-null
X **
X ** ^SIDE-EFFECTS:
X ** All leading and trailing characters from <separators> are removed
***************
*** 605,610 ****
--- 621,627 ----
X ** - advance token_str to point at the next character past the
X ** rightmost NUL-byte (which should be the start of the next token).
X ** end-for
+ ** - vector[numtokens] = NUL
X ** - return the number of tokens parsed.
X ***^^**********************************************************************/
X #ifdef __ANSI_C__
***************
*** 614,620 ****
X register char c, *pread, *pwrite;
X int i, count = 0;
X
! if ( !token_str ) return 0;
X /* if delim-string is NULL, whitespace is used */
X if ( !separators ) separators = WhiteSpace;
X
--- 631,637 ----
X register char c, *pread, *pwrite;
X int i, count = 0;
X
! if ( !token_str ) token_str = "";
X /* if delim-string is NULL, whitespace is used */
X if ( !separators ) separators = WhiteSpace;
X
***************
*** 621,626 ****
--- 638,644 ----
X /* trim leading separators */
X pread = token_str;
X while ( strchr(separators, *pread) ) ++pread;
+ if ( ! *pread ) return 0;
X token_str = pwrite = pread;
X
X /*
***************
*** 627,653 ****
X ** make first pass through string, counting # of tokens and
X ** separating all tokens by a single '\0'
X */
! while ( c = *pread++ ) {
X if ( !strchr(separators, c) ) {
! *pwrite++ = c;
! }
! else {
! *pwrite++ = '\0'; /* null terminate this token */
! ++count; /* update token count */
! while ( strchr(separators, *pread) ) ++pread;
! }
! }/*while*/
! if ( *(pwrite - 1) ) {
! ++count; /* dont forget last token */
! *pwrite = '\0'; /* null-terminate */
! }
X
X /* allocate space for the caller's vector (remember NULL at the end) */
X (*vec) = (char **)malloc( (1 + count) * sizeof( char * ) );
! if ( !*vec ) {
! fprintf( stderr, "out of memory in strsplit() - aborting\n" );
! exit( -1 );
! }
X
X /* now go thru token-string again assigning pointers from vector */
X pread = token_str;
--- 645,669 ----
X ** make first pass through string, counting # of tokens and
X ** separating all tokens by a single '\0'
X */
! for ( c = *pread++ ; c ; ) {
X if ( !strchr(separators, c) ) {
! do {
! *pwrite++ = c;
! } while ( (c = *pread++) && !strchr(separators, c) );
! *pwrite++ = '\0';
! ++count;
! do {
! *pwrite++ = c;
! } while ( (c = *pread++) && !strchr(separators, c) );
! *pwrite++ = '\0';
! ++count;
! }/*if*/
! while ( c && strchr(separators, c) ) c = *pread++;
! }/*for*/
X
X /* allocate space for the caller's vector (remember NULL at the end) */
X (*vec) = (char **)malloc( (1 + count) * sizeof( char * ) );
! if ( !*vec ) syserr( "malloc failed in strsplit()" );
X
X /* now go thru token-string again assigning pointers from vector */
X pread = token_str;
***************
*** 748,753 ****
--- 764,912 ----
X
X
X /***************************************************************************
+ ** ^FUNCTION: get_argpfx - get the prefix portion of a string
+ **
+ ** ^SYNOPSIS:
+ */
+ #ifndef __ANSI_C__
+ int get_argpfx( str )
+ /*
+ ** ^PARAMETERS:
+ */
+ char *str;
+ /* -- the string to parse for a description
+ */
+ #endif /* !__ANSI_C__ */
+
+ /* ^DESCRIPTION:
+ ** Get_argdesc returns the length of the first portion of the string.
+ **
+ ** Two "portions" must be either separated by whitespace or the second
+ ** portion may be within "(),{},[], or <>" delimiters. The second
+ ** portion is assumed to begin with the first alphabetic following
+ ** separator.
+ **
+ ** ^REQUIREMENTS:
+ ** str should be non-null and non-empty
+ **
+ ** ^SIDE-EFFECTS:
+ ** None.
+ **
+ ** ^RETURN-VALUE:
+ ** The length of the first portion.
+ **
+ ** ^ALGORITHM:
+ ** - locate the end of the first portion by scanning for whitespace or
+ ** balanced delimiters.
+ ***^^**********************************************************************/
+ #ifdef __ANSI_C__
+ int get_argpfx( const char *str )
+ #endif
+ {
+ register char *description;
+ static CONST char whitespace[] = " \t\n\r\f\v";
+ static CONST char beg_portion[] = "(<{[";
+
+ description = strpbrk( str, whitespace );
+ if ( !description ) {
+ description = strpbrk( str, beg_portion );
+ }
+
+ return description ? description - str : strlen(str);
+ }
+
+
+ /***************************************************************************
+ ** ^FUNCTION: get_argdesc - get the description portion of a string
+ **
+ ** ^SYNOPSIS:
+ */
+ #ifndef __ANSI_C__
+ char *get_argdesc( str, len )
+ /*
+ ** ^PARAMETERS:
+ */
+ char *str;
+ /* -- the string to parse for a description
+ */
+ int *len;
+ /* -- the pointer to the length
+ */
+ #endif /* !__ANSI_C__ */
+
+ /* ^DESCRIPTION:
+ ** Get_argdesc returns a pointer to the second portion of the string
+ ** and also indicates how long it is.
+ **
+ ** Two "portions" must be either separated by whitespace or the second
+ ** portion may be within "(),{},[], or <>" delimiters. The second
+ ** portion is assumed to begin with the first alphabetic following
+ ** separator.
+ **
+ ** ^REQUIREMENTS:
+ ** str should be non-null and non-empty
+ **
+ ** ^SIDE-EFFECTS:
+ ** The length of the description is written to *len.
+ **
+ ** ^RETURN-VALUE:
+ ** Address of the description (or NULL if the string has no description).
+ **
+ ** ^ALGORITHM:
+ ** - locate the end of the first portion by scanning for whitespace or
+ ** balanced delimiters.
+ ** - locate the beginning of the second portion by scanning for the first
+ ** alpha-numeric following the end of the first portion.
+ ** - return the address of the description.
+ ***^^**********************************************************************/
+ #ifdef __ANSI_C__
+ char *get_argdesc( const char *str, int *len )
+ #endif
+ {
+ register char *description = CHARNULL;
+ BOOL is_end = FALSE, is_balanced = FALSE;
+ char *p;
+ static CONST char whitespace[] = " \t\n\r\f\v";
+ static CONST char beg_portion[] = "(<{[";
+ static CONST char end_portion[] = ")>}]";
+
+ description = strpbrk( str, whitespace );
+ if ( description ) {
+ is_end = TRUE;
+ while ( isspace(*++description) ) continue; /* trim leading ' ' */
+ if ( strchr(beg_portion, *description) ) {
+ is_balanced = TRUE;
+ ++description;
+ }
+ }
+ else {
+ description = strpbrk( str, beg_portion );
+ if ( description ) { /* skip leading '(' */
+ is_end = is_balanced = TRUE;
+ ++description;
+ }
+ }
+
+ if ( !description ) {
+ *len = 0;
+ }
+ else {
+ if ( is_balanced ) { /* remove trailing ')' */
+ p = description + (strlen( description ) - 1);
+ if ( !strchr(end_portion, *p) ) ++p;
+ *len = p - description;
+ }
+ else {
+ while ( !isalnum(*description) ) ++description;
+ *len = strlen( description );
+ }
+ }
+
+ return description;
+ }
+
+
+ /***************************************************************************
X ** ^FUNCTION: get_argname - return the aname (argument-name) of an argument
X **
X ** ^SYNOPSIS:
***************
*** 787,803 ****
X char *get_argname( const char *s, char *buf )
X #endif
X {
! register CONST char *p1 = s, *p2;
X
X /* see if sname and aname are separated by c_ARG_SEP
X ** <buf> must be large enough to hold the result!
X */
! p2 = strchr( p1, c_ARG_SEP );
! if ( p2 ) {
! strlcpy( buf, ++p2 );
X }
X else {
! strlcpy(buf, s);
X }
X return buf;
X }
--- 946,969 ----
X char *get_argname( const char *s, char *buf )
X #endif
X {
! register CONST char *p2;
! int len;
X
X /* see if sname and aname are separated by c_ARG_SEP
X ** <buf> must be large enough to hold the result!
X */
! len = get_argpfx(s);
! p2 = strchr( s, c_ARG_SEP );
! if ( p2 && p2 < &s[len]) {
! ++p2;
! strncpy( buf, p2, len-(p2-s) );
! buf[len-(p2-s)] = 0;
! strlwr(buf);
X }
X else {
! strncpy( buf, s, len );
! buf[len] = 0;
! strlwr(buf);
X }
X return buf;
X }
***************
*** 849,871 ****
X #endif
X {
X register char *p1 = (char *)s, *p2, ch;
X BOOL caps = FALSE;
X
X if ( !p1 ) return CHARNULL;
X
X /* see if sname and aname are separated by c_ARG_SEP */
X p2 = strchr( p1, c_ARG_SEP );
! if ( p2 ) {
! ch = *p2;
! *p2 = '\0';
! KWDCASECOPY( buf, p1 );
! *p2 = ch;
X return buf;
X }
X
X /* copy string into buffer and convert it to desired case */
X /* <buf> must be large enough to hold the result! */
! for ( p2 = buf; *p1 ; p1++ ) {
X if ( isupper(*p1) ) {
X if ( !caps ) {
X caps = TRUE;
--- 1015,1038 ----
X #endif
X {
X register char *p1 = (char *)s, *p2, ch;
+ int len;
X BOOL caps = FALSE;
X
X if ( !p1 ) return CHARNULL;
X
X /* see if sname and aname are separated by c_ARG_SEP */
+ len = get_argpfx( p1 );
X p2 = strchr( p1, c_ARG_SEP );
! if ( p2 && p2 < &p1[len]) {
! strncpy( buf, p1, p2-p1);
! buf[p2-p1] = 0;
! FORCE_KWDCASE(buf);
X return buf;
X }
X
X /* copy string into buffer and convert it to desired case */
X /* <buf> must be large enough to hold the result! */
! for ( p2 = buf; *p1 && len != 0; p1++, len-- ) {
X if ( isupper(*p1) ) {
X if ( !caps ) {
X caps = TRUE;
***************
*** 1145,1151 ****
X ** ^SYNOPSIS:
X */
X #ifndef __ANSI_C__
! VOID indent_para(fp, maxcols, margin, title, indent, text)
X /*
X ** ^PARAMETERS:
X */
--- 1312,1318 ----
X ** ^SYNOPSIS:
X */
X #ifndef __ANSI_C__
! VOID indent_para(fp, maxcols, margin, title, indent, text, textlen)
X /*
X ** ^PARAMETERS:
X */
***************
*** 1167,1172 ****
--- 1334,1342 ----
X char *text;
X /* -- the body of the paragraph
X */
+ int textlen;
+ /* -- the length of the body of the paragraph
+ */
X #endif /* !__ANSI_C__ */
X
X /* ^DESCRIPTION:
***************
*** 1193,1204 ****
X ***^^**********************************************************************/
X #ifdef __ANSI_C__
X void indent_para( FILE *fp, int maxcols, int margin,
! const char *title, int indent, const char *text )
X #endif
X {
X register int idx = 0;
X BOOL first_line = TRUE;
- int text_len = strlen(text);
X char ch;
X
X /* print the title */
--- 1363,1374 ----
X ***^^**********************************************************************/
X #ifdef __ANSI_C__
X void indent_para( FILE *fp, int maxcols, int margin,
! const char *title, int indent, const char *text,
! int textlen )
X #endif
X {
X register int idx = 0;
X BOOL first_line = TRUE;
X char ch;
X
X /* print the title */
***************
*** 1206,1241 ****
X
X idx = maxcols - margin - indent;
X
! if ( text_len <= idx )
! fprintf(fp, "%s\n", text);
X else
X do {
X /* backup to end of previous word */
X while (idx && !isspace(text[idx])) --idx;
X while (idx && isspace(text[idx])) --idx;
X
X /* print leading whitespace */
X if (!first_line)
X fprintf(fp, "%*s%-*s", margin, "", indent, "");
X
! ch = text[ ++idx ];
! *((char *)text + idx) = '\0';
! fprintf(fp, "%s\n", text);
! *((char *)text + idx) = ch;
X first_line = FALSE;
X text = &(text[idx+1]);
! text_len -= (idx+1);
X
X while (isspace(*text)) { /* goto next word */
X ++text;
! --text_len;
X }
X
X idx = maxcols - margin - indent;
X
! if ( text_len <= idx ) /* print-last line */
! fprintf(fp, "%*s%-*s%s\n", margin, "", indent, "", text);
! } while ( text_len > idx );
X }
X
X
--- 1376,1410 ----
X
X idx = maxcols - margin - indent;
X
! if ( textlen <= idx )
! fprintf(fp, "%.*s\n", textlen, text);
X else
X do {
X /* backup to end of previous word */
X while (idx && !isspace(text[idx])) --idx;
X while (idx && isspace(text[idx])) --idx;
+ idx++;
X
X /* print leading whitespace */
X if (!first_line)
X fprintf(fp, "%*s%-*s", margin, "", indent, "");
X
! fprintf(fp, "%.*s\n", idx, text);
!
X first_line = FALSE;
X text = &(text[idx+1]);
! textlen -= (idx+1);
X
X while (isspace(*text)) { /* goto next word */
X ++text;
! --textlen;
X }
X
X idx = maxcols - margin - indent;
X
! if ( textlen <= idx ) /* print-last line */
! fprintf(fp, "%*s%-*s%.*s\n", margin, "", indent, "", textlen, text);
! } while ( textlen > idx );
X }
X
X
*** strfuncs.h.OLD Thu Nov 21 15:21:03 1991
--- strfuncs.h Mon Nov 18 16:19:25 1991
***************
*** 5,10 ****
--- 5,14 ----
X ** External declarations for the functions implemented in strfuncs.c
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Add extra argument to indent_para()
+ ** - Add new prototypes for get_argdesc() and get_argpfx()
+ **
X ** 01/07/91 Brad Appleton <brad@ssd.csd.harris.com> Created
X ***^^**********************************************************************/
X
***************
*** 35,43 ****
X
X EXTERN char *get_argname ARGS(( const char *, char * ));
X EXTERN char *get_kwdname ARGS(( const char *, char * ));
X EXTERN int match ARGS(( const char *, const char * ));
X EXTERN char *basename ARGS(( char * ));
X EXTERN VOID indent_para ARGS(( FILE *, int, int,
! const char *, int, const char * ));
X
X #endif
--- 39,49 ----
X
X EXTERN char *get_argname ARGS(( const char *, char * ));
X EXTERN char *get_kwdname ARGS(( const char *, char * ));
+ EXTERN char *get_argdesc ARGS(( const char *, int * ));
+ EXTERN int get_argpfx ARGS(( const char * ));
X EXTERN int match ARGS(( const char *, const char * ));
X EXTERN char *basename ARGS(( char * ));
X EXTERN VOID indent_para ARGS(( FILE *, int, int,
! const char *, int, const char *, int ));
X
X #endif
*** syserr.c.OLD Thu Nov 21 15:21:10 1991
--- syserr.c Mon Nov 18 16:19:57 1991
***************
*** 10,15 ****
--- 10,18 ----
X ** eprintf() -- print to stderr and return
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com>
X ** - Changed to use varargs/stdargs
X ** - Added structured comment blocks
***************
*** 28,33 ****
--- 31,37 ----
X VERSIONID("$Header: syserr.c,v 2.0 89/12/24 00:56:31 eric Exp $");
X
X extern char *ProgName;
+ extern int ProgNameLen;
X EXTERN int vfprintf ARGS((FILE *, const char *, va_list));
X
X
***************
*** 75,81 ****
X int save_err;
X
X save_err = errno;
! if (ProgName && *ProgName) fprintf(stderr, "%s: ", ProgName);
X
X (VOID) vfprintf(stderr, format, ap);
X
--- 79,86 ----
X int save_err;
X
X save_err = errno;
! if (ProgName && *ProgName)
! fprintf(stderr, "%.*s: ", ProgNameLen, ProgName);
X
X (VOID) vfprintf(stderr, format, ap);
X
*** unix_args.c.OLD Thu Nov 21 15:21:49 1991
--- unix_args.c Mon Nov 18 16:20:49 1991
***************
*** 6,11 ****
--- 6,15 ----
X ** vectors and to print Unix usage messages.
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
+ ** - Use get_argdesc() to access description
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com>
X ** - Added structured block comments
X ** - Added optional arguments to keywords and options
***************
*** 615,623 ****
X /* get screen size */
X get_winsize( fileno(fp), &max_lines, &max_cols );
X
! fprintf(fp, "Usage: %s", ProgName);
X
! ll = strlen( ProgName ) + 7;
X margin = ll + 1;
X longest = 0;
X
--- 619,627 ----
X /* get screen size */
X get_winsize( fileno(fp), &max_lines, &max_cols );
X
! fprintf(fp, "Usage: %.*s", ProgNameLen, ProgName);
X
! ll = ProgNameLen + 7;
X margin = ll + 1;
X longest = 0;
X
***************
*** 693,698 ****
--- 697,704 ----
X for ( args = argd ; args ; args = cmd_defargs(args) ) {
X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
X argName_t buf;
+ char *desc;
+ int desclen;
X
X /* don't display hidden arguments */
X if ( ARG_isHIDDEN(ad) ) continue;
***************
*** 701,707 ****
X
X if ( !options++ ) fprintf(fp, "Options/Arguments:\n");
X fmtarg(ad, buf, usage_flags);
! indent_para( fp, max_cols, 8, buf, longest+2, arg_description(ad) );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
--- 707,714 ----
X
X if ( !options++ ) fprintf(fp, "Options/Arguments:\n");
X fmtarg(ad, buf, usage_flags);
! desc = get_argdesc(arg_description(ad), &desclen);
! indent_para( fp, max_cols, 8, buf, longest+2, desc, desclen );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
*** unix_man.c.OLD Thu Nov 21 15:21:57 1991
--- unix_man.c Mon Nov 18 16:23:09 1991
***************
*** 7,12 ****
--- 7,16 ----
X ** The template is formatted for {n|t}roff using the -man macros.
X **
X ** ^HISTORY:
+ ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
+ ** - Use get_argpfx() to access names
+ **
X ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com> Created
X ***^^**********************************************************************/
X
***************
*** 24,30 ****
X #define MAXCOLS 65
X #define VAL(str) ((str) ? str : "")
X #define COMMENT printf(".\\\"-----------------------------------\n")
! #define TH(title,section) printf(".TH %s %d\n", title, section )
X #define SH(title) printf(".SH %s\n", title )
X #define TP(cols,title) printf(".TP %d\n%s\n", cols, title )
X #define PP printf(".PP\n" )
--- 28,34 ----
X #define MAXCOLS 65
X #define VAL(str) ((str) ? str : "")
X #define COMMENT printf(".\\\"-----------------------------------\n")
! #define TH(title,len,section) printf(".TH %.*s %d\n", len, title, section )
X #define SH(title) printf(".SH %s\n", title )
X #define TP(cols,title) printf(".TP %d\n%s\n", cols, title )
X #define PP printf(".PP\n" )
***************
*** 165,171 ****
X register CONST ARGDESC *ad, *args, *cmd;
X argName_t name;
X CONST char *program, *purpose, *description;
! int len, maxlen, positionals;
X
X /* allow null argument descriptor */
X if ( !argd ) return;
--- 169,175 ----
X register CONST ARGDESC *ad, *args, *cmd;
X argName_t name;
X CONST char *program, *purpose, *description;
! int len, maxlen, positionals, namelen, programlen, purposelen;
X
X /* allow null argument descriptor */
X if ( !argd ) return;
***************
*** 173,187 ****
X if ( !CMD_isINIT(argd) ) init_args( (ARGDESC *)argd );
X cmd = argd;
X
! (VOID) strcpy( name, cmd_name(cmd) );
X if ( cmd_name(cmd) ) {
X program = cmd_name(cmd);
X }
X else if ( cmd_argv0(cmd) ) {
X program = cmd_argv0(cmd);
X }
X
X purpose = cmd_purpose(cmd);
X description = cmd_description(cmd);
X
X printf(".\\\"---------- TO PRINT, USE: {n,t}roff -man file ----------\n");
--- 177,213 ----
X if ( !CMD_isINIT(argd) ) init_args( (ARGDESC *)argd );
X cmd = argd;
X
! name[0] = 0;
! namelen = 0;
X if ( cmd_name(cmd) ) {
+ (VOID) strcpy( name, cmd_name(cmd) );
+ if ( !BTEST(cmd_state(cmd), ps_USERNAME|ps_FREENAME) ) {
+ namelen = get_argpfx( name );
+ name[namelen] = 0;
+ }
+ else {
+ namelen = strlen( cmd_name(cmd) );
+ }
+ }
+
+ program = 0;
+ programlen = 0;
+ if ( cmd_name(cmd) ) {
X program = cmd_name(cmd);
+ programlen = namelen;
X }
X else if ( cmd_argv0(cmd) ) {
X program = cmd_argv0(cmd);
+ programlen = strlen(program);
X }
X
X purpose = cmd_purpose(cmd);
+ if ( !BTEST(cmd_state(cmd), ps_USERPURPOSE|ps_FREEPURPOSE) && purpose ) {
+ purpose = get_argdesc(purpose, &purposelen);
+ }
+ else {
+ purposelen = strlen(VAL(purpose));
+ }
X description = cmd_description(cmd);
X
X printf(".\\\"---------- TO PRINT, USE: {n,t}roff -man file ----------\n");
***************
*** 190,203 ****
X
X COMMENT;
X #ifdef SVR4
! TH( name, 1 );
X #else
! TH( strupr(name), 1 );
X #endif
X
X COMMENT;
X SH( "NAME" );
! printf( "%s \\- %s\n", VAL(program), VAL(purpose) );
X
X COMMENT;
X SH( "SYNOPSIS" );
--- 216,229 ----
X
X COMMENT;
X #ifdef SVR4
! TH( name, namelen, 1 );
X #else
! TH( strupr(name), namelen, 1 );
X #endif
X
X COMMENT;
X SH( "NAME" );
! printf( "%s \\- %.*s\n", VAL(program), purposelen, VAL(purpose) );
X
X COMMENT;
X SH( "SYNOPSIS" );
***************
*** 204,212 ****
X
X len = strlen( program ) + 1;
X #ifdef SVR4
! sprintf( name, "\\f4%s\\fP", program );
X #else
! sprintf( name, "\\fB%s\\fP", program );
X #endif
X TP( len, name );
X
--- 230,238 ----
X
X len = strlen( program ) + 1;
X #ifdef SVR4
! sprintf( name, "\\f4%.*s\\fP", programlen, program );
X #else
! sprintf( name, "\\fB%.*s\\fP", programlen, program );
X #endif
X TP( len, name );
X
***************
*** 246,251 ****
--- 272,279 ----
X for ( args = argd ; args ; args = cmd_defargs(args) ) {
X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
X argName_t buf;
+ char *desc;
+ int desclen;
X
X /* don't display hidden arguments */
X if ( ARG_isHIDDEN(ad) ) continue;
***************
*** 254,260 ****
X
X (VOID) fmtarg( ad, buf );
X TP( maxlen + 2, buf );
! indent_para(stdout, MAXCOLS, 0, "", 0, arg_description(ad) );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
--- 282,289 ----
X
X (VOID) fmtarg( ad, buf );
X TP( maxlen + 2, buf );
! desc = get_argdesc(arg_description(ad), &desclen);
! indent_para(stdout, MAXCOLS, 0, "", 0, desc, desclen );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
*** useful.h.OLD Thu Nov 21 15:22:05 1991
--- useful.h Mon Nov 18 16:23:49 1991
***************
*** 255,262 ****
X EXTERN char *strpbrk ARGS(( const char *, const char * ));
X EXTERN int strspn ARGS(( const char *, const char * ));
X EXTERN int strcspn ARGS(( const char *, const char * ));
! EXTERN char *strtok ARGS(( char *, char * ));
! EXTERN char *strdup ARGS(( const char * ));
X
X # else
X # define strchr(s,c) index(s,c)
--- 255,261 ----
X EXTERN char *strpbrk ARGS(( const char *, const char * ));
X EXTERN int strspn ARGS(( const char *, const char * ));
X EXTERN int strcspn ARGS(( const char *, const char * ));
! EXTERN char *strtok ARGS(( char *, const char * ));
X
X # else
X # define strchr(s,c) index(s,c)
***************
*** 294,299 ****
--- 293,299 ----
X
X #if ( !defined(__ANSI_C__) && !defined(_SIZE_T_DEFINED) )
X # if (defined(sun) && defined(BSD))
+ # include <sys/types.h>
X # if (!defined (__sys_stdtypes_h))
X /* size_t is also defined in <sys/stdtypes.h> in SunOS 4.1 */
X typedef int size_t;
*** vms_args.c.OLD Thu Nov 21 15:22:11 1991
--- vms_args.c Thu Nov 21 15:16:13 1991
***************
*** 6,11 ****
--- 6,22 ----
X ** vectors and to print VMS/DCL usage messages.
X **
X ** ^HISTORY:
+ ** 11/21/91 Brad Appleton <brad@ssd.csd.harris.com>
+ ** - added Mike Levins fix to is_cmdline() to check for 0 length
+ ** returned by lib$get_foreign.
+ ** - added check of ps_NOTCMDLINE state-flag before calling is_cmdline()
+ ** - fixed problem in vms_parse() where ARGVALGIVEN was getting set in
+ ** place of ARGGIVEN.
+ **
+ ** 08/27/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - Use ProgNameLen when accessing ProgName
+ ** - Use get_argdesc() to access description
+ **
X ** 12/03/90 Brad Appleton <brad@ssd.csd.harris.com> Created
X ***^^**********************************************************************/
X
***************
*** 127,137 ****
X static BOOL is_cmdline( const char *argv[], char **result )
X #endif
X {
X unsigned long int stat;
X unsigned short int len;
! register CONST char *aptr, *sptr, *avstr;
! static char str[ MAXCMDLINE ] = "" ;
! #ifdef vms
X $DESCRIPTOR(str_d, str);
X #endif
X
--- 138,150 ----
X static BOOL is_cmdline( const char *argv[], char **result )
X #endif
X {
+ register CONST char *avstr;
+ #ifdef vms
X unsigned long int stat;
X unsigned short int len;
! register CONST char *aptr, *sptr;
! static char str[ MAXCMDLINE ];
! static BOOL got_cmd_line = FALSE;
X $DESCRIPTOR(str_d, str);
X #endif
X
***************
*** 144,155 ****
X
X #else
X /* get the original command-line */
! if ( !*str ) {
X stat = lib$get_foreign( &str_d, VNULL, &len, VNULL );
X str[len] = '\0';
X if (! (stat & 1)) exit( stat );
X }
X
X /* compare the two */
X for ( aptr = avstr, sptr = str ; *aptr && *sptr ; sptr++ ) {
X if ( toupper(*sptr) == toupper(*aptr) ) {
--- 157,175 ----
X
X #else
X /* get the original command-line */
! if ( ! got_cmd_line ) {
X stat = lib$get_foreign( &str_d, VNULL, &len, VNULL );
X str[len] = '\0';
+ got_cmd_line = TRUE;
X if (! (stat & 1)) exit( stat );
X }
X
+ /* if we didnt have a command-line, dont bother comparing */
+ if ( !*str ) {
+ *result = (char *)avstr;
+ return FALSE;
+ }
+
X /* compare the two */
X for ( aptr = avstr, sptr = str ; *aptr && *sptr ; sptr++ ) {
X if ( toupper(*sptr) == toupper(*aptr) ) {
***************
*** 596,602 ****
X
X if ( !argv || !*argv ) return parse_error;
X
! (VOID) is_cmdline( (CONST char **)argv, &avstr );
X BSET( cmd_flags(cmd), pa_COPYF );
X (VOID) dcl_strxlat( avstr );
X if ( !avstr || !*avstr ) return parse_error;
--- 616,624 ----
X
X if ( !argv || !*argv ) return parse_error;
X
! if ( !BTEST(cmd_state(cmd), ps_NOTCMDLINE) ) {
! (VOID) is_cmdline( (CONST char **)argv, &avstr );
! }
X BSET( cmd_flags(cmd), pa_COPYF );
X (VOID) dcl_strxlat( avstr );
X if ( !avstr || !*avstr ) return parse_error;
***************
*** 680,686 ****
X /* now get the real value */
X if ( !s || !(*s) ) {
X if ( ARG_isVALOPTIONAL(ad) ) {
! BSET( arg_flags(ad), ARGVALGIVEN );
X }
X else {
X (VOID) get_kwdname( arg_sname(ad), keyword );
--- 702,708 ----
X /* now get the real value */
X if ( !s || !(*s) ) {
X if ( ARG_isVALOPTIONAL(ad) ) {
! BSET( arg_flags(ad), ARGGIVEN );
X }
X else {
X (VOID) get_kwdname( arg_sname(ad), keyword );
***************
*** 942,950 ****
X : stderr;
X
X /* allow null argument descriptor */
! fprintf(fp, "Format: %s", ProgName);
X
! ll = strlen( ProgName ) + 8;
X margin = ll + 1;
X longest = 0;
X
--- 964,972 ----
X : stderr;
X
X /* allow null argument descriptor */
! fprintf(fp, "Format: %.*s", ProgNameLen, ProgName);
X
! ll = ProgNameLen + 8;
X margin = ll + 1;
X longest = 0;
X
***************
*** 1020,1025 ****
--- 1042,1049 ----
X for ( args = argd ; args ; args = cmd_defargs(args) ) {
X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
X argName_t buf;
+ char *desc;
+ int desclen;
X
X /* don't display hidden arguments */
X if ( ARG_isHIDDEN(ad) ) continue;
***************
*** 1028,1034 ****
X
X if ( !qualifiers++ ) fprintf(fp, "Qualifiers/Parameters:\n");
X (VOID) fmtarg(ad, buf);
! indent_para(fp, max_cols, 8, buf, longest+2, arg_description(ad) );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
--- 1052,1059 ----
X
X if ( !qualifiers++ ) fprintf(fp, "Qualifiers/Parameters:\n");
X (VOID) fmtarg(ad, buf);
! desc = get_argdesc(arg_description(ad), &desclen);
! indent_para(fp, max_cols, 8, buf, longest+2, desc, desclen );
X }/*for each ad */
X }/* for each argd */
X }/* for each parm-type */
*** xparse.c.OLD Thu Nov 21 15:22:30 1991
--- xparse.c Wed Nov 20 11:07:39 1991
***************
*** 98,103 ****
--- 98,112 ----
X ** previous parse-flags should not be reset until AFTER required
X ** arguments are checked for, otherwise we may forget to prompt
X ** for them if $PARSECNTL asked us to do so.
+ **
+ ** 08/27/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
+ ** - split out get_description().
+ ** - add ProgNameLen
+ ** - support for non-writable strings
+ ** - allow sparseargs() to parse empty strings like parseargs()
+ **
+ ** 04/03/91 Brad Appleton <brad@ssd.csd.harris.com>
+ ** - changed vms_style stuff to use ps_NOTCMDLINE
X ***^^**********************************************************************/
X
X #include <stdio.h>
***************
*** 170,176 ****
X
X
X /***************************************************************************
! ** ^GLOBAL-VARIABLE: ProgName
X **
X ** ^VISIBILITY:
X ** external global (visible to functions in all files)
--- 179,185 ----
X
X
X /***************************************************************************
! ** ^GLOBAL-VARIABLE: ProgName, ProgNameLen
X **
X ** ^VISIBILITY:
X ** external global (visible to functions in all files)
***************
*** 179,186 ****
--- 188,197 ----
SHAR_EOF
true || echo 'restore of PATCH09 failed'
fi
echo 'End of part 1'
echo 'File PATCH09 is continued in part 2'
echo 2 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.