Better handling of OpenOCD command invocation result/context.
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 24 Jul 2008 10:16:44 +0000 (10:16 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 24 Jul 2008 10:16:44 +0000 (10:16 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@866 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/helper/command.c
src/openocd.c

index 81eadd3fad41191565ac2d9211c6e2bffcea4d7c..ada745f2ae3dbeb8e6539533e809715a544e6c22 100644 (file)
@@ -55,12 +55,15 @@ static void tcl_output(void *privData, const char *file, int line, const char *f
        Jim_AppendString(interp, tclOutput, string, strlen(string));
 }
 
+extern command_context_t *global_cmd_ctx;
+
+
 static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
        /* the private data is stashed in the interp structure */
        command_t *c;
        command_context_t *context;
-       int *retval;
+       int retval;
        int i;
        int nwords;
        char **words;
@@ -92,26 +95,40 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 
        /* grab the command context from the associated data */
        context = Jim_GetAssocData(interp, "context");
-       retval = Jim_GetAssocData(interp, "retval"); 
-       if (context != NULL && retval != NULL)
+       if (context == NULL)
        {
-               /* capture log output and return it */
-               Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
-               log_add_callback(tcl_output, tclOutput);
-               
-               *retval = run_command(context, c, words, nwords);
-               
-               log_remove_callback(tcl_output, tclOutput);
-               
-               /* We dump output into this local variable */
-               Jim_SetVariableStr(interp, "ocd_output", tclOutput);
+               /* Tcl can invoke commands directly instead of via command_run_line(). This would
+                * happen when the Jim Tcl interpreter is provided by eCos.
+                */
+               context = global_cmd_ctx;
        }
+       
+       /* capture log output and return it */
+       Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
+       /* a garbage collect can happen, so we need a reference count to this object */
+       Jim_IncrRefCount(tclOutput);
+       
+       log_add_callback(tcl_output, tclOutput);
+       
+       retval = run_command(context, c, words, nwords);
+       
+       log_remove_callback(tcl_output, tclOutput);
+
+       /* We dump output into this local variable */
+       Jim_SetVariableStr(interp, "ocd_output", tclOutput);
+       Jim_DecrRefCount(interp, tclOutput);
 
        for (i = 0; i < nwords; i++)
                free(words[i]);
        free(words);
 
-       return (*retval==ERROR_OK)?JIM_OK:JIM_ERR;
+       int *return_retval = Jim_GetAssocData(interp, "retval");
+       if (return_retval != NULL)
+       {
+               *return_retval = retval;
+       }
+       
+       return (retval==ERROR_OK)?JIM_OK:JIM_ERR;
 }
 
 command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help)
@@ -393,21 +410,28 @@ int command_run_line(command_context_t *context, char *line)
         * results
         */
        /* run the line thru a script engine */
-       int retval;
+       int retval=ERROR_FAIL;
        int retcode;
-       Jim_DeleteAssocData(interp, "context"); /* remove existing */
+       /* Beware! This code needs to be reentrant. It is also possible
+        * for OpenOCD commands to be invoked directly from Tcl. This would
+        * happen when the Jim Tcl interpreter is provided by eCos for
+        * instance.
+        */
+       Jim_DeleteAssocData(interp, "context");
        retcode = Jim_SetAssocData(interp, "context", NULL, context);
-       if (retcode != JIM_OK)
-               return ERROR_FAIL;
-
-       /* associated the return value */
-       retval = ERROR_OK;
-       Jim_DeleteAssocData(interp, "retval"); /* remove existing */
-       retcode = Jim_SetAssocData(interp, "retval", NULL, &retval);
-       if (retcode != JIM_OK)
-               return ERROR_FAIL;
-
-       retcode = Jim_Eval(interp, line);       
+       if (retcode == JIM_OK)
+       {
+               /* associated the return value */
+               Jim_DeleteAssocData(interp, "retval");
+               retcode = Jim_SetAssocData(interp, "retval", NULL, &retval);
+               if (retcode == JIM_OK)
+               {
+                       retcode = Jim_Eval(interp, line);
+                       
+                       Jim_DeleteAssocData(interp, "retval");
+               }       
+               Jim_DeleteAssocData(interp, "context");
+       }
        if (retcode == JIM_ERR) {
                if (retval!=ERROR_COMMAND_CLOSE_CONNECTION)
                {
index 6babbb8420d837635181f7df7080546cb3816dd7..c694b6a8afe3d6d5cbaf56b9b25f0896723bd8a3 100644 (file)
@@ -131,11 +131,13 @@ int handle_init_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
        return ERROR_OK;
 }
 
+command_context_t *global_cmd_ctx;
+
 command_context_t *setup_command_handler(void)
 {
        command_context_t *cmd_ctx;
        
-       cmd_ctx = command_init();
+       global_cmd_ctx = cmd_ctx = command_init();
        
        register_command(cmd_ctx, NULL, "version", handle_version_command,
                                         COMMAND_EXEC, "show OpenOCD version");

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)