+#define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \
+ int parse ## name(const char *str, type * ul) \
+ { \
+ if (!*str) { \
+ LOG_ERROR("Invalid command argument"); \
+ return ERROR_COMMAND_ARGUMENT_INVALID; \
+ } \
+ char *end; \
+ errno = 0; \
+ *ul = func(str, &end, 0); \
+ 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_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 DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \
+ int parse ## name(const char *str, type * ul) \
+ { \
+ functype n; \
+ int retval = parse ## funcname(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_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_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(_target_addr, target_addr_t, 0, TARGET_ADDR_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_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)
+
+static int command_parse_bool(const char *in, bool *out,
+ const char *on, const char *off)