|
From: <kin...@us...> - 2025-09-29 08:13:42
|
Revision: 7520
http://sourceforge.net/p/teem/code/7520
Author: kindlmann
Date: 2025-09-29 08:13:39 +0000 (Mon, 29 Sep 2025)
Log Message:
-----------
The new implementation of hestParse, currently called hestParse2, seems to
finally be working. The old hestParse remains, although with some of the
changes below it may leak memory in ways it previously didn't. After further
debugging it will be removed (so parseHest.c) will be much shorter.
- ABI CHANGE: since hest's birth, the hestOpt struct has had an `int alloc`
that helped keep track of what was allocated as a result of parsing, and what
had to be freed. It could take on magic values 1, 2, 3, or 4, and the logic
that hestParseFree had to implement to keep track of all this (in a way that
depended on the option type, and the non-NULL-ity of CB->destroy in the case
of airTypeOther) was just hideous. Instead, now a `airArray *parseMop` is
used, to remember what needs to be freed. Free'ing or destroy'ing callbacks
added here (by _hestParseSingle[type]) with when=airMopAlways. And now,
hestParse(2) just adds hestParseFree to its in-case-of-error mop. This is so
so much simpler and easier than the original code.
- API CHANGE: hestParseFree now returns the the given `hestOpt *hopt`, instead
of void. This facilitates its use in mops.
- API CHANGE: removed the void*-taking-and-returning hestParmFree_vp and
hestOptFree_vp. These were experiments to make their use with an airMop less
clunky, because you no longer need the `(airMopper)` cast, but this was a
dumb idea: adding these _vp variants is work, so hundreds of other functions
in Teem do not have such a _vp variant, plus the `(airMopper)` cast idiom
is well-established.
- in many functions renamed parameter `hestOpt *opt` to `hestOpt *hopt`
for consistency with other hest parameters and variables
Modified Paths:
--------------
teem/trunk/src/hest/hest.h
teem/trunk/src/hest/methodsHest.c
teem/trunk/src/hest/parseHest.c
teem/trunk/src/hest/parsest.c
teem/trunk/src/hest/privateHest.h
teem/trunk/src/hest/test/ex6.c
teem/trunk/src/hest/usage.c
Modified: teem/trunk/src/hest/hest.h
===================================================================
--- teem/trunk/src/hest/hest.h 2025-09-29 07:59:10 UTC (rev 7519)
+++ teem/trunk/src/hest/hest.h 2025-09-29 08:13:39 UTC (rev 7520)
@@ -212,7 +212,7 @@
up in the same struct as the input parameters above, but it also makes sense to keep
all per-opt state in one place. The const-correctness we might want of hestParse is
thwarted by this internal state, but also by the important output fields, below. */
- int kind, /* What kind of option is this, based on min and max:
+ int kind; /* What kind of option is this, based on min and max:
0: (invalid; unset)
1: min == max == 0 stand-alone flag; no parameters
2: min == max == 1 single fixed parameter
@@ -221,15 +221,14 @@
5: min < max; max >= 2 multiple variadic parameters
This is set by hest functions as part of building up an array of hestOpt,
and informs the later action of hestOptFree */
- alloc; /* Information (set by hestParse) about how (if at all) memory was allocated
- by hestParse(). Informs later action of 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 */
+ airArray *parseMop; /* If non-NULL: remembers what was allocated at or behind *valueP
+ as a result of running hestParse(). Free'ing or destroy'ing
+ callbacks added here (by _hestParseSingle[type]) with
+ when=airMopAlways. With the 2025 rewrite, this replaces the
+ previous `int alloc` field with special values 0,1,2,3, which
+ had fussy semantics that complicated hestParseFree()'s work.
+ Now hestParseFree just calls airMopDone on all these (non-NULL)
+ per-option parseMops. */
hestArgVec *havec; // the (non-flag) parm args attributed to this option
/* Since hest's beginning in 2002, the basic container for a set of options was an
array of hestOpt structs (not pointers to them, which rules out argv-style
@@ -258,8 +257,8 @@
whatever values were set in *valueP above. Internally, hest maintains an argc,argv-like
representation of the info to parse, but here it is joined back together into a
space-delimited single string. Note that in the case of single variadic parameter
- options used without a parameter, the value stored will be "inverted" from the string
- here. */
+ options used without a parameter, the value stored will be "inverted" (in the boolean
+ sense of V --> !V) from the value parsed from the string saved here. */
char *parmStr;
/* helpWanted indicates that hestParse() saw something (like "--help") in one of the
given arguments that looks like a call for help, and that respectDashDashHelp is set in
@@ -360,9 +359,8 @@
HEST_EXPORT int hestSourceUser(int src);
HEST_EXPORT hestParm *hestParmNew(void);
HEST_EXPORT hestParm *hestParmFree(hestParm *hparm);
-HEST_EXPORT void *hestParmFree_vp(void *hparm);
HEST_EXPORT int hestParmColumnsIoctl(hestParm *hparm, unsigned int nonIoctlColumns);
-HEST_EXPORT void hestOptSingleSet(hestOpt *opt, const char *flag, const char *name,
+HEST_EXPORT void hestOptSingleSet(hestOpt *hopt, const char *flag, const char *name,
int type, unsigned int min, int max, void *valueP,
const char *dflt, const char *info, unsigned int *sawP,
const airEnum *enm, const hestCB *CB);
@@ -380,30 +378,29 @@
... /* unsigned int *sawP,
const airEnum *enm,
const hestCB *CB */);
-HEST_EXPORT unsigned int hestOptNum(const hestOpt *opt);
-HEST_EXPORT hestOpt *hestOptFree(hestOpt *opt);
-HEST_EXPORT void *hestOptFree_vp(void *opt);
-HEST_EXPORT int hestOptCheck(const hestOpt *opt, char **errP);
-HEST_EXPORT int hestOptParmCheck(const hestOpt *opt, const hestParm *hparm, char **errP);
+HEST_EXPORT unsigned int hestOptNum(const hestOpt *hopt);
+HEST_EXPORT hestOpt *hestOptFree(hestOpt *hopt);
+HEST_EXPORT int hestOptCheck(const hestOpt *hopt, char **errP);
+HEST_EXPORT int hestOptParmCheck(const hestOpt *hopt, const hestParm *hparm, char **errP);
// parseHest.c
-HEST_EXPORT int hestParse(hestOpt *opt, int argc, const char **argv, char **errP,
+HEST_EXPORT int hestParse(hestOpt *hopt, int argc, const char **argv, char **errP,
const hestParm *hparm);
-HEST_EXPORT void *hestParseFree(hestOpt *opt);
-HEST_EXPORT void hestParseOrDie(hestOpt *opt, int argc, const char **argv,
+HEST_EXPORT hestOpt *hestParseFree(hestOpt *hopt);
+HEST_EXPORT void hestParseOrDie(hestOpt *hopt, int argc, const char **argv,
hestParm *hparm, const char *me, const char *info,
int doInfo, int doUsage, int doGlossary);
// parsest.c
-HEST_EXPORT int hestParse2(hestOpt *opt, int argc, const char **argv, char **errP,
+HEST_EXPORT int hestParse2(hestOpt *hopt, int argc, const char **argv, char **errP,
const hestParm *hparm);
// usage.c
HEST_EXPORT void _hestPrintStr(FILE *f, unsigned int indent, unsigned int already,
unsigned int width, const char *_str, int bslash);
-HEST_EXPORT void hestUsage(FILE *file, const hestOpt *opt, const char *argv0,
+HEST_EXPORT void hestUsage(FILE *file, const hestOpt *hopt, const char *argv0,
const hestParm *hparm);
-HEST_EXPORT void hestGlossary(FILE *file, const hestOpt *opt, const hestParm *hparm);
+HEST_EXPORT void hestGlossary(FILE *file, const hestOpt *hopt, const hestParm *hparm);
HEST_EXPORT void hestInfo(FILE *file, const char *argv0, const char *info,
const hestParm *hparm);
Modified: teem/trunk/src/hest/methodsHest.c
===================================================================
--- teem/trunk/src/hest/methodsHest.c 2025-09-29 07:59:10 UTC (rev 7519)
+++ teem/trunk/src/hest/methodsHest.c 2025-09-29 08:13:39 UTC (rev 7520)
@@ -72,9 +72,9 @@
tokens, and to properly tokenize default strings and response files, we should stop using
the airParseStrT functions that internally use airStrtok(): we have exactly one token to
parse. These functions thus return non-zero in case of error, instead of returning the
-number of parsed values. See also comment about _hestP(arse)Pack in privateHest.h */
+number of parsed values. See also comment about _hestP(arse)Pair in privateHest.h */
static int
-parseSingleB(void *_out, const char *str, _hestPPack *hpp) {
+parseSingleB(void *_out, const char *str, _hestPPair *hpp) {
if (!(_out && str && hpp)) return 1;
int *out = (int *)_out;
*out = airEnumVal(airBool, str);
@@ -88,7 +88,7 @@
return ret;
}
-#define _PARSE_1_ARGS void *out, const char *str, _hestPPack *hpp
+#define _PARSE_1_ARGS void *out, const char *str, _hestPPair *hpp
#define _PARSE_1_BODY(typstr, format) \
if (!(out && str && hpp)) return 1; \
int ret = (1 != airSingleSscanf(str, format, out)); \
@@ -111,7 +111,7 @@
static int parseSingleD (_PARSE_1_ARGS) { _PARSE_1_BODY("double", "%lf"); }
// clang-format on
static int
-parseSingleC(void *_out, const char *str, _hestPPack *hpp) {
+parseSingleC(void *_out, const char *str, _hestPPair *hpp) {
if (!(_out && str && hpp)) return 1;
size_t slen = strlen(str);
int ret;
@@ -129,7 +129,7 @@
return ret;
}
static int
-parseSingleS(void *_out, const char *str, _hestPPack *hpp) {
+parseSingleS(void *_out, const char *str, _hestPPair *hpp) {
if (!(_out && str && hpp)) return 1;
char **out = (char **)_out;
*out = airStrdup(str);
@@ -137,21 +137,21 @@
if (ret) {
snprintf(hpp->err, AIR_STRLEN_HUGE + 1, "airStrdup failed!");
} else {
- hpp->alloc = 1;
- airMopMem(hpp->cmop, *out, airMopOnError);
+ if (!hpp->hopt->parseMop) hpp->hopt->parseMop = airMopNew();
+ airMopMem(hpp->hopt->parseMop, out, airMopAlways);
hpp->err[0] = '\0';
}
return ret;
}
static int
-parseSingleE(void *_out, const char *str, _hestPPack *hpp) {
+parseSingleE(void *_out, const char *str, _hestPPair *hpp) {
if (!(_out && str && hpp)) return 1;
int *out = (int *)_out;
- *out = airEnumVal(hpp->enm, str);
- int ret = (airEnumUnknown(hpp->enm) == *out);
+ *out = airEnumVal(hpp->hopt->enm, str);
+ int ret = (airEnumUnknown(hpp->hopt->enm) == *out);
if (ret) {
snprintf(hpp->err, AIR_STRLEN_HUGE + 1, "couldn't parse \"%s\" as %s", str,
- hpp->enm->name);
+ hpp->hopt->enm->name);
} else {
hpp->err[0] = '\0';
}
@@ -158,32 +158,32 @@
return ret;
}
static int
-parseSingleO(void *out, const char *str, _hestPPack *hpp) {
+parseSingleO(void *out, const char *str, _hestPPair *hpp) {
if (!(out && str && hpp)) return 1;
char myerr[AIR_STRLEN_HUGE + 1];
- int ret = hpp->CB->parse(out, str, myerr);
+ int ret = hpp->hopt->CB->parse(out, str, myerr);
if (ret) {
if (strlen(myerr)) {
snprintf(hpp->err, AIR_STRLEN_HUGE + 1, "error parsing \"%s\" as %s:\n%s\n", str,
- hpp->CB->type,
- airStrtrunc(myerr, AIR_STRLEN_HUGE + 1,
- strlen(str) + strlen(hpp->CB->type) + 100));
+ hpp->hopt->CB->type,
+ airStrunc(myerr, AIR_STRLEN_HUGE + 1,
+ strlen(str) + strlen(hpp->hopt->CB->type) + 100));
} else {
snprintf(hpp->err, AIR_STRLEN_HUGE + 1,
- "error parsing \"%s\" as %s: returned %d\n", str, hpp->CB->type, ret);
+ "error parsing \"%s\" as %s: returned %d\n", str, hpp->hopt->CB->type, ret);
}
} else {
- if (hpp->CB->destroy) {
+ if (hpp->hopt->CB->destroy) {
/* out is the address of a void*, we manage the void* */
- hpp->alloc = 1;
- airMopAdd(hpp->cmop, (void **)out, (airMopper)airSetNull, airMopOnError);
- airMopAdd(hpp->cmop, *((void **)out), hpp->CB->destroy, airMopOnError);
+ if (!hpp->hopt->parseMop) hpp->hopt->parseMop = airMopNew();
+ airMopAdd(hpp->hopt->parseMop, (void **)out, (airMopper)airSetNull, airMopAlways);
+ airMopAdd(hpp->hopt->parseMop, *((void **)out), hpp->hopt->CB->destroy, airMopAlways);
}
}
return ret;
}
-int (*const _hestParseSingle[_HEST_TYPE_MAX + 1])(void *, const char *, _hestPPack *) = {
+int (*const _hestParseSingle[_HEST_TYPE_MAX + 1])(void *, const char *, _hestPPair *) = {
NULL, //
parseSingleB, //
parseSingleH, //
@@ -438,26 +438,26 @@
/* initializes all of a hestOpt, even arrAlloc and arrLen */
static void
-optInit(hestOpt *opt) {
+optInit(hestOpt *hopt) {
- opt->flag = NULL;
- opt->name = NULL;
- opt->type = airTypeUnknown; /* h== 0 */
- opt->min = 0;
- opt->max = 0;
- opt->valueP = NULL;
- opt->dflt = opt->info = NULL;
- opt->sawP = NULL;
- opt->enm = NULL;
- opt->CB = NULL;
- opt->sawP = NULL;
- opt->kind = 0; /* means that this hestOpt has not been set */
- opt->alloc = 0;
- opt->havec = NULL;
- opt->arrAlloc = opt->arrLen = 0;
- opt->source = hestSourceUnknown;
- opt->parmStr = NULL;
- opt->helpWanted = AIR_FALSE;
+ hopt->flag = NULL;
+ hopt->name = NULL;
+ hopt->type = airTypeUnknown; /* h== 0 */
+ hopt->min = 0;
+ hopt->max = 0;
+ hopt->valueP = NULL;
+ hopt->dflt = hopt->info = NULL;
+ hopt->sawP = NULL;
+ hopt->enm = NULL;
+ hopt->CB = NULL;
+ hopt->sawP = NULL;
+ hopt->kind = 0; /* means that this hestOpt has not been set */
+ hopt->parseMop = NULL; // will create with airMopNew() only as needed
+ hopt->havec = NULL;
+ hopt->arrAlloc = hopt->arrLen = 0;
+ hopt->source = hestSourceUnknown;
+ hopt->parmStr = NULL;
+ hopt->helpWanted = AIR_FALSE;
}
/*
@@ -469,8 +469,8 @@
terminating hestOpt, but with the introduction of arrAlloc and arrLen that is moot.
*/
unsigned int
-hestOptNum(const hestOpt *opt) {
- return opt ? opt->arrLen : 0;
+hestOptNum(const hestOpt *hopt) {
+ return hopt ? hopt->arrLen : 0;
}
/* like airArrayNew: create an initial segment of the hestOpt array */
@@ -518,39 +518,39 @@
*THIS* is the function that sets opt->kind.
*/
void
-hestOptSingleSet(hestOpt *opt, const char *flag, const char *name, int type,
+hestOptSingleSet(hestOpt *hopt, const char *flag, const char *name, int type,
unsigned int min, int max, void *valueP, const char *dflt,
const char *info, unsigned int *sawP, const airEnum *enm,
const hestCB *CB) {
- if (!opt) return;
- opt->flag = airStrdup(flag);
- opt->name = airStrdup(name);
- opt->type = type;
- opt->min = min;
- opt->max = max;
- opt->valueP = valueP;
- opt->dflt = airStrdup(dflt);
- opt->info = airStrdup(info);
+ if (!hopt) return;
+ hopt->flag = airStrdup(flag);
+ hopt->name = airStrdup(name);
+ hopt->type = type;
+ hopt->min = min;
+ hopt->max = max;
+ hopt->valueP = valueP;
+ hopt->dflt = airStrdup(dflt);
+ hopt->info = airStrdup(info);
// need to set kind now so can be used in later conditionals
- opt->kind = minmaxKind(min, max);
+ hopt->kind = minmaxKind(min, max);
// deal with (what used to be) var args
- opt->sawP = (5 == opt->kind /* */
+ hopt->sawP = (5 == hopt->kind /* */
? sawP
: NULL);
- opt->enm = (airTypeEnum == type /* */
+ hopt->enm = (airTypeEnum == type /* */
? enm
: NULL);
- opt->CB = (airTypeOther == type /* */
+ hopt->CB = (airTypeOther == type /* */
? CB
: NULL);
- // alloc set by hestParse
- opt->havec = hestArgVecNew();
+ // hopt->parseMop may be added to by hestParse and the parseSingleT functions it calls
+ hopt->havec = hestArgVecNew();
// leave arrAlloc, arrLen untouched: managed by caller
// yes, redundant with optInit()
- opt->source = hestSourceUnknown;
- opt->parmStr = NULL;
- opt->helpWanted = AIR_FALSE;
+ hopt->source = hestSourceUnknown;
+ hopt->parmStr = NULL;
+ hopt->helpWanted = AIR_FALSE;
return;
}
@@ -568,7 +568,7 @@
done later, in _hestOPCheck.
*/
unsigned int
-hestOptAdd_nva(hestOpt **optP, const char *flag, const char *name, int type,
+hestOptAdd_nva(hestOpt **hoptP, const char *flag, const char *name, int type,
unsigned int min, int max, void *valueP, const char *dflt,
const char *info, unsigned int *sawP, const airEnum *enm,
const hestCB *CB) {
@@ -575,15 +575,15 @@
unsigned int retIdx;
/* NULL address of opt array: can't proceed */
- if (!optP) return UINT_MAX;
+ if (!hoptP) return UINT_MAX;
/* initialize hestOpt array if necessary */
- if (!(*optP)) {
- optarrNew(optP);
+ if (!(*hoptP)) {
+ optarrNew(hoptP);
}
/* increment logical length of hestOpt array; return index of opt being set here */
- retIdx = optarrIncr(optP);
+ retIdx = optarrIncr(hoptP);
/* set all elements of the opt */
- hestOptSingleSet(*optP + retIdx, flag, name, type, min, max, /* */
+ hestOptSingleSet(*hoptP + retIdx, flag, name, type, min, max, /* */
valueP, dflt, info, /* */
sawP, enm, CB);
return retIdx;
@@ -606,7 +606,7 @@
* parsed. Returns UINT_MAX in case of error.
*/
unsigned int
-hestOptAdd(hestOpt **optP, const char *flag, const char *name, int type,
+hestOptAdd(hestOpt **hoptP, const char *flag, const char *name, int type,
unsigned int min, int max, void *valueP, const char *dflt, const char *info,
...) {
unsigned int *sawP = NULL;
@@ -614,7 +614,7 @@
const hestCB *CB = NULL;
va_list ap;
- if (!optP) return UINT_MAX;
+ if (!hoptP) return UINT_MAX;
/* deal with var args */
if (5 == minmaxKind(min, max)) {
va_start(ap, info);
@@ -634,30 +634,33 @@
CB = va_arg(ap, hestCB *);
va_end(ap);
}
- return hestOptAdd_nva(optP, flag, name, type, min, max, /* */
+ return hestOptAdd_nva(hoptP, flag, name, type, min, max, /* */
valueP, dflt, info, /* */
sawP, enm, CB);
}
static void
-_hestOptFree(hestOpt *opt) {
+_hestOptFree(hestOpt *hopt) {
- opt->flag = (char *)airFree(opt->flag);
- opt->name = (char *)airFree(opt->name);
- opt->dflt = (char *)airFree(opt->dflt);
- opt->info = (char *)airFree(opt->info);
- opt->havec = hestArgVecNix(opt->havec);
+ hopt->flag = (char *)airFree(hopt->flag);
+ hopt->name = (char *)airFree(hopt->name);
+ hopt->dflt = (char *)airFree(hopt->dflt);
+ hopt->info = (char *)airFree(hopt->info);
+ if (hopt->parseMop) {
+ hopt->parseMop = airMopOkay(hopt->parseMop);
+ }
+ hopt->havec = hestArgVecNix(hopt->havec);
return;
}
hestOpt *
-hestOptFree(hestOpt *opt) {
- if (!opt) return NULL;
- uint num = opt->arrLen;
+hestOptFree(hestOpt *hopt) {
+ if (!hopt) return NULL;
+ uint num = hopt->arrLen;
for (uint opi = 0; opi < num; opi++) {
- _hestOptFree(opt + opi);
+ _hestOptFree(hopt + opi);
}
- free(opt);
+ free(hopt);
return NULL;
}
@@ -664,7 +667,7 @@
/* _hestOPCheck
New biff-based container for all logic that originated in _hestOptCheck (which is the
2025 rename of what had long been called _hestPanic): the validation of the given hestOpt
-array `opt` itself (but *not* anything about the command-line or its parsing), relative
+array `hopt` itself (but *not* anything about the command-line or its parsing), relative
to the given (non-NULL) hestParm `hparm`.
Pre-2025, hest did not depend on biff, and this instead took a 'char *err' that somehow
@@ -684,54 +687,54 @@
more appropriately done at the time the option is added.
*/
int
-_hestOPCheck(const hestOpt *opt, const hestParm *hparm) {
- if (!(opt && hparm)) {
- biffAddf(HEST, "%s%sgot NULL opt (%p) or hparm (%p)", _ME_, AIR_VOIDP(opt),
+_hestOPCheck(const hestOpt *hopt, const hestParm *hparm) {
+ if (!(hopt && hparm)) {
+ biffAddf(HEST, "%s%sgot NULL hopt (%p) or hparm (%p)", _ME_, AIR_VOIDP(hopt),
AIR_VOIDP(hparm));
return 1;
}
- uint optNum = opt->arrLen;
+ uint optNum = hopt->arrLen;
uint ufvarNum = 0; // number of unflagged variadic-parameter options
for (uint opi = 0; opi < optNum; opi++) {
- if (!(AIR_IN_OP(airTypeUnknown, opt[opi].type, airTypeLast))) {
+ if (!(AIR_IN_OP(airTypeUnknown, hopt[opi].type, airTypeLast))) {
biffAddf(HEST, "%s%sopt[%u].type (%d) not in valid range [%d,%d]", _ME_, opi,
- opt[opi].type, airTypeUnknown + 1, airTypeLast - 1);
+ hopt[opi].type, airTypeUnknown + 1, airTypeLast - 1);
return 1;
}
// `kind` set by hestOptSingleSet
- if (-1 == opt[opi].kind) {
+ if (-1 == hopt[opi].kind) {
biffAddf(HEST, "%s%sopt[%u]'s min (%d) and max (%d) incompatible", _ME_, opi,
- opt[opi].min, opt[opi].max);
+ hopt[opi].min, hopt[opi].max);
return 1;
}
- if (!(opt[opi].valueP)) {
+ if (!(hopt[opi].valueP)) {
biffAddf(HEST, "%s%sopt[%u]'s valueP is NULL!", _ME_, opi);
return 1;
}
- if (1 == opt[opi].kind) {
- if (!opt[opi].flag) {
+ if (1 == hopt[opi].kind) {
+ if (!hopt[opi].flag) {
biffAddf(HEST, "%s%sstand-alone flag opt[%u] must have a flag", _ME_, opi);
return 1;
}
- if (opt[opi].dflt) {
+ if (hopt[opi].dflt) {
biffAddf(HEST, "%s%sstand-alone flag (opt[%u] %s) should not have a default",
- _ME_, opi, opt[opi].flag);
+ _ME_, opi, hopt[opi].flag);
return 1;
}
- if (opt[opi].name) {
+ if (hopt[opi].name) {
biffAddf(HEST, "%s%sstand-alone flag (opt[%u] %s) should not have a name", _ME_,
- opi, opt[opi].flag);
+ opi, hopt[opi].flag);
return 1;
}
- } else { // ------ end of if (1 == opt[opi].kind)
- if (!opt[opi].name) {
+ } else { // ------ end of if (1 == hopt[opi].kind)
+ if (!hopt[opi].name) {
biffAddf(HEST, "%s%sopt[%u] isn't stand-alone flag: must have \"name\"", _ME_,
opi);
return 1;
}
}
- if (opt[opi].flag) {
- const char *flag = opt[opi].flag;
+ if (hopt[opi].flag) {
+ const char *flag = hopt[opi].flag;
uint fslen = AIR_UINT(strlen(flag));
if (fslen > AIR_STRLEN_SMALL / 2) {
biffAddf(HEST, "%s%sstrlen(opt[%u].flag) %u is too big", _ME_, opi, fslen);
@@ -782,7 +785,7 @@
return (free(tbuff), 1);
}
} else {
- if (!strlen(opt[opi].flag)) {
+ if (!strlen(hopt[opi].flag)) {
biffAddf(HEST, "%s%sopt[%u].flag is zero length", _ME_, opi);
return (free(tbuff), 1);
}
@@ -795,106 +798,106 @@
_ME_, opi, flag);
return (free(tbuff), 1);
}
- } else { // ------ end of if (opt[opi].flag)
- // opt[opi] is unflagged
- if (!opt[opi].min) {
+ } else { // ------ end of if (hopt[opi].flag)
+ // hopt[opi] is unflagged
+ if (!hopt[opi].min) {
// this rules out all unflagged kind 1 and kind 4
// and prevents unflagged kind 5 w/ min=0
biffAddf(HEST, "%s%sunflagged opt[%u] (name %s) must have min >= 1, not 0", _ME_,
- opi, opt[opi].name ? opt[opi].name : "not set");
+ opi, hopt[opi].name ? hopt[opi].name : "not set");
return 1;
}
}
- if (4 == opt[opi].kind) { // single variadic parameter
+ if (4 == hopt[opi].kind) { // single variadic parameter
// immediately above have just ruled out unflagged kind 4
- if (!opt[opi].dflt) {
+ if (!hopt[opi].dflt) {
biffAddf(HEST,
"%s%sopt[%u] -%s is single variadic parameter, but "
"no default set",
- _ME_, opi, opt[opi].flag);
+ _ME_, opi, hopt[opi].flag);
return 1;
}
- if (!(strlen(opt[opi].dflt) && _hestPlainWord(opt[opi].dflt))) {
+ if (!(strlen(hopt[opi].dflt) && _hestPlainWord(hopt[opi].dflt))) {
biffAddf(HEST,
"%s%sopt[%u] -%s is single variadic parameter, but "
"default \"%s\" needs to be non-empty single value",
- _ME_, opi, opt[opi].flag, opt[opi].dflt);
+ _ME_, opi, hopt[opi].flag, hopt[opi].dflt);
return 1;
}
/* pre 2025, these types were allowed for kind 4, but the semantics are just so
weird and thus hard to test + debug. It no longer makes sense to support them */
- if (airTypeChar == opt[opi].type || airTypeString == opt[opi].type
- || airTypeEnum == opt[opi].type || airTypeOther == opt[opi].type) {
+ if (airTypeChar == hopt[opi].type || airTypeString == hopt[opi].type
+ || airTypeEnum == hopt[opi].type || airTypeOther == hopt[opi].type) {
biffAddf(HEST,
"%s%sopt[%u] -%s is single variadic parameter, but sorry, "
"type %s no longer supported",
- _ME_, opi, opt[opi].flag, _hestTypeStr[opt[opi].type]);
+ _ME_, opi, hopt[opi].flag, _hestTypeStr[hopt[opi].type]);
return 1;
}
}
- if (5 == opt[opi].kind && !(opt[opi].sawP)) {
+ if (5 == hopt[opi].kind && !(hopt[opi].sawP)) {
biffAddf(HEST,
"%s%sopt[%u] has multiple variadic parameters (min=%u,max=%d), "
"but sawP is NULL",
- _ME_, opi, opt[opi].min, opt[opi].max);
+ _ME_, opi, hopt[opi].min, hopt[opi].max);
return 1;
}
- if (opt[opi].sawP && 5 != opt[opi].kind) {
+ if (hopt[opi].sawP && 5 != hopt[opi].kind) {
biffAddf(HEST,
"%s%sopt[%u] has non-NULL sawP but is not a (kind=5) "
"multiple variadic parm option (min=%u,max=%d)",
- _ME_, opi, opt[opi].min, opt[opi].max);
+ _ME_, opi, hopt[opi].min, hopt[opi].max);
return 1;
}
- if (airTypeEnum == opt[opi].type && !(opt[opi].enm)) {
+ if (airTypeEnum == hopt[opi].type && !(hopt[opi].enm)) {
biffAddf(HEST,
"%s%sopt[%u] (%s) is type \"enum\", but no "
"airEnum pointer given",
- _ME_, opi, opt[opi].flag ? opt[opi].flag : "unflagged");
+ _ME_, opi, hopt[opi].flag ? hopt[opi].flag : "unflagged");
return 1;
}
- if (opt[opi].enm && airTypeEnum != opt[opi].type) {
+ if (hopt[opi].enm && airTypeEnum != hopt[opi].type) {
biffAddf(HEST,
"%s%sopt[%u] (%s) has non-NULL airEnum pointer, but is not airTypeEnum",
- _ME_, opi, opt[opi].flag ? opt[opi].flag : "unflagged");
+ _ME_, opi, hopt[opi].flag ? hopt[opi].flag : "unflagged");
return 1;
}
- if (airTypeOther == opt[opi].type) {
- if (!(opt[opi].CB)) {
+ if (airTypeOther == hopt[opi].type) {
+ if (!(hopt[opi].CB)) {
biffAddf(HEST,
"%s%sopt[%u] (%s) is type \"other\", but no "
"callbacks given",
- _ME_, opi, opt[opi].flag ? opt[opi].flag : "unflagged");
+ _ME_, opi, hopt[opi].flag ? hopt[opi].flag : "unflagged");
return 1;
}
- if (!(opt[opi].CB->size > 0)) {
+ if (!(hopt[opi].CB->size > 0)) {
biffAddf(HEST, "%s%sopt[%u]'s \"size\" (%u) invalid", _ME_, opi,
- (uint)(opt[opi].CB->size));
+ (uint)(hopt[opi].CB->size));
return 1;
}
- if (!(opt[opi].CB->type)) {
+ if (!(hopt[opi].CB->type)) {
biffAddf(HEST, "%s%sopt[%u]'s \"type\" is NULL", _ME_, opi);
return 1;
}
- if (!(opt[opi].CB->parse)) {
+ if (!(hopt[opi].CB->parse)) {
biffAddf(HEST, "%s%sopt[%u]'s \"parse\" callback NULL", _ME_, opi);
return 1;
}
- if (opt[opi].CB->destroy && (sizeof(void *) != opt[opi].CB->size)) {
+ if (hopt[opi].CB->destroy && (sizeof(void *) != hopt[opi].CB->size)) {
biffAddf(HEST,
"%s%sopt[%u] has a \"destroy\", but size %lu isn't "
"sizeof(void*)",
- _ME_, opi, (unsigned long)(opt[opi].CB->size));
+ _ME_, opi, (unsigned long)(hopt[opi].CB->size));
return 1;
}
}
- if (opt[opi].CB && airTypeOther != opt[opi].type) {
+ if (hopt[opi].CB && airTypeOther != hopt[opi].type) {
biffAddf(HEST, "%s%sopt[%u] (%s) has non-NULL callbacks, but is not airTypeOther",
- _ME_, opi, opt[opi].flag ? opt[opi].flag : "unflagged");
+ _ME_, opi, hopt[opi].flag ? hopt[opi].flag : "unflagged");
return 1;
}
// kind 4 = single variadic parm; kind 5 = multiple variadic parm
- ufvarNum += (opt[opi].kind > 3 && (!opt[opi].flag));
+ ufvarNum += (hopt[opi].kind > 3 && (!hopt[opi].flag));
}
if (ufvarNum > 1) {
biffAddf(HEST, "%s%scan have at most 1 unflagged min<max options, not %u", _ME_,
@@ -904,25 +907,14 @@
return 0;
}
-/* experiments in adding a nixer/free-er that exactly matches the airMopper type,
- as part of trying to avoid all "undefined behavior" */
-void *
-hestParmFree_vp(void *_hparm) {
- return AIR_VOIDP(hestParmFree((hestParm *)_hparm));
-}
-void *
-hestOptFree_vp(void *_opt) {
- return AIR_VOIDP(hestOptFree((hestOpt *)_opt));
-}
-
/*
- * hestOptCheck: check given hestOpt array `opt`, using the default hestParm.
+ * hestOptCheck: check given hestOpt array `hopt`, using the default hestParm.
* Puts any errors into newly allocated (caller responsible to free) `*errP`.
*/
int
-hestOptCheck(const hestOpt *opt, char **errP) {
+hestOptCheck(const hestOpt *hopt, char **errP) {
hestParm *hparm = hestParmNew();
- if (_hestOPCheck(opt, hparm)) {
+ if (_hestOPCheck(hopt, hparm)) {
char *err = biffGetDone(HEST);
if (errP) {
/* they did give a pointer address; they'll free it */
@@ -942,14 +934,14 @@
}
/*
- * hestOptParmCheck: check given hestOpt array `opt` in combination with the given
+ * hestOptParmCheck: check given hestOpt array `hopt` in combination with the given
* hestParm `hparm`. Puts any errors into newly allocated (caller responsible to free)
* `*errP`.
* HEY copy-pasta
*/
int
-hestOptParmCheck(const hestOpt *opt, const hestParm *hparm, char **errP) {
- if (_hestOPCheck(opt, hparm)) {
+hestOptParmCheck(const hestOpt *hopt, const hestParm *hparm, char **errP) {
+ if (_hestOPCheck(hopt, hparm)) {
char *err = biffGetDone(HEST);
if (errP) {
/* they did give a pointer address; they'll free it */
Modified: teem/trunk/src/hest/parseHest.c
===================================================================
--- teem/trunk/src/hest/parseHest.c 2025-09-29 07:59:10 UTC (rev 7519)
+++ teem/trunk/src/hest/parseHest.c 2025-09-29 08:13:39 UTC (rev 7520)
@@ -894,7 +894,6 @@
optNum - 1, optParms[op], ident, opt[op].kind, type, (unsigned int)size);
}
/* we may over-write these */
- opt[op].alloc = 0;
if (opt[op].sawP) {
*(opt[op].sawP) = 0;
}
@@ -933,7 +932,7 @@
}
if (opt[op].CB->destroy) {
/* vP is the address of a void*, we manage the void * */
- opt[op].alloc = 1;
+ /* opt[op].alloc = 1; SORRY old code will leak */
airMopAdd(pmop, (void **)vP, (airMopper)airSetNull, airMopOnError);
airMopAdd(pmop, *((void **)vP), opt[op].CB->destroy, airMopOnError);
}
@@ -949,7 +948,7 @@
}
/* vP is the address of a char* (a char **), but what we
manage with airMop is the char * */
- opt[op].alloc = 1;
+ /* opt[op].alloc = 1; SORRY old code will leak */
airMopMem(pmop, vP, airMopOnError);
break;
default:
@@ -1001,7 +1000,7 @@
free(optParmsCopy);
if (opt[op].CB->destroy) {
/* vP is an array of void*s, we manage the individual void*s */
- opt[op].alloc = 2;
+ /* opt[op].alloc = 2; SORRY old code will leak */
for (p = 0; p < (int)opt[op].min; p++) { /* HEY scrutinize casts */
airMopAdd(pmop, ((void **)vP) + p, (airMopper)airSetNull, airMopOnError);
airMopAdd(pmop, *(((void **)vP) + p), opt[op].CB->destroy, airMopOnError);
@@ -1018,7 +1017,7 @@
}
/* vP is an array of char*s, (a char**), and what we manage
with airMop are the individual vP[p]. */
- opt[op].alloc = 2;
+ /* opt[op].alloc = 2; SORRY old code will leak */
for (p = 0; p < (int)opt[op].min; p++) { /* HEY scrutinize casts */
airMopMem(pmop, &(((char **)vP)[p]), airMopOnError);
}
@@ -1049,7 +1048,7 @@
ident);
return 1;
}
- opt[op].alloc = 0;
+ /* opt[op].alloc = 0; dropped with 2025 rewrite */
break;
case airTypeString:
/* this is a bizarre case: optional single string, with some kind of value
@@ -1067,11 +1066,11 @@
ident);
return 1;
}
- opt[op].alloc = 1;
+ /* opt[op].alloc = 1; SORRY old code will leak */
if (opt[op].flag && 1 == whichCase(opt, optDfltd, optParmNum, appr, op)) {
/* we just parsed the default, but now we want to "invert" it */
*((char **)vP) = (char *)airFree(*((char **)vP));
- opt[op].alloc = 0;
+ /* opt[op].alloc = 0; this is so needlessly confusing */
}
/* vP is the address of a char* (a char**), and what we
manage with airMop is the char * */
@@ -1105,7 +1104,7 @@
}
if (opt[op].CB->destroy) {
/* vP is the address of a void*, we manage the void* */
- opt[op].alloc = 1;
+ /* opt[op].alloc = 1; SORRY old code will leak */
airMopAdd(pmop, vP, (airMopper)airSetNull, airMopOnError);
airMopAdd(pmop, *((void **)vP), opt[op].CB->destroy, airMopOnError);
}
@@ -1117,7 +1116,7 @@
ident);
return 1;
}
- opt[op].alloc = 0;
+ /* opt[op].alloc = 0; dropped with 2025 rewrite */
/* HEY sorry about confusion about hestOpt->parmStr versus the value set
here, due to this "inversion" */
if (1 == whichCase(opt, optDfltd, optParmNum, appr, op)) {
@@ -1160,7 +1159,7 @@
/* so far everything we've done is regardless of type */
switch (type) {
case airTypeEnum:
- opt[op].alloc = 1;
+ /* opt[op].alloc = 1; SORRY old code will leak */
if (optParmNum[op]
!= airParseStrE((int *)(*((void **)vP)), optParms[op], " ",
optParmNum[op], opt[op].enm)) {
@@ -1173,7 +1172,7 @@
case airTypeOther:
cP = (char *)(*((void **)vP));
optParmsCopy = airStrdup(optParms[op]);
- opt[op].alloc = (opt[op].CB->destroy ? 3 : 1);
+ /* opt[op].alloc = (opt[op].CB->destroy ? 3 : 1); SORRY old code will leak */
for (p = 0; p < (int)optParmNum[op]; p++) { /* HEY scrutinize casts */
tok = airStrtok(!p ? optParmsCopy : NULL, " ", &last);
/* (Note from 2023-06-24: "hammerhead" was hammerhead.ucsd.edu, an Intel
@@ -1218,7 +1217,7 @@
}
break;
case airTypeString:
- opt[op].alloc = 3;
+ /* opt[op].alloc = 3; SORRY old code will leak */
if (optParmNum[op]
!= airParseStrS((char **)(*((void **)vP)), optParms[op], " ",
optParmNum[op] /*, hparm->greedySingleString */)) {
@@ -1237,7 +1236,7 @@
(*((char ***)vP))[optParmNum[op]] = NULL;
break;
default:
- opt[op].alloc = 1;
+ /* opt[op].alloc = 1; SORRY old code will leak */
if (optParmNum[op]
!= _hestParseStr[type](*((void **)vP), optParms[op], " ",
optParmNum[op])) {
@@ -1449,67 +1448,23 @@
**
** free()s whatever was allocated by hestParse()
**
-** ignore-able quirk: returns NULL, to facilitate use with the airMop functions
+** ignore-able quirk: returns given pointer, to facilitate use with the airMop functions
*/
-void *
+hestOpt *
hestParseFree(hestOpt *opt) {
+ if (opt) {
uint optNum = opt->arrLen;
- for (uint op = 0; op < optNum; op++) {
- airArrayLenSet(opt[op].havec->hargArr, 0); // but not hestArgVecNix(opt[op].havec);
- opt[op].parmStr = airFree(opt[op].parmStr);
- /*
- printf("!hestParseFree: op = %d/%d -> kind = %d; type = %d; alloc = %d\n",
- op, optNum-1, opt[op].kind, opt[op].type, opt[op].alloc);
- */
- void **vP = (void **)opt[op].valueP;
- void ***vAP = (void ***)opt[op].valueP;
- char **str = (char **)opt[op].valueP;
- char ***strP = (char ***)opt[op].valueP;
- switch (opt[op].alloc) {
- case 0:
- /* nothing was allocated */
- break;
- case 1:
- if (airTypeOther != opt[op].type) {
- *vP = airFree(*vP);
- } else {
- /* alloc is one either because we parsed one thing, and we have a
- destroy callback, or, because we parsed a dynamically-created array
- of things, and we don't have a destroy callback */
- if (opt[op].CB->destroy) {
- *vP = opt[op].CB->destroy(*vP);
- } else {
- *vP = airFree(*vP);
- }
- }
- break;
- case 2:
- if (airTypeString == opt[op].type) {
- for (int i = 0; i < (int)opt[op].min; i++) { /* HEY scrutinize casts */
- str[i] = (char *)airFree(str[i]);
- }
- } else {
- for (int i = 0; i < (int)opt[op].min; i++) { /* HEY scrutinize casts */
- vP[i] = opt[op].CB->destroy(vP[i]);
- }
- }
- break;
- case 3:
- if (airTypeString == opt[op].type) {
- for (uint ui = 0; ui < *(opt[op].sawP); ui++) {
- (*strP)[ui] = (char *)airFree((*strP)[ui]);
- }
- *strP = (char **)airFree(*strP);
- } else {
- for (uint ui = 0; ui < *(opt[op].sawP); ui++) {
- (*vAP)[ui] = opt[op].CB->destroy((*vAP)[ui]);
- }
- *vAP = (void **)airFree(*vAP);
- }
- break;
+ for (uint opi = 0; opi < optNum; opi++) {
+ airArrayLenSet(opt[opi].havec->hargArr, 0); // but not hestArgVecNix(opt[opi].havec);
+ opt[opi].parmStr = airFree(opt[opi].parmStr);
+ /* this gloriously replaces what used to be a lot of dense logic around
+ opt[opi].alloc, opt[opi].type, and opt[opi].CB->destroy */
+ if (opt[opi].parseMop) {
+ opt[opi].parseMop = airMopOkay(opt[opi].parseMop);
}
}
- return NULL;
+ }
+ return opt;
}
/*
Modified: teem/trunk/src/hest/parsest.c
===================================================================
--- teem/trunk/src/hest/parsest.c 2025-09-29 07:59:10 UTC (rev 7519)
+++ teem/trunk/src/hest/parsest.c 2025-09-29 08:13:39 UTC (rev 7520)
@@ -671,12 +671,12 @@
/* whichOptFlag(): for which option (by index) is this the flag?
Given an arg string `flarg` (which may be an flag arg (like "-size") or not (like "512"),
-this finds which one, of the options in the given hestOpt array `opt`, is identified by
+this finds which one, of the options in the given hestOpt array `hopt`, is identified by
`flarg`. If there is a match, returns the index of that option, else returns UINT_MAX.
*/
static uint
-whichOptFlag(const hestOpt *opt, const char *flarg, const hestParm *hparm) {
- uint optNum = opt->arrLen;
+whichOptFlag(const hestOpt *hopt, const char *flarg, const hestParm *hparm) {
+ uint optNum = hopt->arrLen;
if (hparm->verbosity > 3)
printf("%s: looking for maybe-is-flag |%s| in optNum=%u options\n", __func__, flarg,
optNum);
@@ -683,8 +683,8 @@
for (uint optIdx = 0; optIdx < optNum; optIdx++) {
if (hparm->verbosity > 3)
printf("%s: optIdx %u |%s| ?\n", __func__, optIdx,
- opt[optIdx].flag ? opt[optIdx].flag : "(nullflag)");
- const char *optFlag = opt[optIdx].flag;
+ hopt[optIdx].flag ? hopt[optIdx].flag : "(nullflag)");
+ const char *optFlag = hopt[optIdx].flag;
if (!optFlag) continue; // it can't be for this unflagged option
if (strchr(optFlag, MULTI_FLAG_SEP)) {
// look for both long and short versions
@@ -713,36 +713,36 @@
}
/* identStr sprints into `ident` (and returns same `ident`)
- a way to identify `opt` in error and usage messages */
+ a way to identify `hopt` in error and usage messages */
static char *
-identStr(char *ident, const hestOpt *opt) {
- if (opt->flag) {
- if (strchr(opt->flag, MULTI_FLAG_SEP)) {
- char *fcopy = airStrdup(opt->flag);
+identStr(char *ident, const hestOpt *hopt) {
+ if (hopt->flag) {
+ if (strchr(hopt->flag, MULTI_FLAG_SEP)) {
+ char *fcopy = airStrdup(hopt->flag);
char *sep = strchr(fcopy, MULTI_FLAG_SEP);
*sep = '\0';
sprintf(ident, "\"-%s%c--%s\" option", fcopy, MULTI_FLAG_SEP, sep + 1);
free(fcopy);
} else {
- sprintf(ident, "\"-%s\" option", opt->flag);
+ sprintf(ident, "\"-%s\" option", hopt->flag);
}
} else {
- sprintf(ident, "\"<%s>\" option", opt->name);
+ sprintf(ident, "\"<%s>\" option", hopt->name);
}
return ident;
}
/* havecTransfer
-(if `num`) moves `num` args from `hvsrc` (starting at `srcIdx`) to `opt->havec`. This
-takes `hestOpt *opt` instead of `opt->havec` so that we can also set `opt->source`
+(if `num`) moves `num` args from `hvsrc` (starting at `srcIdx`) to `hopt->havec`. This
+takes `hestOpt *hopt` instead of `hopt->havec` so that we can also set `hopt->source`
according to the incoming `hvsrc->harg[]->source`. To minimize cleverness, we set
-`opt->source` with every transferred argument, which means that the per-option source
+`hopt->source` with every transferred argument, which means that the per-option source
remembered is the source of the *last* argument of the option. */
static int
-havecTransfer(hestOpt *opt, hestArgVec *hvsrc, uint srcIdx, uint num,
+havecTransfer(hestOpt *hopt, hestArgVec *hvsrc, uint srcIdx, uint num,
const hestParm *hparm) {
- if (!(opt && hvsrc)) {
- biffAddf(HEST, "%s%sgot NULL opt %p or hvsrc %p", _ME_, AIR_VOIDP(opt),
+ if (!(hopt && hvsrc)) {
+ biffAddf(HEST, "%s%sgot NULL hopt %p or hvsrc %p", _ME_, AIR_VOIDP(hopt),
AIR_VOIDP(hvsrc));
return 1;
}
@@ -758,11 +758,11 @@
return 1;
}
// okay now do the work, starting with emptying destination havec
- hestArgVecReset(opt->havec);
+ hestArgVecReset(hopt->havec);
for (uint ai = 0; ai < num; ai++) {
hestArg *harg = hestArgVecRemove(hvsrc, srcIdx);
- hestArgVecAppendArg(opt->havec, harg);
- opt->source = harg->source;
+ hestArgVecAppendArg(hopt->havec, harg);
+ hopt->source = harg->source;
}
}
return 0;
@@ -769,25 +769,25 @@
}
static void
-optPrint(const hestOpt *opt, uint opi) {
+optPrint(const hestOpt *hopt, uint opi) {
printf("--- opt %u:", opi);
- printf("\t%s%s", opt->flag ? "flag-" : "", opt->flag ? opt->flag : "UNflag");
- printf("\tname|%s|\t k%d (%u)--(%d) \t%s ", opt->name ? opt->name : "(null)",
- opt->kind, opt->min, opt->max, _hestTypeStr[opt->type]);
- printf("\t%sdflt%s%s%s\n", opt->dflt ? "" : "NO-", opt->dflt ? "|" : "",
- opt->dflt ? opt->dflt : "", opt->dflt ? "|" : "");
- printf(" source %s\n", airEnumStr(hestSource, opt->source));
- hestArgVecPrint("", " havec:", opt->havec);
+ printf("\t%s%s", hopt->flag ? "flag-" : "", hopt->flag ? hopt->flag : "UNflag");
+ printf("\tname|%s|\t k%d (%u)--(%d) \t%s ", hopt->name ? hopt->name : "(null)",
+ hopt->kind, hopt->min, hopt->max, _hestTypeStr[hopt->type]);
+ printf("\t%sdflt%s%s%s\n", hopt->dflt ? "" : "NO-", hopt->dflt ? "|" : "",
+ hopt->dflt ? hopt->dflt : "", hopt->dflt ? "|" : "");
+ printf(" source %s\n", airEnumStr(hestSource, hopt->source));
+ hestArgVecPrint("", " havec:", hopt->havec);
return;
}
static void
-optAllPrint(const char *func, const char *ctx, const hestOpt *optall) {
+optAllPrint(const char *func, const char *ctx, const hestOpt *hoptall) {
printf("%s: %s:\n", func, ctx);
printf("%s: v.v.v.v.v.v.v.v.v hestOpt %p has %u options (allocated for %u):\n", func,
- AIR_VOIDP(optall), optall->arrLen, optall->arrAlloc);
- for (uint opi = 0; opi < optall->arrLen; opi++) {
- optPrint(optall + opi, opi);
+ AIR_VOIDP(hoptall), hoptall->arrLen, hoptall->arrAlloc);
+ for (uint opi = 0; opi < hoptall->arrLen; opi++) {
+ optPrint(hoptall + opi, opi);
}
printf("%s: ^'^'^'^'^'^'^'^'^\n", func);
return;
@@ -796,7 +796,7 @@
/* havecExtractFlagged
Extracts the parameter args associated with all flagged options from the given
`hestArgVec *havec` (as generated by histProc()) and stores them the corresponding
-opt->havec. Also sets opt->source according to where that flag arg appeared in the case
+hopt->havec. Also sets hopt->source according to where that flag arg appeared in the case
of stand-alone flags, or (via havecTransfer) wherever the last parm arg came from.
In the case of variadic parameter options, this does the work of figuring out which args
@@ -814,7 +814,7 @@
option. AND, the "--" marker is removed from `havec`.
*/
static int
-havecExtractFlagged(hestOpt *opt, hestArgVec *havec, const hestParm *hparm) {
+havecExtractFlagged(hestOpt *hopt, hestArgVec *havec, const hestParm *hparm) {
char *havStr, ident1[AIR_STRLEN_HUGE + 1], ident2[AIR_STRLEN_HUGE + 1];
uint argIdx = 0;
hestOpt *theOpt = NULL;
@@ -823,7 +823,7 @@
printf("%s: ------------- argIdx = %u (of %u) -> argv[argIdx] = |%s|\n", __func__,
argIdx, havec->len, havec->harg[argIdx]->str);
}
- uint optIdx = whichOptFlag(opt, havec->harg[argIdx]->str, hparm);
+ uint optIdx = whichOptFlag(hopt, havec->harg[argIdx]->str, hparm);
if (UINT_MAX == optIdx) {
// havec->harg[argIdx]->str is not a flag for any option, move on to next arg
if (hparm->verbosity > 2) {
@@ -834,7 +834,7 @@
continue;
}
// else havec->harg[argIdx]->str is a flag for option with index optIdx aka theOpt
- theOpt = opt + optIdx;
+ theOpt = hopt + optIdx;
if (hparm->verbosity)
printf("%s: argv[%u]=|%s| is flag of opt %u \"%s\"\n", __func__, argIdx,
havec->harg[argIdx]->str, optIdx, theOpt->flag);
@@ -841,7 +841,7 @@
/* see if we can associate some parameters with the flag */
if (hparm->verbosity) printf("%s: any associated parms?\n", __func__);
int hitEnd = AIR_FALSE;
- int varParm = (5 == opt[optIdx].kind);
+ int varParm = (5 == hopt[optIdx].kind);
const char VPS[3] = {'-', VAR_PARM_STOP_FLAG, '\0'};
int hitVPS = AIR_FALSE;
uint nextOptIdx = 0, // what is index of option who's flag we hit next
@@ -856,7 +856,7 @@
&& (!varParm || // or, it is a varparm opt, and we aren't looking at "--"
!(hitVPS = !strcmp(VPS, havec->harg[pai]->str)))
&& UINT_MAX // and we aren't looking at start of another flagged option
- == (nextOptIdx = whichOptFlag(opt, havec->harg[pai]->str, hparm))) {
+ == (nextOptIdx = whichOptFlag(hopt, havec->harg[pai]->str, hparm))) {
if (hparm->verbosity)
printf("%s: optIdx %d |%s|; argIdx %u < %u |%s| --> parmNum --> %d\n", __func__,
optIdx, theOpt->flag, argIdx, pai, havec->harg[pai]->str, parmNum + 1);
@@ -887,7 +887,7 @@
identStr(ident1, theOpt), parmNum);
} else if (UINT_MAX != nextOptIdx) {
biffAddf(HEST, "%s%ssaw %s before getting %u parameter%s for %s (got %d)", _ME_,
- identStr(ident2, opt + nextOptIdx), theOpt->min,
+ identStr(ident2, hopt + nextOptIdx), theOpt->min,
theOpt->min > 1 ? "s" : "", identStr(ident1, theOpt), parmNum);
} else {
biffAddf(HEST,
@@ -936,9 +936,9 @@
}
/* make sure that flagged options without default were given */
- uint optNum = opt->arrLen;
+ uint optNum = hopt->arrLen;
for (uint opi = 0; opi < optNum; opi++) {
- theOpt = opt + opi;
+ theOpt = hopt + opi;
if (theOpt->flag) { // this is a flagged option we should have handled above
int needing = (1 != theOpt->kind // this kind of option can take a parm
&& !(theOpt->dflt)); // and this option has no default
@@ -957,7 +957,7 @@
}
if (hparm->verbosity) {
- optAllPrint(__func__, "end of havecExtractFlagged", opt);
+ optAllPrint(__func__, "end of havecExtractFlagged", hopt);
hestArgVecPrint(__func__, "end of havecExtractFlagged", havec);
}
return 0;
@@ -964,9 +964,9 @@
}
/* havecExtractUnflagged()
-Extracts the parameter args associated with all unflagged options (of `hestOpt *opt`)
+Extracts the parameter args associated with all unflagged options (of `hestOpt *hopt`)
from the given `hestArgVec *havec` and (like havecExtractFlagged) extracts those args and
-saves them in the corresponding opt[].havec
+saves them in the corresponding hopt[].havec
This is the function that has to handle the trickly logic of allowing there to be
multiple unflagged options, only one of which may have a variadic number of parms; that
@@ -973,12 +973,12 @@
one has to be extracted last.
*/
static int
-havecExtractUnflagged(hestOpt *opt, hestArgVec *havec, const hestParm *hparm) {
+havecExtractUnflagged(hestOpt *hopt, hestArgVec *havec, const hestParm *hparm) {
char *havStr = NULL, ident[AIR_STRLEN_HUGE + 1];
- uint optNum = opt->arrLen; // number of options (flagged or unflagged)
+ uint optNum = hopt->arrLen; // number of options (flagged or unflagged)
uint ufOptNum = 0; // number of unflagged options
for (uint opi = 0; opi < optNum; opi++) {
- if (!opt[opi].flag) {
+ if (!hopt[opi].flag) {
ufOptNum += 1;
}
}
@@ -993,7 +993,7 @@
assert(ufOpi2);
uint upii = 0; // index into ufOpi2
for (uint opi = 0; opi < optNum; opi++) {
- if (!opt[opi].flag) {
+ if (!hopt[opi].flag) {
ufOpi2[2 * upii + 0] = opi;
upii++;
}
@@ -1016,7 +1016,7 @@
uint ufVarOpi = optNum; // index (if < optNum) of the unflagged variadic parm option
for (upii = 0; upii < ufOptNum; upii++) {
uint opi = ufOpi2[2 * upii + 0];
- if (5 == opt[opi].kind) { // (unflagged) multiple variadic parm
+ if (5 == hopt[opi].kind) { // (unflagged) multiple variadic parm
ufVarOpi = opi;
break;
}
@@ -1030,7 +1030,7 @@
: "is index of single unflagged variadic opt"));
}
- // grab parameters for all unflagged opts before opt[ufVarOpi]
+ // grab parameters for all unflagged opts before hopt[ufVarOpi]
for (upii = 0; upii < ufOptNum; upii++) {
uint opi = ufOpi2[2 * upii + 0]; // 0: increasing index direction
if (opi == ufVarOpi) {
@@ -1037,18 +1037,18 @@
break;
}
if (hparm->verbosity) {
- printf("%s: looking at opi = %u kind %d\n", __func__, opi, opt[opi].kind);
+ printf("%s: looking at opi = %u kind %d\n", __func__, opi, hopt[opi].kind);
}
/* Either we have enough args to satisfy this option (and thus don't care if it has a
default), or, we do *not* have enough args and hence want to use the default. In the
later case, we don't have a default, that's a problem that needs an error message.
So, either way, we try extracting the args and report any problems encountered. */
- if (opt[opi].min /* == max */ < havec->len || !opt[opi].dflt) {
+ if (hopt[opi].min /* == max */ < havec->len || !hopt[opi].dflt) {
havStr = hestArgVecSprint(havec, AIR_TRUE);
- if (havecTransfer(opt + opi, havec, 0, opt[opi].min, hparm)) {
+ if (havecTransfer(hopt + opi, havec, 0, hopt[opi].min, hparm)) {
biffAddf(HEST, "%s%sgiven (index: labeled) argv=|%s|", _ME_, havStr);
biffAddf(HEST, "%s%strouble getting args for %sunflagged %s[%u]", _ME_,
- !opt[opi].dflt ? "default-less " : "", identStr(ident, opt + opi), opi);
+ !hopt[opi].dflt ? "default-less " : "", identStr(ident, hopt + opi), opi);
return (free(havStr), free(ufOpi2), 1);
}
havStr = airFree(havStr);
@@ -1067,18 +1067,18 @@
break;
}
if (hparm->verbosity) {
- printf("%s: looking at (later) opi = %u kind %d\n", __func__, opi, opt[opi].kind);
+ printf("%s: looking at (later) opi = %u kind %d\n", __func__, opi, hopt[opi].kind);
}
// same logic as above
- if (opt[opi].min /* == max */ < havec->len || !opt[opi].dflt) {
- uint idx0 = (opt[opi].min < havec->len // index of first arg for this option
- ? havec->len - opt[opi].min //
+ if (hopt[opi].min /* == max */ < havec->len || !hopt[opi].dflt) {
+ uint idx0 = (hopt[opi].min < havec->len // index of first arg for this option
+ ? havec->len - hopt[opi].min //
: 0);
havStr = hestArgVecSprint(havec, AIR_TRUE);
- if (havecTransfer(opt + opi, havec, idx0, opt[opi].min, hparm)) {
+ if (havecTransfer(hopt + opi, havec, idx0, hopt[opi].min, hparm)) {
biffAddf(HEST, "%s%sgiven (index: labeled) argv=|%s|", _ME_, havStr);
biffAddf(HEST, "%s%strouble getting args for (later) %sunflagged %s[%u]", _ME_,
- !opt[opi].dflt ? "default-less " : "", identStr(ident, opt + opi), opi);
+ !hopt[opi].dflt ? "default-less " : "", identStr(ident, hopt + opi), opi);
return (free(havStr), free(ufOpi2), 1);
}
havStr = airFree(havStr);
@@ -1088,16 +1088,16 @@
// We're here because there is an unflagged variadic option (index ufVarOpi < optNum)
if (hparm->verbosity) {
printf("%s: ufVarOpi=%u min, have, max = %u %u %d\n", __func__, ufVarOpi,
- opt[ufVarOpi].min, havec->len, _hestMax(opt[ufVarOpi].max));
+ hopt[ufVarOpi].min, havec->len, _hestMax(hopt[ufVarOpi].max));
}
- uint minArg = opt[ufVarOpi].min; /* min < max ! */
- if (minArg > havec->len && !opt[ufVarOpi].dflt) {
+ uint minArg = hopt[ufVarOpi].min; /* min < max ! */
+ if (minArg > havec->len && !hopt[ufVarOpi].dflt) {
havStr = hestArgVecSprint(havec, AIR_TRUE);
biffAddf(HEST, "%s%sgiven (index: labeled) argv=|%s|", _ME_, havStr);
biffAddf(HEST,
"%s%shave only %u args left but need %u for "
"(default-less) variadic unflagged %s[%u]",
- _ME_, havec->len, minArg, identStr(ident, opt + ufVarOpi), ufVarOpi);
+ _ME_, havec->len, minArg, identStr(ident, hopt + ufVarOpi), ufVarOpi);
return (free(havStr), free(ufOpi2), 1);
}
// else minArg <= havec->len, or, minArg > havec->len and do have default
@@ -1104,19 +1104,19 @@
if (minArg <= havec->len) {
// can satisfy option from havec, no need to use default
uint getArg = havec->len; // want to grab as many args as possible
- if (-1 != opt[ufVarOpi].max) { // but no more than the option asks for
- getArg = AIR_MIN(getArg, AIR_UINT(opt[ufVarOpi].max));
+ if (-1 != hopt[ufVarOpi].max) { // but no more than the option asks for
+ getArg = AIR_MIN(getArg, AIR_UINT(hopt[ufVarOpi].max));
}
- if (havecTransfer(opt + ufVarOpi, havec, 0, getArg, hparm)) {
+ if (havecTransfer(hopt + ufVarOpi, havec, 0, getArg, hparm)) {
havStr = hestArgVecSprint(havec, AIR_TRUE);
biffAddf(HEST, "%s%sgiven (index: labeled) argv=|%s|", _ME_, havStr);
biffAddf(HEST, "%s%strouble getting args for unflagged variadic %s[%u]", _ME_,
- identStr(ident, opt + ufVarOpi), ufVarOpi);
+ identStr(ident, hopt + ufVarOpi), ufVarOpi);
return (free(havStr), free(ufOpi2), 1);
}
}
/* else minArg > havec->len so can't satisfy from havec, but that's ok for
- opt[ufVarOpi] since it has default. The erroneous presence of extraneous args will be
+ hopt[ufVarOpi] since it has default. The erroneous presence of extraneous args will be
caught next */
finishingup:
@@ -1124,9 +1124,9 @@
// make sure that unflagged options without default were given
for (upii = 0; upii < ufOptNum; upii++) {
uint opi = ufOpi2[2 * upii + 0];
- if (!(opt[opi].dflt) && hestSourceUnknown == opt[opi].source) {
+ if (!(hopt[opi].dflt) && hestSourceUnknown == hopt[opi].source) {
biffAddf(HEST, "%s%sdidn't get required (default-less) unflagged %s[%u]", _ME_,
- identStr(ident, opt + opi), opi);
+ identStr(ident, hopt + opi), opi);
return (free(ufOpi2), 1);
}
}
@@ -1143,7 +1143,7 @@
}
if (hparm->verbosity) {
- optAllPrint(__func__, "end of havecExtractUnflagged", opt);
+ optAllPrint(__func__, "end of havecExtractUnflagged", hopt);
hestArgVecPrint(__func__, "end of havecExtractUnflagged", havec);
}
return (airFree(havStr), airFree(ufOpi2), 0);
@@ -1151,52 +1151,52 @@
/* optProcessDefaults
All the command-line arguments (and any response files invoked therein) should now be
-processed (by transferring the arguments to per-option opt->havec arrays), but we need to
+processed (by transferring the arguments to per-option hopt->havec arrays), but we need to
ensure that every option has information from which to set values. The per-option
-opt->dflt string is what we look to now, to finish setting per-option opt->havec arrays
-for all the options for which opt->havec have not already been set. We use
-`!opt->source` (aka hestSourceUnknown) as the indicator of not already being set.
+hopt->dflt string is what we look to now, to finish setting per-option hopt->havec arrays
+for all the options for which hopt->havec have not already been set. We use
+`!hopt->source` (aka hestSourceUnknown) as the indicator of not already being set.
*/
static int
-optProcessDefaults(hestOpt *opt, hestArg *tharg, hestInputStack *hist,
+optProcessDefaults(hestOpt *hopt, hestArg *tharg, hestInputStack *hist,
const hestParm *hparm) {
char ident[AIR_STRLEN_HUGE + 1];
- uint optNum = opt->arrLen;
+ uint optNum = hopt->arrLen;
for (uint opi = 0; opi < optNum; opi++) {
if (hparm->verbosity) {
printf(" -> %s incoming", __func__);
- optPrint(opt + opi, opi);
+ optPrint(hopt + opi, opi);
}
- if (opt[opi].source) {
+ if (hopt[opi].source) {
/* the source is already set (to something other than hestSourceUnknown),
so there's no need for using the default */
continue;
}
- opt[opi].source = hestSourceDefault;
- if (1 == opt[opi].kind) {
+ hopt[opi].source = hestSourceDefault;
+ if (1 == hopt[opi].kind) {
/* There is no meaningful "default" for stand-alone flags (and in fact
- opt[opi].dflt is enforced to be NULL) so there is no default string to tokenize,
+ hopt[opi].dflt is enforced to be NULL) so there is no default string to tokenize,
but we above set source to default for sake of completeness, and to signal that
the flag was not given by user */
goto nextopt;
}
- identStr(ident, opt + opi);
+ identStr(ident, hopt + opi);
// should have already checked for this but just to make sure
- if (!opt[opi].dflt) {
+ if (!hopt[opi].dflt) {
biffAddf(HEST, "%s%s %s[%u] needs default string but it is NULL", _ME_, ident,
opi);
return 1;
}
/* in some circumstan...
[truncated message content] |