From 166e626c98bc40536f02ec95bce919d1fd13e495 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Oct 2020 17:41:04 +0200 Subject: [PATCH] add u64_y support in argtable-cliparser. --- client/deps/cliparser/argtable3.c | 261 +++++++++++++++++++++++++++++- client/deps/cliparser/argtable3.h | 44 ++--- client/deps/cliparser/cliparser.h | 43 ++--- 3 files changed, 306 insertions(+), 42 deletions(-) diff --git a/client/deps/cliparser/argtable3.c b/client/deps/cliparser/argtable3.c index 5019001e4..f97e9ff25 100644 --- a/client/deps/cliparser/argtable3.c +++ b/client/deps/cliparser/argtable3.c @@ -1408,7 +1408,7 @@ static int arg_dbl_scanfn(struct arg_dbl *parent, const char *argval) { /* extract double from argval into val */ val = strtod(argval, &end); - + printf("ice %lf \n", val); /* if success then store result in parent->dval[] array otherwise return error*/ if (*end == 0) parent->dval[parent->count++] = val; @@ -1927,10 +1927,8 @@ struct arg_file *arg_filen( #include #include #include - #include "argtable3.h" - static void arg_int_resetfn(struct arg_int *parent) { ARG_TRACE(("%s:resetfn(%p)\n", __FILE__, parent)); parent->count = 0; @@ -2226,6 +2224,263 @@ struct arg_int *arg_intn( ARG_TRACE(("arg_intn() returns %p\n", result)); return result; } + + +// uint64_t support +#include +#include +#include +static uint64_t strtollu0X(const char *str, + const char * *endptr, + char X, + int base) { + uint64_t val; /* stores result */ + int s = 1; /* sign is +1 or -1 */ + const char *ptr = str; /* ptr to current position in str */ + + /* skip leading whitespace */ + while (ISSPACE(*ptr)) + ptr++; + // printf("1) %s\n",ptr); + + /* scan optional sign character */ + switch (*ptr) { + case '+': + ptr++; + s = 1; + break; + case '-': + ptr++; + s = -1; + break; + default: + s = 1; + break; + } + // printf("2) %s\n",ptr); + + /* '0X' prefix */ + if ((*ptr++) != '0') { + /* printf("failed to detect '0'\n"); */ + *endptr = str; + return 0; + } + // printf("3) %s\n",ptr); + if (toupper(*ptr++) != toupper(X)) { + /* printf("failed to detect '%c'\n",X); */ + *endptr = str; + return 0; + } + // printf("4) %s\n",ptr); + + /* attempt conversion on remainder of string using strtol() */ + val = strtoull(ptr, (char * *)endptr, base); + + if (*endptr == ptr) { + /* conversion failed */ + *endptr = str; + return 0; + } + + /* success */ + return s * val; +} + + +static void arg_u64_resetfn(struct arg_u64 *parent) { + ARG_TRACE(("%s:resetfn(%p)\n", __FILE__, parent)); + parent->count = 0; +} + +static int arg_u64_scanfn(struct arg_u64 *parent, const char *argval) { + int errorcode = 0; + if (parent->count == parent->hdr.maxcount) { + /* maximum number of arguments exceeded */ + errorcode = EMAXCOUNT; + } else if (!argval) { + /* a valid argument with no argument value was given. */ + /* This happens when an optional argument value was invoked. */ + /* leave parent arguiment value unaltered but still count the argument. */ + parent->count++; + } else { + uint64_t val; + const char *end; + + /* attempt to extract hex integer (eg: +0x123) from argval into val conversion */ + val = strtollu0X(argval, &end, 'X', 16); + if (end == argval) { + /* hex failed, attempt octal conversion (eg +0o123) */ + val = strtollu0X(argval, &end, 'O', 8); + if (end == argval) { + /* octal failed, attempt binary conversion (eg +0B101) */ + val = strtollu0X(argval, &end, 'B', 2); + if (end == argval) { + /* binary failed, attempt decimal conversion with no prefix (eg 1234) */ + val = strtoull(argval, (char * *)&end, 10); + if (end == argval) { + /* all supported number formats failed */ + return EBADINT; + } + } + } + } + + /* Safety check for integer overflow. WARNING: this check */ + /* achieves nothing on machines where size(int)==size(long). */ + if (val > ULLONG_MAX) +#ifdef __STDC_WANT_SECURE_LIB__ + errorcode = EOVERFLOW_; +#else + errorcode = EOVERFLOW; +#endif + + /* Detect any suffixes (KB,MB,GB) and multiply argument value appropriately. */ + /* We need to be mindful of integer overflows when using such big numbers. */ + if (detectsuffix(end, "KB")) { /* kilobytes */ + if (val > (ULLONG_MAX / 1024)) +#ifdef __STDC_WANT_SECURE_LIB__ + errorcode = EOVERFLOW_; /* Overflow would occur if we proceed */ +#else + errorcode = EOVERFLOW; /* Overflow would occur if we proceed */ +#endif + else + val *= 1024; /* 1KB = 1024 */ + } else if (detectsuffix(end, "MB")) { /* megabytes */ + if (val > (ULLONG_MAX / 1048576)) +#ifdef __STDC_WANT_SECURE_LIB__ + errorcode = EOVERFLOW_; /* Overflow would occur if we proceed */ +#else + errorcode = EOVERFLOW; /* Overflow would occur if we proceed */ +#endif + else + val *= 1048576; /* 1MB = 1024*1024 */ + } else if (detectsuffix(end, "GB")) { /* gigabytes */ + if (val > (ULLONG_MAX / 1073741824)) +#ifdef __STDC_WANT_SECURE_LIB__ + errorcode = EOVERFLOW_; /* Overflow would occur if we proceed */ +#else + errorcode = EOVERFLOW; /* Overflow would occur if we proceed */ +#endif + else + val *= 1073741824; /* 1GB = 1024*1024*1024 */ + } else if (!detectsuffix(end, "")) + errorcode = EBADINT; /* invalid suffix detected */ + + /* if success then store result in parent->uval[] array */ + if (errorcode == 0) + parent->uval[parent->count++] = val; + } + + /* printf("%s:scanfn(%p,%p) returns %d\n",__FILE__,parent,argval,errorcode); */ + return errorcode; +} + +static int arg_u64_checkfn(struct arg_u64 *parent) { + int errorcode = (parent->count < parent->hdr.mincount) ? EMINCOUNT : 0; + /*printf("%s:checkfn(%p) returns %d\n",__FILE__,parent,errorcode);*/ + return errorcode; +} + +static void arg_u64_errorfn( + struct arg_u64 *parent, + FILE *fp, + int errorcode, + const char *argval, + const char *progname) { + const char *shortopts = parent->hdr.shortopts; + const char *longopts = parent->hdr.longopts; + const char *datatype = parent->hdr.datatype; + + /* make argval NULL safe */ + argval = argval ? argval : ""; + + fprintf(fp, "%s: ", progname); + switch (errorcode) { + case EMINCOUNT: + fputs("missing option ", fp); + arg_print_option(fp, shortopts, longopts, datatype, "\n"); + break; + + case EMAXCOUNT: + fputs("excess option ", fp); + arg_print_option(fp, shortopts, longopts, argval, "\n"); + break; + + case EBADINT: + fprintf(fp, "invalid argument \"%s\" to option ", argval); + arg_print_option(fp, shortopts, longopts, datatype, "\n"); + break; + +#ifdef __STDC_WANT_SECURE_LIB__ + case EOVERFLOW_: +#else + case EOVERFLOW: +#endif + fputs("integer overflow at option ", fp); + arg_print_option(fp, shortopts, longopts, datatype, " "); + fprintf(fp, "(%s is too large)\n", argval); + break; + } +} + +struct arg_u64 *arg_u64_0( + const char *shortopts, + const char *longopts, + const char *datatype, + const char *glossary) { + return arg_u64_n(shortopts, longopts, datatype, 0, 1, glossary); +} + +struct arg_u64 *arg_u64_1( + const char *shortopts, + const char *longopts, + const char *datatype, + const char *glossary) { + return arg_u64_n(shortopts, longopts, datatype, 1, 1, glossary); +} + +struct arg_u64 *arg_u64_n( + const char *shortopts, + const char *longopts, + const char *datatype, + int mincount, + int maxcount, + const char *glossary) { + size_t nbytes; + struct arg_u64 *result; + + /* foolproof things by ensuring maxcount is not less than mincount */ + maxcount = (maxcount < mincount) ? mincount : maxcount; + + nbytes = sizeof(struct arg_u64) /* storage for struct arg_u64 */ + + maxcount * sizeof(uint64_t); /* storage for uval[maxcount] array */ + + result = (struct arg_u64 *)malloc(nbytes); + if (result) { + /* init the arg_hdr struct */ + result->hdr.flag = ARG_HASVALUE; + result->hdr.shortopts = shortopts; + result->hdr.longopts = longopts; + result->hdr.datatype = datatype ? datatype : ""; + result->hdr.glossary = glossary; + result->hdr.mincount = mincount; + result->hdr.maxcount = maxcount; + result->hdr.parent = result; + result->hdr.resetfn = (arg_resetfn *)arg_u64_resetfn; + result->hdr.scanfn = (arg_scanfn *)arg_u64_scanfn; + result->hdr.checkfn = (arg_checkfn *)arg_u64_checkfn; + result->hdr.errorfn = (arg_errorfn *)arg_u64_errorfn; + + /* store the uval[maxcount] array immediately after the arg_int struct */ + result->uval = (uint64_t *)(result + 1); + result->count = 0; + } + + ARG_TRACE(("arg_u64_n() returns %p\n", result)); + return result; +} + + /******************************************************************************* * This file is part of the argtable3 library. * diff --git a/client/deps/cliparser/argtable3.h b/client/deps/cliparser/argtable3.h index d8e3c53cc..2988d013f 100644 --- a/client/deps/cliparser/argtable3.h +++ b/client/deps/cliparser/argtable3.h @@ -35,6 +35,7 @@ #include /* FILE */ #include /* struct tm */ +#include #ifdef __cplusplus extern "C" { @@ -110,6 +111,12 @@ struct arg_int { int *ival; /* Array of parsed argument values */ }; +struct arg_u64 { + struct arg_hdr hdr; /* The mandatory argtable header struct */ + int count; /* Number of matching command line args */ + uint64_t *uval; /* Array of parsed argument values */ +}; + struct arg_dbl { struct arg_hdr hdr; /* The mandatory argtable header struct */ int count; /* Number of matching command line args */ @@ -176,32 +183,29 @@ struct arg_lit *arg_litn(const char *shortopts, int maxcount, const char *glossary); -struct arg_key *arg_key0(const char *keyword, - int flags, +struct arg_key *arg_key0(const char *keyword, int flags, const char *glossary); +struct arg_key *arg_key1(const char *keyword, int flags, const char *glossary); +struct arg_key *arg_keyn(const char *keyword, int flags, int mincount, int maxcount, const char *glossary); + +struct arg_int *arg_int0(const char *shortopts, const char *longopts, const char *datatype, const char *glossary); +struct arg_int *arg_int1(const char *shortopts, const char *longopts, const char *datatype, const char *glossary); +struct arg_int *arg_intn(const char *shortopts, const char *longopts, const char *datatype, int mincount, int maxcount, const char *glossary); + +struct arg_u64 *arg_u64_0(const char *shortopts, + const char *longopts, + const char *datatype, const char *glossary); -struct arg_key *arg_key1(const char *keyword, - int flags, +struct arg_u64 *arg_u64_1(const char *shortopts, + const char *longopts, + const char *datatype, const char *glossary); -struct arg_key *arg_keyn(const char *keyword, - int flags, +struct arg_u64 *arg_u64_n(const char *shortopts, + const char *longopts, + const char *datatype, int mincount, int maxcount, const char *glossary); -struct arg_int *arg_int0(const char *shortopts, - const char *longopts, - const char *datatype, - const char *glossary); -struct arg_int *arg_int1(const char *shortopts, - const char *longopts, - const char *datatype, - const char *glossary); -struct arg_int *arg_intn(const char *shortopts, - const char *longopts, - const char *datatype, - int mincount, - int maxcount, - const char *glossary); struct arg_dbl *arg_dbl0(const char *shortopts, const char *longopts, diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index f82c40f7e..68beca038 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -17,34 +17,39 @@ #define arg_param_begin arg_lit0("h", "help", "This help") #define arg_param_end arg_end(20) -#define arg_getsize(a) (sizeof(a) / sizeof(a[0])) -#define arg_get_lit(ctx, n) (((struct arg_lit*)((ctx)->argtable)[n])->count) +#define arg_getsize(a) (sizeof(a) / sizeof(a[0])) +#define arg_get_lit(ctx, n) (((struct arg_lit*)((ctx)->argtable)[(n)])->count) -#define arg_get_int_count(ctx, n)(((struct arg_int*)((ctx)->argtable)[n])->count) -#define arg_get_int(ctx, n) (((struct arg_int*)((ctx)->argtable)[n])->ival[0]) -#define arg_get_int_def(ctx, n, def)(arg_get_int_count((ctx), n) ? (arg_get_int((ctx), n)) : (def)) +#define arg_get_int_count(ctx, n) (((struct arg_int*)((ctx)->argtable)[(n)])->count) +#define arg_get_int(ctx, n) (((struct arg_int*)((ctx)->argtable)[(n)])->ival[0]) +#define arg_get_int_def(ctx, n, def)(arg_get_int_count((ctx), (n)) ? (arg_get_int((ctx), (n))) : (def)) -#define arg_get_dbl_count(ctx, n)(((struct arg_dbl*)((ctx)->argtable)[n])->count) -#define arg_get_dbl(ctx, n) (((struct arg_dbl*)((ctx)->argtable)[n])->dval[0]) -#define arg_get_dbl_def(ctx, n, def)(arg_get_dbl_count((ctx), n) ? (arg_get_dbl((ctx), n)) : (def)) +#define arg_get_dbl_count(ctx, n) (((struct arg_dbl*)((ctx)->argtable)[(n)])->count) +#define arg_get_dbl(ctx, n) (((struct arg_dbl*)((ctx)->argtable)[(n)])->dval[0]) +#define arg_get_dbl_def(ctx, n, def)(arg_get_dbl_count((ctx), (n)) ? (arg_get_dbl((ctx), (n))) : (def)) -#define arg_get_u32(ctx, n) (uint32_t)(((struct arg_dbl*)((ctx)->argtable)[n])->dval[0]) -#define arg_get_u32_def(ctx, n, def) (arg_get_dbl_count((ctx), n) ? (arg_get_u32((ctx), n)) : (uint32_t)(def)) +#define arg_get_u32(ctx, n) (uint32_t)(((struct arg_u64*)((ctx)->argtable)[(n)])->uval[0]) +#define arg_get_u32_def(ctx, n, def) (arg_get_u64_count((ctx), (n)) ? (arg_get_u32((ctx), (n))) : (uint32_t)(def)) -#define arg_get_str(ctx, n) ((struct arg_str*)((ctx)->argtable)[n]) -#define arg_get_str_len(ctx, n) (strlen(((struct arg_str*)((ctx)->argtable)[n])->sval[0])) +#define arg_get_u64_count(ctx, n) (((struct arg_u64*)((ctx)->argtable)[(n)])->count) +#define arg_get_u64(ctx, n) (((struct arg_u64*)((ctx)->argtable)[(n)])->uval[0]) +#define arg_get_u64_def(ctx, n, def) (arg_get_u64_count((ctx), (n)) ? (arg_get_u64((ctx), (n))) : (uint64_t)(def)) + +#define arg_get_str(ctx, n) ((struct arg_str*)((ctx)->argtable)[(n)]) +#define arg_get_str_len(ctx, n) (strlen(((struct arg_str*)((ctx)->argtable)[(n)])->sval[0])) #define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary))) #define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary))) -#define arg_u32_0 arg_dbl0 -#define arg_u32_1 arg_dbl1 +#define CLIParserFree(ctx) if ((ctx)) {arg_freetable((ctx)->argtable, (ctx)->argtableLen); free((ctx)); (ctx)=NULL;} -#define CLIParserFree(ctx) if ((ctx)) {arg_freetable(ctx->argtable, ctx->argtableLen); free((ctx)); (ctx)=NULL;} -#define CLIExecWithReturn(ctx, cmd, atbl, ifempty) if (CLIParserParseString(ctx, cmd, atbl, arg_getsize(atbl), ifempty)) {CLIParserFree((ctx)); return PM3_ESOFT;} -#define CLIGetHexBLessWithReturn(ctx, paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;} -#define CLIGetHexWithReturn(ctx, paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;} -#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define CLIExecWithReturn(ctx, cmd, atbl, ifempty) if (CLIParserParseString((ctx), (cmd), (atbl), arg_getsize((atbl)), (ifempty))) {CLIParserFree((ctx)); return PM3_ESOFT;} + +#define CLIGetHexBLessWithReturn(ctx, paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str((ctx), (paramnum)), (data), sizeof((data)) - (delta), (datalen))) {CLIParserFree((ctx)); return PM3_ESOFT;} + +#define CLIGetHexWithReturn(ctx, paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str((ctx), (paramnum)), (data), sizeof((data)), (datalen))) {CLIParserFree((ctx)); return PM3_ESOFT;} + +#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str((ctx), (paramnum)), (data), sizeof((data)), (datalen))) {CLIParserFree((ctx)); return PM3_ESOFT;} typedef struct { void **argtable;