helper: command: rewrite command 'ocd_find' as COMMAND_HANDLER
[openocd.git] / src / helper / command.c
index 42cb8c71ea8cba79a1efd643edc1a02e3192dcd5..235bec8580001c591ba493156b949954a05baa91 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
  *   part of this file is taken from libcli (libcli.sourceforge.net)       *
  *   Copyright (C) David Parrish (david@dparrish.com)                      *
- *                                                                         *
- *   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/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-/* see Embedded-HOWTO.txt in Jim Tcl project hosted on BerliOS*/
-#define JIM_EMBEDDED
-
 /* @todo the inclusion of target.h here is a layering violation */
 #include <jtag/jtag.h>
 #include <target/target.h>
@@ -137,41 +123,6 @@ static void command_log_capture_finish(struct log_capture_state *state)
        free(state);
 }
 
-/*
- * FIXME: workaround for memory leak in jimtcl 0.80
- * Jim API Jim_CreateCommand() converts the command name in a Jim object and
- * does not free the object. Fixed for jimtcl 0.81 by e4416cf86f0b
- * Use the internal jimtcl API Jim_CreateCommandObj, not exported by jim.h,
- * and override the bugged API through preprocessor's macro.
- * This workaround works only when jimtcl is compiled as OpenOCD submodule.
- * It's broken on macOS, so it's currently restricted on Linux only.
- * If jimtcl is linked-in from a precompiled library, either static or dynamic,
- * the symbol Jim_CreateCommandObj is not exported and the build will use the
- * bugged API.
- * To be removed when OpenOCD will switch to jimtcl 0.81
- */
-#if JIM_VERSION == 80 && defined __linux__
-static int workaround_createcommand(Jim_Interp *interp, const char *cmdName,
-       Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc);
-int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj,
-       Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
-__attribute__((weak, alias("workaround_createcommand")));
-static int workaround_createcommand(Jim_Interp *interp, const char *cmdName,
-       Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
-{
-       if ((void *)Jim_CreateCommandObj == (void *)workaround_createcommand)
-               return Jim_CreateCommand(interp, cmdName, cmdProc, privData, delProc);
-
-       Jim_Obj *cmd_name = Jim_NewStringObj(interp, cmdName, -1);
-       Jim_IncrRefCount(cmd_name);
-       int retval = Jim_CreateCommandObj(interp, cmd_name, cmdProc, privData, delProc);
-       Jim_DecrRefCount(interp, cmd_name);
-       return retval;
-}
-#define Jim_CreateCommand workaround_createcommand
-#endif /* JIM_VERSION == 80 && defined __linux__*/
-/* FIXME: end of workaround for memory leak in jimtcl 0.80 */
-
 static int command_retval_set(Jim_Interp *interp, int retval)
 {
        int *return_retval = Jim_GetAssocData(interp, "retval");
@@ -589,8 +540,16 @@ static int run_command(struct command_context *context,
                if (retval != ERROR_OK)
                        LOG_DEBUG("Command '%s' failed with error code %d",
                                                words[0], retval);
-               /* Use the command output as the Tcl result */
-               Jim_SetResult(context->interp, cmd.output);
+               /*
+                * Use the command output as the Tcl result.
+                * Drop last '\n' to allow command output concatenation
+                * while keep using command_print() everywhere.
+                */
+               const char *output_txt = Jim_String(cmd.output);
+               int len = strlen(output_txt);
+               if (len && output_txt[len - 1] == '\n')
+                       --len;
+               Jim_SetResultString(context->interp, output_txt, len);
        }
        Jim_DecrRefCount(context->interp, cmd.output);
 
@@ -703,31 +662,33 @@ void command_done(struct command_context *cmd_ctx)
 }
 
 /* find full path to file */
-static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+COMMAND_HANDLER(handle_find)
 {
-       if (argc != 2)
-               return JIM_ERR;
-       const char *file = Jim_GetString(argv[1], NULL);
-       char *full_path = find_file(file);
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       char *full_path = find_file(CMD_ARGV[0]);
        if (!full_path)
-               return JIM_ERR;
-       Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+
+       command_print(CMD, "%s", full_path);
        free(full_path);
 
-       Jim_SetResult(interp, result);
-       return JIM_OK;
+       return ERROR_OK;
 }
 
-COMMAND_HANDLER(jim_echo)
+COMMAND_HANDLER(handle_echo)
 {
        if (CMD_ARGC == 2 && !strcmp(CMD_ARGV[0], "-n")) {
                LOG_USER_N("%s", CMD_ARGV[1]);
-               return JIM_OK;
+               return ERROR_OK;
        }
+
        if (CMD_ARGC != 1)
-               return JIM_ERR;
+               return ERROR_FAIL;
+
        LOG_USER("%s", CMD_ARGV[0]);
-       return JIM_OK;
+       return ERROR_OK;
 }
 
 /* Capture progress output and return as tcl return value. If the
@@ -746,14 +707,12 @@ static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
         * This is necessary in order to avoid accidentally getting a non-empty
         * string for tcl fn's.
         */
-       bool save_poll = jtag_poll_get_enabled();
-
-       jtag_poll_set_enabled(false);
+       bool save_poll_mask = jtag_poll_mask();
 
        const char *str = Jim_GetString(argv[1], NULL);
        int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__);
 
-       jtag_poll_set_enabled(save_poll);
+       jtag_poll_unmask(save_poll_mask);
 
        command_log_capture_finish(state);
 
@@ -954,8 +913,6 @@ static int exec_command(Jim_Interp *interp, struct command_context *cmd_ctx,
 
 static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
 {
-       script_debug(interp, argc, argv);
-
        /* check subcommands */
        if (argc > 1) {
                char *s = alloc_printf("%s %s", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL));
@@ -971,6 +928,8 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a
                Jim_DecrRefCount(interp, js);
        }
 
+       script_debug(interp, argc, argv);
+
        struct command *c = jim_to_command(interp);
        if (!c->jim_handler && !c->handler) {
                Jim_EvalObjPrefix(interp, Jim_NewStringObj(interp, "usage", -1), 1, argv);
@@ -982,7 +941,7 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a
        if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL)))
                return JIM_ERR;
 
-       target_call_timer_callbacks_now();
+       target_call_timer_callbacks();
 
        /*
         * Black magic of overridden current target:
@@ -1178,6 +1137,7 @@ COMMAND_HANDLER(handle_sleep_command)
                int64_t then = timeval_ms();
                while (timeval_ms() - then < (int64_t)duration) {
                        target_call_timer_callbacks_now();
+                       keep_alive();
                        usleep(1000);
                }
        } else
@@ -1205,7 +1165,7 @@ static const struct command_registration command_builtin_handlers[] = {
        {
                .name = "ocd_find",
                .mode = COMMAND_ANY,
-               .jim_handler = jim_find,
+               .handler = handle_find,
                .help = "find full path to file",
                .usage = "file",
        },
@@ -1219,7 +1179,7 @@ static const struct command_registration command_builtin_handlers[] = {
        },
        {
                .name = "echo",
-               .handler = jim_echo,
+               .handler = handle_echo,
                .mode = COMMAND_ANY,
                .help = "Logs a message at \"user\" priority. "
                        "Option \"-n\" suppresses trailing newline",

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)