mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
add u64_y support in argtable-cliparser.
This commit is contained in:
parent
ad494a152c
commit
166e626c98
3 changed files with 306 additions and 42 deletions
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue