home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/awk -f
-
- ##########################################################################
- ## ^FILE: parseargs.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 to 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:
- ## Assumes that short-options are NOT disabled by $PARSECNTL.
- ##
- ## 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 '\t' -- '%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'" ,
- "' ', ARGREQ, 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] );
-
- }
-