|
From: <kin...@us...> - 2023-07-11 21:18:08
|
Revision: 7071
http://sourceforge.net/p/teem/code/7071
Author: kindlmann
Date: 2023-07-11 21:18:05 +0000 (Tue, 11 Jul 2023)
Log Message:
-----------
the min argument to hestOptAdd and friends is now an unsigned int, as it should have been as soon as hestOpt->min was unsigned. ALSO: API NEW: 85 new type-specific hestOptAdd_N_T functions, created by some macro magic
Modified Paths:
--------------
teem/trunk/src/hest/adders.c
teem/trunk/src/hest/hest.h
teem/trunk/src/hest/methodsHest.c
teem/trunk/src/hest/parseHest.c
teem/trunk/src/hest/test/ex6.c
Modified: teem/trunk/src/hest/adders.c
===================================================================
--- teem/trunk/src/hest/adders.c 2023-07-11 12:45:20 UTC (rev 7070)
+++ teem/trunk/src/hest/adders.c 2023-07-11 21:18:05 UTC (rev 7071)
@@ -36,27 +36,30 @@
would have caught the above error.
The underlying issue there, though, is the total lack of type-checking associated with
-the var-args functions. The functions in this file help do as much type-checking as
-possible with hest. These functions cover nearly all uses of hest within Teem (and in
-GLK's SciVIs class), in a way that is specific to the type of the value storage pointer
-valueP, which is still a void* even in hestOptAdd_nva. Many of the possibilities here
-are unlikely to be needed (an option for 4 booleans?), but are generated here for
-completeness (an option for 4 floats or 4 doubles is great for R,G,B,A).
+the var-args functions. Even without var-args, the "void*" type of the value storage
+pointer is still a problem. Therefore, the functions in this file help do as much
+type-checking as possible with hest. These functions cover nearly all uses of hest
+within Teem (and in GLK's SciVis class), in a way that is specific to the type of the
+value storage pointer valueP, which is still a void* even in hestOptAdd_nva. Many of the
+possibilities here are unlikely to be needed (an option for 4 booleans?), but are
+generated here for completeness (an option for 4 floats or 4 doubles is great for
+R,G,B,A values).
-However with airTypeOther, in which case the caller passes a hestCB struct of callbacks
-to parse arbitrary things from the command-line, there is still unfortunately a
-type-checking black hole void* involved. And, there is no away around that:
-the non-NULL-ity of hestCB->destroy determines wether the thing being parsed is
-merely space to be initialized (valueP is an array of structs), versus a
-struct to be allocated (valueP is an array of pointers to structs), we want that to
-determine the type of valueP. But the struct itself as to be void type, and void** is
-not a generic pointer to pointer type (like void* is the generic pointer type). Still
-the _Other versions of the function are generated here to slightly simplify the
-hestOptAdd call (no more NULL, NULL for sawP and enum). Actually, there is around
+However with airTypeOther, when the caller passes a hestCB struct of callbacks to parse
+arbitrary things from the command-line, there is still unfortunately a type-checking
+black hole void* involved. And, there is no away around that: either valueP is an array
+of structs (when hestCB->destroy is NULL) or an array of pointers to structs
+(hestCB->destroy is non-NULL), for which the most specific type for valueP would be
+either void* or void**, respectively. But void** is not a generic pointer to pointer type
+(like void* is the generic pointer type), and, we're not doing compile-time checks on the
+non-NULL-ity of hestCB->destroy. So it all devolves back to plain void*. Still, the
+hestOptAdd_*_Other function are generated here to slightly simplify the hestOptAdd call,
+since there is no more NULL and NULL for sawP and enum. Actually, there is a way around
a type-checking black hole: extreme attentiveness!
*/
/* --------------------------------------------------------------- 1 == kind */
+/* (there is only one kind of kind==1 option) */
unsigned int
hestOptAdd_Flag(hestOpt **hoptP, const char *flag, int *valueP, const char *info) {
@@ -65,274 +68,271 @@
NULL, NULL, NULL);
}
-/* --------------------------------------------------------------- 2 == kind */
-unsigned int
-hestOptAdd_1_Bool(hestOpt **hoptP, const char *flag, const char *name, /* */
- int *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeBool, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+/* The number of very similar functions to define here justifies macro tricks,
+which follow these naming conventions:
-unsigned int
-hestOptAdd_1_Int(hestOpt **hoptP, const char *flag, const char *name, /* */
- int *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeInt, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+DCL_ = declaration (for the header file)
+IMP- = implementation (for this file)
+DEF_ = definition = declaration + implementation
+_T_ = simple scalar types
+_E_ = airEnum
+_O_ = Other (needs hestCB)
+_1 = single parameter, either fixed (kind 2) or variable (kind 4)
+_M = 2, 3, or 4 = COMPILE-TIME fixed # of parameters (kind 3)
+ (these exist as a convenience, covering many common hest uses)
+_N = RUN_TIME user-given fixed # of parameters (still kind 3)
+_V = RUN_TIME variable # of parameters (kind 5)
-unsigned int
-hestOptAdd_1_UInt(hestOpt **hoptP, const char *flag, const char *name, /* */
- unsigned int *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeUInt, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+*/
-unsigned int
-hestOptAdd_1_LongInt(hestOpt **hoptP, const char *flag, const char *name, /* */
- long int *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeLongInt, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+/* utility concatenators, used to form the name of macros to expand further */
+#define CONC(A, B) A##_##B
+#define CONC3(A, B, C) A##_##B##_##C
-unsigned int
-hestOptAdd_1_ULongInt(hestOpt **hoptP, const char *flag, const char *name, /* */
- unsigned long int *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeULongInt, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+/*
+_1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1
+_1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1
+_1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1 _1
+*/
-unsigned int
-hestOptAdd_1_Size_t(hestOpt **hoptP, const char *flag, const char *name, /* */
- size_t *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeSize_t, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+/* "_1v_" functions (declared via _DCL_T_0) are for a single variable parm opt (kind 4),
+ "_1_" functions (declared via _DCL_T_1) are for a single fixed parm opt (kind 2)
+*/
+#define _DCL_T_0(ATYP, CTYP) \
+ unsigned int hestOptAdd_1v_##ATYP(hestOpt **hoptP, const char *flag, \
+ const char *name, CTYP *valueP, const char *dflt, \
+ const char *info)
+#define _DCL_T_1(ATYP, CTYP) \
+ unsigned int hestOptAdd_1_##ATYP(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, CTYP *valueP, const char *dflt, \
+ const char *info)
+/* DCL_T_1(M) chooses between _DCL_T_0 and _DCL_T_1 */
+#define DCL_T_1(M, ATYP, CTYP) CONC(_DCL_T, M)(ATYP, CTYP)
+/* IMP_T_1(M) passes M as minimum # parms;
+ M=0 --> kind 4
+ M=1 --> kind 2; max # parms is 1 for both */
+#define IMP_T_1(M, ATYP, CTYP) \
+ { \
+ return hestOptAdd_nva(hoptP, flag, name, airType##ATYP, M, 1, /* */ \
+ valueP, dflt, info, /* */ \
+ NULL, NULL, NULL); \
+ }
+#define DEF_T_1(M, ATYP, CTYP) DCL_T_1(M, ATYP, CTYP) IMP_T_1(M, ATYP, CTYP)
+/* copy-pasta for Enum -------------- */
+#define _DCL_E_0 \
+ unsigned int hestOptAdd_1v_Enum(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, int *valueP, const char *dflt, \
+ const char *info, const airEnum *enm)
+#define _DCL_E_1 \
+ unsigned int hestOptAdd_1_Enum(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, int *valueP, const char *dflt, \
+ const char *info, const airEnum *enm)
+#define DCL_E_1(M) CONC(_DCL_E, M)
+#define IMP_E_1(M) \
+ { \
+ return hestOptAdd_nva(hoptP, flag, name, airTypeEnum, M, 1, /* */ \
+ valueP, dflt, info, /* */ \
+ NULL, enm, NULL); \
+ }
+#define DEF_E_1(M) DCL_E_1(M) IMP_E_1(M)
+/* copy-pasta for Other -------------- */
+#define _DCL_O_0 \
+ unsigned int hestOptAdd_1v_Other(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, void *valueP, const char *dflt, \
+ const char *info, const hestCB *CB)
+#define _DCL_O_1 \
+ unsigned int hestOptAdd_1_Other(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, void *valueP, const char *dflt, \
+ const char *info, const hestCB *CB)
+#define DCL_O_1(M) CONC(_DCL_O, M)
+#define IMP_O_1(M) \
+ { \
+ return hestOptAdd_nva(hoptP, flag, name, airTypeOther, M, 1, /* */ \
+ valueP, dflt, info, /* */ \
+ NULL, NULL, CB); \
+ }
+#define DEF_O_1(M) DCL_O_1(M) IMP_O_1(M)
-unsigned int
-hestOptAdd_1_Float(hestOpt **hoptP, const char *flag, const char *name, /* */
- float *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeFloat, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
+/*
+_M and _N _M and _N _M and _N _M and _N _M and _N _M and _N _M and _N
+_M and _N _M and _N _M and _N _M and _N _M and _N _M and _N _M and _N
+_M and _N _M and _N _M and _N _M and _N _M and _N _M and _N _M and _N
+*/
-unsigned int
-hestOptAdd_1_Double(hestOpt **hoptP, const char *flag, const char *name, /* */
- double *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeDouble, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
-
-unsigned int
-hestOptAdd_1_Char(hestOpt **hoptP, const char *flag, const char *name, /* */
- char *valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeChar, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
-
-unsigned int
-hestOptAdd_1_String(hestOpt **hoptP, const char *flag, const char *name, /* */
- char **valueP, const char *dflt, const char *info) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeString, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, NULL);
-}
-
-unsigned int
-hestOptAdd_1_Enum(hestOpt **hoptP, const char *flag, const char *name, /* */
- int *valueP, const char *dflt, const char *info, /* */
- const airEnum *enm) {
-
- return hestOptAdd_nva(hoptP, flag, name, airTypeEnum, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, enm, NULL);
-}
-
-unsigned int
-hestOptAdd_1_Other(hestOpt **hoptP, const char *flag, const char *name, /* */
- void *valueP, const char *dflt, const char *info, /* */
- const hestCB *CB) {
- return hestOptAdd_nva(hoptP, flag, name, airTypeOther, 1, 1, /* */
- valueP, dflt, info, /* */
- NULL, NULL, CB);
-}
-
-/* --------------------------------------------------------------- 2 == kind */
-
-/* for some reason writing out code above (and their declarations in hest.h) by hand was
-tolerated, but from here on out the coding is going to use a lot of macro tricks, with
-these name conventions:
-
-M = 2, 3, or 4 = fixed # of parameters
-N = user-given fixed # of parameters
-_S = simple scalar types
-_E = airEnum
-_O = Other
-
-Some way of gracefully handling the 10 different simple types, plus the airEnum and
-Other, with the context of the functional-ish MAP macros, is surely possible, but it
-eludes GLK at this time */
-
-/* _S: simple scalar types */
-#define DCL_M_S(M, ATYP, CTYP) \
+/* copy-pasta for _T scalar types for (compile-time) M or (run-time) N fixed parms */
+#define DCL_T_M(M, ATYP, CTYP) \
unsigned int hestOptAdd_##M##_##ATYP(hestOpt **hoptP, const char *flag, \
const char *name, CTYP valueP[M], \
const char *dflt, const char *info)
-#define BODY_M_S(M, ATYP, CTYP) \
+#define IMP_T_M(M, ATYP, CTYP) \
{ \
return hestOptAdd_nva(hoptP, flag, name, airType##ATYP, M, M, valueP, dflt, info, \
NULL, NULL, NULL); \
}
-#define DEF_M_S(M, ATYP, CTYP) DCL_M_S(M, ATYP, CTYP) BODY_M_S(M, ATYP, CTYP)
-#define DCL_N_S(ATYP, CTYP) \
+#define DEF_T_M(M, ATYP, CTYP) DCL_T_M(M, ATYP, CTYP) IMP_T_M(M, ATYP, CTYP)
+#define DCL_T_N(_, ATYP, CTYP) \
unsigned int hestOptAdd_N_##ATYP(hestOpt **hoptP, const char *flag, const char *name, \
unsigned int N, CTYP *valueP, const char *dflt, \
const char *info)
-#define BODY_N_S(ATYP, CTYP) \
+#define IMP_T_N(_, ATYP, CTYP) \
{ \
return hestOptAdd_nva(hoptP, flag, name, airType##ATYP, N, N, valueP, dflt, info, \
NULL, NULL, NULL); \
}
-#define DEF_N_S(ATYP, CTYP) DCL_N_S(ATYP, CTYP) BODY_N_S(ATYP, CTYP)
-
-/* _E: Enum */
-#define DCL_M_E(M) \
+#define DEF_T_N(_, ATYP, CTYP) DCL_T_N(_, ATYP, CTYP) IMP_T_N(_, ATYP, CTYP)
+/* copy-pasta for _E Enums */
+#define DCL_E_M(M) \
unsigned int hestOptAdd_##M##_Enum(hestOpt **hoptP, const char *flag, \
const char *name, int valueP[M], const char *dflt, \
const char *info, const airEnum *enm)
-#define BODY_M_E(M) \
+#define IMP_E_M(M) \
{ \
return hestOptAdd_nva(hoptP, flag, name, airTypeEnum, M, M, valueP, dflt, info, \
NULL, enm, NULL); \
}
-#define DEF_M_E(M) DCL_M_E(M) BODY_M_E(M)
-#define DCL_N_E \
+#define DEF_E_M(M) DCL_E_M(M) IMP_E_M(M)
+#define DCL_E_N(_) \
unsigned int hestOptAdd_N_Enum(hestOpt **hoptP, const char *flag, const char *name, \
unsigned int N, int *valueP, const char *dflt, \
const char *info, const airEnum *enm)
-#define BODY_N_E \
+#define IMP_E_N(_) \
{ \
return hestOptAdd_nva(hoptP, flag, name, airTypeEnum, N, N, valueP, dflt, info, \
NULL, enm, NULL); \
}
-#define DEF_N_E DCL_N_E BODY_N_E
-
-/* _O: Other */
-#define DCL_M_O(M) \
+#define DEF_E_N(_) DCL_E_N(_) IMP_E_N(_)
+/* copy-pasta for _O Other */
+#define DCL_O_M(M) \
unsigned int hestOptAdd_##M##_Other(hestOpt **hoptP, const char *flag, \
const char *name, void *valueP, const char *dflt, \
const char *info, const hestCB *CB)
-#define BODY_M_O(M) \
+#define IMP_O_M(M) \
{ \
return hestOptAdd_nva(hoptP, flag, name, airTypeOther, M, M, valueP, dflt, info, \
NULL, NULL, CB); \
}
-#define DEF_M_O(M) DCL_M_O(M) BODY_M_O(M)
-#define DCL_N_O \
+#define DEF_O_M(M) DCL_O_M(M) IMP_O_M(M)
+#define DCL_O_N(_) \
unsigned int hestOptAdd_N_Other(hestOpt **hoptP, const char *flag, const char *name, \
unsigned int N, void *valueP, const char *dflt, \
const char *info, const hestCB *CB)
-#define BODY_N_O \
+#define IMP_O_N(_) \
{ \
return hestOptAdd_nva(hoptP, flag, name, airTypeOther, N, N, valueP, dflt, info, \
NULL, NULL, CB); \
}
-#define DEF_N_O DCL_N_O BODY_N_O
+#define DEF_O_N(_) DCL_O_N(_) IMP_O_N(_)
-/* MAP_M_S takes a macro MMAC that (like DCL_M_S or DEF_M_S) takes three args
--- M, ATYP, CTYP -- and applies it to all the simple scalar types.
-MAP_N_S takes a macro NMAC (like DCL_N_S or DEF_N_S) that takes just two args
--- ATYP, CTYPE -- and applies to the scalar types */
-#define MAP_M_S(MMAC, M) \
- MMAC(M, Bool, int) \
- MMAC(M, Int, int) \
- MMAC(M, UInt, unsigned int) \
- MMAC(M, LongInt, long int) \
- MMAC(M, ULongInt, unsigned long int) \
- MMAC(M, Size_t, size_t) \
- MMAC(M, Float, float) \
- MMAC(M, Double, double) \
- MMAC(M, Char, char) \
- MMAC(M, String, char *)
-/* (yes would be nicer to avoid copy-pasta, but how?) */
-#define MAP_N_S(NMAC) \
- NMAC(Bool, int) \
- NMAC(Int, int) \
- NMAC(UInt, unsigned int) \
- NMAC(LongInt, long int) \
- NMAC(ULongInt, unsigned long int) \
- NMAC(Size_t, size_t) \
- NMAC(Float, float) \
- NMAC(Double, double) \
- NMAC(Char, char) \
- NMAC(String, char *)
+/*
+_V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V
+_V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V
+_V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V _V
+*/
-/* v.v.v.v.v.v.v.v.v Actual code! v.v.v.v.v.v.v.v.v */
-MAP_M_S(DEF_M_S, 2)
-DEF_M_E(2)
-DEF_M_O(2)
-MAP_M_S(DEF_M_S, 3)
-DEF_M_E(3)
-DEF_M_O(3)
-MAP_M_S(DEF_M_S, 4)
-DEF_M_E(4)
-DEF_M_O(4)
-MAP_N_S(DEF_N_S)
-DEF_N_E
-DEF_N_O
-/* ^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^'^ */
+#define DCL_T_V(_, ATYP, CTYP) \
+ unsigned int hestOptAdd_Nv_##ATYP(hestOpt **hoptP, const char *flag, \
+ const char *name, unsigned int min, int max, \
+ CTYP **valueP, const char *dflt, const char *info, \
+ unsigned int *sawP)
+#define IMP_T_V(_, ATYP, CTYP) \
+ { \
+ return hestOptAdd_nva(hoptP, flag, name, airType##ATYP, min, max, /* */ \
+ valueP, dflt, info, /* */ \
+ sawP, NULL, NULL); \
+ }
+#define DEF_T_V(M, ATYP, CTYP) DCL_T_V(M, ATYP, CTYP) IMP_T_V(M, ATYP, CTYP)
+/* copy-pasta for Enum -------------- */
+#define DCL_E_V(_) \
+ unsigned int hestOptAdd_Nv_Enum(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, unsigned int min, int max, \
+ int **valueP, const char *dflt, const char *info, \
+ unsigned int *sawP, const airEnum *enm)
+#define IMP_E_V(_) \
+ { \
+ return hestOptAdd_nva(hoptP, flag, name, airTypeEnum, min, max, /* */ \
+ valueP, dflt, info, /* */ \
+ sawP, enm, NULL); \
+ }
+#define DEF_E_V(_) DCL_E_V(_) IMP_E_V(_)
+/* copy-pasta for Other -------------- */
+#define DCL_O_V(_) \
+ unsigned int hestOptAdd_Nv_Other(hestOpt **hoptP, const char *flag, /* */ \
+ const char *name, unsigned int min, int max, \
+ void *valueP, const char *dflt, const char *info, \
+ unsigned int *sawP, const hestCB *CB)
+#define IMP_O_V(_) \
+ { \
+ return hestOptAdd_nva(hoptP, flag, name, airTypeOther, min, max, /* */ \
+ valueP, dflt, info, /* */ \
+ sawP, NULL, CB); \
+ }
+#define DEF_O_V(_) DCL_O_V(_) IMP_O_V(_)
-/* Macro for making a string out of whatever something has been #define'd to, exactly,
- without chasing down a sequence of #includes.
+/* MAP_T takes a macro MAC that (like DCL_T_M or DEF_T_M) takes three args
+(M, ATYP, CTYP) and applies it to all the simple scalar types */
+#define MAP_T(MAC, M) \
+ MAC(M, Bool, int) \
+ MAC(M, Int, int) \
+ MAC(M, UInt, unsigned int) \
+ MAC(M, LongInt, long int) \
+ MAC(M, ULongInt, unsigned long int) \
+ MAC(M, Size_t, size_t) \
+ MAC(M, Float, float) \
+ MAC(M, Double, double) \
+ MAC(M, Char, char) \
+ MAC(M, String, char *)
+
+/* MAP(BSN, X, M) takes a macro basename BSN (like DEF) and
+expands it to the _T, _E, and _O cases for _X. E.g. "MAP(DEF, 1, 0)" expands to:
+MAP_T(DEF_T_1, 0)
+DEF_E_1(0)
+DEF_O_1(0)
+*/
+#define MAP(BSN, X, M) MAP_T(CONC3(BSN, T, X), M) CONC3(BSN, E, X)(M) CONC3(BSN, O, X)(M)
+
+/* DOIT does expansion over all possibilities of BSN */
+#define DOIT(BSN) \
+ MAP(BSN, 1, 0) \
+ MAP(BSN, 1, 1) \
+ MAP(BSN, M, 2) \
+ MAP(BSN, M, 3) \
+ MAP(BSN, M, 4) \
+ MAP(BSN, N, _) \
+ MAP(BSN, V, _)
+
+/* !!! HERE IS THE ACTUAL CODE FOR ALL THE hestOptAdd_*_* CASES !!! */
+DOIT(DEF)
+
+/* Macro for making a string out of whatever something has been #define'd to
https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html */
#define __STR(name) #name
#define _STR(name) __STR(name)
/* for generating body of hestOptAddDeclsPrint;
-NOTE assuming the local FILE *ff */
-#define PRINT_M_S(M, ATYP, CTYP) \
- fprintf(ff, "HEST_EXPORT " _STR(DCL_M_S(M, ATYP, CTYP)) ";\n");
-#define PRINT_M_E(M) fprintf(ff, "HEST_EXPORT " _STR(DCL_M_E(M)) ";\n");
-#define PRINT_M_O(M) fprintf(ff, "HEST_EXPORT " _STR(DCL_M_O(M)) ";\n");
-#define PRINT_N_S(ATYP, CTYP) \
- fprintf(ff, "HEST_EXPORT " _STR(DCL_N_S(ATYP, CTYP)) ";\n");
-#define PRINT_N_E fprintf(ff, "HEST_EXPORT " _STR(DCL_N_E) ";\n");
-#define PRINT_N_O fprintf(ff, "HEST_EXPORT " _STR(DCL_N_O) ";\n");
+NOTE assuming the local variable FILE *ff */
+#define PRINT_T_1(M, ATYP, CTYP) \
+ fprintf(ff, "HEST_EXPORT " _STR(DCL_T_1(M, ATYP, CTYP)) ";\n");
+#define PRINT_E_1(M) fprintf(ff, "HEST_EXPORT " _STR(DCL_E_1(M)) ";\n");
+#define PRINT_O_1(M) fprintf(ff, "HEST_EXPORT " _STR(DCL_O_1(M)) ";\n");
+#define PRINT_T_M(M, ATYP, CTYP) \
+ fprintf(ff, "HEST_EXPORT " _STR(DCL_T_M(M, ATYP, CTYP)) ";\n");
+#define PRINT_E_M(M) fprintf(ff, "HEST_EXPORT " _STR(DCL_E_M(M)) ";\n");
+#define PRINT_O_M(M) fprintf(ff, "HEST_EXPORT " _STR(DCL_O_M(M)) ";\n");
+#define PRINT_T_N(_, ATYP, CTYP) \
+ fprintf(ff, "HEST_EXPORT " _STR(DCL_T_N(_, ATYP, CTYP)) ";\n");
+#define PRINT_E_N(_) fprintf(ff, "HEST_EXPORT " _STR(DCL_E_N(_)) ";\n");
+#define PRINT_O_N(_) fprintf(ff, "HEST_EXPORT " _STR(DCL_O_N(_)) ";\n");
+#define PRINT_T_V(_, ATYP, CTYP) \
+ fprintf(ff, "HEST_EXPORT " _STR(DCL_T_V(_, ATYP, CTYP)) ";\n");
+#define PRINT_E_V(_) fprintf(ff, "HEST_EXPORT " _STR(DCL_E_V(_)) ";\n");
+#define PRINT_O_V(_) fprintf(ff, "HEST_EXPORT " _STR(DCL_O_V(_)) ";\n");
-/* prints declarations for everything defined by macro above, which
-HEY does not include the hestOptAdd_Flag and hestOptAdd_1_* functions */
+/* prints declarations for everything defined by macro magic above */
void
hestOptAddDeclsPrint(FILE *ff) {
- /* HEY copy-pasta from "Actual code" above */
- MAP_M_S(PRINT_M_S, 2)
- PRINT_M_E(2)
- PRINT_M_O(2)
- MAP_M_S(PRINT_M_S, 3)
- PRINT_M_E(3)
- PRINT_M_O(3)
- MAP_M_S(PRINT_M_S, 4)
- PRINT_M_E(4)
- PRINT_M_O(4)
- MAP_N_S(PRINT_N_S)
- PRINT_N_E
- PRINT_N_O
+ /* the flag is the one case not handled by macro expansion */
+ fprintf(ff, "HEST_EXPORT unsigned int hestOptAdd_Flag(hestOpt **optP, "
+ "const char *flag, int *valueP, const char *info);\n");
+ /* declarations for all other cases */
+ DOIT(PRINT)
}
-
-/*
-hestOptSetXX(hestOpt *opt, )
-1v<T>, Nv<T> need sawP
-
-<T>=
-Bool, Int, UInt, LongInt, ULongInt, Size_t,
-Float, Double, Char, String,
-Enum, need Enum
-Other, need CB
-*/
Modified: teem/trunk/src/hest/hest.h
===================================================================
--- teem/trunk/src/hest/hest.h 2023-07-11 12:45:20 UTC (rev 7070)
+++ teem/trunk/src/hest/hest.h 2023-07-11 21:18:05 UTC (rev 7071)
@@ -97,7 +97,7 @@
int type; /* type of option (from airType enum) */
unsigned int min; /* min # of parameters for option */
int max; /* max # of parameters for option,
- or -1 for "there is no max" */
+ or -1 for "there is no max; # parms is unbounded" */
void *valueP; /* storage of parsed values */
char *dflt, /* default value written out as string */
*info; /* description to be printed with "glossary" info */
@@ -246,17 +246,17 @@
HEST_EXPORT hestParm *hestParmFree(hestParm *parm);
HEST_EXPORT void *hestParmFree_vp(void *parm);
HEST_EXPORT void hestOptSingleSet(hestOpt *opt, const char *flag, const char *name,
- int type, int min, int max, void *valueP,
+ int type, unsigned int min, int max, void *valueP,
const char *dflt, const char *info, unsigned int *sawP,
const airEnum *enm, const hestCB *CB);
HEST_EXPORT unsigned int hestOptAdd_nva(hestOpt **optP, const char *flag,
- const char *name, int type, int min, int max,
- void *valueP, const char *dflt, const char *info,
- unsigned int *sawP, const airEnum *enm,
- const hestCB *CB);
+ 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);
HEST_EXPORT unsigned int hestOptAdd(hestOpt **optP,
const char *flag, const char *name,
- int type, int min, int max,
+ int type, unsigned int min, int max,
void *valueP, const char *dflt,
const char *info,
... /* unsigned int *sawP,
@@ -288,49 +288,87 @@
/* adders.c */
HEST_EXPORT void hestOptAddDeclsPrint(FILE *f);
+/* these declarations are from clang-format of hestOptAddDeclsPrint output */
HEST_EXPORT unsigned int hestOptAdd_Flag(hestOpt **optP, const char *flag, int *valueP,
const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Bool(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1v_Bool(hestOpt **hoptP, const char *flag,
+ const char *name, int *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_Int(hestOpt **hoptP, const char *flag,
const char *name, int *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Int(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1v_UInt(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_LongInt(hestOpt **hoptP, const char *flag,
+ const char *name, long int *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_ULongInt(hestOpt **hoptP, const char *flag,
+ const char *name,
+ unsigned long int *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_Size_t(hestOpt **hoptP, const char *flag,
+ const char *name, size_t *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_Float(hestOpt **hoptP, const char *flag,
+ const char *name, float *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_Double(hestOpt **hoptP, const char *flag,
+ const char *name, double *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_Char(hestOpt **hoptP, const char *flag,
+ const char *name, char *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_String(hestOpt **hoptP, const char *flag,
+ const char *name, char **valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1v_Enum(hestOpt **hoptP, const char *flag,
+ const char *name, int *valueP,
+ const char *dflt, const char *info,
+ const airEnum *enm);
+HEST_EXPORT unsigned int hestOptAdd_1v_Other(hestOpt **hoptP, const char *flag,
+ const char *name, void *valueP,
+ const char *dflt, const char *info,
+ const hestCB *CB);
+HEST_EXPORT unsigned int hestOptAdd_1_Bool(hestOpt **hoptP, const char *flag,
+ const char *name, int *valueP,
+ const char *dflt, const char *info);
+HEST_EXPORT unsigned int hestOptAdd_1_Int(hestOpt **hoptP, const char *flag,
const char *name, int *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_UInt(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_UInt(hestOpt **hoptP, const char *flag,
const char *name, unsigned int *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_LongInt(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_LongInt(hestOpt **hoptP, const char *flag,
const char *name, long int *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_ULongInt(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_ULongInt(hestOpt **hoptP, const char *flag,
const char *name,
unsigned long int *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Size_t(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_Size_t(hestOpt **hoptP, const char *flag,
const char *name, size_t *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Float(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_Float(hestOpt **hoptP, const char *flag,
const char *name, float *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Double(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_Double(hestOpt **hoptP, const char *flag,
const char *name, double *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Char(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_Char(hestOpt **hoptP, const char *flag,
const char *name, char *valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_String(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_String(hestOpt **hoptP, const char *flag,
const char *name, char **valueP,
const char *dflt, const char *info);
-HEST_EXPORT unsigned int hestOptAdd_1_Enum(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_Enum(hestOpt **hoptP, const char *flag,
const char *name, int *valueP,
const char *dflt, const char *info,
const airEnum *enm);
-HEST_EXPORT unsigned int hestOptAdd_1_Other(hestOpt **optP, const char *flag,
+HEST_EXPORT unsigned int hestOptAdd_1_Other(hestOpt **hoptP, const char *flag,
const char *name, void *valueP,
const char *dflt, const char *info,
const hestCB *CB);
-/* from here on, declarations are from calling hestOptAddDeclsPrint and then
-clang-formatting */
HEST_EXPORT unsigned int hestOptAdd_2_Bool(hestOpt **hoptP, const char *flag,
const char *name, int valueP[2],
const char *dflt, const char *info);
@@ -494,6 +532,58 @@
const char *name, unsigned int N,
void *valueP, const char *dflt,
const char *info, const hestCB *CB);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Bool(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ int **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Int(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ int **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_UInt(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ unsigned int **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_LongInt(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min,
+ int max, long int **valueP,
+ const char *dflt, const char *info,
+ unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_ULongInt(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min,
+ int max, unsigned long int **valueP,
+ const char *dflt, const char *info,
+ unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Size_t(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min,
+ int max, size_t **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Float(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ float **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Double(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min,
+ int max, double **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Char(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ char **valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_String(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min,
+ int max, char ***valueP, const char *dflt,
+ const char *info, unsigned int *sawP);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Enum(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ int **valueP, const char *dflt,
+ const char *info, unsigned int *sawP,
+ const airEnum *enm);
+HEST_EXPORT unsigned int hestOptAdd_Nv_Other(hestOpt **hoptP, const char *flag,
+ const char *name, unsigned int min, int max,
+ void *valueP, const char *dflt,
+ const char *info, unsigned int *sawP,
+ const hestCB *CB);
#ifdef __cplusplus
}
Modified: teem/trunk/src/hest/methodsHest.c
===================================================================
--- teem/trunk/src/hest/methodsHest.c 2023-07-11 12:45:20 UTC (rev 7070)
+++ teem/trunk/src/hest/methodsHest.c 2023-07-11 21:18:05 UTC (rev 7071)
@@ -96,17 +96,11 @@
/* opt_kind determines the kind (1,2,3,4, or 5) of an opt,
from being passed its min and max fields */
static int
-opt_kind(unsigned int _min, int _max) {
- int min, max;
+opt_kind(unsigned int min, int _max) {
+ int max;
- min = AIR_CAST(int, _min);
- if (min < 0) {
- /* invalid */
- return -1;
- }
-
max = _hestMax(_max);
- if (!(min <= max)) {
+ if (!(AIR_CAST(int, min) <= max)) {
/* invalid */
return -1;
}
@@ -121,7 +115,7 @@
return 2;
}
- if (2 <= min && 2 <= max && min == max) {
+ if (2 <= min && 2 <= max && AIR_CAST(int, min) == max) {
/* multiple fixed parameters */
return 3;
}
@@ -221,9 +215,10 @@
Note that this makes no attempt at error-checking; that is all in hestOptCheck
*/
void
-hestOptSingleSet(hestOpt *opt, const char *flag, const char *name, int type, int min,
- int max, void *valueP, const char *dflt, const char *info,
- unsigned int *sawP, const airEnum *enm, const hestCB *CB) {
+hestOptSingleSet(hestOpt *opt, 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);
@@ -262,9 +257,10 @@
Like hestOptAdd has done since 2013: returns UINT_MAX in case of error.
*/
unsigned int
-hestOptAdd_nva(hestOpt **optP, const char *flag, const char *name, int type, int min,
- int max, void *valueP, const char *dflt, const char *info,
- unsigned int *sawP, const airEnum *enm, const hestCB *CB) {
+hestOptAdd_nva(hestOpt **optP, 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) {
unsigned int retIdx;
/* NULL address of opt array: can't proceed */
@@ -287,8 +283,9 @@
** option just added. Returns UINT_MAX in case of error.
*/
unsigned int
-hestOptAdd(hestOpt **optP, const char *flag, const char *name, int type, int min,
- int max, void *valueP, const char *dflt, const char *info, ...) {
+hestOptAdd(hestOpt **optP, 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;
const airEnum *enm = NULL;
const hestCB *CB = NULL;
Modified: teem/trunk/src/hest/parseHest.c
===================================================================
--- teem/trunk/src/hest/parseHest.c 2023-07-11 12:45:20 UTC (rev 7070)
+++ teem/trunk/src/hest/parseHest.c 2023-07-11 21:18:05 UTC (rev 7071)
@@ -193,8 +193,11 @@
** _hestPanic()
**
** all error checking on the given hest array itself (not the
-** command line to be parsed). Also, sets the "kind" field of
-** the opt struct
+** command line to be parsed).
+**
+** 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_*_*)
*/
int
_hestPanic(hestOpt *opt, char *err, const hestParm *parm) {
@@ -836,7 +839,7 @@
break;
case 4:
/* -------- optional single variables -------- */
- /* if the flag appeared (if there is a flag) but the paramter didn't,
+ /* if the flag appeared (if there is a flag) but the parameter didn't,
we'll "invert" the default; if the flag didn't appear (or if there
isn't a flag) and the parameter also didn't appear, we'll use the
default. In either case, nprm[op] will be zero, and in both cases,
@@ -1156,6 +1159,39 @@
/* -------- optional single variables -------- */
if (prms[op] && vP) {
switch (type) {
+ case airTypeChar:
+ /* 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 != airParseStr[type](vP, prms[op], " ", 1)) {
+ sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident);
+ return 1;
+ }
+ opt[op].alloc = 0;
+ break;
+ case airTypeString:
+ /* this is a bizarre case: optional single string, with some kind of value
+ "inversion". 2023 GLK would prefer to make this like Char, Enum, and Other: for
+ which there is no attempt at "inversion". But for some reason the inversion of
+ a non-empty default string to a NULL string value, when the flag is used
+ without a parameter, was implemented from the early days of hest. Assuming
+ that a younger GLK long ago had a reason for that, that functionality now
+ persists.*/
+ if (1 != airParseStr[type](vP, prms[op], " ", 1, parm->greedySingleString)) {
+ sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
+ udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident);
+ return 1;
+ }
+ opt[op].alloc = 1;
+ if (opt[op].flag && 1 == whichCase(opt, udflt, nprm, appr, op)) {
+ /* we just parsed the default, but now we want to "invert" it */
+ *((char **)vP) = (char *)airFree(*((char **)vP));
+ opt[op].alloc = 0;
+ }
+ /* vP is the address of a char* (a char**), and what we
+ manage with airMop is the char * */
+ airMopMem(pmop, vP, airMopOnError);
+ break;
case airTypeEnum:
if (1 != airParseStrE((int *)vP, prms[op], " ", 1, opt[op].enm)) {
sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
@@ -1164,7 +1200,7 @@
}
break;
case airTypeOther:
- /* we're parsing an "other". We will not perform the special
+ /* we're parsing an single single "other". We will not perform the special
flagged single variable parameter games as done above, so
whether this option is flagged or unflagged, we're going
to treat it like an unflagged single variable parameter option:
@@ -1189,22 +1225,6 @@
airMopAdd(pmop, *((void **)vP), opt[op].CB->destroy, airMopOnError);
}
break;
- case airTypeString:
- if (1 != airParseStr[type](vP, prms[op], " ", 1, parm->greedySingleString)) {
- sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
- udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident);
- return 1;
- }
- opt[op].alloc = 1;
- if (opt[op].flag && 1 == whichCase(opt, udflt, nprm, appr, op)) {
- /* we just parsed the default, but now we want to "invert" it */
- *((char **)vP) = (char *)airFree(*((char **)vP));
- opt[op].alloc = 0;
- }
- /* vP is the address of a char* (a char**), and what we
- manage with airMop is the char * */
- airMopMem(pmop, vP, airMopOnError);
- break;
default:
if (1 != airParseStr[type](vP, prms[op], " ", 1)) {
sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s", ME,
Modified: teem/trunk/src/hest/test/ex6.c
===================================================================
--- teem/trunk/src/hest/test/ex6.c 2023-07-11 12:45:20 UTC (rev 7070)
+++ teem/trunk/src/hest/test/ex6.c 2023-07-11 21:18:05 UTC (rev 7071)
@@ -92,6 +92,7 @@
/* going past C89 to have declarations here */
int flag;
hestOptAdd_Flag(&opt, "f,flag", &flag, "a flag created via hestOptAdd_Flag");
+
int b1;
hestOptAdd_1_Bool(&opt, "b1", "bool1", &b1, "false", "test of hestOptAdd_1_Bool");
int i1;
@@ -124,8 +125,43 @@
Quat *q1;
hestOptAdd_1_Other(&opt, "q1", "quat", &q1, "12.34", "test of hestOptAdd_1_Other B",
&quatCB);
- printf("----- &q1 = %p\n", &q1);
+ int b1v;
+ hestOptAdd_1v_Bool(&opt, "b1v", "bool1", &b1v, "false", "test of hestOptAdd_1v_Bool");
+ int i1v;
+ hestOptAdd_1v_Int(&opt, "i1v", "int1", &i1v, "42", "test of hestOptAdd_1v_Int");
+ unsigned int ui1v;
+ hestOptAdd_1v_UInt(&opt, "ui1v", "uint1", &ui1v, "42", "test of hestOptAdd_1v_UInt");
+ long int li1v;
+ hestOptAdd_1v_LongInt(&opt, "li1v", "lint1", &li1v, "42",
+ "test of hestOptAdd_1v_LongInt");
+ unsigned long int uli1v;
+ hestOptAdd_1v_ULongInt(&opt, "uli1v", "ulint1", &uli1v, "42",
+ "test of hestOptAdd_1v_ULongInt");
+ size_t sz1v;
+ hestOptAdd_1v_Size_t(&opt, "sz1v", "size1", &sz1v, "42",
+ "test of hestOptAdd_1v_Size_t");
+ float fl1v;
+ hestOptAdd_1v_Float(&opt, "fl1v", "float1", &fl1v, "0.0",
+ "test of hestOptAdd_1v_Float");
+ double db1v;
+ hestOptAdd_1v_Double(&opt, "db1v", "double1", &db1v, "4.2",
+ "test of hestOptAdd_1v_Double");
+ char c1v;
+ hestOptAdd_1v_Char(&opt, "c1v", "char1", &c1v, "x", "test of hestOptAdd_1v_Char");
+ char *s1v;
+ hestOptAdd_1v_String(&opt, "s1v", "string1", &s1v, "bingo",
+ "test of hestOptAdd_1v_String");
+ int e1v;
+ hestOptAdd_1v_Enum(&opt, "e1v", "enum1", &e1v, "little", "test of hestOptAdd_1v_Enum",
+ airEndian);
+ double p1v[2];
+ hestOptAdd_1v_Other(&opt, "p1v", "pos", &p1v, "1.5,5.25",
+ "test of hestOptAdd_1v_Other A", &posCB);
+ Quat *q1v;
+ hestOptAdd_1v_Other(&opt, "q1v", "quat", &q1v, "12.34",
+ "test of hestOptAdd_1v_Other B", &quatCB);
+
int b2[2];
hestOptAdd_2_Bool(&opt, "b2", "bool1 bool2", b2, "true false",
"test of hestOptAdd_2_Bool");
@@ -289,10 +325,74 @@
"15.55 55.51 66.77 88.99 100.2", "test of hestOptAdd_N_Other B",
&quatCB);
+ /* HEY also try 0, -1 */
+ int *bv;
+ unsigned int bvSaw;
+ hestOptAdd_Nv_Bool(&opt, "bv", "bool1 bool2", 1, -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);
+ unsigned int *uiv;
+ unsigned int uivSaw;
+ hestOptAdd_Nv_UInt(&opt, "uiv", "uint1 uint2", 1, -1, &uiv, "42 24",
+ "test of hestOptAdd_Nv_UInt", &uivSaw);
+ long int *liv;
+ unsigned int livSaw;
+ hestOptAdd_Nv_LongInt(&opt, "liv", "lint1 ...", 1, -1, &liv, "42 24",
+ "test of hestOptAdd_Nv_LongInt", &livSaw);
+ unsigned long int *uliv;
+ unsigned int ulivSaw;
+ hestOptAdd_Nv_ULongInt(&opt, "uliv", "ulint1 ...", 1, -1, &uliv, "42 24",
+ "test of hestOptAdd_Nv_ULongInt", &ulivSaw);
+ size_t *szv;
+ unsigned int szvSaw;
+ hestOptAdd_Nv_Size_t(&opt, "szv", "size1 ...", 1, -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",
+ "test of hestOptAdd_Nv_Float", &flvSaw);
+ double *dbv;
+ unsigned int dbvSaw;
+ hestOptAdd_Nv_Double(&opt, "dbv", "double1 ...", 1, -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",
+ "test of hestOptAdd_Nv_Char", &cvSaw);
+ char **sv;
+ unsigned int svSaw;
+ hestOptAdd_Nv_String(&opt, "sv", "str1 ...", 1, -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",
+ "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",
+ "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",
+ "test of hestOptAdd_Nv_Other B", &qvSaw, &quatCB);
+
+ if (2 == argc && !strcmp("decls", argv[1])) {
+ printf("Writing decls.h and then bailing ...\n");
+ FILE *ff = fopen("decls.h", "w");
+ hestOptAddDeclsPrint(ff);
+ fclose(ff);
+ exit(0);
+ }
+ /* else not writing decls.h; remove it to ensure freshness */
+ remove("decls.h");
+
hestParseOrDie(opt, argc - 1, argv + 1, parm, argv[0], info, AIR_TRUE, AIR_TRUE,
AIR_TRUE);
- if (1) {
+ if (0) {
unsigned int opi, numO;
numO = hestOptNum(opt);
for (opi = 0; opi < numO; opi++) {
@@ -305,40 +405,51 @@
printf(" parmStr=|%s|\n", opt[opi].parmStr ? opt[opi].parmStr : "(null)");
}
}
- if (1) {
- printf("(err = %s)\n", err ? err : "(null)");
- printf("flag = %d\n", flag);
- printf("b1 = %d\n", b1);
- printf("i1 = %d\n", i1);
- printf("ui1 = %u\n", ui1);
- printf("li1 = %ld\n", li1);
- printf("uli1 = %lu\n", uli1);
- printf("sz1 = %zu\n", sz1);
- printf("fl1 = %g\n", fl1);
- printf("db1 = %g\n", db1);
- printf("c1 = %c\n", c1);
- printf("s1 = |%s|\n", s1);
- ...
[truncated message content] |