/* progargs - a simple, extensible package for handling command line
 * arguments and tooltypes.
 *
 * Copyright © 1993 by Peter Schachte
 *
 * I hereby grant everyone the right to use this code for any purpose
 * whatsoever, so long as this copyright notice remains intact.
 */

struct arg_descriptor {
    char *name;		/* argument name for cmd line and tooltypes */
    int (*parser)(char *, void *, void **);
			/* function to parse value part of this arg and */
			/* store the result in specified location */
    void *extra_parse_arg; /* extra (2nd) arg passed to parser() function */
    int value_allowed;	/* option can be specified with a value?  If false, */
			/* then parser() must not look at its first arg */
    void **variable;	/* variable to set when option is specified */
};

/* Parse the command line args or tooltypes.  The first two args are
 * the argc and argv as passed to main().  The third arg is an array
 * of arg_descriptor structs.  The easiest way to build one of these
 * is as a static array initialized with the help of the macros below.
 */

void handle_args(int argc, char **argv, struct arg_descriptor *args);

/* This must be called just before exiting the program, to allow
 * cleanup of resources allocated by handle_args().
 */

void handle_args_finish(void);


/* These shouldn't be called directly, they are used by the macros below */
int parse_int_arg(char *string, void *extra, void **value);
int parse_string_arg(char *string, void *extra, void **value);
int parse_bool_arg(char *string, void *extra, void **value);

/* specify an integer argument named name, whose value is in var */
#define INT_ARG(name, var) \
    { (name), parse_int_arg, NULL, 1, (void *)(&(var)) }
/* specify a string argument named name, whose value is in var */
#define STRING_ARG(name, var) \
    { (name), parse_string_arg, NULL, 1, (void *)(&(var)) }
/* specify a boolean argument named name.  var is pos when name is specified
 * and !pos when NOname is specified.
 */
#define BOOL_ARG(name, var, pos) \
    { name, parse_string_arg, (void*)(pos), 0, (void *)(&(var)) }, \
    { "NO" name, parse_string_arg, (void*)!(pos), 0, (void *)(&(var)) }
