|
From: <kin...@us...> - 2025-09-29 04:38:04
|
Revision: 7516
http://sourceforge.net/p/teem/code/7516
Author: kindlmann
Date: 2025-09-29 04:38:01 +0000 (Mon, 29 Sep 2025)
Log Message:
-----------
still hacking
Modified Paths:
--------------
teem/trunk/src/hest/README.md
teem/trunk/src/hest/argvHest.c
teem/trunk/src/hest/methodsHest.c
teem/trunk/src/hest/parsest.c
teem/trunk/src/hest/privateHest.h
teem/trunk/src/hest/test/ex6.c
Modified: teem/trunk/src/hest/README.md
===================================================================
--- teem/trunk/src/hest/README.md 2025-09-28 18:28:35 UTC (rev 7515)
+++ teem/trunk/src/hest/README.md 2025-09-29 04:38:01 UTC (rev 7516)
@@ -29,7 +29,7 @@
## The different `kind`s of options, and how to `hestOptAdd` them.
-There are lot of moving pieces inside `hestParse`, and the description of how it works is complicated by how flexible a `hestOpt` can be. Two of the fields in the `hestOpt` are `min` and `max`: the min and max number of parameters that may be parsed for that option. All the different traditional uses of the command-line can be parameterized in terms of `min` and `max`, but the full range of possibilities of `min`,`max` (which `hest` supports) include some less conventional uses. Once the possibility of mapping out all possibilities for command-line options in terms of `min` and `max` was recognized, `hest` implementation was organized around that, even if typical uses of `hest` are not thought of that way. See also the **concrete examples** below.
+There are lot of moving pieces inside `hestParse`, and the description of how it works is complicated by how flexible a `hestOpt` can be. Two of the most important yet unconventional fields in the `hestOpt` are `min` and `max`: the min and max number of parameters that may be parsed for that option. All the different traditional uses of the command-line can be parameterized in terms of `min` and `max`, but the full range of possibilities of `min`,`max` (which `hest` supports) include unusual use-cases. Once the possibility of mapping out all possibilities for command-line options in terms of `min` and `max` was recognized, `hest` implementation was organized around that, even if typical uses of `hest` are not thought of that way. Refer also to the **concrete examples** above and below.
The _`kind`_ is `hest`'s term for a numeric identifier for the kind of option that a `hestOpt` describes. The following ASCII-art illustrates how `min` and `max` determine:
Modified: teem/trunk/src/hest/argvHest.c
===================================================================
--- teem/trunk/src/hest/argvHest.c 2025-09-28 18:28:35 UTC (rev 7515)
+++ teem/trunk/src/hest/argvHest.c 2025-09-29 04:38:01 UTC (rev 7516)
@@ -180,7 +180,7 @@
/* hestArgVecSprint goes is opposite of the shell-style tokenization of
parsest.c/argstGo: generate a single human-friendly string that could be tokenized to
recover the hestArgVec we started with.
-ChatGPT helped with prototyping plainWord and argAddQuotedString
+ChatGPT helped with prototyping _hestPlainWord and argAddQuotedString
(and in this file, only those two functions)
Here are instructive examples of the same kind of argv pretty-printing:
https://github.com/git/git/blob/master/quote.c
@@ -188,9 +188,9 @@
with its (more baroque) quotearg_buffer_restyled() function
*/
-// plainWord(str) is true if nothing in str needs quoting or escaping
-static int
-plainWord(const char *s) {
+// _hestPlainWord(str) is true if nothing in str needs quoting or escaping
+int
+_hestPlainWord(const char *s) {
if (*s == '\0') {
// wut - we got the empty string, yes needs quoting
return 0;
@@ -258,7 +258,7 @@
hestArgAddChar(retArg, ':');
}
const char *astr = havec->harg[ai]->str;
- if (plainWord(astr)) {
+ if (_hestPlainWord(astr)) {
hestArgAddString(retArg, astr);
} else {
argAddQuotedString(retArg, astr);
Modified: teem/trunk/src/hest/methodsHest.c
===================================================================
--- teem/trunk/src/hest/methodsHest.c 2025-09-28 18:28:35 UTC (rev 7515)
+++ teem/trunk/src/hest/methodsHest.c 2025-09-29 04:38:01 UTC (rev 7516)
@@ -663,9 +663,9 @@
/* _hestOPCheck
New biff-based container for all logic that originated 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`.
+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
+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.
@@ -795,22 +795,6 @@
_ME_, opi, flag);
return (free(tbuff), 1);
}
- if (4 == opt[opi].kind) {
- if (!opt[opi].dflt) {
- biffAddf(HEST,
- "%s%sflagged single variadic parameter must "
- "specify a default",
- _ME_);
- return 1;
- }
- if (!strlen(opt[opi].dflt)) {
- biffAddf(HEST,
- "%s%sflagged single variadic parameter default "
- "must be non-zero length",
- _ME_);
- return 1;
- }
- }
} else { // ------ end of if (opt[opi].flag)
// opt[opi] is unflagged
if (!opt[opi].min) {
@@ -822,7 +806,7 @@
}
}
if (4 == opt[opi].kind) { // single variadic parameter
- // immediately above have ruled out unflagged kind 4
+ // immediately above have just ruled out unflagged kind 4
if (!opt[opi].dflt) {
biffAddf(HEST,
"%s%sopt[%u] -%s is single variadic parameter, but "
@@ -830,8 +814,15 @@
_ME_, opi, opt[opi].flag);
return 1;
}
- /* pre 2025, these types were allowed kind 4, but the semantics are just so weird
- and thus hard to test + debug, that it no longer makes sense to support them */
+ if (!(strlen(opt[opi].dflt) && _hestPlainWord(opt[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);
+ 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) {
biffAddf(HEST,
Modified: teem/trunk/src/hest/parsest.c
===================================================================
--- teem/trunk/src/hest/parsest.c 2025-09-28 18:28:35 UTC (rev 7515)
+++ teem/trunk/src/hest/parsest.c 2025-09-29 04:38:01 UTC (rev 7516)
@@ -1262,8 +1262,11 @@
line. The inscrutability of the hest code (or really the self-reinforcing
learned fear of working with the hest code) seems to have been the barrier.
(2025 GLK notes that the fear was justified, given how long the re-write took ...) */
- opt[opi].parmStr = hestArgVecSprint(opt[opi].havec, AIR_FALSE);
- /* not: airStrdup(optParms[opi]); since 2025 havec adoption */
+ if (4 != opt[opi].kind) {
+ // single variadic options are weird, handled differently below
+ opt[opi].parmStr = hestArgVecSprint(opt[opi].havec, AIR_FALSE);
+ }
+ /* since 2025 havec adoption, not: airStrdup(optParms[opi]); */
int type = opt[opi].type;
size_t size = (airTypeEnum == type /* */
? sizeof(int)
@@ -1341,6 +1344,8 @@
if (invert) {
_hestInvertScalar[type](valueP);
}
+ // special handling of parmStr for kind 4
+ opt[opi].parmStr = airStrdup(strsrc);
} // end case 4 {
break;
case 2: // -------- one required parameter --------
@@ -1384,7 +1389,7 @@
}
*(opt[opi].sawP) = opt[opi].havec->len;
cvalueP = *((void **)valueP);
- // RIP hammerhead.ucsd.edu and Intel Itanium
+ // (RIP hammerhead.ucsd.edu, Intel Itanium, and last days of grad school)
for (uint argi = 0; argi < opt[opi].havec->len; argi++) {
if (_hestParseSingle[type](cvalueP + size * argi,
opt[opi].havec->harg[argi]->str, hpp)) {
@@ -1416,7 +1421,9 @@
The basic phases of parsing are:
-0) Error checking on given `opt` array
+0) Error checking on given `opt` array. If this fails (i.e. because the previous
+calls to hestOptAdd were malformed), the return is 2, not the 1 returned from errors in
+any of the subsequent steps.
1) Generate internal representation of command-line that includes expanding any
response files; this all goes into the `hestArgVec *havec`.
@@ -1465,7 +1472,7 @@
if (_hestOPCheck(opt, HPARM)) {
DO_ERR("problem with given hestOpt array");
airMopError(mop);
- return 1;
+ return 2;
}
if (HPARM->verbosity > 1) {
printf("%s: _hestOPCheck passed\n", __func__);
Modified: teem/trunk/src/hest/privateHest.h
===================================================================
--- teem/trunk/src/hest/privateHest.h 2025-09-28 18:28:35 UTC (rev 7515)
+++ teem/trunk/src/hest/privateHest.h 2025-09-29 04:38:01 UTC (rev 7516)
@@ -98,6 +98,9 @@
extern int _hestMax(int max);
extern int _hestOPCheck(const hestOpt *opt, const hestParm *parm);
+// argvHest.c
+extern int _hestPlainWord(const char *s);
+
/* wacky hack to use with biffAddf(HEST), so that normal hest users, who haven't
cranked up hestParm->verbosity to debug hest itself and don't want error messages
prefixed by a lot of weird hest function names:
Modified: teem/trunk/src/hest/test/ex6.c
===================================================================
--- teem/trunk/src/hest/test/ex6.c 2025-09-28 18:28:35 UTC (rev 7515)
+++ teem/trunk/src/hest/test/ex6.c 2025-09-29 04:38:01 UTC (rev 7516)
@@ -88,7 +88,6 @@
hestParmColumnsIoctl(hparm, 80);
opt = NULL;
- /* going past C89 to have declarations here */
int flag;
hestOptAdd_Flag(&opt, "f,flag", &flag, "a flag created via hestOptAdd_Flag");
@@ -324,62 +323,65 @@
"15.55 55.51 66.77 88.99 100.2", "test of hestOptAdd_N_Other B",
&quatCB);
- /* HEY also try 0, -1 */
+// HEY try both!
+// #define VMIN 0
+#define VMIN 1
int *bv;
unsigned int bvSaw;
- hestOptAdd_Nv_Bool(&opt, "bv", "bool1", 1, -1, &bv, "true false",
+ hestOptAdd_Nv_Bool(&opt, "bv", "bool1", VMIN, -1, &bv, "true false",
"test of hestOptAdd_Nv_Bool", &bvSaw);
int *iv;
unsigned int ivSaw;
- hestOptAdd_Nv_Int(&opt, "iv", "int1", 1, -1, &iv, "42 24", "test of hestOptAdd_Nv_Int",
- &ivSaw);
+ hestOptAdd_Nv_Int(&opt, "iv", "int1", VMIN, -1, &iv, "42 24",
+ "test of hestOptAdd_Nv_Int", &ivSaw);
unsigned int *uiv;
unsigned int uivSaw;
- hestOptAdd_Nv_UInt(&opt, "uiv", "uint1", 1, -1, &uiv, "42 24",
+ hestOptAdd_Nv_UInt(&opt, "uiv", "uint1", VMIN, -1, &uiv, "42 24",
"test of hestOptAdd_Nv_UInt", &uivSaw);
long int *liv;
unsigned int livSaw;
- hestOptAdd_Nv_Long(&opt, "liv", "lint1", 1, -1, &liv, "42 24",
+ hestOptAdd_Nv_Long(&opt, "liv", "lint1", VMIN, -1, &liv, "42 24",
"test of hestOptAdd_Nv_Long", &livSaw);
unsigned long int *uliv;
unsigned int ulivSaw;
- hestOptAdd_Nv_ULong(&opt, "uliv", "ulint1", 1, -1, &uliv, "42 24",
+ hestOptAdd_Nv_ULong(&opt, "uliv", "ulint1", VMIN, -1, &uliv, "42 24",
"test of hestOptAdd_Nv_ULong", &ulivSaw);
size_t *szv;
unsigned int szvSaw;
- hestOptAdd_Nv_Size_t(&opt, "szv", "size1", 1, -1, &szv, "42 24",
+ hestOptAdd_Nv_Size_t(&opt, "szv", "size1", VMIN, -1, &szv, "42 24",
"test of hestOptAdd_Nv_Size_t", &szvSaw);
float *flv;
unsigned int flvSaw;
- hestOptAdd_Nv_Float(&opt, "flv", "float1", 1, -1, &flv, "4.2 2.4",
+ hestOptAdd_Nv_Float(&opt, "flv", "float1", VMIN, -1, &flv, "4.2 2.4",
"test of hestOptAdd_Nv_Float", &flvSaw);
double *dbv;
unsigned int dbvSaw;
- hestOptAdd_Nv_Double(&opt, "dbv", "double1", 1, -1, &dbv, "4.2 2.4",
+ hestOptAdd_Nv_Double(&opt, "dbv", "double1", VMIN, -1, &dbv, "4.2 2.4",
"test of hestOptAdd_Nv_Double", &dbvSaw);
char *cv;
unsigned int cvSaw;
- hestOptAdd_Nv_Char(&opt, "cv", "char1", 1, -1, &cv, "x y",
+ hestOptAdd_Nv_Char(&opt, "cv", "char1", VMIN, -1, &cv, "x y",
"test of hestOptAdd_Nv_Char", &cvSaw);
char **sv;
unsigned int svSaw;
- hestOptAdd_Nv_String(&opt, "sv", "str1", 1, -1, &sv, "bingo bob",
+ hestOptAdd_Nv_String(&opt, "sv", "str1", VMIN, -1, &sv, "bingo bob",
"test of hestOptAdd_Nv_String", &svSaw);
int *ev;
unsigned int evSaw;
- hestOptAdd_Nv_Enum(&opt, "ev", "enum1", 1, -1, &ev, "little big",
+ hestOptAdd_Nv_Enum(&opt, "ev", "enum1", VMIN, -1, &ev, "little big",
"test of hestOptAdd_Nv_Enum", &evSaw, airEndian);
double *pv;
unsigned int pvSaw;
- hestOptAdd_Nv_Other(&opt, "pv", "pos1", 1, -1, &pv, "1.5,5.25 2.9,9.2",
+ hestOptAdd_Nv_Other(&opt, "pv", "pos1", VMIN, -1, &pv, "1.5,5.25 2.9,9.2",
"test of hestOptAdd_Nv_Other A", &pvSaw, &posCB);
Quat **qv;
unsigned int qvSaw;
- hestOptAdd_Nv_Other(&opt, "qv", "quat1", 1, -1, &qv, "12.34 43.21",
+ hestOptAdd_Nv_Other(&opt, "qv", "quat1", VMIN, -1, &qv, "12.34 43.21",
"test of hestOptAdd_Nv_Other B", &qvSaw, &quatCB);
- if (hestParse2(opt, argc - 1, argv + 1, NULL, hparm)) {
+ int eret;
+ if ((eret = hestParse2(opt, argc - 1, argv + 1, NULL, hparm))) {
// have already fprintf'd to stderr
- hestUsage(stderr, opt, argv[0], hparm);
+ if (2 != eret) hestUsage(stderr, opt, argv[0], hparm);
hestParmFree(hparm);
hestOptFree(opt);
exit(0);
@@ -395,7 +397,7 @@
AIR_TRUE);
*/
- if (0) {
+ if (1) {
unsigned int opi, numO;
numO = hestOptNum(opt);
for (opi = 0; opi < numO; opi++) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|