diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am index 1f3d76b6e..8a2d472e9 100644 --- a/src/helper/Makefile.am +++ b/src/helper/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = $(all_includes) +INCLUDES = -I$(top_srcdir)/src $(all_includes) METASOURCES = AUTO AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@ noinst_LIBRARIES = libhelper.a diff --git a/src/helper/command.c b/src/helper/command.c index d2abb0c2a..e536cca51 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -38,6 +38,8 @@ #include #include +#include + int fast_and_dangerous = 0; void command_print_help_line(command_context_t* context, struct command_s *command, int indent); @@ -65,10 +67,9 @@ command_t* register_command(command_context_t *context, command_t *parent, char c->children = NULL; c->handler = handler; c->mode = mode; - if (help) - c->help = strdup(help); - else - c->help = NULL; + if (!help) + help=""; + c->help = strdup(help); c->next = NULL; /* place command in tree */ @@ -100,7 +101,22 @@ command_t* register_command(command_context_t *context, command_t *parent, char context->commands = c; } } + /* accumulate help text in Tcl helptext list. */ + Jim_Obj *helptext=Jim_GetGlobalVariableStr(interp, "ocd_helptext", JIM_ERRMSG); + Jim_Obj *cmd_entry=Jim_NewListObj(interp, NULL, 0); + Jim_Obj *cmd_list=Jim_NewListObj(interp, NULL, 0); + + /* maximum of two levels :-) */ + if (c->parent!=NULL) + { + Jim_ListAppendElement(interp, cmd_list, Jim_NewStringObj(interp, c->parent->name, -1)); + } + Jim_ListAppendElement(interp, cmd_list, Jim_NewStringObj(interp, c->name, -1)); + + Jim_ListAppendElement(interp, cmd_entry, cmd_list); + Jim_ListAppendElement(interp, cmd_entry, Jim_NewStringObj(interp, c->help, -1)); + Jim_ListAppendElement(interp, helptext, cmd_entry); return c; } diff --git a/src/helper/configuration.c b/src/helper/configuration.c index ff8b0272e..e9a13ead1 100644 --- a/src/helper/configuration.c +++ b/src/helper/configuration.c @@ -106,6 +106,7 @@ FILE *open_file_from_path (char *file, char *mode) int parse_config_file(struct command_context_s *cmd_ctx) { + int retval; char **cfg; if (!config_file_names) @@ -115,7 +116,9 @@ int parse_config_file(struct command_context_s *cmd_ctx) while (*cfg) { - command_run_line(cmd_ctx, *cfg); + retval=command_run_line(cmd_ctx, *cfg); + if (retval!=ERROR_OK) + return retval; cfg++; } diff --git a/src/openocd.c b/src/openocd.c index 1dfe5515c..8cac5530a 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -697,10 +697,22 @@ static char* openocd_jim_fgets(char *s, int size, void *cookie) void add_jim(const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help) { Jim_CreateCommand(interp, name, cmd, NULL, NULL); - /* FIX!!! add scheme to accumulate help! */ + /* FIX!!! it would be prettier to invoke add_help_text... + accumulate help text in Tcl helptext list. */ + Jim_Obj *helptext=Jim_GetGlobalVariableStr(interp, "ocd_helptext", JIM_ERRMSG); + Jim_Obj *cmd_entry=Jim_NewListObj(interp, NULL, 0); + + Jim_Obj *cmd_list=Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, cmd_list, Jim_NewStringObj(interp, name, -1)); + + Jim_ListAppendElement(interp, cmd_entry, cmd_list); + Jim_ListAppendElement(interp, cmd_entry, Jim_NewStringObj(interp, help, -1)); + Jim_ListAppendElement(interp, helptext, cmd_entry); } +extern const unsigned char filedata_startup[]; + void initJim(void) { Jim_CreateCommand(interp, "openocd", Jim_Command_openocd, NULL, NULL); @@ -719,13 +731,9 @@ void initJim(void) interp->cb_vfprintf = openocd_jim_vfprintf; interp->cb_fflush = openocd_jim_fflush; interp->cb_fgets = openocd_jim_fgets; -} - -extern const unsigned char filedata_startup[]; - -/* after command line parsing */ -void initJim2(void) -{ + + add_default_dirs(); + if (Jim_Eval(interp, filedata_startup)==JIM_ERR) { LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)"); @@ -735,6 +743,7 @@ void initJim2(void) } + int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { FILE *script_file; @@ -752,7 +761,7 @@ command_context_t *setup_command_handler(void) command_context_t *cmd_ctx; cmd_ctx = command_init(); - + register_command(cmd_ctx, NULL, "version", handle_version_command, COMMAND_EXEC, "show OpenOCD version"); register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG, @@ -825,10 +834,7 @@ int openocd_main(int argc, char *argv[]) active_cmd_ctx=cfg_cmd_ctx; - add_default_dirs(); - initJim2(); - if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK) return EXIT_FAILURE; diff --git a/src/startup.tcl b/src/startup.tcl index acf93be4c..029c4e4b2 100644 --- a/src/startup.tcl +++ b/src/startup.tcl @@ -5,6 +5,20 @@ # Embedded into OpenOCD executable # + +# Help text list. A list of command + help text pairs. +# +# Commands can be more than one word and they are stored +# as "flash banks" "help text x x x" + +global ocd_helptext +set ocd_helptext {} + +proc add_help_text {cmd cmd_help} { + global ocd_helptext + lappend ocd_helptext [list $cmd $cmd_help] +} + # Production command # FIX!!! need to figure out how to feed back relevant output # from e.g. "flash banks" command... @@ -48,6 +62,20 @@ proc flash args { openocd_throw "flash $args" } +#Print help text for a command +proc tcl_help {args} { + global ocd_helptext + set cmd $args + foreach a [lsort $ocd_helptext] { + if {[string length $cmd]==0||[string first $cmd $a]!=-1} { + puts [format "%18s - %s" [lindex $a 0] [lindex $a 1]] + } + } +} + +add_help_text tcl_help "Tcl implementation of help command" + + # If a fn is unknown to Tcl, we try to execute it as an OpenOCD command proc unknown {args} { if {[string length $args]>0} {