Content-type: text/html
const char*parseerror(int error)
const char *parseusage(char *progname, int width, char *format, ...)
int badusage(int retval)
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.
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).
#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"
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)