Esempio n. 1
0
static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
                      bool show_help, const char *match)
{
    if (!command_can_run(CMD_CTX, c))
        return ERROR_OK;

    char *cmd_name = command_name(c, ' ');
    if (NULL == cmd_name)
        return -ENOMEM;

    /* If the match string occurs anywhere, we print out
     * stuff for this command. */
    bool is_match = (strstr(cmd_name, match) != NULL) ||
                    ((c->usage != NULL) && (strstr(c->usage, match) != NULL)) ||
                    ((c->help != NULL) && (strstr(c->help, match) != NULL));

    if (is_match)
    {
        command_help_show_indent(n);
        LOG_USER_N("%s", cmd_name);
    }
    free(cmd_name);

    if (is_match)
    {
        if (c->usage) {
            LOG_USER_N(" ");
            command_help_show_wrap(c->usage, 0, n + 5);
        }
        else
            LOG_USER_N("\n");
    }

    if (is_match && show_help)
    {
        char *msg;

        /* Normal commands are runtime-only; highlight exceptions */
        if (c->mode != COMMAND_EXEC) {
            const char *stage_msg = "";

            switch (c->mode) {
            case COMMAND_CONFIG:
                stage_msg = " (configuration command)";
                break;
            case COMMAND_ANY:
                stage_msg = " (command valid any time)";
                break;
            default:
                stage_msg = " (?mode error?)";
                break;
            }
            msg = alloc_printf("%s%s", c->help ? : "", stage_msg);
        } else
Esempio n. 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, 0, 0);

			Jim_DeleteAssocData(interp, "retval");
		}
		Jim_DeleteAssocData(interp, "context");
	}
	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");
		}
		retval = ERROR_OK;
	} else if (retcode == JIM_EXIT) {
		/* ignore.
		 * exit(Jim_GetExitCode(interp)); */
	} else if (retcode == ERROR_COMMAND_CLOSE_CONNECTION) {
		return retcode;
	} else {
		Jim_MakeErrorMessage(interp);
		LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL));

		if (retval == ERROR_OK) {
			/* It wasn't a low level OpenOCD command that failed */
			return ERROR_FAIL;
		}
		return retval;
	}

	return retval;
}