Rewrite arm11_handle_bool to provide a generic on/off command helper. Refactors COMMAND_PARSE_BOOL to use new command_parse_bool helper, which gets reused by the new command_parse_bool_any helper. This later helper is called by the new command helper function to accepts any on/off, enable/disable, true/false, yes/no, or 0/1 parameter.tags/v0.4.0-rc1
@@ -954,3 +954,53 @@ DEFINE_PARSE_LONG(_int, int, n < INT_MIN, INT_MAX) | |||||
DEFINE_PARSE_LONG(_s32, int32_t, n < INT32_MIN, INT32_MAX) | DEFINE_PARSE_LONG(_s32, int32_t, n < INT32_MIN, INT32_MAX) | ||||
DEFINE_PARSE_LONG(_s16, int16_t, n < INT16_MIN, INT16_MAX) | DEFINE_PARSE_LONG(_s16, int16_t, n < INT16_MIN, INT16_MAX) | ||||
DEFINE_PARSE_LONG(_s8, int8_t, n < INT8_MIN, INT8_MAX) | DEFINE_PARSE_LONG(_s8, int8_t, n < INT8_MIN, INT8_MAX) | ||||
int command_parse_bool(const char *in, bool *out, | |||||
const char *on, const char *off) | |||||
{ | |||||
if (strcasecmp(in, on) == 0) | |||||
*out = true; | |||||
else if (strcasecmp(in, off) == 0) | |||||
*out = false; | |||||
else | |||||
return ERROR_COMMAND_SYNTAX_ERROR; | |||||
return ERROR_OK; | |||||
} | |||||
int command_parse_bool_any(const char *in, bool *out) | |||||
{ | |||||
if (command_parse_bool(in, out, "on", "off") == ERROR_OK) | |||||
return ERROR_OK; | |||||
if (command_parse_bool(in, out, "enable", "disable") == ERROR_OK) | |||||
return ERROR_OK; | |||||
if (command_parse_bool(in, out, "true", "false") == ERROR_OK) | |||||
return ERROR_OK; | |||||
if (command_parse_bool(in, out, "yes", "no") == ERROR_OK) | |||||
return ERROR_OK; | |||||
if (command_parse_bool(in, out, "1", "0") == ERROR_OK) | |||||
return ERROR_OK; | |||||
return ERROR_INVALID_ARGUMENTS; | |||||
} | |||||
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label) | |||||
{ | |||||
switch (CMD_ARGC) { | |||||
case 1: { | |||||
const char *in = CMD_ARGV[0]; | |||||
if (command_parse_bool_any(in, out) != ERROR_OK) | |||||
{ | |||||
LOG_ERROR("%s: argument '%s' is not valid", CMD_NAME, in); | |||||
return ERROR_INVALID_ARGUMENTS; | |||||
} | |||||
// fall through | |||||
} | |||||
case 0: | |||||
LOG_INFO("%s is %s", label, *out ? "enabled" : "disabled"); | |||||
break; | |||||
default: | |||||
return ERROR_INVALID_ARGUMENTS; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
@@ -271,19 +271,22 @@ DECLARE_PARSE_WRAPPER(_s8, int8_t); | |||||
*/ | */ | ||||
#define COMMAND_PARSE_BOOL(in, out, on, off) \ | #define COMMAND_PARSE_BOOL(in, out, on, off) \ | ||||
do { \ | do { \ | ||||
if (strcmp(in, on) == 0) \ | |||||
out = true; \ | |||||
else if (strcmp(in, off) == 0) \ | |||||
out = false; \ | |||||
else { \ | |||||
bool value; \ | |||||
int retval = command_parse_bool(in, &value, on, off); \ | |||||
if (ERROR_OK != retval) { \ | |||||
command_print(CMD_CTX, stringify(out) \ | command_print(CMD_CTX, stringify(out) \ | ||||
" option value ('%s') is not valid", in); \ | " option value ('%s') is not valid", in); \ | ||||
command_print(CMD_CTX, " choices are '%s' or '%s'", \ | command_print(CMD_CTX, " choices are '%s' or '%s'", \ | ||||
on, off); \ | on, off); \ | ||||
return ERROR_COMMAND_SYNTAX_ERROR; \ | |||||
return retval; \ | |||||
} \ | } \ | ||||
out = value; \ | |||||
} while (0) | } while (0) | ||||
int command_parse_bool(const char *in, bool *out, | |||||
const char *on, const char *off); | |||||
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label); | |||||
/// parses an on/off command argument | /// parses an on/off command argument | ||||
#define COMMAND_PARSE_ON_OFF(in, out) \ | #define COMMAND_PARSE_ON_OFF(in, out) \ | ||||
COMMAND_PARSE_BOOL(in, out, "on", "off") | COMMAND_PARSE_BOOL(in, out, "on", "off") | ||||
@@ -1981,52 +1981,17 @@ static int arm11_build_reg_cache(struct target *target) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
static COMMAND_HELPER(arm11_handle_bool, bool *var, char *name) | |||||
{ | |||||
if (CMD_ARGC == 0) | |||||
{ | |||||
LOG_INFO("%s is %s.", name, *var ? "enabled" : "disabled"); | |||||
return ERROR_OK; | |||||
} | |||||
if (CMD_ARGC != 1) | |||||
return ERROR_COMMAND_SYNTAX_ERROR; | |||||
switch (CMD_ARGV[0][0]) | |||||
{ | |||||
case '0': /* 0 */ | |||||
case 'f': /* false */ | |||||
case 'F': | |||||
case 'd': /* disable */ | |||||
case 'D': | |||||
*var = false; | |||||
break; | |||||
case '1': /* 1 */ | |||||
case 't': /* true */ | |||||
case 'T': | |||||
case 'e': /* enable */ | |||||
case 'E': | |||||
*var = true; | |||||
break; | |||||
} | |||||
LOG_INFO("%s %s.", *var ? "Enabled" : "Disabled", name); | |||||
return ERROR_OK; | |||||
} | |||||
#define BOOL_WRAPPER(name, print_name) \ | |||||
COMMAND_HANDLER(arm11_handle_bool_##name) \ | |||||
{ \ | |||||
return CALL_COMMAND_HANDLER(arm11_handle_bool, \ | |||||
&arm11_config_##name, print_name); \ | |||||
} | |||||
#define ARM11_BOOL_WRAPPER(name, print_name) \ | |||||
COMMAND_HANDLER(arm11_handle_bool_##name) \ | |||||
{ \ | |||||
return CALL_COMMAND_HANDLER(handle_command_parse_bool, \ | |||||
&arm11_config_##name, print_name); \ | |||||
} | |||||
BOOL_WRAPPER(memwrite_burst, "memory write burst mode") | |||||
BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes") | |||||
BOOL_WRAPPER(step_irq_enable, "IRQs while stepping") | |||||
BOOL_WRAPPER(hardware_step, "hardware single step") | |||||
ARM11_BOOL_WRAPPER(memwrite_burst, "memory write burst mode") | |||||
ARM11_BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes") | |||||
ARM11_BOOL_WRAPPER(step_irq_enable, "IRQs while stepping") | |||||
ARM11_BOOL_WRAPPER(hardware_step, "hardware single step") | |||||
COMMAND_HANDLER(arm11_handle_vcr) | COMMAND_HANDLER(arm11_handle_vcr) | ||||
{ | { | ||||