Skip to content

Commit 48c49f9

Browse files
committed
genericCMPClient_util.{c,h}: introduce OPT_SEL and OPT_POS_INT for CONF_read_check_options()
1 parent 1b6ce4c commit 48c49f9

2 files changed

Lines changed: 44 additions & 6 deletions

File tree

include/genericCMPClient_util.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,17 @@ typedef void uta_ctx; /* dummy */
9999
/* config.h: */
100100
/* extended from opt.h */
101101
#define OPT_REQUIRED 0x8000U
102-
#define OPT_EMPTY_OK 0x4000U
102+
#define OPT_EMPTY_OK 0x4000U /* ignored unless OPT_REQUIRED is set */
103103
typedef enum
104104
{
105105
OPT_TXT, /** String variable receives a pointer to the option argument */
106+
OPT_SEL, /** enumeration of selectable tags, index returned in 'int1' choice */
106107
OPT_NUM, /** Long integer variable receives the decimal number given as argument */
107108
OPT_INT, /** As before, but regular integer variable */
108109
OPT_POS_INT, /** As before, but restriction to positive integers */
109110
OPT_BOOL,/** Boolean variable receives a truth value */
110111
OPT_TXT_REQUIRED = OPT_TXT | OPT_REQUIRED,
112+
OPT_SEL_REQUIRED = OPT_SEL | OPT_REQUIRED,
111113
OPT_NUM_REQUIRED = OPT_NUM | OPT_REQUIRED,
112114
OPT_INT_REQUIRED = OPT_INT | OPT_REQUIRED,
113115
OPT_POS_INT_REQUIRED = OPT_POS_INT | OPT_REQUIRED,
@@ -117,7 +119,7 @@ typedef enum
117119
union varval_union {
118120
const char *txt; /** String value */
119121
long num; /** Long integer value, or vpm_opt */
120-
int int1; /** Integer value, may be restricted to being positive */
122+
int int1; /** Integer/selection value, may be restricted to being positive */
121123
bool bit; /** Boolean value */
122124
};
123125

@@ -135,9 +137,11 @@ typedef struct opt_t
135137
union varval_union default_value; /** default value for the option */
136138
union varref_union varref_u; /** reference to the variable to receive the option value */
137139
const char *help_str; /** a short description of the option for help output */
138-
} opt_t; /** an option with its name, type, default value, variable, and help string */
140+
const char **selectable; /** values to choose from with OPT_SEL, NULL-terminated array */
141+
} opt_t; /** an option with its name, type, default value, variable,
142+
optional help string, and optional selectable tags */
139143

140-
#define OPT_END { NULL, OPT_BOOL, {.bit = false}, {NULL}, NULL}
144+
#define OPT_END { NULL, OPT_BOOL, {.bit = false}, {.bit = NULL}, NULL}
141145
CONF *CONF_load_config(OPTIONAL ossl_unused uta_ctx *ctx, const char *file);
142146
bool CONF_entry_in_sections(const CONF *conf, const char *sections, const char *entry);
143147
bool CONF_read_check_options(const CONF *conf, const char *source,

src/genericCMPClient_util.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,11 @@ static bool CONF_read_options_ex(const CONF *conf, const char *source,
454454
for (; opt->name != NULL; opt++) {
455455
opttype_t bare_type = opt->type & ~(OPT_REQUIRED | OPT_EMPTY_OK);
456456

457-
if (opt->varref_u.txt == NULL)
458-
continue; /* skip if no variable reference given */
457+
if (opt->varref_u.txt == NULL) {
458+
LOG(FL_ERR, "internal: Config '%s' section(s) [%s] option '%s': missing referene to the variable where to store the value",
459+
source, sections, opt->name);
460+
return false;
461+
}
459462
ERR_set_mark();
460463
switch (bare_type) {
461464
case OPT_TXT:
@@ -465,6 +468,37 @@ static bool CONF_read_options_ex(const CONF *conf, const char *source,
465468
*opt->varref_u.txt = str[0] == '\0' ? opt->default_value.txt : str;
466469
}
467470
break;
471+
case OPT_SEL:
472+
/* stores the selcetion from the key opt->name in opt->varref_u.int1 */
473+
str = conf_get_string(conf, sections, opt->name);
474+
if (str != NULL) {
475+
const char *const *sel = ((opt_t *)opt)->selectable;
476+
477+
ERR_pop_to_mark();
478+
if (sel == NULL) {
479+
LOG(FL_ERR, "internal: Config '%s' section(s) [%s] option '%s' of type OPT_SEL: missing list of selectable values",
480+
source, sections, opt->name);
481+
return false;
482+
}
483+
if (str[0] == '\0') {
484+
*opt->varref_u.int1 = opt->default_value.int1;
485+
return true;
486+
}
487+
for (; *sel != NULL && strcmp(*sel, str) != 0; sel++)
488+
val++;
489+
if (*sel == NULL) {
490+
LOG(FL_ERR, "Config '%s' section(s) [%s] option '%s': illegal value '%s'",
491+
source, sections, opt->name, str);
492+
return false;
493+
}
494+
if (val > INT_MAX) {
495+
LOG(FL_ERR, "Config '%s' section(s) [%s] option '%s' selection value %ld is too large, can be at most %d",
496+
source, sections, opt->name, val, INT_MAX);
497+
return false;
498+
}
499+
*opt->varref_u.int1 = (int)val;
500+
}
501+
break;
468502
case OPT_NUM:
469503
/* restores default value if empty string is given */
470504
str = conf_get_string(conf, sections, opt->name);

0 commit comments

Comments
 (0)