Merge branch 'master' into from_upstream
Change-Id: I036350ee06aa396344fb8a80c7dba148ec24c9c8
This commit is contained in:
@@ -16,6 +16,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la
|
||||
%D%/jep106.c \
|
||||
%D%/jim-nvp.c \
|
||||
%D%/binarybuffer.h \
|
||||
%D%/bits.h \
|
||||
%D%/configuration.h \
|
||||
%D%/ioutil.h \
|
||||
%D%/list.h \
|
||||
|
||||
@@ -118,7 +118,7 @@ static inline uint32_t buf_get_u32(const uint8_t *_buffer,
|
||||
uint32_t result = 0;
|
||||
for (unsigned i = first; i < first + num; i++) {
|
||||
if (((buffer[i / 8] >> (i % 8)) & 1) == 1)
|
||||
result |= 1 << (i - first);
|
||||
result |= 1U << (i - first);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The content of this file is mainly copied/inspired from Linux kernel
|
||||
* code in include/linux/types.h include/linux/bitmap.h include/linux/bitops.h
|
||||
*/
|
||||
|
||||
#ifndef OPENOCD_HELPER_BITS_H
|
||||
#define OPENOCD_HELPER_BITS_H
|
||||
|
||||
#include <helper/types.h>
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
#define BITS_PER_BYTE 8
|
||||
#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
|
||||
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
#define DECLARE_BITMAP(name, bits) unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
/**
|
||||
* bitmap_zero - Clears all the bits in memory
|
||||
* @dst: the address of the bitmap
|
||||
* @nbits: the number of bits to clear
|
||||
*/
|
||||
static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
|
||||
{
|
||||
unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear_bit - Clear a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*/
|
||||
static inline void clear_bit(unsigned int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
|
||||
*p &= ~mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_bit - Set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*/
|
||||
static inline void set_bit(unsigned int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
|
||||
*p |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* test_bit - Determine whether a bit is set
|
||||
* @nr: bit number to test
|
||||
* @addr: Address to start counting from
|
||||
*/
|
||||
static inline int test_bit(unsigned int nr, const volatile unsigned long *addr)
|
||||
{
|
||||
return 1UL & (addr[BIT_WORD(nr)] >> (nr % BITS_PER_LONG));
|
||||
}
|
||||
|
||||
#endif /* OPENOCD_HELPER_BITS_H */
|
||||
+104
-112
@@ -190,7 +190,7 @@ struct command_context *current_command_context(Jim_Interp *interp)
|
||||
}
|
||||
|
||||
static int script_command_run(Jim_Interp *interp,
|
||||
int argc, Jim_Obj * const *argv, struct command *c, bool capture)
|
||||
int argc, Jim_Obj * const *argv, struct command *c)
|
||||
{
|
||||
target_call_timer_callbacks_now();
|
||||
LOG_USER_N("%s", ""); /* Keep GDB connection alive*/
|
||||
@@ -200,15 +200,9 @@ static int script_command_run(Jim_Interp *interp,
|
||||
if (NULL == words)
|
||||
return JIM_ERR;
|
||||
|
||||
struct log_capture_state *state = NULL;
|
||||
if (capture)
|
||||
state = command_log_capture_start(interp);
|
||||
|
||||
struct command_context *cmd_ctx = current_command_context(interp);
|
||||
int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
|
||||
|
||||
command_log_capture_finish(state);
|
||||
|
||||
script_command_args_free(words, nwords);
|
||||
return command_retval_set(interp, retval);
|
||||
}
|
||||
@@ -220,7 +214,7 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
struct command *c = interp->cmdPrivData;
|
||||
assert(c);
|
||||
script_debug(interp, c->name, argc, argv);
|
||||
return script_command_run(interp, argc, argv, c, true);
|
||||
return script_command_run(interp, argc, argv, c);
|
||||
}
|
||||
|
||||
static struct command *command_root(struct command *c)
|
||||
@@ -316,7 +310,7 @@ static struct command *command_new(struct command_context *cmd_ctx,
|
||||
* arguments.
|
||||
*/
|
||||
if ((cr->jim_handler == NULL) && (cr->usage == NULL)) {
|
||||
LOG_DEBUG("BUG: command '%s%s%s' does not have the "
|
||||
LOG_ERROR("BUG: command '%s%s%s' does not have the "
|
||||
"'.usage' field filled out",
|
||||
parent && parent->name ? parent->name : "",
|
||||
parent && parent->name ? " " : "",
|
||||
@@ -357,27 +351,11 @@ static int register_command_handler(struct command_context *cmd_ctx,
|
||||
struct command *c)
|
||||
{
|
||||
Jim_Interp *interp = cmd_ctx->interp;
|
||||
char *ocd_name = alloc_printf("ocd_%s", c->name);
|
||||
if (NULL == ocd_name)
|
||||
return JIM_ERR;
|
||||
|
||||
LOG_DEBUG("registering '%s'...", ocd_name);
|
||||
LOG_DEBUG("registering '%s'...", c->name);
|
||||
|
||||
Jim_CmdProc *func = c->handler ? &script_command : &command_unknown;
|
||||
int retval = Jim_CreateCommand(interp, ocd_name, func, c, NULL);
|
||||
free(ocd_name);
|
||||
if (JIM_OK != retval)
|
||||
return retval;
|
||||
|
||||
/* we now need to add an overrideable proc */
|
||||
char *override_name = alloc_printf(
|
||||
"proc %s {args} {eval ocd_bouncer %s $args}",
|
||||
c->name, c->name);
|
||||
if (NULL == override_name)
|
||||
return JIM_ERR;
|
||||
|
||||
retval = Jim_Eval_Named(interp, override_name, 0, 0);
|
||||
free(override_name);
|
||||
int retval = Jim_CreateCommand(interp, c->name, func, c, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -502,7 +480,7 @@ void command_output_text(struct command_context *context, const char *data)
|
||||
context->output_handler(context, data);
|
||||
}
|
||||
|
||||
void command_print_sameline(struct command_context *context, const char *format, ...)
|
||||
void command_print_sameline(struct command_invocation *cmd, const char *format, ...)
|
||||
{
|
||||
char *string;
|
||||
|
||||
@@ -510,13 +488,13 @@ void command_print_sameline(struct command_context *context, const char *format,
|
||||
va_start(ap, format);
|
||||
|
||||
string = alloc_vprintf(format, ap);
|
||||
if (string != NULL) {
|
||||
if (string != NULL && cmd) {
|
||||
/* we want this collected in the log + we also want to pick it up as a tcl return
|
||||
* value.
|
||||
*
|
||||
* The latter bit isn't precisely neat, but will do for now.
|
||||
*/
|
||||
LOG_USER_N("%s", string);
|
||||
Jim_AppendString(cmd->ctx->interp, cmd->output, string, -1);
|
||||
/* We already printed it above
|
||||
* command_output_text(context, string); */
|
||||
free(string);
|
||||
@@ -525,7 +503,7 @@ void command_print_sameline(struct command_context *context, const char *format,
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void command_print(struct command_context *context, const char *format, ...)
|
||||
void command_print(struct command_invocation *cmd, const char *format, ...)
|
||||
{
|
||||
char *string;
|
||||
|
||||
@@ -533,7 +511,7 @@ void command_print(struct command_context *context, const char *format, ...)
|
||||
va_start(ap, format);
|
||||
|
||||
string = alloc_vprintf(format, ap);
|
||||
if (string != NULL) {
|
||||
if (string != NULL && cmd) {
|
||||
strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one
|
||||
*char longer */
|
||||
/* we want this collected in the log + we also want to pick it up as a tcl return
|
||||
@@ -541,7 +519,7 @@ void command_print(struct command_context *context, const char *format, ...)
|
||||
*
|
||||
* The latter bit isn't precisely neat, but will do for now.
|
||||
*/
|
||||
LOG_USER_N("%s", string);
|
||||
Jim_AppendString(cmd->ctx->interp, cmd->output, string, -1);
|
||||
/* We already printed it above
|
||||
* command_output_text(context, string); */
|
||||
free(string);
|
||||
@@ -628,6 +606,9 @@ static int run_command(struct command_context *context,
|
||||
if (c->jim_handler_data)
|
||||
context->current_target_override = c->jim_handler_data;
|
||||
|
||||
cmd.output = Jim_NewEmptyStringObj(context->interp);
|
||||
Jim_IncrRefCount(cmd.output);
|
||||
|
||||
int retval = c->handler(&cmd);
|
||||
|
||||
if (c->jim_handler_data)
|
||||
@@ -642,15 +623,17 @@ static int run_command(struct command_context *context,
|
||||
}
|
||||
} else if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
|
||||
/* just fall through for a shutdown request */
|
||||
} else if (retval != ERROR_OK) {
|
||||
/* we do not print out an error message because the command *should*
|
||||
* have printed out an error
|
||||
*/
|
||||
char *full_name = command_name(c, ' ');
|
||||
LOG_DEBUG("Command '%s' failed with error code %d",
|
||||
full_name ? full_name : c->name, retval);
|
||||
free(full_name);
|
||||
} else {
|
||||
if (retval != ERROR_OK) {
|
||||
char *full_name = command_name(c, ' ');
|
||||
LOG_DEBUG("Command '%s' failed with error code %d",
|
||||
full_name ? full_name : c->name, retval);
|
||||
free(full_name);
|
||||
}
|
||||
/* Use the command output as the Tcl result */
|
||||
Jim_SetResult(context->interp, cmd.output);
|
||||
}
|
||||
Jim_DecrRefCount(context->interp, cmd.output);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -669,9 +652,11 @@ int command_run_line(struct command_context *context, char *line)
|
||||
* happen when the Jim Tcl interpreter is provided by eCos for
|
||||
* instance.
|
||||
*/
|
||||
struct target *saved_target_override = context->current_target_override;
|
||||
context->current_target_override = NULL;
|
||||
|
||||
Jim_Interp *interp = context->interp;
|
||||
struct command_context *old_context = Jim_GetAssocData(interp, "context");
|
||||
Jim_DeleteAssocData(interp, "context");
|
||||
retcode = Jim_SetAssocData(interp, "context", NULL, context);
|
||||
if (retcode == JIM_OK) {
|
||||
@@ -684,25 +669,19 @@ int command_run_line(struct command_context *context, char *line)
|
||||
Jim_DeleteAssocData(interp, "retval");
|
||||
}
|
||||
Jim_DeleteAssocData(interp, "context");
|
||||
int inner_retcode = Jim_SetAssocData(interp, "context", NULL, old_context);
|
||||
if (retcode == JIM_OK)
|
||||
retcode = inner_retcode;
|
||||
}
|
||||
context->current_target_override = saved_target_override;
|
||||
if (retcode == JIM_OK) {
|
||||
const char *result;
|
||||
int reslen;
|
||||
|
||||
result = Jim_GetString(Jim_GetResult(interp), &reslen);
|
||||
if (reslen > 0) {
|
||||
int i;
|
||||
char buff[256 + 1];
|
||||
for (i = 0; i < reslen; i += 256) {
|
||||
int chunk;
|
||||
chunk = reslen - i;
|
||||
if (chunk > 256)
|
||||
chunk = 256;
|
||||
strncpy(buff, result + i, chunk);
|
||||
buff[chunk] = 0;
|
||||
LOG_USER_N("%s", buff);
|
||||
}
|
||||
LOG_USER_N("\n");
|
||||
command_output_text(context, result);
|
||||
command_output_text(context, "\n");
|
||||
}
|
||||
retval = ERROR_OK;
|
||||
} else if (retcode == JIM_EXIT) {
|
||||
@@ -712,6 +691,7 @@ int command_run_line(struct command_context *context, char *line)
|
||||
return retcode;
|
||||
} else {
|
||||
Jim_MakeErrorMessage(interp);
|
||||
/* error is broadcast */
|
||||
LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL));
|
||||
|
||||
if (retval == ERROR_OK) {
|
||||
@@ -827,8 +807,6 @@ static COMMAND_HELPER(command_help_find, struct command *head,
|
||||
if (0 == CMD_ARGC)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
*out = command_find(head, CMD_ARGV[0]);
|
||||
if (NULL == *out && strncmp(CMD_ARGV[0], "ocd_", 4) == 0)
|
||||
*out = command_find(head, CMD_ARGV[0] + 4);
|
||||
if (NULL == *out)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
if (--CMD_ARGC == 0)
|
||||
@@ -982,34 +960,85 @@ COMMAND_HANDLER(handle_help_command)
|
||||
}
|
||||
|
||||
static int command_unknown_find(unsigned argc, Jim_Obj *const *argv,
|
||||
struct command *head, struct command **out, bool top_level)
|
||||
struct command *head, struct command **out)
|
||||
{
|
||||
if (0 == argc)
|
||||
return argc;
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
struct command *c = command_find(head, cmd_name);
|
||||
if (NULL == c && top_level && strncmp(cmd_name, "ocd_", 4) == 0)
|
||||
c = command_find(head, cmd_name + 4);
|
||||
if (NULL == c)
|
||||
return argc;
|
||||
*out = c;
|
||||
return command_unknown_find(--argc, ++argv, (*out)->children, out, false);
|
||||
return command_unknown_find(--argc, ++argv, (*out)->children, out);
|
||||
}
|
||||
|
||||
static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
char *prev, *all;
|
||||
int i;
|
||||
|
||||
assert(argc >= 1);
|
||||
|
||||
all = strdup(Jim_GetString(argv[0], NULL));
|
||||
if (!all) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
prev = all;
|
||||
all = alloc_printf("%s %s", all, Jim_GetString(argv[i], NULL));
|
||||
free(prev);
|
||||
if (!all) {
|
||||
LOG_ERROR("Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
static int run_usage(Jim_Interp *interp, int argc_valid, int argc, Jim_Obj * const *argv)
|
||||
{
|
||||
struct command_context *cmd_ctx = current_command_context(interp);
|
||||
char *command;
|
||||
int retval;
|
||||
|
||||
assert(argc_valid >= 1);
|
||||
assert(argc >= argc_valid);
|
||||
|
||||
command = alloc_concatenate_strings(argc_valid, argv);
|
||||
if (!command)
|
||||
return JIM_ERR;
|
||||
|
||||
retval = command_run_linef(cmd_ctx, "usage %s", command);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("unable to execute command \"usage %s\"", command);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
if (argc_valid == argc)
|
||||
LOG_ERROR("%s: command requires more arguments", command);
|
||||
else {
|
||||
free(command);
|
||||
command = alloc_concatenate_strings(argc - argc_valid, argv + argc_valid);
|
||||
if (!command)
|
||||
return JIM_ERR;
|
||||
LOG_ERROR("invalid subcommand \"%s\"", command);
|
||||
}
|
||||
|
||||
free(command);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||
if (strcmp(cmd_name, "unknown") == 0) {
|
||||
if (argc == 1)
|
||||
return JIM_OK;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
script_debug(interp, cmd_name, argc, argv);
|
||||
|
||||
struct command_context *cmd_ctx = current_command_context(interp);
|
||||
struct command *c = cmd_ctx->commands;
|
||||
int remaining = command_unknown_find(argc, argv, c, &c, true);
|
||||
int remaining = command_unknown_find(argc, argv, c, &c);
|
||||
/* if nothing could be consumed, then it's really an unknown command */
|
||||
if (remaining == argc) {
|
||||
const char *cmd = Jim_GetString(argv[0], NULL);
|
||||
@@ -1017,7 +1046,6 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
bool found = true;
|
||||
Jim_Obj *const *start;
|
||||
unsigned count;
|
||||
if (c->handler || c->jim_handler) {
|
||||
@@ -1025,14 +1053,10 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
count = remaining + 1;
|
||||
start = argv + (argc - remaining - 1);
|
||||
} else {
|
||||
c = command_find(cmd_ctx->commands, "usage");
|
||||
if (NULL == c) {
|
||||
LOG_ERROR("unknown command, but usage is missing too");
|
||||
return JIM_ERR;
|
||||
}
|
||||
count = argc - remaining;
|
||||
start = argv;
|
||||
found = false;
|
||||
run_usage(interp, count, argc, start);
|
||||
return JIM_ERR;
|
||||
}
|
||||
/* pass the command through to the intended handler */
|
||||
if (c->jim_handler) {
|
||||
@@ -1043,7 +1067,7 @@ static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
return (*c->jim_handler)(interp, count, start);
|
||||
}
|
||||
|
||||
return script_command_run(interp, count, start, c, found);
|
||||
return script_command_run(interp, count, start, c);
|
||||
}
|
||||
|
||||
static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
@@ -1053,7 +1077,7 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
|
||||
if (argc > 1) {
|
||||
struct command *c = cmd_ctx->commands;
|
||||
int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
|
||||
int remaining = command_unknown_find(argc - 1, argv + 1, c, &c);
|
||||
/* if nothing could be consumed, then it's an unknown command */
|
||||
if (remaining == argc - 1) {
|
||||
Jim_SetResultString(interp, "unknown", -1);
|
||||
@@ -1082,32 +1106,6 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int jim_command_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
if (1 == argc)
|
||||
return JIM_ERR;
|
||||
|
||||
struct command_context *cmd_ctx = current_command_context(interp);
|
||||
struct command *c = cmd_ctx->commands;
|
||||
int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
|
||||
/* if nothing could be consumed, then it's an unknown command */
|
||||
if (remaining == argc - 1) {
|
||||
Jim_SetResultString(interp, "unknown", -1);
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
if (c->jim_handler)
|
||||
Jim_SetResultString(interp, "native", -1);
|
||||
else if (c->handler)
|
||||
Jim_SetResultString(interp, "simple", -1);
|
||||
else if (remaining == 0)
|
||||
Jim_SetResultString(interp, "group", -1);
|
||||
else
|
||||
Jim_SetResultString(interp, "unknown", -1);
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
int help_add_command(struct command_context *cmd_ctx, struct command *parent,
|
||||
const char *cmd_name, const char *help_text, const char *usage)
|
||||
{
|
||||
@@ -1119,7 +1117,7 @@ int help_add_command(struct command_context *cmd_ctx, struct command *parent,
|
||||
.name = cmd_name,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = help_text,
|
||||
.usage = usage,
|
||||
.usage = usage ? : "",
|
||||
};
|
||||
nc = register_command(cmd_ctx, parent, &cr);
|
||||
if (NULL == nc) {
|
||||
@@ -1144,8 +1142,9 @@ int help_add_command(struct command_context *cmd_ctx, struct command *parent,
|
||||
if (usage) {
|
||||
bool replaced = false;
|
||||
if (nc->usage) {
|
||||
if (*nc->usage)
|
||||
replaced = true;
|
||||
free(nc->usage);
|
||||
replaced = true;
|
||||
}
|
||||
nc->usage = strdup(usage);
|
||||
if (replaced)
|
||||
@@ -1227,15 +1226,6 @@ static const struct command_registration command_subcommand_handlers[] = {
|
||||
"Returns 'unknown' if an unknown command is given. "
|
||||
"Command can be multiple tokens.",
|
||||
},
|
||||
{
|
||||
.name = "type",
|
||||
.mode = COMMAND_ANY,
|
||||
.jim_handler = jim_command_type,
|
||||
.usage = "command_name [...]",
|
||||
.help = "Returns the type of built-in command:"
|
||||
"'native', 'simple', 'group', or 'unknown'. "
|
||||
"Command can be multiple tokens.",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
@@ -1294,6 +1284,7 @@ static const struct command_registration command_builtin_handlers[] = {
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "core command group (introspection)",
|
||||
.chain = command_subcommand_handlers,
|
||||
.usage = "",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
@@ -1403,6 +1394,7 @@ void process_jim_events(struct command_context *cmd_ctx)
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID; \
|
||||
} \
|
||||
char *end; \
|
||||
errno = 0; \
|
||||
*ul = func(str, &end, 0); \
|
||||
if (*end) { \
|
||||
LOG_ERROR("Invalid command argument"); \
|
||||
|
||||
+11
-5
@@ -79,6 +79,7 @@ struct command_invocation {
|
||||
const char *name;
|
||||
unsigned argc;
|
||||
const char **argv;
|
||||
Jim_Obj *output;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -121,6 +122,11 @@ struct command_invocation {
|
||||
*/
|
||||
#define COMMAND_HELPER(name, extra ...) __COMMAND_HANDLER(name, extra)
|
||||
|
||||
/**
|
||||
* Use this macro to access the command being handled,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
*/
|
||||
#define CMD (cmd)
|
||||
/**
|
||||
* Use this macro to access the context of the command being handled,
|
||||
* rather than accessing the variable directly. It may be moved.
|
||||
@@ -348,9 +354,9 @@ struct command_context *copy_command_context(struct command_context *cmd_ctx);
|
||||
*/
|
||||
void command_done(struct command_context *context);
|
||||
|
||||
void command_print(struct command_context *context, const char *format, ...)
|
||||
void command_print(struct command_invocation *cmd, const char *format, ...)
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
|
||||
void command_print_sameline(struct command_context *context, const char *format, ...)
|
||||
void command_print_sameline(struct command_invocation *cmd, const char *format, ...)
|
||||
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
|
||||
int command_run_line(struct command_context *context, char *line);
|
||||
int command_run_linef(struct command_context *context, const char *format, ...)
|
||||
@@ -404,7 +410,7 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);
|
||||
do { \
|
||||
int retval_macro_tmp = parse_ ## type(in, &(out)); \
|
||||
if (ERROR_OK != retval_macro_tmp) { \
|
||||
command_print(CMD_CTX, stringify(out) \
|
||||
command_print(CMD, stringify(out) \
|
||||
" option value ('%s') is not valid", in); \
|
||||
return retval_macro_tmp; \
|
||||
} \
|
||||
@@ -424,9 +430,9 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);
|
||||
bool value; \
|
||||
int retval_macro_tmp = command_parse_bool_arg(in, &value); \
|
||||
if (ERROR_OK != retval_macro_tmp) { \
|
||||
command_print(CMD_CTX, stringify(out) \
|
||||
command_print(CMD, stringify(out) \
|
||||
" option value ('%s') is not valid", in); \
|
||||
command_print(CMD_CTX, " choices are '%s' or '%s'", \
|
||||
command_print(CMD, " choices are '%s' or '%s'", \
|
||||
on, off); \
|
||||
return retval_macro_tmp; \
|
||||
} \
|
||||
|
||||
+8
-7
@@ -113,10 +113,10 @@ COMMAND_HANDLER(handle_cat_command)
|
||||
|
||||
int retval = load_file(CMD_ARGV[0], &data, &len);
|
||||
if (retval == ERROR_OK) {
|
||||
command_print(CMD_CTX, "%s", data);
|
||||
command_print(CMD, "%s", data);
|
||||
free(data);
|
||||
} else
|
||||
command_print(CMD_CTX, "%s not found", CMD_ARGV[0]);
|
||||
command_print(CMD, "%s not found", CMD_ARGV[0]);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -146,10 +146,10 @@ COMMAND_HANDLER(handle_meminfo_command)
|
||||
info = mallinfo();
|
||||
|
||||
if (prev > 0)
|
||||
command_print(CMD_CTX, "Diff: %d", prev - info.fordblks);
|
||||
command_print(CMD, "Diff: %d", prev - info.fordblks);
|
||||
prev = info.fordblks;
|
||||
|
||||
command_print(CMD_CTX, "Available ram: %d", info.fordblks);
|
||||
command_print(CMD, "Available ram: %d", info.fordblks);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ COMMAND_HANDLER(handle_cp_command)
|
||||
if (retval != ERROR_OK)
|
||||
break;
|
||||
|
||||
command_print(CMD_CTX, "%zu", len - pos);
|
||||
command_print(CMD, "%zu", len - pos);
|
||||
|
||||
pos += chunk;
|
||||
|
||||
@@ -226,9 +226,9 @@ COMMAND_HANDLER(handle_cp_command)
|
||||
}
|
||||
|
||||
if (retval == ERROR_OK)
|
||||
command_print(CMD_CTX, "Copied %s to %s", CMD_ARGV[0], CMD_ARGV[1]);
|
||||
command_print(CMD, "Copied %s to %s", CMD_ARGV[0], CMD_ARGV[1]);
|
||||
else
|
||||
command_print(CMD_CTX, "copy failed");
|
||||
command_print(CMD, "copy failed");
|
||||
|
||||
if (data != NULL)
|
||||
free(data);
|
||||
@@ -472,6 +472,7 @@ static const struct command_registration ioutil_command_handlers[] = {
|
||||
.handler = handle_meminfo_command,
|
||||
.mode = COMMAND_ANY,
|
||||
.help = "display free heap space",
|
||||
.usage = "",
|
||||
},
|
||||
#endif
|
||||
{
|
||||
|
||||
+2
-2
@@ -213,7 +213,7 @@ COMMAND_HANDLER(handle_debug_level_command)
|
||||
} else if (CMD_ARGC > 1)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
command_print(CMD_CTX, "debug_level: %i", debug_level);
|
||||
command_print(CMD, "debug_level: %i", debug_level);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -236,7 +236,7 @@ COMMAND_HANDLER(handle_log_output_command)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static struct command_registration log_command_handlers[] = {
|
||||
static const struct command_registration log_command_handlers[] = {
|
||||
{
|
||||
.name = "log_output",
|
||||
.handler = handle_log_output_command,
|
||||
|
||||
@@ -269,19 +269,14 @@ int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])
|
||||
break;
|
||||
case 'd': /* --debug | -d */
|
||||
{
|
||||
char *command = alloc_printf("debug_level %s", optarg ? optarg : "3");
|
||||
int retval = command_run_line(cmd_ctx, command);
|
||||
free(command);
|
||||
int retval = command_run_linef(cmd_ctx, "debug_level %s", optarg ? optarg : "3");
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
break;
|
||||
}
|
||||
case 'l': /* --log_output | -l */
|
||||
if (optarg) {
|
||||
char *command = alloc_printf("log_output %s", optarg);
|
||||
command_run_line(cmd_ctx, command);
|
||||
free(command);
|
||||
}
|
||||
if (optarg)
|
||||
command_run_linef(cmd_ctx, "log_output %s", optarg);
|
||||
break;
|
||||
case 'c': /* --command | -c */
|
||||
if (optarg)
|
||||
|
||||
@@ -3,43 +3,6 @@
|
||||
# Embedded into OpenOCD executable
|
||||
#
|
||||
|
||||
|
||||
# We need to explicitly redirect this to the OpenOCD command
|
||||
# as Tcl defines the exit proc
|
||||
proc exit {} {
|
||||
ocd_throw exit
|
||||
}
|
||||
|
||||
# All commands are registered with an 'ocd_' prefix, while the "real"
|
||||
# command is a wrapper that calls this function. Its primary purpose is
|
||||
# to discard 'handler' command output.
|
||||
# Due to the two nested proc calls, this wrapper has to explicitly run
|
||||
# the wrapped command in the stack frame two levels above.
|
||||
proc ocd_bouncer {name args} {
|
||||
set cmd [format "ocd_%s" $name]
|
||||
set type [eval ocd_command type $cmd $args]
|
||||
set errcode error
|
||||
set skiplevel [expr [eval info level] > 1 ? 2 : 1]
|
||||
if {$type == "native"} {
|
||||
return [uplevel $skiplevel $cmd $args]
|
||||
} else {if {$type == "simple"} {
|
||||
set errcode [catch {uplevel $skiplevel $cmd $args}]
|
||||
if {$errcode == 0} {
|
||||
return ""
|
||||
} else {
|
||||
# 'classic' commands output error message as part of progress output
|
||||
set errmsg ""
|
||||
}
|
||||
} else {if {$type == "group"} {
|
||||
catch {eval ocd_usage $name $args}
|
||||
set errmsg [format "%s: command requires more arguments" \
|
||||
[concat $name " " $args]]
|
||||
} else {
|
||||
set errmsg [format "invalid subcommand \"%s\"" $args]
|
||||
}}}
|
||||
return -code $errcode $errmsg
|
||||
}
|
||||
|
||||
# Try flipping / and \ to find file if the filename does not
|
||||
# match the precise spelling
|
||||
proc find {filename} {
|
||||
|
||||
Reference in New Issue
Block a user