This is an automated email from Gerrit. Alamy Liu ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/3324
-- gerrit commit c43e4cf9173e7537892a40dab0eb2cfedc2b0d56 Author: Alamy Liu <[email protected]> Date: Fri Nov 20 16:12:34 2015 -0800 Extra helper functions to parse number on different bases Background Original helper functions are good for string number that has prefix to specific its own base. (i.e.: 0x, 0, 0b). There are some cases that the the string number is in hex without prefix. For example: protocol. It's nice to have these helper function available. Design Keep original macro for backward compatibility and introduce new Macro(s) with base option. i.e.: DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) DEFINE_PARSE_NUM_TYPE_BASE(name, type, base, func, min, max) Usage: parse_uint(str, &value); COMMAND_PARSE_NUMBER(uint, str, value); parse_u64_base16(str, &value); COMMAND_PARSE_NUMBER_BASE16 or COMMAND_PARSE_NUMBER_HEX Original helper functions parse_ulong() --> strtoul (str, &end, 0) parse_ullong() --> strtoull(str, &end, 0) parse_long() --> strtol (str, &end, 0) parse_llong() --> strtoll (str, &end, 0) parse_<unsigned_type> --> parse_ullong() parse_<signed_type> --> parse_llong() Extra new helper functions (only _base16 are defined for now) parse_ulong_base2() --> strtoul (str, &end, 2) parse_ulong_base8() --> strtoul (str, &end, 8) parse_ulong_base10() --> strtoul (str, &end, 10) parse_ulong_base16() --> strtoul (str, &end, 16) parse_ullong_base*() --> strtoull(str, &end, *) parse_long_base*() --> strtol (str, &end, *) parse_llong_base*() --> strtoll (str, &end, *) parse_<unsigned_type>_<base> --> parse_ullong_<base> parse_<signed_type>_<base> --> parse_llong_<base> Note unsigned_type: umax uint u64 u32 u16 u8 uintmax_t unsigned uint64_t uint32_t uint16_t uint8_t signed_type: smax int s64 s32 s16 s8 intmax_t int int64_t int32_t int16_t int8_t Change-Id: I696278bd504812397c2444406e61ee954123af02 Signed-off-by: Alamy Liu <[email protected]> diff --git a/src/helper/command.c b/src/helper/command.c index 9862a2d..8555c77 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1384,11 +1384,48 @@ void process_jim_events(struct command_context *cmd_ctx) } \ return ERROR_OK; \ } +#define DEFINE_PARSE_NUM_TYPE_BASE(name, type, base, func, min, max) \ + int parse ## name ## _base ## base(const char *str, type * ul) \ + { \ + if (!*str) { \ + LOG_ERROR("Invalid command argument"); \ + return ERROR_COMMAND_ARGUMENT_INVALID; \ + } \ + char *end; \ + *ul = func(str, &end, base); \ + if (*end) { \ + LOG_ERROR("Invalid command argument"); \ + return ERROR_COMMAND_ARGUMENT_INVALID; \ + } \ + if ((max == *ul) && (ERANGE == errno)) { \ + LOG_ERROR("Argument overflow"); \ + return ERROR_COMMAND_ARGUMENT_OVERFLOW; \ + } \ + if (min && (min == *ul) && (ERANGE == errno)) { \ + LOG_ERROR("Argument underflow"); \ + return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \ + } \ + return ERROR_OK; \ + } +#define DEFINE_PARSE_NUM_TYPE_BIN(name, type, func, min, max) \ + DEFINE_PARSE_NUM_TYPE_BASE(name, type, 2, func, min, max) +#define DEFINE_PARSE_NUM_TYPE_OCT(name, type, func, min, max) \ + DEFINE_PARSE_NUM_TYPE_BASE(name, type, 8, func, min, max) +#define DEFINE_PARSE_NUM_TYPE_DEC(name, type, func, min, max) \ + DEFINE_PARSE_NUM_TYPE_BASE(name, type, 10, func, min, max) +#define DEFINE_PARSE_NUM_TYPE_HEX(name, type, func, min, max) \ + DEFINE_PARSE_NUM_TYPE_BASE(name, type, 16, func, min, max) + DEFINE_PARSE_NUM_TYPE(_ulong, unsigned long, strtoul, 0, ULONG_MAX) DEFINE_PARSE_NUM_TYPE(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX) DEFINE_PARSE_NUM_TYPE(_long, long, strtol, LONG_MIN, LONG_MAX) DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX) +DEFINE_PARSE_NUM_TYPE_HEX(_ulong, unsigned long, strtoul, 0, ULONG_MAX) +DEFINE_PARSE_NUM_TYPE_HEX(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX) +DEFINE_PARSE_NUM_TYPE_HEX(_long, long, strtol, LONG_MIN, LONG_MAX) +DEFINE_PARSE_NUM_TYPE_HEX(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX) + #define DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \ int parse ## name(const char *str, type * ul) \ { \ @@ -1403,25 +1440,77 @@ DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX) *ul = n; \ return ERROR_OK; \ } +#define DEFINE_PARSE_WRAPPER_BASE(name, type, base, min, max, functype, funcname) \ + int parse ## name ## _base ## base(const char *str, type * ul) \ + { \ + functype n; \ + int retval = parse ## funcname ## _base ## base(str, &n); \ + if (ERROR_OK != retval) \ + return retval; \ + if (n > max) \ + return ERROR_COMMAND_ARGUMENT_OVERFLOW; \ + if (min) \ + return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \ + *ul = n; \ + return ERROR_OK; \ + } +#define DEFINE_PARSE_WRAPPER_BIN(name, type, min, max, functype, funcname) \ + DEFINE_PARSE_WRAPPER_BASE(name, type, 2, min, max, functype, funcname) +#define DEFINE_PARSE_WRAPPER_OCT(name, type, min, max, functype, funcname) \ + DEFINE_PARSE_WRAPPER_BASE(name, type, 8, min, max, functype, funcname) +#define DEFINE_PARSE_WRAPPER_DEC(name, type, min, max, functype, funcname) \ + DEFINE_PARSE_WRAPPER_BASE(name, type, 10, min, max, functype, funcname) +#define DEFINE_PARSE_WRAPPER_HEX(name, type, min, max, functype, funcname) \ + DEFINE_PARSE_WRAPPER_BASE(name, type, 16, min, max, functype, funcname) #define DEFINE_PARSE_ULONGLONG(name, type, min, max) \ DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong) -DEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX) +#define DEFINE_PARSE_ULONGLONG_BIN(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_BIN(name, type, min, max, unsigned long long, _ullong) +#define DEFINE_PARSE_ULONGLONG_OCT(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_OCT(name, type, min, max, unsigned long long, _ullong) +#define DEFINE_PARSE_ULONGLONG_DEC(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_DEC(name, type, min, max, unsigned long long, _ullong) +#define DEFINE_PARSE_ULONGLONG_HEX(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_HEX(name, type, min, max, unsigned long long, _ullong) DEFINE_PARSE_ULONGLONG(_umax, uintmax_t, 0, UINTMAX_MAX) -DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX) -DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX) -DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX) -DEFINE_PARSE_ULONGLONG(_u8, uint8_t, 0, UINT8_MAX) +DEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX) +DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX) +DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX) +DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX) +DEFINE_PARSE_ULONGLONG(_u8, uint8_t, 0, UINT8_MAX) + +DEFINE_PARSE_ULONGLONG_HEX(_umax, uintmax_t, 0, UINTMAX_MAX) +DEFINE_PARSE_ULONGLONG_HEX(_uint, unsigned, 0, UINT_MAX) +DEFINE_PARSE_ULONGLONG_HEX(_u64, uint64_t, 0, UINT64_MAX) +DEFINE_PARSE_ULONGLONG_HEX(_u32, uint32_t, 0, UINT32_MAX) +DEFINE_PARSE_ULONGLONG_HEX(_u16, uint16_t, 0, UINT16_MAX) +DEFINE_PARSE_ULONGLONG_HEX(_u8, uint8_t, 0, UINT8_MAX) #define DEFINE_PARSE_LONGLONG(name, type, min, max) \ DEFINE_PARSE_WRAPPER(name, type, min, max, long long, _llong) -DEFINE_PARSE_LONGLONG(_int, int, n < INT_MIN, INT_MAX) +#define DEFINE_PARSE_LONGLONG_BIN(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_BIN(name, type, min, max, long long, _llong) +#define DEFINE_PARSE_LONGLONG_OCT(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_OCT(name, type, min, max, long long, _llong) +#define DEFINE_PARSE_LONGLONG_DEC(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_DEC(name, type, min, max, long long, _llong) +#define DEFINE_PARSE_LONGLONG_HEX(name, type, min, max) \ + DEFINE_PARSE_WRAPPER_HEX(name, type, min, max, long long, _llong) DEFINE_PARSE_LONGLONG(_smax,intmax_t,n < INTMAX_MIN,INTMAX_MAX) +DEFINE_PARSE_LONGLONG(_int, int, n < INT_MIN, INT_MAX) DEFINE_PARSE_LONGLONG(_s64, int64_t, n < INT64_MIN, INT64_MAX) DEFINE_PARSE_LONGLONG(_s32, int32_t, n < INT32_MIN, INT32_MAX) DEFINE_PARSE_LONGLONG(_s16, int16_t, n < INT16_MIN, INT16_MAX) DEFINE_PARSE_LONGLONG(_s8, int8_t, n < INT8_MIN, INT8_MAX) +DEFINE_PARSE_LONGLONG_HEX(_smax,intmax_t,n < INTMAX_MIN,INTMAX_MAX) +DEFINE_PARSE_LONGLONG_HEX(_int, int, n < INT_MIN, INT_MAX) +DEFINE_PARSE_LONGLONG_HEX(_s64, int64_t, n < INT64_MIN, INT64_MAX) +DEFINE_PARSE_LONGLONG_HEX(_s32, int32_t, n < INT32_MIN, INT32_MAX) +DEFINE_PARSE_LONGLONG_HEX(_s16, int16_t, n < INT16_MIN, INT16_MAX) +DEFINE_PARSE_LONGLONG_HEX(_s8, int8_t, n < INT8_MIN, INT8_MAX) + static int command_parse_bool(const char *in, bool *out, const char *on, const char *off) { diff --git a/src/helper/command.h b/src/helper/command.h index b962de0..67388c1 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -351,6 +351,16 @@ int parse_llong(const char *str, long long *ul); #define DECLARE_PARSE_WRAPPER(name, type) \ int parse ## name(const char *str, type * ul) +#define DECLARE_PARSE_WRAPPER_BASE(name, type, base) \ + int parse ## name ## _base ## base(const char *str, type * ul) +#define DECLARE_PARSE_WRAPPER_BIN(name, type) \ + DECLARE_PARSE_WRAPPER_BASE(name, type, 2) +#define DECLARE_PARSE_WRAPPER_OCT(name, type) \ + DECLARE_PARSE_WRAPPER_BASE(name, type, 8) +#define DECLARE_PARSE_WRAPPER_DEC(name, type) \ + DECLARE_PARSE_WRAPPER_BASE(name, type, 10) +#define DECLARE_PARSE_WRAPPER_HEX(name, type) \ + DECLARE_PARSE_WRAPPER_BASE(name, type, 16) DECLARE_PARSE_WRAPPER(_uint, unsigned); DECLARE_PARSE_WRAPPER(_umax, uintmax_t); @@ -366,6 +376,20 @@ DECLARE_PARSE_WRAPPER(_s32, int32_t); DECLARE_PARSE_WRAPPER(_s16, int16_t); DECLARE_PARSE_WRAPPER(_s8, int8_t); +DECLARE_PARSE_WRAPPER_HEX(_uint, unsigned); +DECLARE_PARSE_WRAPPER_HEX(_umax, uintmax_t); +DECLARE_PARSE_WRAPPER_HEX(_u64, uint64_t); +DECLARE_PARSE_WRAPPER_HEX(_u32, uint32_t); +DECLARE_PARSE_WRAPPER_HEX(_u16, uint16_t); +DECLARE_PARSE_WRAPPER_HEX(_u8, uint8_t); + +DECLARE_PARSE_WRAPPER_HEX(_int, int); +DECLARE_PARSE_WRAPPER_HEX(_smax, intmax_t); +DECLARE_PARSE_WRAPPER_HEX(_s64, int64_t); +DECLARE_PARSE_WRAPPER_HEX(_s32, int32_t); +DECLARE_PARSE_WRAPPER_HEX(_s16, int16_t); +DECLARE_PARSE_WRAPPER_HEX(_s8, int8_t); + /** * @brief parses the string @a in into @a out as a @a type, or prints * a command error and passes the error code to the caller. If an error @@ -386,6 +410,29 @@ DECLARE_PARSE_WRAPPER(_s8, int8_t); return retval_macro_tmp; \ } \ } while (0) +#define COMMAND_PARSE_NUMBER_BASE(type, base, in, out) \ + do { \ + int retval_macro_tmp = parse_ ## type ## _base ## base(in, &(out)); \ + if (ERROR_OK != retval_macro_tmp) { \ + command_print(CMD_CTX, stringify(out) \ + " option value ('%s') is not valid", in); \ + return retval_macro_tmp; \ + } \ + } while (0) +#define COMMAND_PARSE_NUMBER_BIN(type, in, out) \ + COMMAND_PARSE_NUMBER_BASE(type, 2, in, out) +#define COMMAND_PARSE_NUMBER_OCT(type, in, out) \ + COMMAND_PARSE_NUMBER_BASE(type, 8, in, out) +#define COMMAND_PARSE_NUMBER_DEC(type, in, out) \ + COMMAND_PARSE_NUMBER_BASE(type, 10, in, out) +#define COMMAND_PARSE_NUMBER_HEX(type, in, out) \ + COMMAND_PARSE_NUMBER_BASE(type, 16, in, out) + +/* Alias */ +#define COMMAND_PARSE_NUMBER_BASE2 COMMAND_PARSE_NUMBER_BIN +#define COMMAND_PARSE_NUMBER_BASE8 COMMAND_PARSE_NUMBER_OCT +#define COMMAND_PARSE_NUMBER_BASE10 COMMAND_PARSE_NUMBER_DEC +#define COMMAND_PARSE_NUMBER_BASE16 COMMAND_PARSE_NUMBER_HEX /** * Parse the string @c as a binary parameter, storing the boolean value -- ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140 _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
