/* -*-c-*-
*
- * $Id: mdwopt.c,v 1.4 1999/05/15 10:25:38 mdw Exp $
+ * $Id: mdwopt.c,v 1.5 1999/05/19 20:23:59 mdw Exp $
*
* Options parsing, similar to GNU @getopt_long@
*
/*----- Revision history --------------------------------------------------*
*
* $Log: mdwopt.c,v $
+ * Revision 1.5 1999/05/19 20:23:59 mdw
+ * Change naming to match newer mLib conventions.
+ *
* Revision 1.4 1999/05/15 10:25:38 mdw
* Fix copyright information.
*
mdwopt_data mdwopt_global = {0, 0, 0, 1, 0, 0, 0, 0, 0};
enum {
- ord__permute = 0, /* Permute the options (default) */
- ord__return = 1, /* Return non-option things */
- ord__posix = 2, /* Do POSIX-type hacking */
- ord__negate = 4 /* Magic negate-next-thing flag */
+ ORD_PERMUTE = 0, /* Permute the options (default) */
+ ORD_RETURN = 1, /* Return non-option things */
+ ORD_POSIX = 2, /* Do POSIX-type hacking */
+ ORD_NEGATE = 4 /* Magic negate-next-thing flag */
};
/*----- Main code ---------------------------------------------------------*/
-/* --- @mo__nextWord@ --- *
+/* --- @nextWord@ --- *
*
* Arguments: @int argc@ = number of command line options
* @char *argv[]@ = pointer to command line options
* variable.
*/
-static char *mo__nextWord(int argc, char *const *argv, mdwopt_data *data)
+static char *nextWord(int argc, char *const *argv, mdwopt_data *data)
{
if (data->ind == -1) {
char *p = data->env;
return (argv[data->next++]);
}
-/* --- @mo__permute@ --- *
+/* --- @permute@ --- *
*
* Arguments: @char *argv[]@ = pointer to command line arguments
* @mdwopt_data *data@ = pointer to persistent data
* Use: Moves a command line option into the right place.
*/
-static void mo__permute(char *const *argv, mdwopt_data *data)
+static void permute(char *const *argv, mdwopt_data *data)
{
char **v = (char **)argv;
if (data->ind != -1) {
}
}
-/* --- @mo__findOpt@ --- *
+/* --- @findOpt@ --- *
*
* Arguments: @int o@ = which option to search for
* @const char *shortopt@ = short options string to search
* Use: Looks up a short option in the given string.
*/
-static const char *mo__findOpt(int o, const char *shortopt,
+static const char *findOpt(int o, const char *shortopt,
mdwopt_data *data)
{
const char *p = shortopt; /* Point to short opts table */
if (!*p) /* No more options left */
return (0);
- if (o != *p || (p[1] != '+' && data->order & ord__negate)) {
+ if (o != *p || (p[1] != '+' && data->order & ORD_NEGATE)) {
p++; /* Skip this option entry */
while (*p == '+') /* Jump a `%|+|%' sign */
p++;
* the caller. A pointer to an argument is stored in
* @data->arg@, or @NULL@ is stored if there was no argument.
* If a negated option was found, the option character is
- * returned ORred with @gFlag_negated@ (bit 8 set).
+ * returned ORred with @OPTF_NEGATED@ (bit 8 set).
*
* Long options are described in a table. Each entry in the
* table is of type @struct option@, and the table is terminated
* table entry. If @flag@ is nonzero, it points to an integer
* to be modified by mdwopt. Usually the value in the @val@
* field is simply stored in the @flag@ variable. If the flag
- * @gFlag_switch@ is set, however, the value is combined with
+ * @OPTF_SWITCH@ is set, however, the value is combined with
* the existing value of the flags using a bitwise OR. If
- * @gFlag_negate@ is set, then the flag bit will be cleared if a
+ * @OPTF_NEGATE@ is set, then the flag bit will be cleared if a
* matching negated long option is found. The value 0 is
* returned.
*
* Numeric options, if enabled, cause the value `%|#|%' to be
* returned, and the numeric value to be stored in @data->opt@.
*
- * If the flag @gFlag_envVar@ is set on entry, options will be
+ * If the flag @OPTF_ENVVAR@ is set on entry, options will be
* extracted from an environment variable whose name is built by
* capitalising all the letters of the program's name. (This
* allows a user to have different default settings for a
/* --- See if this is the first time --- */
- if (data->ind == 0 || (data->ind == 1 && ~flags & gFlag_noProgName)) {
+ if (data->ind == 0 || (data->ind == 1 && ~flags & OPTF_NOPROGNAME)) {
/* --- Sort out default returning order --- */
if (getenv("_POSIX_OPTION_ORDER") || /* Examine environment for opts */
getenv("POSIXLY_CORRECT")) /* To see if we disable features */
- data->order = ord__posix; /* If set, use POSIX ordering */
+ data->order = ORD_POSIX; /* If set, use POSIX ordering */
else
- data->order = ord__permute; /* Otherwise mangle the options */
+ data->order = ORD_PERMUTE; /* Otherwise mangle the options */
/* --- Now see what the caller actually wants --- */
switch (shortopt[0]) { /* Look at the first character */
case '-': /* `%|-|%' turns on in-orderness */
- data->order = ord__return;
+ data->order = ORD_RETURN;
break;
case '+': /* `%|+|%' turns on POSIXness */
- data->order = ord__posix;
+ data->order = ORD_POSIX;
break;
case '!': /* `%|!|%' ignores POSIXness */
- data->order = ord__permute;
+ data->order = ORD_PERMUTE;
break;
}
/* --- Now decide on the program's name --- */
- if (~flags & gFlag_noProgName) {
+ if (~flags & OPTF_NOPROGNAME) {
p = q = (char *)argv[0];
while (*p) {
if (*p++ == PATHSEP)
* support this option.
*/
- if (flags & gFlag_envVar && strlen(data->prog) < 48) {
+ if (flags & OPTF_ENVVAR && strlen(data->prog) < 48) {
char buf[64];
* We identify options as being things starting with `%|-|%', and which
* aren't equal to `%|-|%' or `%|--|%'. We'll look for options until:
*
- * * We find something which isn't an option AND @order == ord__posix@
+ * * We find something which isn't an option AND @order == ORD_POSIX@
* * We find a `%|--|%'
* * We reach the end of the list
*
*/
for (;;) { /* Keep looping for a while */
- p = mo__nextWord(argc, argv, data); /* Get the next word out */
+ p = nextWord(argc, argv, data); /* Get the next word out */
if (!p) /* If there's no next word */
return (EOF); /* There's no more now */
/* --- See if we've found an option --- */
- if ((p[0] == '-' || (p[0] == '+' && flags & gFlag_negation)) &&
+ if ((p[0] == '-' || (p[0] == '+' && flags & OPTF_NEGATION)) &&
p[1] != 0) {
if (strcmp(p, "--") == 0) { /* If this is the magic marker */
- mo__permute(argv, data); /* Stow the magic marker item */
+ permute(argv, data); /* Stow the magic marker item */
return (EOF); /* There's nothing else to do */
}
break; /* We've found something! */
/* --- Figure out how to proceed --- */
switch (data->order & 3) {
- case ord__posix: /* POSIX option order */
+ case ORD_POSIX: /* POSIX option order */
return (EOF); /* This is easy */
break;
- case ord__permute: /* Permute the option order */
+ case ORD_PERMUTE: /* Permute the option order */
break;
- case ord__return: /* Return each argument */
- mo__permute(argv, data); /* Insert word in same place */
+ case ORD_RETURN: /* Return each argument */
+ permute(argv, data); /* Insert word in same place */
data->arg = p; /* Point to the argument */
return (0); /* Return the value */
}
/* --- We found an option --- */
- mo__permute(argv, data); /* Do any permuting necessary */
+ permute(argv, data); /* Do any permuting necessary */
/* --- Check for a numeric option --- *
*
* sign). This ought to be enough.
*/
- if (flags & gFlag_numbers && (p[0] == '-' || flags & gFlag_negNumber)) {
+ if (flags & OPTF_NUMBERS && (p[0] == '-' || flags & OPTF_NEGNUMBER)) {
if (((p[1] == '+' || p[1] == '-') && isdigit((unsigned char)p[2])) ||
isdigit((unsigned char)p[1])) {
data->opt = strtol(p + 1, &data->arg, 10);
data->arg++;
if (!data->arg[0])
data->arg = 0;
- return (p[0] == '-' ? '#' : '#' | gFlag_negated);
+ return (p[0] == '-' ? '#' : '#' | OPTF_NEGATED);
}
}
/* --- Check for a long option --- */
if (p[0] == '+')
- data->order |= ord__negate;
+ data->order |= ORD_NEGATE;
if (((p[0] == '-' && p[1] == '-') ||
- (flags & gFlag_noShorts && !mo__findOpt(p[1], shortopt, data))) &&
- (~flags & gFlag_noLongs)) /* Is this a long option? */
+ (flags & OPTF_NOSHORTS && !findOpt(p[1], shortopt, data))) &&
+ (~flags & OPTF_NOLONGS)) /* Is this a long option? */
{
int match = -1; /* Count matches as we go */
if (p[0] == '+') { /* If it's negated */
- data->order |= ord__negate; /* Set the negate flag */
+ data->order |= ORD_NEGATE; /* Set the negate flag */
p++; /* Point to the main text */
prefix = "+"; /* Set the prefix string up */
} else if (p[1] == '-') { /* If this is a `%|--|%' option */
- if ((flags & gFlag_negation) && strncmp(p + 2, "no-", 3) == 0) {
+ if ((flags & OPTF_NEGATION) && strncmp(p + 2, "no-", 3) == 0) {
p += 5; /* Point to main text */
prefix = "--no-"; /* And set the prefix */
- data->order |= ord__negate; /* Set the negatedness flag */
+ data->order |= ORD_NEGATE; /* Set the negatedness flag */
} else {
p += 2; /* Point to the main text */
prefix = "--"; /* Remember the prefix string */
}
} else {
- if ((flags & gFlag_negation) && strncmp(p + 1, "no-", 3) == 0) {
+ if ((flags & OPTF_NEGATION) && strncmp(p + 1, "no-", 3) == 0) {
p += 4; /* Find the text */
prefix = "-no-"; /* Set the prefix */
- data->order |= ord__negate; /* Set negatedness flag */
+ data->order |= ORD_NEGATE; /* Set negatedness flag */
} else {
p++; /* Otherwise find the text */
prefix = "-"; /* And remember the prefix */
}
for (i = 0; longopts[i].name; i++) { /* Loop through the options */
- if ((data->order & ord__negate) &&
- (~longopts[i].has_arg & gFlag_negate))
+ if ((data->order & ORD_NEGATE) &&
+ (~longopts[i].has_arg & OPTF_NEGATE))
continue; /* If neg and opt doesn't allow */
r = (char *) longopts[i].name; /* Point to the name string */
case required_argument:
if (!p) { /* If no argument given */
- p = mo__nextWord(argc, argv, data);
+ p = nextWord(argc, argv, data);
if (!p) { /* If no more arguments */
if (data->err) {
return (noarg);
}
- mo__permute(argv, data);
+ permute(argv, data);
}
break;
/* --- Do correct things now we have a match --- */
if (longopts[match].flag) { /* If he has a @flag@ argument */
- if (longopts[match].has_arg & gFlag_switch) {
- if (data->order & ord__negate)
+ if (longopts[match].has_arg & OPTF_SWITCH) {
+ if (data->order & ORD_NEGATE)
*longopts[match].flag &= ~longopts[match].val;
else
*longopts[match].flag |= longopts[match].val;
} else {
- if (data->order & ord__negate)
+ if (data->order & ORD_NEGATE)
*longopts[match].flag = 0;
else
*longopts[match].flag = longopts[match].val;
}
return (0); /* And return something */
} else {
- if (data->order & ord__negate)
- return (longopts[match].val | gFlag_negated);
+ if (data->order & ORD_NEGATE)
+ return (longopts[match].val | OPTF_NEGATED);
else
return (longopts[match].val);
}
else {
if (p[0] == '+') /* If starts with a `%|+|%' */
- data->order |= ord__negate;
+ data->order |= ORD_NEGATE;
data->list = p + 1; /* Omit leading `%|-|%'/`%|+|%' */
}
}
i = *data->list++; /* Get the next option letter */
data->opt = i; /* Store this away nicely */
- p = (char *) mo__findOpt(i, shortopt, data);
+ p = (char *) findOpt(i, shortopt, data);
if (!p) { /* No more options left */
if (data->err) {
fprintf(stderr, "%s: unknown option `%c%c'\n",
data->prog,
- data->order & ord__negate ? '+' : '-',
+ data->order & ORD_NEGATE ? '+' : '-',
i);
}
return ('?');
/* --- Same code as before --- */
- q = mo__nextWord(argc, argv, data); /* Read the next word */
+ q = nextWord(argc, argv, data); /* Read the next word */
if (!q) { /* If no more arguments */
if (data->err) {
fprintf(stderr, "%s: option `%c%c' requires an argument\n",
data->prog,
- data->order & ord__negate ? '+' : '-',
+ data->order & ORD_NEGATE ? '+' : '-',
i);
}
return (noarg);
}
- mo__permute(argv, data);
+ permute(argv, data);
}
data->arg = q;
}
- return ((data->order & ord__negate) ? i | gFlag_negated : i);
+ return ((data->order & ORD_NEGATE) ? i | OPTF_NEGATED : i);
}
/*----- That's all, folks -------------------------------------------------*/
/* -*-c-*-
*
- * $Id: mdwopt.h,v 1.4 1999/05/15 10:25:38 mdw Exp $
+ * $Id: mdwopt.h,v 1.5 1999/05/19 20:23:59 mdw Exp $
*
* Options parsing, similar to GNU @getopt_long@
*
/*----- Revision history --------------------------------------------------*
*
* $Log: mdwopt.h,v $
+ * Revision 1.5 1999/05/19 20:23:59 mdw
+ * Change naming to match newer mLib conventions.
+ *
* Revision 1.4 1999/05/15 10:25:38 mdw
* Fix copyright information.
*
/* --- @mdwopt_data@ --- *
*
* Contains all the information needed by the @mdwopt@ routine to do its
- * work.
+ * work. Try not to use @prog@ any more. If you're using mLib, the @quis@/
+ * @ego@ interface works better.
*/
typedef struct {
+
/* --- Public variables --- */
char *arg; /* Arg of current option, or 0 */
/* --- New style flag names --- */
enum {
- gFlag_argReq = 1, /* Required argument */
- gFlag_argOpt = 2, /* Optional argument */
- gFlag_switch = 4, /* OR val into flag, don't store */
- gFlag_negate = 8, /* Allow long option to be negated */
- gFlag__last_long_opt_flag = 0 /* Dummy value */
+ OPTF_ARGREQ = 1, /* Required argument */
+ OPTF_ARGOPT = 2, /* Optional argument */
+ OPTF_SWITCH = 4, /* OR val into flag, don't store */
+ OPTF_NEGATE = 8 /* Allow long option to be negated */
+};
+
+enum {
+ OPTF_NOLONGS = 1, /* Don't read long options */
+ OPTF_NOSHORTS = 2, /* Don't read short options */
+ OPTF_NUMBERS = 4, /* Read numeric options */
+ OPTF_NEGATION = 8, /* Allow `%|+|%' for negations */
+ OPTF_ENVVAR = 16, /* Parse options from env var */
+ OPTF_NOPROGNAME = 32, /* Don't set @optprog@ */
+ OPTF_NEGNUMBER = 64 /* Allow negated number options */
+};
+
+enum {
+ OPTF_NEGATED = 256 /* Option flag was negated by user */
+};
+
+/* --- Older new-style names --- */
+
+enum {
+ gFlag_argReq = 1, gFlag_argOpt = 2, gFlag_switch = 4, gFlag_negate = 8
};
enum {
- gFlag_noLongs = 1, /* Don't read long options */
- gFlag_noShorts = 2, /* Don't read short options */
- gFlag_numbers = 4, /* Read numeric options */
- gFlag_negation = 8, /* Allow `%|+|%' for negations */
- gFlag_envVar = 16, /* Parse options from env var */
- gFlag_noProgName = 32, /* Don't set @optprog@ */
- gFlag_negNumber = 64, /* Allow negated number options */
- gFlag__last_mdwopt_flag = 0 /* Dummy value */
+ gFlag_noLongs = 1, gFlag_noShorts = 2, gFlag_numbers = 4,
+ gFlag_negation = 8, gFlag_envVar = 16, gFlag_noProgName = 32,
+ gFlag_negNumber = 64
};
enum {
- gFlag_negated = 256, /* Option flag was negated by user */
- gFlag__last_return_flag = 0 /* Dummy value */
+ gFlag_negated = 256
};
/*----- Main code ---------------------------------------------------------*/