Example #1
0
/*
 * Now we try to write big enough code to duplication our array in Jim's
 * list implementation. Later, we try to load a sample script in Tcl that
 * could print our list.
 */
int
main(int argc, char **argv)
{
	struct mystate *jconf;
	Jim_Interp *interp;
	Jim_Obj *errstr;
	Jim_Obj *n;
	Jim_Obj *v;
	int error;

	errstr = n = v = NULL;
	error = 0;

	/* This is the first function embedders should call. */
	Jim_InitEmbedded();

	/* Create an interpreter */
	interp = Jim_CreateInterp();
	assert(interp != NULL && "couldn't create interpreter");

	/*
	 * Then, we register base commands, so that we actually implement Tcl.
	 */
	Jim_RegisterCoreCommands(interp);

	/*
	 * Create unique state for our sample parser and register all
	 * Jim commands.
	 */
	jconf = mystate_new();
	Jim_CreateCommand(interp, "interface", InterfaceFunc, jconf, NULL);
	Jim_CreateCommand(interp, "ip", InterfaceIPFunc, jconf, NULL);

	/*
	 * Parse a script.
	 */
	error = Jim_EvalFile(interp, "./net.tcl");
	if (error == JIM_ERR) {
		fprintf(stderr, "Couldn't execute Jim's script. "
		    "Error occured\n");
		Jim_PrintErrorMessage(interp);
		Jim_FreeInterp(interp);
		exit(EXIT_FAILURE);
	}

	ShowInterfaces(jconf->head);
	
	mystate_destroy(jconf);

	if (n != NULL)
		Jim_FreeObj(interp, n);
	Jim_FreeInterp(interp);
	return (EXIT_SUCCESS);
}
Example #2
0
static int run_command(struct command_context *context,
                       struct command *c, const char *words[], unsigned num_words)
{
    if (!command_can_run(context, c))
    {
        /* Many commands may be run only before/after 'init' */
        const char *when;
        switch (c->mode) {
        case COMMAND_CONFIG:
            when = "before";
            break;
        case COMMAND_EXEC:
            when = "after";
            break;
        // handle the impossible with humor; it guarantees a bug report!
        default:
            when = "if Cthulhu is summoned by";
            break;
        }
        LOG_ERROR("The '%s' command must be used %s 'init'.",
                  c->name, when);
        return ERROR_FAIL;
    }

    struct command_invocation cmd = {
        .ctx = context,
        .current = c,
        .name = c->name,
        .argc = num_words - 1,
        .argv = words + 1,
    };
    int retval = c->handler(&cmd);
    if (retval == ERROR_COMMAND_SYNTAX_ERROR)
    {
        /* Print help for command */
        char *full_name = command_name(c, ' ');
        if (NULL != full_name) {
            command_run_linef(context, "usage %s", full_name);
            free(full_name);
        } else
            retval = -ENOMEM;
    }
    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
         */
        LOG_DEBUG("Command failed with error code %d", retval);
    }

    return retval;
}

int command_run_line(struct command_context *context, char *line)
{
    /* all the parent commands have been registered with the interpreter
     * so, can just evaluate the line as a script and check for
     * results
     */
    /* run the line thru a script engine */
    int retval = ERROR_FAIL;
    int retcode;
    /* 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_Interp *interp = context->interp;
    Jim_DeleteAssocData(interp, "context");
    retcode = Jim_SetAssocData(interp, "context", NULL, context);
    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_Named(interp, line, __THIS__FILE__, __LINE__);

            Jim_DeleteAssocData(interp, "retval");
        }
        Jim_DeleteAssocData(interp, "context");
    }
    if (retcode == JIM_ERR) {
        if (retval != ERROR_COMMAND_CLOSE_CONNECTION)
        {
            /* We do not print the connection closed error message */
            Jim_PrintErrorMessage(interp);
        }
        if (retval == ERROR_OK)
        {
            /* It wasn't a low level OpenOCD command that failed */
            return ERROR_FAIL;
        }
        return retval;
    } else if (retcode == JIM_EXIT) {
        /* ignore. */
        /* exit(Jim_GetExitCode(interp)); */
    } else {
        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("%s", "\n");
        }
        retval = ERROR_OK;
    }
    return retval;
}