add u64_y support in argtable-cliparser.

This commit is contained in:
iceman1001 2020-10-04 17:41:04 +02:00
commit 166e626c98
3 changed files with 306 additions and 42 deletions

View file

@ -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 <stdlib.h>
#include <limits.h>
#include <ctype.h>
#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 <stdint.h>
#include <limits.h>
#include <inttypes.h>
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 : "<u64>";
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.
*

View file

@ -35,6 +35,7 @@
#include <stdio.h> /* FILE */
#include <time.h> /* struct tm */
#include <stdint.h>
#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,

View file

@ -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;