Content-type: text/html Manpage of parseargs

parseargs

Section: C Library Functions (3)
Updated: libutils.h
Index Return to Main Contents
 

NAME

parseargs - parse command line arguments in a single pass using a format string. Return the values in a variable argument list of string.  

VERSION

This manpage refers to version 1.0 of libutils.  

SYNOPSIS

int parseargs(int args, char *arg[], char *format, char *flags, char *ext[], ...)

const char*parseerror(int error)

const char *parseusage(char *progname, int width, char *format, ...)

int badusage(int retval)

 

DESCRIPTION

The parseargs funtion, and its related support functions parseerror, parseusage, and badusage, are replacements for the getopts function from the standard UNIX library, that are simpler to use and offer some extended functionality.

parseargs parses command line arguments into flags, flags with values, optionally flagged positional parameters, optional positional parameters and required positional parameters. Each recognized argument is stored into a string provided by the caller in a variable argument list, similar to the printf or scanf functions from the standard C library.

The format string is a superset of the string used by getopts with extensions to support the other types of arguments.

 

Flags:

to specify a flag you simply place the flag character in the string. Flags can use any character other than a color (:), equals sign (=), hash mark (#), or plus sign (+), which are used in the format string to specify other kinds of arguments.

 

Flags with a Value:

you can specify a flag with a Value by following the flag character with a colon (:), exactly as you would if you were using getopts. The main difference from getopts is that parseargs will allow the value to either be part of the same argument (-fvalue) or be in the next argument (-f value).

 

Repeatable Flags with a Value:

you can specify repeatable flagged values by following the flag character with an asterisk (*). In the argument list you must provide a variable that can accept an array of character pointers. The Parseargs routine will allocate the array for you, so you must not allocate an array yourself. When you are done with the array of pointers you can dispose of it with the standard C library free() function.

 

Parameter with Optional Flag:

you can specify a positional parameter which can have an optional flag (in order to identify the parameter when it is not in the default position) by following the flag character with an equal sign (=). The flag and the parameter can either occupy the same argument (-fparameter) or in neighboring arguments (-f parameter).

 

Positional Parameter:

a plain positional parameter (without an optional flag) is specified by inserting a hash mark (#) into the format.

 

Required Positional Parameter:

a required positional parameter is specified with a plus sign (+) in the format.

With the various positional parameter specifications the order in the format string is of vital importance. All required parameters must appear before any optional parameters or optional flagged parameters. The parseargs routines will return an error if the format string is badly constructed with respect to the order of required and optional parameters. With flags and flag/value pairs, however, the order is irrelevent.

Finally, you can specify the that your program can accept further arguments than those specified in the format string by ending the format string with a question mark (?). These 'extended' parameters will be placed in the ext parameter. When you are done with the extended parameters you can dispose of the pointer array with the free() function.

Once you have construted a format string, you pass it to the routine along with string variables for each value or parameter specified. The string variables must occur in the same order as the format specifiecations in a similar manner to printf or scanf. You also need to provide a string that will contain each of the flags that have been seen by the parser.

You can also use the format string parseusage function to generate a usage string for your program. The usage string will be formatted in a similar manner to the usage strings in the SYNOPSIS sections of various UNIX manpages. You need to provide the name of the program (usually gotten from the first element (0) in the command line arguments list) and a name for each value or parameter. This is also done in a manner similar to the printf function.

Finally, the parseerror and badusage functions can be used to present errors returned by parseargs in a human readable form and to determine when an error code indicates that the program was called with bad arguments (which should prompt the program to display a usage message).

 

EXIT STATUS

The function parseargs returns either the number of arguments it has processed (meaning that the index of the first unprocessed argument is equal to the return code: i.e. arg[rv]) on success, or a negative number on failure. The failure value still has, in the low order digits, the number of arguments processed when the failure occurred. You can get this value by masking off the high order digits using division modulo 1000. The high order digits contain a code specifying where and why the routine failed. The parseerror routine will convert the return code into a human readable string explaning the failure.

 

FILES

The functions are contained in the libutils.a library. The protoypes can be found in either the utils.h or parseargs.h header file. (both should be present in the installation)

 

EXAMPLE

The following C program shows the proper usage of all four functions:

#include <stdio.h>
#include <string.h>
#include "utils.h"

int main(int args, char *arg[]){
        char *fmt="ab:+c=#";
        char val_b[256], param_c[256], rparam[256], oparam[256];
        char opts[256];
        int rv;
        
        strcpy(val_b,"");       /* you can initialize these strings */
        strcpy(param_c,"");     /* to other default values as well */
        strcpy(rparam,"");
        strcpy(oparam,"");
        strcpy(opts,"");
        
        rv=parseargs(args,arg,fmt,flags,NULL,val_b,param_c,rparam,oparam);
        if(rv<0){
                if(badusage(rv)){
                        fprintf(stderr,"\nUsage:\n%s\n\n",parseusage(arg[0],
                                80, fmt,"value-b","r-param","param-c","o-param"));
                        fprintf(stderr,"\t-a  this is a flag\n\n");
                        /* note that you still need to provide your own
                        explanations of the various flags and such. Each line
                        of explanation should be tabbed in once to match the
                        indention of the usage string as well. */
                        return 0;
                }else{
                        fprintf(stderr,"Parser Error #%d: %s\n",parseerror(rv));
                        return rv;
                }
        }
        if(strlen(opts))
                printf("flags=\"%s\"\n",opts);
        if(strlen(val_b))
                printf("val b=\"%s\"\n",val_b);
        if(strlen(param_c))
                printf("param c=\"%s\"\n",param_c);
        if(strlen(rparam))
                printf("rparam=\"%s\"\n",rparam);
        if(strlen(oparam))
                printf("oparam=\"%s\"\n",oparam);
        return 0;
}

The above program, when compiled and run without any arguments (which is a bad usage, because the program specifies a reqired parameter) will produce the following output:

$ a.out

Usage:
        a.out [-a] [-b value-b] r-param [[-c] param-c] [o-param]

        -a  this is a flag

When called with various combinations of arguments, the program produces this output:

$ a.out one
param c="one"

$ a.out one two
param c="one"
rparam="two"

$ a.out one two three
param c="one"
rparam="two"
oparam="three"

 

CAVEATS

Obviously there are some minor caveats with the use of parseargs, especially when you specify required parameters. The interpretation of required parameters is tricky and can lead to unexpected results unless you arrange the parameters in a very precise order. Even then, the way parseargs asigns things can suprise you.  

KNOWN BUGS

The odd handling of arguments in the presence of required parameters could easily be termed a bug. Hopefully I'll figure out a way to fix the behaviour.

Also, due to the function's use of basic string handling functions there is a reasonable chance of buffer overruns. Be sure to allocate enough space in your value strings for any conceivable arguments. (since most command shells impose an upper limit on the length of an entire command line, this problem should not occur in practice)  

AUTHOR

Jeffrey S. Dutky <dutky@bellatlantic.net>


 

Index

NAME
VERSION
SYNOPSIS
DESCRIPTION
Flags:
Flags with a Value:
Repeatable Flags with a Value:
Parameter with Optional Flag:
Positional Parameter:
Required Positional Parameter:
EXIT STATUS
FILES
EXAMPLE
CAVEATS
KNOWN BUGS
AUTHOR

This document was created by man2html, using the manual pages.
Time: 03:49:37 GMT, July 12, 2001