Dependencies:
hest depends on the air library
for the airType enum, the airParseStr[] array of
parsing functions, the airStrtok() and airStrntok()
functions, and the airMop functionality (used for memory
management).
Structs:
The hestOpt struct is the important one:
the struct contains all the information and state used to deal with
identifying and parsing one command-line option. The last two members
of the struct are used by hestParse() for book-keeping,
and should be of no interest to hest users.
typedef struct {
char *flag, /* how the option is identified on the cmd line */
*name; /* simple description of option's parameter(s) */
int type, /* type of option (from airType enum) */
min, max; /* min and max # of parameters for option */
void *valueP; /* storage of parsed values */
char *dflt, /* default value written out as string */
*info; /* description to be printed with "glossary" info */
int *sawP, /* used ONLY for multiple variable parameter options
(min < max > 2): storage of # of parsed values */
/* --------------------- end of user-defined fields */
kind, /* what kind of option is this, based on min and max,
set by hestParse() (actually _hestPanic()),
later used by hestFree():
1: min == max == 0
a binary flag, no parameters
2: min == max == 1
one required parameter
3: min == max >= 2
multiple required parameters
4: min == 0; max == 1;
one optional parameter
5: max - min >= 1; max >= 2
multiple optional parameter */
alloc; /* information about whether flag is non-NULL, and what
parameters were used, that determines whether or
not memory was allocated by hestParse(); info
later used by hestParseFree():
0: no free()ing needed
1: free(*valueP), either because it is a single
string, or because was a dynamically allocated
array of non-strings
2: free((*valueP)[i]), because they are elements
of a fixed-length array of strings
3: free((*valueP)[i]) and free(*valueP), because
it is a dynamically allocated array of strings */
} hestOpt;
All the hest functions which take a hestOpt* has one
of their arguments expect an array of these structs (and not an array
of pointers to the structs). Such an array can be created statically
or dynamically, see usage basics. The
hest functions assume that the array is terminated by a struct
who's tag and name are both NULL, and
who's type is zero (not a valid type value in the
airType enum).
The hestParm struct contains various parameters affecting the
behavior of the hest functions, is the place for future
customizations and extra control. If you are happy with the defaults,
you can always pass NULL instead of a hestParm pointer.
typedef struct {
int verbosity, /* verbose diagnostic messages to stdout */
respFileEnable, /* whether or not to use response files */
columns; /* number of printable columns in output */
char respFileFlag, /* the character at the beginning of an argument
indicating that this is a response file name */
respFileComment, /* comment character for the repose files */
varParamStopFlag; /* prefixed by '-' to form the flag which signals
the end of a flagged variable parameter option
(single or multiple) */
} hestParm;
Globals:
These define the default behavior that you get by passing a NULL
hestParm to any of the hest functions. When a
hestParmNew() creates a new hestParm, the fields are
initialized to the values shown below. This is an extract from
the defaults.c file which defines these variables:
int hestVerbosity = 0;
int hestRespFileEnable = AIR_FALSE;
int hestColumns = 80;
char hestRespFileFlag = '@';
char hestRespFileComment = '#';
char hestVarParamStopFlag = '-';
Note that response files are not enabled by default. The
hestColumns variable controls word wrap-around in the
printing that hestInfo(), hestUsage() and
hestGlossary do. The hestRespFileFlag character
should be chosen to be a very very unlikely first character of any
unflagged parameters.
The Important Functions:
Note: See the examples page for
demonstrations of the output of the functions below for a variety
of different options.
int hestParse(hestOpt *opt, int argc, char **argv,
char **errP, hestParm *parm);
- The return value is 0 if there was no problem, and 1 if there was
a problem.
- opt is an array of hestOpt structs, created by either of the
means illustrated in usage basics.
- argc, argv are the part of the
command line that hestParse() is supposed to make sense of.
For most programs, the executable name is in argv[0],
so you would pass argc-1, argv+1
where argc and argv are the arguments
to your main() function. hestParse() will not
alter the contents of these arrays, all the work it does are with
local copies.
- errP is the address of a char*. If there
is an error in parsing, hestParse() will set *errP
to the address of a newly allocated the error message. If you pass
NULL, no error message is allocated, and you don't get to know what
went wrong. If you do pass a non-NULL errP and there
is an error, it is your responsibility to free() the
resulting error message buffer. hestParseFree() will not do
it for you.
- parm is how you control behavior relating to how
parsing is done. If all the defaults are just fine with you
(as seen in Globals above), then you
just pass NULL. Otherwise, you
create a hestParm with hestParmNew(), and set the members as you
wish, before passing it to all the hest functions which take a
hestParm. When you're done, delete it with hestParmFree().
void hestParseFree(hestOpt *opt);
- As described in usage details,
hestParse() sometimes allocates memory in order to save the
values that are parsed from the command line. If its important to you
to stay on top of each and every bit of dynamic memory allocation,
then you can call hestParseFree() to free all the memory that
hestParse() allocates.
- The information that is ultimately being passed to
free() is the valueP member of the hestOpt
struct, which generally is set to the address of some pointer variable
in the user's program. hestParseFree() will set the
pointer variable to NULL to make sure no one accidentally uses
freed memory.
- Obviously, you need to pass to hestParseFree() the same
opt argument you've previously passed to
hestParse().
void hestUsage(FILE *file, hestOpt *opt,
char *argv0, hestParm *parm);
- The usage information is printed to the given FILE*;
stderr is a likely choice.
- opt is as described above.
- argv0 is a string containing the executable name
of the program for which you want the usage information. This string
precedes all the identification of the options in the printed usage
line.
- parm is as described above.
- How an option is identified in the usage information is a little
complicated, but the basics are:
- If the option is optional (since default information has been
supplied), then its identification is deliminated by square bracets.
- If the option is flagged, then the flag is printed at the beginning
of the identification
- The "name" of the option (the name member of the
hestOpt struct) appears in angle brackets.
void hestGlossary(FILE *file, hestOpt *opt,
hestParm *parm);
- The glossary information is printed to the given FILE*;
stderr is a likely choice.
- The role of the glossary information is to display the
info member of the hestOpt struct (a longer and more
detailed explanation of the option), to identify what information will
be parsed on the command line (how many parameters, and of what type),
and to indicate what the default values (if any) are for the option.
void hestInfo(FILE *file, char *argv0,
char *info, hestParm *parm);
- Sometimes, in addition to the usage or glossary information, it
is nice to print a longer description of what a program does in
general. hestInfo() simply prints that information, subject to
the word wrapping imposed by the number of columns.
- The general information is printed to the given FILE*;
stderr is a likely choice.
- argv0 is a string containing the executable name
of the program for which you want the general information.
- info is a string containing the general information.
Utility Functions:
hestParm *hestParmNew();
hestParm *hestParmFree(hestParm *parm);
- These are the pseudo-constructors and destructors for the
hestParm struct
- The return value of hestParmNew() is the address of a
newly allocated and initialized hestParm, using the default
values set in defaults.c.
- The return value of hestParmFree() is NULL, to assist
in the avoidance of pointers to freed memory.
- Currently the hestParm has no dynamically allocated
elements, so these functions are currently slightly overkill.
void hestOptAdd(hestOpt **optP, char *flag, char *name,
int type, int min, int max,
void *valueP, char *dflt, char *info, ...);
- This is the function which is called repeatedly to build up an
array of hestOpt structs, to be passed on to the other
hest functions.
- The first argument to this is the address of a hestOpt
pointer. You start building an option list by passing the address of
a pointer initialized to NULL. With each call, a bigger array is
allocated and the old contents are copied over, so the value of
*optP may change after each call. Maximally slick, fast, and
efficient? No-- but who cares: we're just parsing a stupid command
line, and a single function to build the option list is nice to have.
- The next eight arguments are exactly the same as the first
eight members of the hestOpt struct.
- You should not try to mix static and dynamic hestOpt
array declarations.
- Notice that the last argument is a va_list variable
argument list. This argument is only for multiple variable
parameter options (min < max; max >
1), and in this case it must be used. As is shown in usage basics, pass the address of an
int for this argument, so that you can learn how many elements were
parsed on the command line.
- As is the general practice in teem, the strings arguments
to this function are always duplicated, so you need not
worry about the char*s in the hestOpt array pointing
to memory which you might want to free.
int hestOptCheck(hestOpt *opt, char **errP);
- This is how you check to make sure that you're hestOpt
array is well-defined. This applies to hestOpt arrays
created either statically or dynamically.
- The return value is 0 if there are no problems, and 1 if there
are problems.
- If you pass the address of a char* as errP,
and there is an error, then hestOptCheck() will set *errP
to a newly allocated string containing the error message. It is up
to you to free this string. If there is no error, then *errP
is set to NULL.
- You can pass NULL as errP, but you won't know why the
hestOpt array is broken. The return value of hestOptCheck()
is still a useful indicator.
hestOpt *hestOptFree(hestOpt *opt);
- This frees the hestOpt array that was created
dynamically by repeated calls to hestOptAdd(), and this also
frees the numerous strings that hang off the hestOpt struct.
- This is only for freeing a hestOpt array created
dynamically (with hestOptAdd()).