home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume29
/
parseargs
/
part03
/
test.awk
< prev
next >
Wrap
Text File
|
1992-05-19
|
7KB
|
173 lines
#!/usr/bin/awk -f
##########################################################################
## ^FILE: test.awk - parseargs for awk programs
##
## ^DESCRIPTION:
## This file defines an awk function named parseargs to parse
## command-line arguments for awk scripts. It also contains a
## bare-bones template of what such an awk-script might contain.
##
## ^HISTORY:
## 02/21/91 Brad Appleton <brad@ssd.csd.harris.com> Created
###^^#####################################################################
#########
## ^FUNCTION: parseargs - parse command-line argument vectors
##
## ^SYNOPSIS:
## parseargs( argc, argv, argd, arr )
##
## ^PARAMETERS:
## argc -- the number of elements in argv (usually ARGC-1).
## argv -- the vector of command-line arguments (usually ARGV).
## argd -- the argument-description string
## arr -- the associative array to assign command-line values from
##
## ^DESCRIPTION:
## Parseargs will invoke parseargs(1) to parse the command-line given
## in <argv> for the command defined by <argd>. The resulting values
## will be assigned to elements of the associative array given by <arr>.
## Values are assigned using using the syntax: arr [ "argname" ] = value;
## The exception to this is that if the <argname> is "ARGV" then the global
## array ARGV is reset to the given array (using tab separated fields).
##
## ^REQUIREMENTS:
## Any desired initial values for items in <arr> should be assigned BEFORE
## calling this function (using the syntax: arr[ "argname" ] = initial-val).
##
## The following global variables may be assigned before calling parseargs:
##
## PROGNAME -- name of the current awk script (default= ARGV[0])
## PARSEOPTS -- any extra options to pass toi parseargs() (default="-ul")
## PARSEINPUT -- input file for parseargs(1) (default=unique-name)
## PARSEOUTPUT -- output file for parseargs(1) (default=unique-name)
##
## ^SIDE-EFFECTS:
## The files PARSEINPUT and PARSEOUTPUT are created and then deleted.
##
## The return value from parseargs(1) will be stored in the global-variable
## named PARSESTATUS.
##
## The global variable PARSEARGS will contain the command-line used to
## invoke parseargs(1).
##
## ARGV and ARGC may be reset, all other values are (re)set in <arr>.
##
## ^RETURN-VALUE:
## The exit code returned by parseargs(1).
##
## ^BUGS:
## Due to the limited ability of awk, scripts using parseargs(1) cannot
## use short-options (with a dash '-') because awk will attempt to interpret
## any such arguments as options to awk and remove them from ARGV (regardless
## of whether or not they are valid awk-options). Keyword options (with a
## plus sign '+') may still be used without this difficulty. Dash-options
## may be successfully processed if they did not first appear on the command
## to the awk-script, so the full syntax of unix-style options could be
## provided in an array other than ARGV.
##
## ^ALGORITHM:
## - set defaults for PROGNAME, PARSEOPTS, PARSEINPUT, and PARSEOUTPUT.
## - build the parseargs command (dont forget to quote arguments).
## - redirect input and output of the parseargs command.
## - run parseargs(1)
## - assign the exit-code from parseargs(1) to PARSESTATUS
## - remove PARSEINPUT
## - if PARSESTATUS != 0
## - save RS and FS and reset RS = "" and FS = "\n"
## - for each record in PARSEOUTPUT
## - $1 is the argname and $2 is the value
## - if $1 is "ARGV" reset ARGV and ARGC ($2 is a tab separated array)
## - else assign arr[ $1 ] = $2
## end-for
## - restore RS and FS to previous values
## - remove PARSEOUTPUT
## - return PARSESTATUS
###^^####
function parseargs(argc, argv, argd, arr) {
## set defaults -- use $$ to get a unique suffix string
if ( ! PROGNAME ) PROGNAME = ARGV[0];
if ( ! PARSEOPTS ) PARSEOPTS = "-u -l";
"echo ${TMP:-/tmp}/parseargs.${$}_" | getline TMPFILE;
if ( ! PARSEINPUT ) PARSEINPUT = TMPFILE "in";
if ( ! PARSEOUTPUT ) PARSEOUTPUT = TMPFILE "out";
## build the options and required arguments for parseargs(1)
PARSEARGS = sprintf( "parseargs -s awk %s -- '%s'", PARSEOPTS, PROGNAME );
## quote each elemnt in argv and append it to the parseargs-command
for ( i = 1 ; i <= argc ; i++ ) {
arg = argv[i];
gsub( /'/, "'\\''", arg );
PARSEARGS = PARSEARGS " '" arg "'";
}
## set up i/o redirection
PARSEARGS = PARSEARGS " <" PARSEINPUT " >" PARSEOUTPUT;
print argd > PARSEINPUT;
## invoke parseargs(1) and save the status
PARSESTATUS = system( PARSEARGS );
system( "/bin/rm -f " PARSEINPUT ); ## dont need input anymore
## if successful status, read the result
if ( PARSESTATUS == 0 ) {
save_RS = RS; save_FS = FS;
RS = ""; FS = "\n";
while ( getline < PARSEOUTPUT > 0 ) {
gsub( /\034/, "\n" );
if ( $1 == "ARGV" ) {
ARGC = 1 + split( $2, ARGV, "\t" );
ARGV[0] = PROGNAME;
}
else arr[ $1 ] = $2;
}
RS = save_RS; FS = save_FS;
}
system( "/bin/rm -f " PARSEOUTPUT );
return PARSESTATUS;
}
BEGIN {
PROGNAME = "test.awk";
ARGD = sprintf( "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
"'?', ARGHIDDEN, argUsage, NULL, 'Help : print usage and exit'" ,
"'S', ARGVALOPT, argStr, string, 'STRing : optional string arg'" ,
"'g', ARGLIST, argStr, groups, 'newsGROUPS : groups to test'" ,
"'r', ARGOPT, argInt, count, 'REPcount : group repeat count'" ,
"'d', ARGOPT, argStr, dirname, 'DIRectory : working directory'" ,
"'x', ARGOPT, argBool, xflag, 'Xflag : turn on X-mode'" ,
"'y', ARGOPT, argUBool, yflag, 'Yflag : turn off Y-mode'" ,
"'s', ARGOPT, argChar, sepch, 'SEPchar : field separator'" ,
"'f', ARGLIST, argStr, files, 'files : files to process'" ,
"'n', ARGREQ|ARGPOS, argStr, name, 'name : name to use'" ,
"' ', ARGLIST, argStr, argv, 'argv : any remaining arguments'" ,
"ENDOFARGS" );
Args[ "count" ] = 1;
Args[ "dirname" ] = ".";
Args[ "sepch" ] = ",";
Args[ "yflag" ] = "TRUE";
rc = parseargs( ARGC-1, ARGV, ARGD, Args );
if ( rc != 0 ) exit( rc );
## print the parsed arguments (use defaults if not defined)
print "ARGUMENTS:";
print "==========";
for ( i in Args )
printf( "Args[\"%s\"] = \"%s\"\n", i, Args[i] );
argc = split( Args[ "argv" ], argv, "\t" );
for ( i = 1 ; i <= argc ; i++ )
printf( "argv[%d] = \"%s\"\n", i, argv[i] );
}