parse.c: parse command-line arguments
William R. Ward
hermit at ucscf.UCSC.EDU
Sat Jan 5 08:24:54 AEST 1991
The following utility, to be linked into c programs which use
command-line arguments.
example program that uses this utility:
#include "parse.h"
int main( argc, argv )
int argc;
char **argv;
{
char c;
struct arg *args;
args = parse_args( argc, argv );
for ( c='a' ; c!='z'; c++ )
if ( args[ chindex( c )].ch )
if ( args[ chindex( c )].str )
printf( "Argument for %c is %s.\n", c,
args[ chindex( c )].str );
else
printf( "Flag %c set.\n", c );
}
Note that parse_args() returns a pointer to a series of struct
args. (an array, but the returned value is a pointer, which is
almost the same thing.) The index of the array is from 0 to
MAXARGS-1 (52), with 0 being any arguments specified without a -x
option (ie, if you gave the command "foo bar" the "bar" would be
in args[0]). 1-26 is for lower case characters ("foo -m bar" goes
in args[13]) and 27-52 are for uppercase characters. The macros
chindex() and indexch() in parse.h perform the conversion between
character <-> index.
If the flag exists, args[n].ch contains the character corresponding
to 'n' and args[n].str contains any argument(s) associated with
it. Also, note that if more than one argument is given for any
flag (or without any flags) they are concatenated with one space
between arguments. This means that any flagless arg must precede
any flags or it will *not* end up in args[0]. I decided this was
better than only allowing one argument. If you want to fix it, go
ahead, but please send me a patch so I can have both versions--both
are useful. (Examples: The command "foo -n14 bar" puts "14 bar"
in args[12]; "foo -n hello -xn world" places "hello world" in
args[12].str and NULL in args[24].str.)
checksums using BSD4.3 'sum' program:
36727 2 parse.c
18452 1 parse.h
to unbundle, "sh" this file -- DO NOT use csh
SHAR archive format. Archive created Fri Jan 4 12:45:26 PST 1991
-- cut here --
#!/bin/sh
echo x - parse.c
sed 's/^X//' > parse.c <<'+FUNKY+STUFF+'
X/*
X * parse.c William R. Ward <hermit at ucscb.UCSC.EDU>
X *
X * Given parameters (argc,argv) representing command-line
X * arguments, function parse_args() returns an array of argument
X * values. The array is of type struct arg, which is described in
X * the file parse.h.
X *
X * The routine defines a argument as follows: all uppercase or
X * lowercase letters in a word starting with '-' up to the first
X * non-letter in the word, with any words not beginning with '-'
X * or parts of a word after and including the last argument letter
X * given as that argument's parameter.
X *
X * For example, given the following strings in (argc, argv),
X * parse_args recognizes the following as arguments:
X *
X * input: argument(s): parameter:
X * -r r (none)
X * -abc a (none)
X * b (none)
X * c (none)
X * -xy74 x (none)
X * y 74
X * -z45h z 45h
X * -f filename f filename
X */
X
X#include "parse.h"
X#include <stdio.h>
X#include <strings.h>
X
Xstruct arg *parse_args( argc, argv )
Xint argc;
Xchar *argv[];
X{
X int i, set_ch();
X static struct arg args[ MAXARGS ];
X char *p, last = 0;
X void set_str();
X
X for( i=1; i<argc; i++ )
X if ( *argv[i] == '-' && *(argv[i]+1) ) {
X for( p=argv[i]+1; chindex(*p); p++ )
X if ( set_ch( args, *p ))
X last = *p;
X if ( *p )
X if ( p==argv[i]+1 )
X set_str( args, p-1, last );
X else
X set_str( args, p, last );
X } else
X set_str( args, argv[i], last );
X return args;
X}
X
Xint set_ch( args, x )
Xstruct arg args[];
Xchar x;
X{
X int index;
X
X index = chindex(x);
X if ( index ) {
X args[ index ].ch = 1;
X return 1;
X } else
X return 0;
X}
X
Xvoid set_str( args, x, last )
Xstruct arg args[];
Xchar *x,
X last;
X{
X char *t;
X int index;
X
X index = chindex( last );
X if ( args[ index ].str == NULL ) {
X t = ( char * )calloc( strlen( x ), sizeof( char ));
X strcpy( t, x );
X } else {
X t = ( char * )calloc( strlen( args[ index ].str ) +
X strlen( x ) + 1, sizeof( char ));
X strcpy( t, args[ index ].str );
X strcat( t, " " );
X strcat( t, x );
X }
X free( args[ index ].str );
X args[ index ].str = t;
X}
+FUNKY+STUFF+
echo '-rw------- 1 hermit 2037 Feb 9 1990 parse.c (as sent)'
chmod u=rw,g=,o= parse.c
ls -l parse.c
echo x - parse.h
sed 's/^X//' > parse.h <<'+FUNKY+STUFF+'
X#include <ctype.h>
X
X#define MAXARGS 53
X /* 26 lowercase + 26 uppercase + zero for non-letter */
X#define chindex(x) ( isalpha(x) ? ( islower(x) ? (x)-'a'+1 : (x)-'A'+27 ) : 0 )
X /* macro, given a char x, returns the index into args[] */
X#define indexch(x) ( (x) ? ( (x)<=26 ? (x)+'a'-1 : (x)+'A'-27 ) : 0 )
X /* macro, given an index into args[] 0 <= x <= MAXARGS, returns char */
X
Xstruct arg {
X char ch; /* true/false: is there an arg for this letter? */
X char *str; /* holds pointer to string containing parameter
X or NULL if no parameter */
X};
+FUNKY+STUFF+
echo '-rw------- 1 hermit 551 Feb 9 1990 parse.h (as sent)'
chmod u=rw,g=,o= parse.h
ls -l parse.h
exit 0
-- cut here --
--
------------------------------------------------------------------------
William R. Ward | UC Santa Cruz, CIS | [backbone]!ucbvax!
(408) 426-7267 | hermit at ucscf.UCSC.EDU | ucscc!ucscf!hermit
UCSC-Cowell-787 +--------------------------------------------------
Santa Cruz, CA 95064 | Disclaimer: Nobody reads this anyway.
------------------------------------------------------------------------
More information about the Alt.sources
mailing list