|
From: <kin...@us...> - 2025-09-22 20:35:14
|
Revision: 7467
http://sourceforge.net/p/teem/code/7467
Author: kindlmann
Date: 2025-09-22 20:35:11 +0000 (Mon, 22 Sep 2025)
Log Message:
-----------
API CHANGE: removed: int hestMinNumArgs(const hestOpt *opt);
because it was not being used anywhere else in Teem
Also belatedly add `const` to: hestOptCheck(const hestOpt *opt, char **errP);
API NEW: added "int hestOptParmCheck(const hestOpt *opt, const hestParm *hparm, char **errP);
for checking a hestOpt and a non-NULL hestParm together
2025 rewrite continues, and now a lot more of hest uses biff internally
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/tparse.c
teem/trunk/src/hest/usage.c
Modified: teem/trunk/src/hest/hest.h
===================================================================
--- teem/trunk/src/hest/hest.h 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/hest.h 2025-09-22 20:35:11 UTC (rev 7467)
@@ -183,7 +183,9 @@
/* --------------------- Output
Things set/allocated by hestParse. */
- /* from the hestSource* enum; from whence was this information learned */
+ /* from the hestSource* enum; from whence was this information learned. Can use
+ hestSourceUser(opt->source) to test for the sources associated with the user:
+ hestSourceCommandLine or hestSourceResponseFile */
int source;
/* if parseStr is non-NULL: a string (freed by hestParseFree) that is a lot like the
string (storing zero or many parameters), from which hestParse ultimately parsed
@@ -367,11 +369,12 @@
... /* unsigned int *sawP,
const airEnum *enm,
const hestCB *CB */);
-// SEE ALSO all the special-purpose and type-checked versions in adders.c, below
+// SEE ALSO (from adders.c) all the 99 type-checked versions of hestOptAdd_, below!
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(hestOpt *opt, char **errP);
+HEST_EXPORT int hestOptCheck(const hestOpt *opt, char **errP);
+HEST_EXPORT int hestOptParmCheck(const hestOpt *opt, const hestParm *hparm, char **errP);
// parseHest.c
HEST_EXPORT int hestParse(hestOpt *opt, int argc, const char **argv, char **errP,
@@ -384,7 +387,6 @@
// usage.c
HEST_EXPORT void _hestPrintStr(FILE *f, unsigned int indent, unsigned int already,
unsigned int width, const char *_str, int bslash);
-HEST_EXPORT int hestMinNumArgs(const hestOpt *opt);
HEST_EXPORT void hestUsage(FILE *file, const hestOpt *opt, const char *argv0,
const hestParm *hparm);
HEST_EXPORT void hestGlossary(FILE *file, const hestOpt *opt, const hestParm *hparm);
@@ -406,7 +408,7 @@
min < max; max >= 2 hestOptAdd_Nv_T 5 multiple variable parameters
The type T can be: Bool, Short, UShort, Int, UInt, Long, ULong, Size_t, Float, Double,
-Char, String, Enum, and Other. An airEnum* is passed with the T=Enum functions, or a
+Char, String, Enum, or Other. An airEnum* is passed with the T=Enum functions, or a
hestCB* is passed for the T=Other functions. The number of parameters *sawP that hestParm
saw on the command-line is passed for the _Nv_ options.
Modified: teem/trunk/src/hest/methodsHest.c
===================================================================
--- teem/trunk/src/hest/methodsHest.c 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/methodsHest.c 2025-09-22 20:35:11 UTC (rev 7467)
@@ -113,9 +113,6 @@
.sense = AIR_FALSE};
const airEnum *const hestSource = &_hestSource;
-// see documentation in parseHest.c
-#define ME ((hparm && hparm->verbosity) ? me : "")
-
int
hestSourceUser(int src) {
return (hestSourceCommandLine == src || hestSourceResponseFile == src);
@@ -353,7 +350,8 @@
/*
hestOptSingleSet: a completely generic setter for a single hestOpt
-Note that this makes no attempt at error-checking; that is all in hestOptCheck
+Note that this makes no attempt at error-checking; that is all in _hestOPCheck.
+*THIS* is the function that sets opt->kind.
*/
void
hestOptSingleSet(hestOpt *opt, const char *flag, const char *name, int type,
@@ -392,15 +390,11 @@
/*
hestOptAdd_nva: A new (as of 2023) non-var-args ("_nva") version of hestOptAdd;
-now hestOptAdd is a wrapper around this. And, the per-hestOpt logic has now
-been moved to hestOptSingleSet.
+The per-hestOpt logic (including setting opt->kind) has now been moved to
+hestOptSingleSet. The venerable var-args hestOptAdd is now a wrapper around this.
+and the 99 non-var-args hestOptAdd_* functions also all call this.
Like hestOptAdd has done since 2013: returns UINT_MAX in case of error.
-
-Note: (as of 2023) you probably shouldn't use this function; instead use
-one of hestOptAdd_Flag, hestOptAdd_1_T, hestOptAdd_{2,3,4,N}_T, hestOptAdd_1v_T,
-or hestOptAdd_Nv_T for T=Bool, Int, UInt, LongInt, ULongInt, Size_t, Float, Double,
-Char, String, Enum, Other
*/
unsigned int
hestOptAdd_nva(hestOpt **optP, const char *flag, const char *name, int type,
@@ -425,9 +419,21 @@
}
/*
-** as of Sept 2013 this returns information: the index of the
-** option just added. Returns UINT_MAX in case of error.
-*/
+ * hestOptAdd
+ *
+ * Until 2023, this was the main way of using hest: a var-args function that could do no
+ * useful type-checking, and was very easy to call incorrectly, leading to inscrutable
+ * errors.
+ *
+ * Now, thankfully, you have 99 better hestOptAdd_ functions to use instead:
+ * hestOptAdd_Flag, hestOptAdd_1_T, hestOptAdd_{2,3,4,N}_T, hestOptAdd_1v_T, or
+ * hestOptAdd_Nv_T for T=Bool, Short, UShort, Int, UInt, LongInt, ULongInt, Size_t,
+ * Float, Double, Char, String, Enum, or Other.
+ *
+ * This returns the index of the option just added, to so the caller can remember it and
+ * this speed up later checking the `hestOpt->source` to learn where how the option was
+ * parsed. Returns UINT_MAX in case of error.
+ */
unsigned int
hestOptAdd(hestOpt **optP, const char *flag, const char *name, int type,
unsigned int min, int max, void *valueP, const char *dflt, const char *info,
@@ -487,181 +493,150 @@
}
/*
-_hestOptCheck() (formerly _hestPanic, in parseHest.c)
-
-This performs the validation of the given hestOpt array itself (not the command line to
-be parsed), with descriptive error messages sprintf'ed into err, if given. hestOptCheck()
-is the expected way for users to access this.
-
-Prior to 2023 code revisit; this used to set the "kind" in all the opts but now that is
-more appropriately done at the time the option is added (by hestOptAdd, hestOptAdd_nva,
-hestOptSingleSet, or hestOptAdd_*_*)
-*/
+ * _hestOPCheck
+ *
+ * new biff-based container for all logic that used to be in _hestOptCheck (which is
+ * the 2025 rename of _hestPanic): the validation of the given hestOpt array `opt` 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 magically had to be allocated for the size of any possible error message
+ * generated here. The 2025 re-write recognized that biff is the right way to accumulate
+ * error messages, but the use of biff is internal to biff, but not (unusually for Teem)
+ * part of the the expected use of biff's API. Thus, public functions hestOptCheck() and
+ * hestOptParmCheck(), which are the expected way to access the functionality herein,
+ * take a `char **errP` arg into which a message is sprintf'ed, after allocation.
+ *
+ * The shift to using biff removed how this function used to fprintf(stderr) some message
+ * like "panic 0.5" which as completely uninformative. Now, hestOptCheck() and
+ * hestOptParmCheck() fprintf(stderr) the biff message.
+ *
+ * Prior to 2023 code revisit: this used to set the "kind" in all the opts, but now that
+ * is more appropriately done at the time the option is added.
+ */
int
-_hestOptCheck(const hestOpt *opt, char *err, const hestParm *hparm) {
- /* see note on ME (at top) for why me[] ends with ": " */
- static const char me[] = "_hestOptCheck: ";
- char tbuff[AIR_STRLEN_HUGE + 1], *sep;
- int numvar, opi, optNum;
-
- optNum = hestOptNum(opt);
- numvar = 0;
- for (opi = 0; opi < optNum; opi++) {
+_hestOPCheck(const hestOpt *opt, const hestParm *hparm) {
+ if (!(opt && hparm)) {
+ biffAddf(HEST, "%s: got NULL opt (%p) or hparm (%p)", __func__, AIR_VOIDP(opt),
+ AIR_VOIDP(hparm));
+ return 1;
+ }
+ uint optNum = opt->arrLen;
+ uint varNum = 0; // number of variable-parameter options
+ for (uint opi = 0; opi < optNum; opi++) {
if (!(AIR_IN_OP(airTypeUnknown, opt[opi].type, airTypeLast))) {
- if (err)
- sprintf(err, "%sopt[%d].type (%d) not in valid range [%d,%d]", ME, opi,
- opt[opi].type, airTypeUnknown + 1, airTypeLast - 1);
- else
- fprintf(stderr, "%s: panic 0\n", me);
+ biffAddf(HEST, "%s: opt[%u].type (%d) not in valid range [%d,%d]", __func__, opi,
+ opt[opi].type, airTypeUnknown + 1, airTypeLast - 1);
return 1;
}
if (!(opt[opi].valueP)) {
- if (err)
- sprintf(err, "%sopt[%d]'s valueP is NULL!", ME, opi);
- else
- fprintf(stderr, "%s: panic 0.5\n", me);
+ biffAddf(HEST, "%s: opt[%u]'s valueP is NULL!", __func__, opi);
return 1;
}
+ // `kind` set by hestOptSingleSet
if (-1 == opt[opi].kind) {
- if (err)
- sprintf(err, "%sopt[%d]'s min (%d) and max (%d) incompatible", ME, opi,
- opt[opi].min, opt[opi].max);
- else
- fprintf(stderr, "%s: panic 1\n", me);
+ biffAddf(HEST, "%s: opt[%u]'s min (%d) and max (%d) incompatible", __func__, opi,
+ opt[opi].min, opt[opi].max);
return 1;
}
if (5 == opt[opi].kind && !(opt[opi].sawP)) {
- if (err)
- sprintf(err,
- "%shave multiple variable parameters, "
- "but sawP is NULL",
- ME);
- else
- fprintf(stderr, "%s: panic 2\n", me);
+ biffAddf(HEST,
+ "%s: have multiple variable parameters, "
+ "but sawP is NULL",
+ __func__);
return 1;
}
if (airTypeEnum == opt[opi].type) {
if (!(opt[opi].enm)) {
- if (err) {
- sprintf(err,
- "%sopt[%d] (%s) is type \"enum\", but no "
- "airEnum pointer given",
- ME, opi, opt[opi].flag ? opt[opi].flag : "?");
- } else {
- fprintf(stderr, "%s: panic 3\n", me);
- }
+ biffAddf(HEST,
+ "%s: opt[%u] (%s) is type \"enum\", but no "
+ "airEnum pointer given",
+ __func__, opi, opt[opi].flag ? opt[opi].flag : "?");
return 1;
}
}
if (airTypeOther == opt[opi].type) {
if (!(opt[opi].CB)) {
- if (err) {
- sprintf(err,
- "%sopt[%d] (%s) is type \"other\", but no "
- "callbacks given",
- ME, opi, opt[opi].flag ? opt[opi].flag : "?");
- } else {
- fprintf(stderr, "%s: panic 4\n", me);
- }
+ biffAddf(HEST,
+ "%s: opt[%u] (%s) is type \"other\", but no "
+ "callbacks given",
+ __func__, opi, opt[opi].flag ? opt[opi].flag : "?");
return 1;
}
if (!(opt[opi].CB->size > 0)) {
- if (err)
- sprintf(err, "%sopt[%d]'s \"size\" (%d) invalid", ME, opi,
- (int)(opt[opi].CB->size));
- else
- fprintf(stderr, "%s: panic 5\n", me);
+ biffAddf(HEST, "%s: opt[%u]'s \"size\" (%u) invalid", __func__, opi,
+ (uint)(opt[opi].CB->size));
return 1;
}
if (!(opt[opi].CB->type)) {
- if (err)
- sprintf(err, "%sopt[%d]'s \"type\" is NULL", ME, opi);
- else
- fprintf(stderr, "%s: panic 6\n", me);
+ biffAddf(HEST, "%s: opt[%u]'s \"type\" is NULL", __func__, opi);
return 1;
}
if (!(opt[opi].CB->parse)) {
- if (err)
- sprintf(err, "%sopt[%d]'s \"parse\" callback NULL", ME, opi);
- else
- fprintf(stderr, "%s: panic 7\n", me);
+ biffAddf(HEST, "%s: opt[%u]'s \"parse\" callback NULL", __func__, opi);
return 1;
}
if (opt[opi].CB->destroy && (sizeof(void *) != opt[opi].CB->size)) {
- if (err)
- sprintf(err,
- "%sopt[%d] has a \"destroy\", but size %lu isn't "
- "sizeof(void*)",
- ME, opi, (unsigned long)(opt[opi].CB->size));
- else
- fprintf(stderr, "%s: panic 8\n", me);
+ biffAddf(HEST,
+ "%sopt[%u] has a \"destroy\", but size %lu isn't "
+ "sizeof(void*)",
+ __func__, opi, (unsigned long)(opt[opi].CB->size));
return 1;
}
}
if (opt[opi].flag) {
- strcpy(tbuff, opt[opi].flag);
+ char *tbuff = airStrdup(opt[opi].flag);
+ if (!tbuff) {
+ biffAddf(HEST, "%s: could not strdup() opi[%u].flag", __func__, opi);
+ return 1;
+ }
+ // no map, have to call free(tbuff) !
+ char *sep;
if ((sep = strchr(tbuff, MULTI_FLAG_SEP))) {
*sep = '\0';
if (!(strlen(tbuff) && strlen(sep + 1))) {
- if (err)
- sprintf(err,
- "%seither short (\"%s\") or long (\"%s\") flag"
- " of opt[%d] is zero length",
- ME, tbuff, sep + 1, opi);
- else
- fprintf(stderr, "%s: panic 9\n", me);
- return 1;
+ biffAddf(HEST,
+ "%s: either short (\"%s\") or long (\"%s\") flag"
+ " of opt[%u] is zero length",
+ __func__, tbuff, sep + 1, opi);
+ return (free(tbuff), 1);
}
if (hparm->respectDashDashHelp && !strcmp("help", sep + 1)) {
- if (err)
- sprintf(err,
- "%slong \"--%s\" flag of opt[%d] is same as \"--help\" "
- "that requested hparm->respectDashDashHelp handles separately",
- ME, sep + 1, opi);
- else
- fprintf(stderr, "%s: panic 9.5\n", me);
- return 1;
+ biffAddf(HEST,
+ "%s: long \"--%s\" flag of opt[%u] is same as \"--help\" "
+ "that requested hparm->respectDashDashHelp handles separately",
+ __func__, sep + 1, opi);
+ return (free(tbuff), 1);
}
} else {
if (!strlen(opt[opi].flag)) {
- if (err)
- sprintf(err, "%sopt[%d].flag is zero length", ME, opi);
- else
- fprintf(stderr, "%s: panic 10\n", me);
- return 1;
+ biffAddf(HEST, "%s: opt[%u].flag is zero length", __func__, opi);
+ return (free(tbuff), 1);
}
}
if (hparm->respectDashBraceComments
&& (strchr(opt[opi].flag, '{') || strchr(opt[opi].flag, '}'))) {
- if (err)
- sprintf(err,
- "%srequested hparm->respectDashBraceComments but opt[%d]'s flag "
- "\"%s\" confusingly contains '{' or '}'",
- ME, opi, opt[opi].flag);
- else
- fprintf(stderr, "%s: panic 10.5\n", me);
- return 1;
+ biffAddf(HEST,
+ "%s: requested hparm->respectDashBraceComments but opt[%u]'s flag "
+ "\"%s\" confusingly contains '{' or '}'",
+ __func__, opi, opt[opi].flag);
+ return (free(tbuff), 1);
}
if (4 == opt[opi].kind) {
if (!opt[opi].dflt) {
- if (err)
- sprintf(err,
- "%sflagged single variable parameter must "
- "specify a default",
- ME);
- else
- fprintf(stderr, "%s: panic 11\n", me);
- return 1;
+ biffAddf(HEST,
+ "%s: flagged single variable parameter must "
+ "specify a default",
+ __func__);
+ return (free(tbuff), 1);
}
if (!strlen(opt[opi].dflt)) {
- if (err)
- sprintf(err,
- "%sflagged single variable parameter default "
- "must be non-zero length",
- ME);
- else
- fprintf(stderr, "%s: panic 12\n", me);
- return 1;
+ biffAddf(HEST,
+ "%s: flagged single variable parameter default "
+ "must be non-zero length",
+ __func__);
+ return (free(tbuff), 1);
}
}
/*
@@ -668,47 +643,37 @@
sprintf(tbuff, "-%s", opt[op].flag);
if (1 == sscanf(tbuff, "%f", &tmpF)) {
if (err)
- sprintf(err, "%sopt[%d].flag (\"%s\") is numeric, bad news",
+ sprintf(err, "%sopt[%u].flag (\"%s\") is numeric, bad news",
ME, op, opt[op].flag);
return 1;
}
*/
}
+ // ------ end of if (opt[opi].flag)
if (1 == opt[opi].kind) {
if (!opt[opi].flag) {
- if (err)
- sprintf(err, "%sflags must have flags", ME);
- else
- fprintf(stderr, "%s: panic 13\n", me);
+ biffAddf(HEST, "%s: opt[%u] flag must have a flag", __func__, opi);
return 1;
}
} else {
if (!opt[opi].name) {
- if (err)
- sprintf(err, "%sopt[%d] isn't a flag: must have \"name\"", ME, opi);
- else
- fprintf(stderr, "%s: panic 14\n", me);
+ biffAddf(HEST, "%s: opt[%u] isn't a flag: must have \"name\"", __func__, opi);
return 1;
}
}
if (4 == opt[opi].kind && !opt[opi].dflt) {
- if (err)
- sprintf(err,
- "%sopt[%d] is single variable parameter, but "
- "no default set",
- ME, opi);
- else
- fprintf(stderr, "%s: panic 15\n", me);
+ biffAddf(HEST,
+ "%s: opt[%u] is single variable parameter, but "
+ "no default set",
+ __func__, opi);
return 1;
}
- numvar += ((int)opt[opi].min < _hestMax(opt[opi].max)
+ varNum += ((int)opt[opi].min < _hestMax(opt[opi].max)
&& (NULL == opt[opi].flag)); /* HEY scrutinize casts */
}
- if (numvar > 1) {
- if (err)
- sprintf(err, "%scan't have %d unflagged min<max opts, only one", ME, numvar);
- else
- fprintf(stderr, "%s: panic 16\n", me);
+ if (varNum > 1) {
+ biffAddf(HEST, "%s: can't have %u unflagged min<max options, only one", __func__,
+ varNum);
return 1;
}
return 0;
@@ -725,30 +690,21 @@
return AIR_VOIDP(hestOptFree((hestOpt *)_opt));
}
+/*
+ * hestOptCheck: check given hestOpt array `opt`, using the default hestParm.
+ * Puts any errors into newly allocated (caller responsible to free) `*errP`.
+ */
int
-hestOptCheck(hestOpt *opt, char **errP) {
- static const char me[] = "hestOptCheck";
- char *err;
- hestParm *hparm;
- int big;
-
- big = _hestErrStrlen(opt, 0, NULL);
- if (!(err = AIR_CALLOC(big, char))) {
- fprintf(stderr,
- "%s PANIC: couldn't allocate error message "
- "buffer (size %d)\n",
- me, big);
- if (errP) *errP = NULL;
- return 1;
- }
- hparm = hestParmNew();
- if (_hestOptCheck(opt, err, hparm)) {
- /* problems */
+hestOptCheck(const hestOpt *opt, char **errP) {
+ hestParm *hparm = hestParmNew();
+ if (_hestOPCheck(opt, hparm)) {
+ char *err = biffGetDone(HEST);
if (errP) {
/* they did give a pointer address; they'll free it */
*errP = err;
} else {
- /* they didn't give a pointer address; their loss */
+ /* they didn't give a pointer address; we dump to stderr */
+ fprintf(stderr, "%s: problem with given hestOpt array:\n%s", __func__, err);
free(err);
}
hestParmFree(hparm);
@@ -756,7 +712,31 @@
}
/* else, no problems */
if (errP) *errP = NULL;
- free(err);
hestParmFree(hparm);
return 0;
}
+
+/*
+ * hestOptParmCheck: check given hestOpt array `opt` 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)) {
+ char *err = biffGetDone(HEST);
+ if (errP) {
+ /* they did give a pointer address; they'll free it */
+ *errP = err;
+ } else {
+ /* they didn't give a pointer address; we dump to stderr */
+ fprintf(stderr, "%s: problem with given hestOpt array:\n%s", __func__, err);
+ free(err);
+ }
+ return 1;
+ }
+ /* else, no problems */
+ if (errP) *errP = NULL;
+ return 0;
+}
Modified: teem/trunk/src/hest/parseHest.c
===================================================================
--- teem/trunk/src/hest/parseHest.c 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/parseHest.c 2025-09-22 20:35:11 UTC (rev 7467)
@@ -46,7 +46,7 @@
single arg, and we do not do any VTAB-separating of args here.
*/
static int
-argsInResponseFiles(int *argsNumP, int *respFileNumP, const char **argv, char *err,
+argsInResponseFiles(int *argsNumP, int *respFileNumP, const char **argv,
const hestParm *hparm) {
FILE *file;
static const char me[] = "argsInResponseFiles: ";
@@ -69,7 +69,7 @@
again by copyArgv */
if (!(file = fopen(argv[argIdx] + 1, "rb"))) {
/* can't open the indicated response file for reading */
- sprintf(err, "%scouldn't open \"%s\" for reading as response file", ME,
+ fprintf(stderr, "%scouldn't open \"%s\" for reading as response file", ME,
argv[argIdx] + 1);
*argsNumP = 0;
*respFileNumP = 0;
@@ -225,35 +225,10 @@
return newArgc;
}
-uint
-_hestErrStrlen(const hestOpt *opt, int argc, const char **argv) {
- uint ret = 0;
- uint optNum = hestOptNum(opt);
- int other = AIR_FALSE;
- if (argv) {
- for (uint ai = 0; ai < (uint)argc; ai++) {
- ret = AIR_MAX(ret, airStrlen(argv[ai]));
- }
- }
- for (uint ai = 0; ai < optNum; ai++) {
- ret = AIR_MAX(ret, airStrlen(opt[ai].flag));
- ret = AIR_MAX(ret, airStrlen(opt[ai].name));
- other |= opt[ai].type == airTypeOther;
- }
- for (uint ai = airTypeUnknown + 1; ai < airTypeLast; ai++) {
- ret = AIR_MAX(ret, airStrlen(_hestTypeStr[ai]));
- }
- if (other) {
- /* the callback's error() function may sprintf an error message
- into a buffer which is size AIR_STRLEN_HUGE+1 */
- ret += AIR_STRLEN_HUGE + 1;
- }
- ret += 4 * 12; /* as many as 4 ints per error message */
- ret += 257; /* function name and text of hest's error message */
+/* uint _hestErrStrlen(const hestOpt *opt, int argc, const char **argv) ...
+ * This was a bad idea, so has been removed for TeemV2. Now hest internally uses biff
+ */
- return ret;
-}
-
/*
identStr()
copies into ident a string for identifying an option in error and usage messages
@@ -423,8 +398,7 @@
*/
static int
extractFlagged(char **optParms, unsigned int *optParmNum, int *optAprd, int *argcP,
- char **argv, hestOpt *opt, char *err, const hestParm *hparm,
- airArray *pmop) {
+ char **argv, hestOpt *opt, const hestParm *hparm, airArray *pmop) {
/* see note on ME (at top) for why me[] ends with ": " */
static const char me[] = "extractFlagged: ";
char ident1[AIR_STRLEN_HUGE + 1], ident2[AIR_STRLEN_HUGE + 1];
@@ -474,20 +448,20 @@
if (parmNum < (int)opt[optIdx].min) { /* HEY scrutinize casts */
/* didn't get minimum number of parameters */
if (!(argIdx + parmNum + 1 <= *argcP - 1)) {
- sprintf(err,
+ fprintf(stderr,
"%sgot to end of line before getting %d parameter%s "
- "for %s (got %d)",
+ "for %s (got %d)\n",
ME, opt[optIdx].min, opt[optIdx].min > 1 ? "s" : "",
identStr(ident1, opt + optIdx, hparm, AIR_TRUE), parmNum);
} else if (-2 != nextOptIdx) {
- sprintf(err, "%ssaw %s before getting %d parameter%s for %s (got %d)", ME,
+ fprintf(stderr, "%ssaw %s before getting %d parameter%s for %s (got %d)\n", ME,
identStr(ident1, opt + nextOptIdx, hparm, AIR_FALSE), opt[optIdx].min,
opt[optIdx].min > 1 ? "s" : "",
identStr(ident2, opt + optIdx, hparm, AIR_FALSE), parmNum);
} else {
- sprintf(err,
+ fprintf(stderr,
"%ssaw \"-%c\" (option-parameter-stop flag) before getting %d "
- "parameter%s for %s (got %d)",
+ "parameter%s for %s (got %d)\n",
ME, VAR_PARM_STOP_FLAG, opt[optIdx].min, opt[optIdx].min > 1 ? "s" : "",
identStr(ident2, opt + optIdx, hparm, AIR_FALSE), parmNum);
}
@@ -528,7 +502,7 @@
optNum = hestOptNum(opt);
for (op = 0; op < optNum; op++) {
if (1 != opt[op].kind && opt[op].flag && !opt[op].dflt && !optAprd[op]) {
- sprintf(err, "%sdidn't get required %s", ME,
+ fprintf(stderr, "%sdidn't get required %s\n", ME,
identStr(ident1, opt + op, hparm, AIR_FALSE));
return 1;
}
@@ -560,7 +534,7 @@
*/
static int
extractUnflagged(char **optParms, unsigned int *optParmNum, int *argcP, char **argv,
- hestOpt *opt, char *err, const hestParm *hparm, airArray *pmop) {
+ hestOpt *opt, const hestParm *hparm, airArray *pmop) {
/* see note on ME (at top) for why me[] ends with ": " */
static const char me[] = "extractUnflagged: ";
char ident[AIR_STRLEN_HUGE + 1];
@@ -597,8 +571,8 @@
}
np = opt[op].min; /* min == max, as implied by how unflagVar was set */
if (!(np <= *argcP)) {
- sprintf(err, "%sdon't have %d parameter%s %s%s%sfor %s", ME, np, np > 1 ? "s" : "",
- argv[0] ? "starting at \"" : "", argv[0] ? argv[0] : "",
+ fprintf(stderr, "%sdon't have %d parameter%s %s%s%sfor %s\n", ME, np,
+ np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv[0] : "",
argv[0] ? "\" " : "", identStr(ident, opt + op, hparm, AIR_TRUE));
return 1;
}
@@ -618,7 +592,7 @@
if (nvp < 0) {
op = nextUnflagged(unflagVar + 1, opt, optNum);
np = opt[op].min;
- sprintf(err, "%sdon't have %d parameter%s for %s", ME, np, np > 1 ? "s" : "",
+ fprintf(stderr, "%sdon't have %d parameter%s for %s\n", ME, np, np > 1 ? "s" : "",
identStr(ident, opt + op, hparm, AIR_FALSE));
return 1;
}
@@ -651,7 +625,7 @@
triggered this error message when there were zero given parms, but the default
could have supplied them */
if (nvp < AIR_INT(opt[unflagVar].min)) {
- sprintf(err, "%sdidn't get minimum of %d arg%s for %s (got %d)", ME,
+ fprintf(stderr, "%sdidn't get minimum of %d arg%s for %s (got %d)\n", ME,
opt[unflagVar].min, opt[unflagVar].min > 1 ? "s" : "",
identStr(ident, opt + unflagVar, hparm, AIR_TRUE), nvp);
return 1;
@@ -673,7 +647,7 @@
static int
_hestDefaults(char **optParms, int *optDfltd, unsigned int *optParmNum,
- const int *optAprd, const hestOpt *opt, char *err, const hestParm *hparm,
+ const int *optAprd, const hestOpt *opt, const hestParm *hparm,
airArray *mop) {
/* see note on ME (at top) for why me[] ends with ": " */
static const char me[] = "_hestDefaults: ";
@@ -756,14 +730,16 @@
if (!AIR_IN_CL(AIR_INT(opt[optIdx].min), AIR_INT(optParmNum[optIdx]),
_hestMax(opt[optIdx].max))) {
if (-1 == opt[optIdx].max) {
- sprintf(err, "%s# parameters (in default) for %s is %d, but need %d or more",
- ME, identStr(ident, opt + optIdx, hparm, AIR_TRUE), optParmNum[optIdx],
+ fprintf(stderr,
+ "%s# parameters (in default) for %s is %d, but need %d or more\n", ME,
+ identStr(ident, opt + optIdx, hparm, AIR_TRUE), optParmNum[optIdx],
opt[optIdx].min);
} else {
- sprintf(err,
- "%s# parameters (in default) for %s is %d, but need between %d and %d",
- ME, identStr(ident, opt + optIdx, hparm, AIR_TRUE), optParmNum[optIdx],
- opt[optIdx].min, _hestMax(opt[optIdx].max));
+ fprintf(
+ stderr,
+ "%s# parameters (in default) for %s is %d, but need between %d and %d\n", ME,
+ identStr(ident, opt + optIdx, hparm, AIR_TRUE), optParmNum[optIdx],
+ opt[optIdx].min, _hestMax(opt[optIdx].max));
}
return 1;
}
@@ -884,7 +860,7 @@
static int
setValues(char **optParms, int *optDfltd, unsigned int *optParmNum, int *appr,
- hestOpt *opt, char *err, const hestParm *hparm, airArray *pmop) {
+ hestOpt *opt, const hestParm *hparm, airArray *pmop) {
/* see note on ME (at top) for why me[] ends with ": " */
static const char me[] = "setValues: ";
char ident[AIR_STRLEN_HUGE + 1], cberr[AIR_STRLEN_HUGE + 1], *tok, *last,
@@ -937,7 +913,7 @@
switch (type) {
case airTypeEnum:
if (1 != airParseStrE((int *)vP, optParms[op], " ", 1, opt[op].enm)) {
- sprintf(err, "%scouldn\'t parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn\'t parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], opt[op].enm->name,
ident);
return 1;
@@ -948,10 +924,10 @@
ret = opt[op].CB->parse(vP, optParms[op], cberr);
if (ret) {
if (strlen(cberr)) {
- sprintf(err, "%serror parsing \"%s\" as %s for %s:\n%s", ME, optParms[op],
- opt[op].CB->type, ident, cberr);
+ fprintf(stderr, "%serror parsing \"%s\" as %s for %s:\n%s\n", ME,
+ optParms[op], opt[op].CB->type, ident, cberr);
} else {
- sprintf(err, "%serror parsing \"%s\" as %s for %s: returned %d", ME,
+ fprintf(stderr, "%serror parsing \"%s\" as %s for %s: returned %d\n", ME,
optParms[op], opt[op].CB->type, ident, ret);
}
return ret;
@@ -967,7 +943,7 @@
if (1
!= airParseStrS((char **)vP, optParms[op], " ", 1
/*, hparm->greedySingleString */)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], _hestTypeStr[type],
ident);
return 1;
@@ -980,7 +956,7 @@
default:
/* type isn't string or enum, so no last arg to hestParseStr[type] */
if (1 != _hestParseStr[type](vP, optParms[op], " ", 1)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], _hestTypeStr[type],
ident);
return 1;
@@ -996,7 +972,7 @@
case airTypeEnum:
if (opt[op].min != /* min == max */
airParseStrE((int *)vP, optParms[op], " ", opt[op].min, opt[op].enm)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %d %s%s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], opt[op].min,
opt[op].enm->name, opt[op].min > 1 ? "s" : "", ident);
return 1;
@@ -1010,14 +986,14 @@
ret = opt[op].CB->parse(cP + p * size, tok, cberr);
if (ret) {
if (strlen(cberr))
- sprintf(err,
+ fprintf(stderr,
"%serror parsing \"%s\" (in \"%s\") as %s "
- "for %s:\n%s",
+ "for %s:\n%s\n",
ME, tok, optParms[op], opt[op].CB->type, ident, cberr);
else
- sprintf(err,
+ fprintf(stderr,
"%serror parsing \"%s\" (in \"%s\") as %s "
- "for %s: returned %d",
+ "for %s: returned %d\n",
ME, tok, optParms[op], opt[op].CB->type, ident, ret);
free(optParmsCopy);
return 1;
@@ -1036,7 +1012,7 @@
case airTypeString:
if (opt[op].min != /* min == max */
_hestParseStr[type](vP, optParms[op], " ", opt[op].min)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %d %s%s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], opt[op].min,
_hestTypeStr[type], opt[op].min > 1 ? "s" : "", ident);
return 1;
@@ -1051,7 +1027,7 @@
default:
if (opt[op].min != /* min == max */
_hestParseStr[type](vP, optParms[op], " ", opt[op].min)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %d %s%s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], opt[op].min,
_hestTypeStr[type], opt[op].min > 1 ? "s" : "", ident);
return 1;
@@ -1069,7 +1045,7 @@
/* no "inversion" for chars: using the flag with no parameter is the same as
not using the flag i.e. we just parse from the default string */
if (1 != _hestParseStr[type](vP, optParms[op], " ", 1)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], _hestTypeStr[type],
ident);
return 1;
@@ -1087,7 +1063,7 @@
pret = _hestParseStr[type](vP, optParms[op], " ",
1 /*, hparm->greedySingleString */);
if (1 != pret) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], _hestTypeStr[type],
ident);
return 1;
@@ -1104,7 +1080,7 @@
break;
case airTypeEnum:
if (1 != airParseStrE((int *)vP, optParms[op], " ", 1, opt[op].enm)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], opt[op].enm->name,
ident);
return 1;
@@ -1121,10 +1097,10 @@
ret = opt[op].CB->parse(vP, optParms[op], cberr);
if (ret) {
if (strlen(cberr))
- sprintf(err, "%serror parsing \"%s\" as %s for %s:\n%s", ME, optParms[op],
- opt[op].CB->type, ident, cberr);
+ fprintf(stderr, "%serror parsing \"%s\" as %s for %s:\n%s\n", ME,
+ optParms[op], opt[op].CB->type, ident, cberr);
else
- sprintf(err, "%serror parsing \"%s\" as %s for %s: returned %d", ME,
+ fprintf(stderr, "%serror parsing \"%s\" as %s for %s: returned %d\n", ME,
optParms[op], opt[op].CB->type, ident, ret);
return 1;
}
@@ -1137,7 +1113,7 @@
break;
default:
if (1 != _hestParseStr[type](vP, optParms[op], " ", 1)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], _hestTypeStr[type],
ident);
return 1;
@@ -1189,7 +1165,7 @@
if (optParmNum[op]
!= airParseStrE((int *)(*((void **)vP)), optParms[op], " ",
optParmNum[op], opt[op].enm)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %u %s%s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %u %s%s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], optParmNum[op],
opt[op].enm->name, optParmNum[op] > 1 ? "s" : "", ident);
return 1;
@@ -1216,15 +1192,15 @@
ret = opt[op].CB->parse(cP + p * size, tok, cberr);
if (ret) {
if (strlen(cberr))
- sprintf(err,
+ fprintf(stderr,
"%serror parsing \"%s\" (in \"%s\") as %s "
- "for %s:\n%s",
+ "for %s:\n%s\n",
ME, tok, optParms[op], opt[op].CB->type, ident, cberr);
else
- sprintf(err,
+ fprintf(stderr,
"%serror parsing \"%s\" (in \"%s\") as %s "
- "for %s: returned %d",
+ "for %s: returned %d\n",
ME, tok, optParms[op], opt[op].CB->type, ident, ret);
free(optParmsCopy);
return 1;
@@ -1247,7 +1223,7 @@
if (optParmNum[op]
!= airParseStrS((char **)(*((void **)vP)), optParms[op], " ",
optParmNum[op] /*, hparm->greedySingleString */)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %d %s%s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], optParmNum[op],
_hestTypeStr[type], optParmNum[op] > 1 ? "s" : "", ident);
return 1;
@@ -1266,7 +1242,7 @@
if (optParmNum[op]
!= _hestParseStr[type](*((void **)vP), optParms[op], " ",
optParmNum[op])) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s", ME,
+ fprintf(stderr, "%scouldn't parse %s\"%s\" as %d %s%s for %s\n", ME,
optDfltd[op] ? "(default) " : "", optParms[op], optParmNum[op],
_hestTypeStr[type], optParmNum[op] > 1 ? "s" : "", ident);
return 1;
@@ -1287,12 +1263,12 @@
** documentation?
*/
int
-hestParse(hestOpt *opt, int _argc, const char **_argv, char **_errP,
+hestParse(hestOpt *opt, int _argc, const char **_argv, char **errP,
const hestParm *_hparm) {
/* see note on ME (at top) for why me[] ends with ": " */
static const char me[] = "hestParse: ";
- char **argv, **optParms, *err;
- int a, argc, argc_used, respArgNum, *optAprd, *optDfltd, respFileNum, optNum, big, ret,
+ char **argv, **optParms;
+ int a, argc, argc_used, respArgNum, *optAprd, *optDfltd, respFileNum, optNum, ret,
sawHelp;
unsigned int *optParmNum;
airArray *mop;
@@ -1313,31 +1289,15 @@
/* how to const-correctly use hparm or _hparm in an expression */
#define HPARM (_hparm ? _hparm : hparm)
- /* -------- allocate the err string. To determine its size with total
- ridiculous safety we have to find the biggest things which can appear
- in the string. */
- big = _hestErrStrlen(opt, _argc, _argv);
- if (!(err = AIR_CALLOC(big, char))) {
- fprintf(stderr,
- "%s PANIC: couldn't allocate error message "
- "buffer (size %d)\n",
- me, big);
- /* exit(1); */
- }
- if (_errP) {
- /* if they care about the error string, than it is mopped only
- when there _wasn't_ an error */
- *_errP = err;
- airMopAdd(mop, _errP, (airMopper)airSetNull, airMopOnOkay);
- airMopAdd(mop, err, airFree, airMopOnOkay);
- } else {
- /* otherwise, we're making the error string just for our own
- convenience, and we'll always clean it up on exit */
- airMopAdd(mop, err, airFree, airMopAlways);
- }
-
/* -------- check on validity of the hestOpt array */
- if (_hestOptCheck(opt, err, HPARM)) {
+ if (_hestOPCheck(opt, HPARM)) {
+ char *err = biffGetDone(HEST);
+ if (errP) {
+ *errP = err;
+ } else {
+ airMopAdd(mop, err, airFree, airMopAlways);
+ fprintf(stderr, "%s: problem given hestOpt, hestParm:\n%s", __func__, err);
+ }
airMopError(mop);
return 1;
}
@@ -1360,7 +1320,7 @@
by seeing how many args are in the response files, and then adding
on the args from the actual argv (getting this right the first time
greatly simplifies the problem of eliminating memory leaks) */
- if (argsInResponseFiles(&respArgNum, &respFileNum, _argv, err, HPARM)) {
+ if (argsInResponseFiles(&respArgNum, &respFileNum, _argv, HPARM)) {
airMopError(mop);
return 1;
}
@@ -1393,7 +1353,7 @@
}
/* else !sawHelp; do sanity check on argc_used vs argc */
if (argc_used < argc) {
- sprintf(err, "%sargc_used %d < argc %d; sorry, confused", ME, argc_used, argc);
+ fprintf(stderr, "%sargc_used %d < argc %d; sorry, confused", ME, argc_used, argc);
airMopError(mop);
return 1;
}
@@ -1400,8 +1360,7 @@
/* -------- extract flags and their associated parameters from argv */
if (HPARM->verbosity) printf("%s: #### calling extractFlagged\n", me);
- if (extractFlagged(optParms, optParmNum, optAprd, &argc_used, argv, opt, err, HPARM,
- mop)) {
+ if (extractFlagged(optParms, optParmNum, optAprd, &argc_used, argv, opt, HPARM, mop)) {
airMopError(mop);
return 1;
}
@@ -1409,7 +1368,7 @@
/* -------- extract args for unflagged options */
if (HPARM->verbosity) printf("%s: #### calling extractUnflagged\n", me);
- if (extractUnflagged(optParms, optParmNum, &argc_used, argv, opt, err, HPARM, mop)) {
+ if (extractUnflagged(optParms, optParmNum, &argc_used, argv, opt, HPARM, mop)) {
airMopError(mop);
return 1;
}
@@ -1422,12 +1381,12 @@
char stops[3] = "-X";
stops[1] = VAR_PARM_STOP_FLAG;
if (strcmp(stops, argv[0])) {
- sprintf(err, "%sunexpected arg%s: \"%s\"", ME,
+ fprintf(stderr, "%sunexpected arg%s: \"%s\"\n", ME,
('-' == argv[0][0] ? " (or unrecognized flag)" : ""), argv[0]);
} else {
- sprintf(err,
+ fprintf(stderr,
"%sunexpected end-of-parameters flag \"%s\": "
- "not ending a flagged variable-parameter option",
+ "not ending a flagged variable-parameter option\n",
ME, stops);
}
airMopError(mop);
@@ -1436,7 +1395,7 @@
/* -------- learn defaults */
if (HPARM->verbosity) printf("%s: #### calling hestDefaults\n", me);
- if (_hestDefaults(optParms, optDfltd, optParmNum, optAprd, opt, err, HPARM, mop)) {
+ if (_hestDefaults(optParms, optDfltd, optParmNum, optAprd, opt, HPARM, mop)) {
airMopError(mop);
return 1;
}
@@ -1469,7 +1428,7 @@
/* -------- now, the actual parsing of values */
if (HPARM->verbosity) printf("%s: #### calling setValues\n", me);
/* this will also set hestOpt->parmStr */
- ret = setValues(optParms, optDfltd, optParmNum, optAprd, opt, err, HPARM, mop);
+ ret = setValues(optParms, optDfltd, optParmNum, optAprd, opt, HPARM, mop);
if (ret) {
airMopError(mop);
return ret;
@@ -1480,6 +1439,9 @@
parseEnd:
airMopOkay(mop);
+ if (*errP) {
+ *errP = NULL;
+ }
return 0;
}
Modified: teem/trunk/src/hest/parsest.c
===================================================================
--- teem/trunk/src/hest/parsest.c 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/parsest.c 2025-09-22 20:35:11 UTC (rev 7467)
@@ -618,15 +618,13 @@
/*
hestParse(2): parse the `argc`,`argv` commandline according to the hestOpt array `opt`.
-
+The basic phases of parsing are:
+0) Error checking on given `opt` array
*/
int
-hestParse2(hestOpt *opt, int argc, const char **argv, char **_errP,
+hestParse2(hestOpt *opt, int argc, const char **argv, char **errP,
const hestParm *_hparm) {
- /* how to const-correctly use hparm or _hparm in an expression */
-#define HPARM (_hparm ? _hparm : hparm)
-
// -------- initialize the mop
airArray *mop = airMopNew();
@@ -636,37 +634,31 @@
hparm = hestParmNew();
airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
}
+ // how to const-correctly use hparm or _hparm in an expression
+#define HPARM (_hparm ? _hparm : hparm)
if (HPARM->verbosity > 1) {
- printf("%s: hparm->verbosity %d\n", __func__, HPARM->verbosity);
+ printf("%s: (%s) hparm->verbosity %d\n", __func__, _hparm ? "given" : "default",
+ HPARM->verbosity);
}
- // -------- allocate the err string. We do it a dumb way for now.
- // TODO: make this allocation smarter
- uint eslen = 2 * AIR_STRLEN_HUGE;
- char *err = AIR_CALLOC(eslen + 1, char);
- assert(err);
- if (_errP) {
- // they care about the error string, so mop it only when there is _not_ an error
- *_errP = err;
- airMopAdd(mop, _errP, (airMopper)airSetNull, airMopOnOkay);
- airMopAdd(mop, err, airFree, airMopOnOkay);
- } else {
- /* otherwise, we're making the error string just for our own convenience,
- so we always clean it up on exit */
- airMopAdd(mop, err, airFree, airMopAlways);
+ // error string song and dance
+#define DO_ERR(WUT) \
+ char *err = biffGetDone(HEST); \
+ if (errP) { \
+ *errP = err; \
+ } else { \
+ fprintf(stderr, "%s: " WUT ":\n%s", __func__, err); \
+ free(err); \
}
- if (HPARM->verbosity > 1) {
- printf("%s: err %p\n", __func__, AIR_VOIDP(err));
- }
- // -------- check on validity of the hestOpt array
- if (_hestOptCheck(opt, err, HPARM)) {
- // error message has been sprinted into err
+ // --0--0--0--0--0-- check on validity of the hestOpt array
+ if (_hestOPCheck(opt, HPARM)) {
+ DO_ERR("problem with given hestOpt array");
airMopError(mop);
return 1;
}
if (HPARM->verbosity > 1) {
- printf("%s: _hestOptCheck passed\n", __func__);
+ printf("%s: _hestOPCheck passed\n", __func__);
}
// -------- allocate the state we use during parsing
@@ -683,16 +675,14 @@
// -------- initialize input stack w/ given argc,argv, then process it
if (histPushCommandLine(hist, argc, argv, HPARM)
|| histProcess(havec, &(opt->helpWanted), tharg, hist, HPARM)) {
- char *bferr = biffGetDone(HEST);
- airMopAdd(mop, bferr, airFree, airMopAlways);
- strcpy(err, bferr);
+ DO_ERR("problem with initial processing of command-line");
airMopError(mop);
return 1;
}
-
- // (debugging) have finished input stack, what argvec did it leave us with?
- hestArgVecPrint(__func__, havec);
-
+ if (HPARM->verbosity > 1) {
+ // have finished input stack, what argvec did it leave us with?
+ hestArgVecPrint(__func__, havec);
+ }
if (opt->helpWanted) {
// once the call for help is made, we respect it: clean up and return
airMopOkay(mop);
Modified: teem/trunk/src/hest/privateHest.h
===================================================================
--- teem/trunk/src/hest/privateHest.h 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/privateHest.h 2025-09-22 20:35:11 UTC (rev 7467)
@@ -73,11 +73,8 @@
extern const char *const _hestBiffKey;
extern int _hestKind(const hestOpt *opt);
extern int _hestMax(int max);
-extern int _hestOptCheck(const hestOpt *opt, char *err, const hestParm *parm);
+extern int _hestOPCheck(const hestOpt *opt, const hestParm *parm);
-/* parseHest.c */
-extern uint _hestErrStrlen(const hestOpt *opt, int argc, const char **argv);
-
#ifdef __cplusplus
}
#endif
Modified: teem/trunk/src/hest/test/tparse.c
===================================================================
--- teem/trunk/src/hest/test/tparse.c 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/test/tparse.c 2025-09-22 20:35:11 UTC (rev 7467)
@@ -34,7 +34,7 @@
hestParm *hparm = hestParmNew();
hparm->respectDashDashHelp = AIR_TRUE;
hparm->responseFileEnable = AIR_TRUE;
- hparm->verbosity = 0;
+ hparm->verbosity = 10;
int res[2];
hestOptAdd_2_Int(&opt, "res", "sx sy", res, NULL, "image resolution");
Modified: teem/trunk/src/hest/usage.c
===================================================================
--- teem/trunk/src/hest/usage.c 2025-09-22 20:29:18 UTC (rev 7466)
+++ teem/trunk/src/hest/usage.c 2025-09-22 20:35:11 UTC (rev 7467)
@@ -134,67 +134,6 @@
free(str);
}
-/*
-******** hestMinNumArgs
-
-The idea is that this helps quickly determine if the options given on the command line
-are insufficient, in order to produce general usage information instead of some specific
-parse error.
-
-Because hest is strictly agnostic with respect to how many command-line arguments
-actually constitute the command itself ("rmdir": one argument, "svn checkout": two
-arguments), it only concerns itself with the command-line arguments following the
-command aka argv[0].
-
-Thus, hestMinMinArgs() returns the minimum number of command-line arguments (following
-the command) that could be valid. If your command is only one argument (like "rmdir"),
-then you might use the true argc passed by the OS to main() as such:
-
- if (argc-1 < hestMinNumArgs(opt)) {
- ... usage ...
- }
-
-But if your command is two arguments (like "svn checkout"):
-
- if (argc-2 < hestMinNumArgs(opt)) {
- ... usage ...
- }
-
-HOWEVER! don't forget the response files can complicate all this: in one argument a
-response file can provide information for any number of arguments, and the argc itself is
-kind of meaningless. The code examples above only really apply when hparm->respFileEnable
-is false. For example, in unrrdu (private.h) we find:
-
- if ( (hparm->respFileEnable && !argc) ||
- (!hparm->respFileEnable && argc < hestMinNumArgs(opt)) ) {
- ... usage ...
- }
-
-*/
-int
-hestMinNumArgs(const hestOpt *opt) {
- hestParm *hparm;
- int i, count, numOpts;
-
- hparm = hestParmNew();
- if (_hestOptCheck(opt, NULL, hparm)) {
- hestParmFree(hparm);
- return _hestMax(-1);
- }
- count = 0;
- numOpts = hestOptNum(opt);
- for (i = 0; i < numOpts; i++) {
- if (!opt[i].dflt) {
- count += opt[i].min;
- if (!(0 == opt[i].min && 0 == opt[i].max)) {
- count += !!opt[i].flag;
- }
- }
- }
- hestParmFree(hparm);
- return count;
-}
-
#define HPARM (_hparm ? _hparm : hparm)
void
@@ -221,6 +160,12 @@
}
}
+// error string song and dance
+#define DO_ERR \
+ char *err = biffGetDone(HEST); \
+ fprintf(stderr, "%s: problem with given hestOpt array\n%s", __func__, err); \
+ free(err)
+
void
hestUsage(FILE *f, const hestOpt *opt, const char *argv0, const hestParm *_hparm) {
int i, numOpts;
@@ -228,12 +173,11 @@
Previous to the 2023 revisit, it was for max lenth 2*AIR_STRLEN_HUGE, but
test/ex6.c blew past that. May have to increment again in the future :) */
char buff[64 * AIR_STRLEN_HUGE + 1], tmpS[AIR_STRLEN_SMALL + 1];
- hestParm *hparm;
+ hestParm *hparm = _hparm ? NULL : hestParmNew();
- hparm = _hparm ? NULL : hestParmNew();
-
- if (_hestOptCheck(opt, NULL, HPARM)) {
+ if (_hestOPCheck(opt, HPARM)) {
/* we can't continue; the opt array is botched */
+ DO_ERR;
if (hparm) {
hestParmFree(hparm);
}
@@ -270,12 +214,11 @@
unsigned int len;
/* See note above about overflowing buff[] */
char buff[64 * AIR_STRLEN_HUGE + 1], tmpS[AIR_STRLEN_HUGE + 1];
- hestParm *hparm;
+ hestParm *hparm = _hparm ? NULL : hestParmNew();
- hparm = _hparm ? NULL : hestParmNew();
-
- if (_hestOptCheck(opt, NULL, HPARM)) {
+ if (_hestOPCheck(opt, HPARM)) {
/* we can't continue; the opt array is botched */
+ DO_ERR;
if (hparm) {
hestParmFree(hparm);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|