cli parser text options

This commit is contained in:
merlokk 2021-07-03 00:07:21 +03:00
parent a73c6ef90a
commit 850e36ab31
2 changed files with 64 additions and 0 deletions

View file

@ -298,6 +298,58 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
return 0;
}
int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array, size_t option_array_len, int *value) {
char data[200] = {0};
int datalen = 0;
int res = CLIParamStrToBuf(argstr, (uint8_t *)data, sizeof(data), &datalen);
if (res)
return res;
// no data to check - we do not touch *value, just return
if (datalen == 0)
return 0;
str_lower(data);
int val = -1;
int cntr = 0;
for (int i = 0; i < option_array_len; i++) {
// exact match
if (strcmp(option_array[i].text, data) == 0) {
*value = option_array[i].code;
return 0;
}
// partial match
if (strncmp(option_array[i].text, data, datalen) == 0) {
val = option_array[i].code;
cntr++;
}
}
// check partial match
if (cntr == 0) {
PrintAndLogEx(ERR, "Parameter error: No similar option to `%s`. Valid options: %s\n", argstr->sval[0], argstr->hdr.datatype);
return 20;
}
if (cntr > 1) {
PrintAndLogEx(ERR, "Parameter error: Several options fit to `%s`. Valid options: %s\n", argstr->sval[0], argstr->hdr.datatype);
return 21;
}
*value = val;
return 0;
}
const char *CLIGetOptionListStr(const CLIParserOption *option_array, size_t option_array_len, int value) {
static const char *errmsg = "n/a";
for (int i = 0; i < option_array_len; i++)
if (option_array[i].code == value)
return option_array[i].text;
return errmsg;
}
// hexstr -> u64, w optional len input and default value fallback.
// 0 = failed
// 1 = OK

View file

@ -51,6 +51,8 @@
#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str((ctx), (paramnum)), (data), (*datalen), (datalen))) {CLIParserFree((ctx)); return PM3_ESOFT;}
#define CLIGetOptionListWithReturn(ctx, paramnum, option_array, option_array_len, value) if (CLIGetOptionList(arg_get_str((ctx), (paramnum)), (option_array), (option_array_len), (value))) {CLIParserFree((ctx)); return PM3_ESOFT;}
typedef struct {
void **argtable;
size_t argtableLen;
@ -59,6 +61,12 @@ typedef struct {
const char *programHelp;
char buf[1024 + 60];
} CLIParserContext;
typedef struct {
int code;
const char *text;
} CLIParserOption;
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp);
void CLIParserPrintHelp(CLIParserContext *ctx);
int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec);
@ -69,6 +77,10 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
int CLIParamBinToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
// names in the CLIParserOption array must be in the lowercase format
int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array, size_t option_array_len, int *value);
const char *CLIGetOptionListStr(const CLIParserOption *option_array, size_t option_array_len, int value);
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def);
int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional);
int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out);