|
Packit |
022b05 |
/* $Id: shhopt.c 1418 2002-07-22 17:06:19Z schoenw $ */
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| FILE shhopt.c
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| DESCRIPTION Functions for parsing command line arguments. Values
|
|
Packit |
022b05 |
| of miscellaneous types may be stored in variables,
|
|
Packit |
022b05 |
| or passed to functions as specified.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| REQUIREMENTS Some systems lack the ANSI C -function strtoul. If your
|
|
Packit |
022b05 |
| system is one of those, you'll ned to write one yourself,
|
|
Packit |
022b05 |
| or get the GNU liberty-library (from prep.ai.mit.edu).
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| WRITTEN BY Sverre H. Huseby <sverrehu@online.no>
|
|
Packit |
022b05 |
+----------------------------------------------------------------------*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include <stdio.h>
|
|
Packit |
022b05 |
#include <stdlib.h>
|
|
Packit |
022b05 |
#include <stdarg.h>
|
|
Packit |
022b05 |
#include <string.h>
|
|
Packit |
022b05 |
#include <ctype.h>
|
|
Packit |
022b05 |
#include <limits.h>
|
|
Packit |
022b05 |
#include <errno.h>
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
#include "shhopt.h"
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*-----------------------------------------------------------------------+
|
|
Packit |
022b05 |
| PRIVATE DATA |
|
|
Packit |
022b05 |
+-----------------------------------------------------------------------*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
static void optFatalFunc(const char *, ...);
|
|
Packit |
022b05 |
static void (*optFatal)(const char *format, ...) = optFatalFunc;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*-----------------------------------------------------------------------+
|
|
Packit |
022b05 |
| PRIVATE FUNCTIONS |
|
|
Packit |
022b05 |
+-----------------------------------------------------------------------*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optFatalFunc
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Show given message and abort the program.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT format, ...
|
|
Packit |
022b05 |
| Arguments used as with printf().
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Never returns. The program is aborted.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
void
|
|
Packit |
022b05 |
optFatalFunc(const char *format, ...)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
va_list ap;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
fflush(stdout);
|
|
Packit |
022b05 |
va_start(ap, format);
|
|
Packit |
022b05 |
vfprintf(stderr, format, ap);
|
|
Packit |
022b05 |
va_end(ap);
|
|
Packit |
022b05 |
exit(99);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optStructCount
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Get number of options in a optStruct.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT opt array of possible options.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Number of options in the given array.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| DESCRIPTION Count elements in an optStruct-array. The strcture must
|
|
Packit |
022b05 |
| be ended using an element of type OPT_END.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
static int
|
|
Packit |
022b05 |
optStructCount(optStruct opt[])
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int ret = 0;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
while (opt[ret].type != OPT_END)
|
|
Packit |
022b05 |
++ret;
|
|
Packit |
022b05 |
return ret;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optMatch
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Find a matching option.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT opt array of possible options.
|
|
Packit |
022b05 |
| s string to match, without `-' or `--'.
|
|
Packit |
022b05 |
| lng match long option, otherwise short.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Index to the option if found, -1 if not found.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| DESCRIPTION Short options are matched from the first character in
|
|
Packit |
022b05 |
| the given string.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
static int
|
|
Packit |
022b05 |
optMatch(optStruct opt[], const char *s, int lng)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int nopt, q;
|
|
Packit |
022b05 |
const char *p;
|
|
Packit |
022b05 |
size_t matchlen = 0;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
nopt = optStructCount(opt);
|
|
Packit |
022b05 |
if (lng) {
|
|
Packit |
022b05 |
if ((p = strchr(s, '=')) != NULL)
|
|
Packit |
022b05 |
matchlen = p - s;
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
matchlen = strlen(s);
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
for (q = 0; q < nopt; q++) {
|
|
Packit |
022b05 |
if (lng) {
|
|
Packit |
022b05 |
if (!opt[q].longName)
|
|
Packit |
022b05 |
continue;
|
|
Packit |
022b05 |
if (strncmp(s, opt[q].longName, matchlen) == 0)
|
|
Packit |
022b05 |
return q;
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
if (!opt[q].shortName)
|
|
Packit |
022b05 |
continue;
|
|
Packit |
022b05 |
if (*s == opt[q].shortName)
|
|
Packit |
022b05 |
return q;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
return -1;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optString
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Return a (static) string with the option name.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT opt the option to stringify.
|
|
Packit |
022b05 |
| lng is it a long option?
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Pointer to static string.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
static char *
|
|
Packit |
022b05 |
optString(optStruct *opt, int lng)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
static char ret[31];
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (lng) {
|
|
Packit |
022b05 |
strcpy(ret, "--");
|
|
Packit |
022b05 |
strncpy(ret + 2, opt->longName, 28);
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
ret[0] = '-';
|
|
Packit |
022b05 |
ret[1] = opt->shortName;
|
|
Packit |
022b05 |
ret[2] = '\0';
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
return ret;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optNeedsArgument
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Check if an option requires an argument.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT opt the option to check.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Boolean value.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
static int
|
|
Packit |
022b05 |
optNeedsArgument(optStruct *opt)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
return opt->type == OPT_STRING
|
|
Packit |
022b05 |
|| opt->type == OPT_INT
|
|
Packit |
022b05 |
|| opt->type == OPT_UINT
|
|
Packit |
022b05 |
|| opt->type == OPT_LONG
|
|
Packit |
022b05 |
|| opt->type == OPT_ULONG;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME argvRemove
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Remove an entry from an argv-array.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT argc pointer to number of options.
|
|
Packit |
022b05 |
| argv array of option-/argument-strings.
|
|
Packit |
022b05 |
| i index of option to remove.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| OUTPUT argc new argument count.
|
|
Packit |
022b05 |
| argv array with given argument removed.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
static void
|
|
Packit |
022b05 |
argvRemove(int *argc, char *argv[], int i)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
if (i >= *argc)
|
|
Packit |
022b05 |
return;
|
|
Packit |
022b05 |
while (i++ < *argc)
|
|
Packit |
022b05 |
argv[i - 1] = argv[i];
|
|
Packit |
022b05 |
--*argc;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optExecute
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Perform the action of an option.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT opt array of possible options.
|
|
Packit |
022b05 |
| arg argument to option, if it applies.
|
|
Packit |
022b05 |
| lng was the option given as a long option?
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Nothing. Aborts in case of error.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
static void
|
|
Packit |
022b05 |
optExecute(optStruct *opt, char *arg, int lng)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
switch (opt->type) {
|
|
Packit |
022b05 |
case OPT_FLAG:
|
|
Packit |
022b05 |
if (opt->flags & OPT_CALLFUNC)
|
|
Packit |
022b05 |
((void (*)(void)) opt->arg)();
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
*((int *) opt->arg) = 1;
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
case OPT_STRING:
|
|
Packit |
022b05 |
if (opt->flags & OPT_CALLFUNC)
|
|
Packit |
022b05 |
((void (*)(char *)) opt->arg)(arg);
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
*((char **) opt->arg) = arg;
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
case OPT_INT:
|
|
Packit |
022b05 |
case OPT_LONG: {
|
|
Packit |
022b05 |
long tmp;
|
|
Packit |
022b05 |
char *e;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
tmp = strtol(arg, &e, 10);
|
|
Packit |
022b05 |
if (*e)
|
|
Packit |
022b05 |
optFatal("invalid number `%s'\n", arg);
|
|
Packit |
022b05 |
if (errno == ERANGE
|
|
Packit |
022b05 |
|| (opt->type == OPT_INT && (tmp > INT_MAX || tmp < INT_MIN)))
|
|
Packit |
022b05 |
optFatal("number `%s' to `%s' out of range\n",
|
|
Packit |
022b05 |
arg, optString(opt, lng));
|
|
Packit |
022b05 |
if (opt->type == OPT_INT) {
|
|
Packit |
022b05 |
if (opt->flags & OPT_CALLFUNC)
|
|
Packit |
022b05 |
((void (*)(int)) opt->arg)((int) tmp);
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
*((int *) opt->arg) = (int) tmp;
|
|
Packit |
022b05 |
} else /* OPT_LONG */ {
|
|
Packit |
022b05 |
if (opt->flags & OPT_CALLFUNC)
|
|
Packit |
022b05 |
((void (*)(long)) opt->arg)(tmp);
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
*((long *) opt->arg) = tmp;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
case OPT_UINT:
|
|
Packit |
022b05 |
case OPT_ULONG: {
|
|
Packit |
022b05 |
unsigned long tmp;
|
|
Packit |
022b05 |
char *e;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
tmp = strtoul(arg, &e, 10);
|
|
Packit |
022b05 |
if (*e)
|
|
Packit |
022b05 |
optFatal("invalid number `%s'\n", arg);
|
|
Packit |
022b05 |
if (errno == ERANGE
|
|
Packit |
022b05 |
|| (opt->type == OPT_UINT && tmp > UINT_MAX))
|
|
Packit |
022b05 |
optFatal("number `%s' to `%s' out of range\n",
|
|
Packit |
022b05 |
arg, optString(opt, lng));
|
|
Packit |
022b05 |
if (opt->type == OPT_UINT) {
|
|
Packit |
022b05 |
if (opt->flags & OPT_CALLFUNC)
|
|
Packit |
022b05 |
((void (*)(unsigned)) opt->arg)((unsigned) tmp);
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
*((unsigned *) opt->arg) = (unsigned) tmp;
|
|
Packit |
022b05 |
} else /* OPT_ULONG */ {
|
|
Packit |
022b05 |
if (opt->flags & OPT_CALLFUNC)
|
|
Packit |
022b05 |
((void (*)(unsigned long)) opt->arg)(tmp);
|
|
Packit |
022b05 |
else
|
|
Packit |
022b05 |
*((unsigned long *) opt->arg) = tmp;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
default:
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*-----------------------------------------------------------------------+
|
|
Packit |
022b05 |
| PUBLIC FUNCTIONS |
|
|
Packit |
022b05 |
+-----------------------------------------------------------------------*/
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optSetFatalFunc
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Set function used to display error message and exit.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| SYNOPSIS #include "shhopt.h"
|
|
Packit |
022b05 |
| void optSetFatalFunc(void (*f)(const char *, ...));
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT f function accepting printf()'like parameters,
|
|
Packit |
022b05 |
| that _must_ abort the program.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
void
|
|
Packit |
022b05 |
optSetFatalFunc(void (*f)(const char *, ...))
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
optFatal = f;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*------------------------------------------------------------------------
|
|
Packit |
022b05 |
| NAME optParseOptions
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| FUNCTION Parse commandline options.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| SYNOPSIS #include "shhopt.h"
|
|
Packit |
022b05 |
| void optParseOptions(int *argc, char *argv[],
|
|
Packit |
022b05 |
| optStruct opt[], int allowNegNum);
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| INPUT argc Pointer to number of options.
|
|
Packit |
022b05 |
| argv Array of option-/argument-strings.
|
|
Packit |
022b05 |
| opt Array of possible options.
|
|
Packit |
022b05 |
| allowNegNum
|
|
Packit |
022b05 |
| a negative number is not to be taken as
|
|
Packit |
022b05 |
| an option.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| OUTPUT argc new argument count.
|
|
Packit |
022b05 |
| argv array with arguments removed.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| RETURNS Nothing. Aborts in case of error.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| DESCRIPTION This function checks each option in the argv-array
|
|
Packit |
022b05 |
| against strings in the opt-array, and `executes' any
|
|
Packit |
022b05 |
| matching action. Any arguments to the options are
|
|
Packit |
022b05 |
| extracted and stored in the variables or passed to
|
|
Packit |
022b05 |
| functions pointed to by entries in opt.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| Options and arguments used are removed from the argv-
|
|
Packit |
022b05 |
| array, and argc is decreased accordingly.
|
|
Packit |
022b05 |
|
|
|
Packit |
022b05 |
| Any error leads to program abortion.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
void
|
|
Packit |
022b05 |
optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
|
|
Packit |
022b05 |
{
|
|
Packit |
022b05 |
int ai, /* argv index. */
|
|
Packit |
022b05 |
optarg, /* argv index of option argument, or -1 if none. */
|
|
Packit |
022b05 |
mi, /* Match index in opt. */
|
|
Packit |
022b05 |
done;
|
|
Packit |
022b05 |
char *arg, /* Pointer to argument to an option. */
|
|
Packit |
022b05 |
*o, /* pointer to an option character */
|
|
Packit |
022b05 |
*p;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/*
|
|
Packit |
022b05 |
* Loop through all arguments.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
for (ai = 0; ai < *argc; ) {
|
|
Packit |
022b05 |
/*
|
|
Packit |
022b05 |
* "--" indicates that the rest of the argv-array does not
|
|
Packit |
022b05 |
* contain options.
|
|
Packit |
022b05 |
*/
|
|
Packit |
022b05 |
if (strcmp(argv[ai], "--") == 0) {
|
|
Packit |
022b05 |
argvRemove(argc, argv, ai);
|
|
Packit |
022b05 |
break;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
if (allowNegNum && argv[ai][0] == '-' && isdigit(argv[ai][1])) {
|
|
Packit |
022b05 |
++ai;
|
|
Packit |
022b05 |
continue;
|
|
Packit |
022b05 |
} else if (strncmp(argv[ai], "--", 2) == 0) {
|
|
Packit |
022b05 |
/* long option */
|
|
Packit |
022b05 |
/* find matching option */
|
|
Packit |
022b05 |
if ((mi = optMatch(opt, argv[ai] + 2, 1)) < 0)
|
|
Packit |
022b05 |
optFatal("unrecognized option `%s'\n", argv[ai]);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/* possibly locate the argument to this option. */
|
|
Packit |
022b05 |
arg = NULL;
|
|
Packit |
022b05 |
if ((p = strchr(argv[ai], '=')) != NULL)
|
|
Packit |
022b05 |
arg = p + 1;
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/* does this option take an argument? */
|
|
Packit |
022b05 |
optarg = -1;
|
|
Packit |
022b05 |
if (optNeedsArgument(&opt[mi])) {
|
|
Packit |
022b05 |
/* option needs an argument. find it. */
|
|
Packit |
022b05 |
if (!arg) {
|
|
Packit |
022b05 |
if ((optarg = ai + 1) == *argc)
|
|
Packit |
022b05 |
optFatal("option `%s' requires an argument\n",
|
|
Packit |
022b05 |
optString(&opt[mi], 1));
|
|
Packit |
022b05 |
arg = argv[optarg];
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
if (arg)
|
|
Packit |
022b05 |
optFatal("option `%s' doesn't allow an argument\n",
|
|
Packit |
022b05 |
optString(&opt[mi], 1));
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
/* perform the action of this option. */
|
|
Packit |
022b05 |
optExecute(&opt[mi], arg, 1);
|
|
Packit |
022b05 |
/* remove option and any argument from the argv-array. */
|
|
Packit |
022b05 |
if (optarg >= 0)
|
|
Packit |
022b05 |
argvRemove(argc, argv, ai);
|
|
Packit |
022b05 |
argvRemove(argc, argv, ai);
|
|
Packit |
022b05 |
} else if (*argv[ai] == '-') {
|
|
Packit |
022b05 |
/* A dash by itself is not considered an option. */
|
|
Packit |
022b05 |
if (argv[ai][1] == '\0') {
|
|
Packit |
022b05 |
++ai;
|
|
Packit |
022b05 |
continue;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
/* Short option(s) following */
|
|
Packit |
022b05 |
o = argv[ai] + 1;
|
|
Packit |
022b05 |
done = 0;
|
|
Packit |
022b05 |
optarg = -1;
|
|
Packit |
022b05 |
while (*o && !done) {
|
|
Packit |
022b05 |
/* find matching option */
|
|
Packit |
022b05 |
if ((mi = optMatch(opt, o, 0)) < 0)
|
|
Packit |
022b05 |
optFatal("unrecognized option `-%c'\n", *o);
|
|
Packit |
022b05 |
|
|
Packit |
022b05 |
/* does this option take an argument? */
|
|
Packit |
022b05 |
optarg = -1;
|
|
Packit |
022b05 |
arg = NULL;
|
|
Packit |
022b05 |
if (optNeedsArgument(&opt[mi])) {
|
|
Packit |
022b05 |
/* option needs an argument. find it. */
|
|
Packit |
022b05 |
arg = o + 1;
|
|
Packit |
022b05 |
if (!*arg) {
|
|
Packit |
022b05 |
if ((optarg = ai + 1) == *argc)
|
|
Packit |
022b05 |
optFatal("option `%s' requires an argument\n",
|
|
Packit |
022b05 |
optString(&opt[mi], 0));
|
|
Packit |
022b05 |
arg = argv[optarg];
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
done = 1;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
/* perform the action of this option. */
|
|
Packit |
022b05 |
optExecute(&opt[mi], arg, 0);
|
|
Packit |
022b05 |
++o;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
/* remove option and any argument from the argv-array. */
|
|
Packit |
022b05 |
if (optarg >= 0)
|
|
Packit |
022b05 |
argvRemove(argc, argv, ai);
|
|
Packit |
022b05 |
argvRemove(argc, argv, ai);
|
|
Packit |
022b05 |
} else {
|
|
Packit |
022b05 |
/* a non-option argument */
|
|
Packit |
022b05 |
++ai;
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|
|
Packit |
022b05 |
}
|