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; }
int BuiltInSubProc::call(struct Jim_Interp * interp, int argc, Jim_Obj * const * argv) { bool help = false; const char * cmdName = Jim_String(argv[0]); if (argc < 2) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdName, " command ...\"\n", NULL); Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdName, " -help ?command?\" for help about the command", NULL); return JIM_ERR; } Jim_Obj * cmd = argv[1]; // Check for the help command if (Jim_CompareStringImmediate(interp, cmd, "-help")) { if (argc == 2) { showCommandUsage(interp, argc, argv, subCommands_); return JIM_OK; } help = true; cmd = argv[2]; } // Check for special builtin '-commands' command first if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { /* Build the result here */ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); addSubCommands(interp, subCommands_, " "); return JIM_OK; } for (int i = 0; i < subCommands_.size() / 3; ++i) { if (Jim_CompareStringImmediate(interp, cmd, subCommands_[i * 3])) { if (help) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", cmdName, " ", subCommands_[i * 3], NULL); if (strlen(subCommands_[i * 3 + 1]) > 0) Jim_AppendStrings(interp, Jim_GetResult(interp), " ", subCommands_[i * 3 + 1], NULL); Jim_AppendStrings(interp, Jim_GetResult(interp), "\""); if (strlen(subCommands_[i * 3 + 2]) > 0) Jim_AppendStrings(interp, Jim_GetResult(interp), " ", subCommands_[i * 3 + 2], NULL); return JIM_OK; } else { return proc_(interp, i, argc - 2, argv + 2); } } } Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), cmdName, ", unknown command \"", Jim_String(cmd), "\" should be one of: ", NULL); addSubCommands(interp, subCommands_, ", "); return JIM_ERR; }
std::string result() { return std::string(Jim_String(Jim_GetResult(interpreter_))); }
static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *const *argv) { struct sigaction sa; int i; if (argc == 0) { Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); for (i = 1; i < MAX_SIGNALS; i++) { if (siginfo[i].status == action) { /* Add signal name to the list */ Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, Jim_SignalId(i), -1)); } } return JIM_OK; } /* Catch all the signals we care about */ if (action != SIGNAL_ACTION_DEFAULT) { memset(&sa, 0, sizeof(sa)); if (action == SIGNAL_ACTION_HANDLE) { sa.sa_handler = signal_handler; } else { sa.sa_handler = signal_ignorer; } } /* Iterate through the provided signals */ for (i = 0; i < argc; i++) { int sig = find_signal_by_name(interp, Jim_String(argv[i])); if (sig < 0) { return JIM_ERR; } if (action != siginfo[sig].status) { /* Need to change the action for this signal */ switch (action) { case SIGNAL_ACTION_HANDLE: case SIGNAL_ACTION_IGNORE: if (siginfo[sig].status == SIGNAL_ACTION_DEFAULT) { if (!sa_old) { /* Allocate the structure the first time through */ sa_old = Jim_Alloc(sizeof(*sa_old) * MAX_SIGNALS); } sigaction(sig, &sa, &sa_old[sig]); } else { sigaction(sig, &sa, 0); } break; case SIGNAL_ACTION_DEFAULT: /* Restore old handler */ if (sa_old) { sigaction(sig, &sa_old[sig], 0); } } siginfo[sig].status = action; } } return JIM_OK; }
static void showCommandUsage(struct Jim_Interp * interp, int argc, Jim_Obj * const * argv, std::vector<const char *> const& subCommands) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]), " command ... \", where command is one of: ", NULL); addSubCommands(interp, subCommands, ", "); }
static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *nsObj; Jim_Obj *objPtr; int option; static const char * const options[] = { "eval", "current", "canonical", "qualifiers", "parent", "tail", "delete", "origin", "code", "inscope", "import", "export", "which", "upvar", NULL }; enum { OPT_EVAL, OPT_CURRENT, OPT_CANONICAL, OPT_QUALIFIERS, OPT_PARENT, OPT_TAIL, OPT_DELETE, OPT_ORIGIN, OPT_CODE, OPT_INSCOPE, OPT_IMPORT, OPT_EXPORT, OPT_WHICH, OPT_UPVAR, }; if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { return JIM_ERR; } switch (option) { case OPT_EVAL: if (argc < 4) { Jim_WrongNumArgs(interp, 2, argv, "name arg ?arg...?"); return JIM_ERR; } if (argc == 4) { objPtr = argv[3]; } else { objPtr = Jim_ConcatObj(interp, argc - 3, argv + 3); } nsObj = JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]); return Jim_EvalNamespace(interp, objPtr, nsObj); case OPT_CURRENT: if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } Jim_SetResult(interp, JimNamespaceCurrent(interp)); return JIM_OK; case OPT_CANONICAL: if (argc > 4) { Jim_WrongNumArgs(interp, 2, argv, "?current? ?name?"); return JIM_ERR; } if (argc == 2) { Jim_SetResult(interp, interp->framePtr->nsObj); } else if (argc == 3) { Jim_SetResult(interp, JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2])); } else { Jim_SetResult(interp, JimCanonicalNamespace(interp, argv[2], argv[3])); } return JIM_OK; case OPT_QUALIFIERS: if (argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "string"); return JIM_ERR; } Jim_SetResult(interp, Jim_NamespaceQualifiers(interp, argv[2])); return JIM_OK; case OPT_IMPORT: case OPT_EXPORT: return JIM_OK; case OPT_TAIL: if (argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "string"); return JIM_ERR; } Jim_SetResult(interp, Jim_NamespaceTail(interp, argv[2])); return JIM_OK; case OPT_PARENT: if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?name?"); return JIM_ERR; } else { const char *name; if (argc == 3) { objPtr = argv[2]; } else { objPtr = interp->framePtr->nsObj; } if (Jim_Length(objPtr) == 0 || Jim_CompareStringImmediate(interp, objPtr, "::")) { return JIM_OK; } objPtr = Jim_NamespaceQualifiers(interp, objPtr); name = Jim_String(objPtr); if (name[0] != ':' || name[1] != ':') { /* Make it fully scoped */ Jim_SetResultString(interp, "::", 2); Jim_AppendObj(interp, Jim_GetResult(interp), objPtr); Jim_IncrRefCount(objPtr); Jim_DecrRefCount(interp, objPtr); } else { Jim_SetResult(interp, objPtr); } } return JIM_OK; } /* Implemented as a Tcl helper proc. * Note that calling a proc will change the current namespace, * so helper procs must call [uplevel namespace canon] to get the callers * namespace. */ return Jim_EvalEnsemble(interp, "namespace", options[option], argc - 2, argv + 2); }
/* Calls to [aio.file] create commands that are implemented by this * C command. */ static int JimAioHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); int option; const char *options[] = { "close", "seek", "tell", "gets", "read", "puts", "flush", "eof", NULL }; enum {OPT_CLOSE, OPT_SEEK, OPT_TELL, OPT_GETS, OPT_READ, OPT_PUTS, OPT_FLUSH, OPT_EOF }; if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], options, &option, "AIO method", JIM_ERRMSG) != JIM_OK) return JIM_ERR; /* CLOSE */ if (option == OPT_CLOSE) { if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL)); return JIM_OK; } else if (option == OPT_SEEK) { /* SEEK */ int orig = SEEK_SET; long offset; if (argc != 3 && argc != 4) { Jim_WrongNumArgs(interp, 2, argv, "offset ?origin?"); return JIM_ERR; } if (argc == 4) { if (Jim_CompareStringImmediate(interp, argv[3], "start")) orig = SEEK_SET; else if (Jim_CompareStringImmediate(interp, argv[3], "current")) orig = SEEK_CUR; else if (Jim_CompareStringImmediate(interp, argv[3], "end")) orig = SEEK_END; else { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "bad origin \"", Jim_GetString(argv[3], NULL), "\" must be: start, current, or end", NULL); return JIM_ERR; } } if (Jim_GetLong(interp, argv[2], &offset) != JIM_OK) return JIM_ERR; if (fseek(af->fp, offset, orig) == -1) { JimAioSetError(interp); return JIM_ERR; } return JIM_OK; } else if (option == OPT_TELL) { /* TELL */ long position; if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } position = ftell(af->fp); Jim_SetResult(interp, Jim_NewIntObj(interp, position)); return JIM_OK; } else if (option == OPT_GETS) { /* GETS */ char buf[AIO_BUF_LEN]; Jim_Obj *objPtr; if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?varName?"); return JIM_ERR; } objPtr = Jim_NewStringObj(interp, NULL, 0); while (1) { int more = 0; buf[AIO_BUF_LEN-1] = '_'; if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL) break; if (buf[AIO_BUF_LEN-1] == '\0' && buf[AIO_BUF_LEN] == '\n') more = 1; if (more) { Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN-1); } else { /* strip "\n" */ Jim_AppendString(interp, objPtr, buf, strlen(buf)-1); } if (!more) break; } if (ferror(af->fp)) { /* I/O error */ Jim_IncrRefCount(objPtr); Jim_DecrRefCount(interp, objPtr); JimAioSetError(interp); return JIM_ERR; } /* On EOF returns -1 if varName was specified, or the empty string. */ if (feof(af->fp) && Jim_Length(objPtr) == 0) { Jim_IncrRefCount(objPtr); Jim_DecrRefCount(interp, objPtr); if (argc == 3) Jim_SetResult(interp, Jim_NewIntObj(interp, -1)); return JIM_OK; } if (argc == 3) { int totLen; Jim_GetString(objPtr, &totLen); if (Jim_SetVariable(interp, argv[2], objPtr) != JIM_OK) { Jim_IncrRefCount(objPtr); Jim_DecrRefCount(interp, objPtr); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, totLen)); } else { Jim_SetResult(interp, objPtr); } return JIM_OK; } else if (option == OPT_READ) { /* READ */ char buf[AIO_BUF_LEN]; Jim_Obj *objPtr; int nonewline = 0; int neededLen = -1; /* -1 is "read as much as possible" */ if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? ?len?"); return JIM_ERR; } if (argc == 3 && Jim_CompareStringImmediate(interp, argv[2], "-nonewline")) { nonewline = 1; argv++; argc--; } if (argc == 3) { jim_wide wideValue; if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK) return JIM_ERR; if (wideValue < 0) { Jim_SetResultString(interp, "invalid parameter: negative len", -1); return JIM_ERR; } neededLen = (int) wideValue; } objPtr = Jim_NewStringObj(interp, NULL, 0); while (neededLen != 0) { int retval; int readlen; if (neededLen == -1) { readlen = AIO_BUF_LEN; } else { readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen); } retval = fread(buf, 1, readlen, af->fp); if (retval > 0) { Jim_AppendString(interp, objPtr, buf, retval); if (neededLen != -1) { neededLen -= retval; } } if (retval != readlen) break; } /* Check for error conditions */ if (ferror(af->fp)) { /* I/O error */ Jim_FreeNewObj(interp, objPtr); JimAioSetError(interp); return JIM_ERR; } if (nonewline) { int len; const char *s = Jim_GetString(objPtr, &len); if (len > 0 && s[len-1] == '\n') { objPtr->length--; objPtr->bytes[objPtr->length] = '\0'; } } Jim_SetResult(interp, objPtr); return JIM_OK; } else if (option == OPT_PUTS) { /* PUTS */ int wlen; const char *wdata; if (argc != 3 && (argc != 4 || !Jim_CompareStringImmediate( interp, argv[2], "-nonewline"))) { Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? string"); return JIM_ERR; } wdata = Jim_GetString(argv[2+(argc==4)], &wlen); if (fwrite(wdata, 1, wlen, af->fp) != (unsigned)wlen || (argc == 3 && fwrite("\n", 1, 1, af->fp) != 1)) { JimAioSetError(interp); return JIM_ERR; } return JIM_OK; } else if (option == OPT_FLUSH) { /* FLUSH */ if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } if (fflush(af->fp) == EOF) { JimAioSetError(interp); return JIM_ERR; } return JIM_OK; } else if (option == OPT_EOF) { /* EOF */ if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, feof(af->fp))); return JIM_OK; } return JIM_OK; }
/* [tcl::prefix] */ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objPtr; Jim_Obj *stringObj; int option; static const char * const options[] = { "match", "all", "longest", NULL }; enum { OPT_MATCH, OPT_ALL, OPT_LONGEST }; if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) return Jim_CheckShowCommands(interp, argv[1], options); switch (option) { case OPT_MATCH:{ int i; int ret; int tablesize; const char **table; Jim_Obj *tableObj; Jim_Obj *errorObj = NULL; const char *message = "option"; static const char * const matchoptions[] = { "-error", "-exact", "-message", NULL }; enum { OPT_MATCH_ERROR, OPT_MATCH_EXACT, OPT_MATCH_MESSAGE }; int flags = JIM_ERRMSG | JIM_ENUM_ABBREV; if (argc < 4) { Jim_WrongNumArgs(interp, 2, argv, "?options? table string"); return JIM_ERR; } tableObj = argv[argc - 2]; stringObj = argv[argc - 1]; argc -= 2; for (i = 2; i < argc; i++) { int matchoption; if (Jim_GetEnum(interp, argv[i], matchoptions, &matchoption, "option", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) return JIM_ERR; switch (matchoption) { case OPT_MATCH_EXACT: flags &= ~JIM_ENUM_ABBREV; break; case OPT_MATCH_ERROR: if (++i == argc) { Jim_SetResultString(interp, "missing error options", -1); return JIM_ERR; } errorObj = argv[i]; if (Jim_Length(errorObj) % 2) { Jim_SetResultString(interp, "error options must have an even number of elements", -1); return JIM_ERR; } break; case OPT_MATCH_MESSAGE: if (++i == argc) { Jim_SetResultString(interp, "missing message", -1); return JIM_ERR; } message = Jim_String(argv[i]); break; } } /* Do the match */ tablesize = Jim_ListLength(interp, tableObj); table = Jim_Alloc((tablesize + 1) * sizeof(*table)); for (i = 0; i < tablesize; i++) { Jim_ListIndex(interp, tableObj, i, &objPtr, JIM_NONE); table[i] = Jim_String(objPtr); } table[i] = NULL; ret = Jim_GetEnum(interp, stringObj, table, &i, message, flags); Jim_Free(table); if (ret == JIM_OK) { Jim_ListIndex(interp, tableObj, i, &objPtr, JIM_NONE); Jim_SetResult(interp, objPtr); return JIM_OK; } if (tablesize == 0) { Jim_SetResultFormatted(interp, "bad %s \"%#s\": no valid options", message, stringObj); return JIM_ERR; } if (errorObj) { if (Jim_Length(errorObj) == 0) { Jim_SetEmptyResult(interp); return JIM_OK; } /* Do this the easy way. Build a list to evaluate */ objPtr = Jim_NewStringObj(interp, "return -level 0 -code error", -1); Jim_ListAppendList(interp, objPtr, errorObj); Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); return Jim_EvalObjList(interp, objPtr); } return JIM_ERR; } case OPT_ALL: if (argc != 4) { Jim_WrongNumArgs(interp, 2, argv, "table string"); return JIM_ERR; } else { int i; int listlen = Jim_ListLength(interp, argv[2]); objPtr = Jim_NewListObj(interp, NULL, 0); for (i = 0; i < listlen; i++) { Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i); if (Jim_StringCompareLenObj(interp, argv[3], valObj, 0) == 0) { Jim_ListAppendElement(interp, objPtr, valObj); } } Jim_SetResult(interp, objPtr); return JIM_OK; } case OPT_LONGEST: if (argc != 4) { Jim_WrongNumArgs(interp, 2, argv, "table string"); return JIM_ERR; } else if (Jim_ListLength(interp, argv[2])) { const char *longeststr = NULL; int longestlen = 0; int i; int listlen = Jim_ListLength(interp, argv[2]); stringObj = argv[3]; for (i = 0; i < listlen; i++) { Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i); if (Jim_StringCompareLenObj(interp, stringObj, valObj, 0)) { /* Does not begin with 'string' */ continue; } if (longeststr == NULL) { longestlen = Jim_Utf8Length(interp, valObj); longeststr = Jim_String(valObj); } else { longestlen = JimStringCommonLength(longeststr, longestlen, Jim_String(valObj), Jim_Utf8Length(interp, valObj)); } } if (longeststr) { Jim_SetResultString(interp, longeststr, longestlen); } return JIM_OK; } } return JIM_ERR; /* Cannot ever get here */ }
int rtos_create(Jim_GetOptInfo *goi, struct target * target) { int x; char *cp; if (! goi->isconfigure) { if (goi->argc != 0) { if (goi->argc != 0) { Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS"); return JIM_ERR; } Jim_SetResultString(goi->interp, target_type_name(target), -1); } } if (target->rtos) { free((void *)(target->rtos)); } // e = Jim_GetOpt_String(goi, &cp, NULL); // target->rtos = strdup(cp); Jim_GetOpt_String(goi, &cp, NULL); /* now does target type exist */ if ( 0 == strcmp( cp, "auto") ) { // auto detection of RTOS target->rtos_auto_detect = true; x = 0; } else { for (x = 0 ; rtos_types[x] ; x++) { if (0 == strcmp(cp, rtos_types[x]->name)) { /* found */ break; } } if (rtos_types[x] == NULL) { Jim_SetResultFormatted(goi->interp, "Unknown rtos type %s, try one of ", cp); for (x = 0 ; rtos_types[x] ; x++) { if (rtos_types[x + 1]) { Jim_AppendStrings(goi->interp, Jim_GetResult(goi->interp), rtos_types[x]->name, ", ", NULL); } else { Jim_AppendStrings(goi->interp, Jim_GetResult(goi->interp), " or ", rtos_types[x]->name,NULL); } } return JIM_ERR; } } /* Create it */ target->rtos = calloc(1,sizeof(struct rtos)); target->rtos->type = rtos_types[x]; target->rtos->current_thread = 0; target->rtos->symbols = NULL; target->rtos->target = target; if ( 0 != strcmp( cp, "auto") ) { target->rtos->type->create( target ); } return JIM_OK; }
const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, Jim_Obj *const *argv) { const jim_subcmd_type *ct; const jim_subcmd_type *partial = 0; int cmdlen; Jim_Obj *cmd; const char *cmdstr; const char *cmdname; int help = 0; cmdname = Jim_String(argv[0]); if (argc < 2) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname, " command ...\"\n", NULL); Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL); return 0; } cmd = argv[1]; /* Check for the help command */ if (Jim_CompareStringImmediate(interp, cmd, "-help")) { if (argc == 2) { /* Usage for the command, not the subcommand */ show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } help = 1; /* Skip the 'help' command */ cmd = argv[2]; } /* Check for special builtin '-commands' command first */ if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { /* Build the result here */ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); add_commands(interp, command_table, " "); return &dummy_subcmd; } cmdstr = Jim_GetString(cmd, &cmdlen); for (ct = command_table; ct->cmd; ct++) { if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { /* Found an exact match */ break; } if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { if (partial) { /* Ambiguous */ if (help) { /* Just show the top level help here */ show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]); return 0; } partial = ct; } continue; } /* If we had an unambiguous partial match */ if (partial && !ct->cmd) { ct = partial; } if (!ct->cmd) { /* No matching command */ if (help) { /* Just show the top level help here */ show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]); return 0; } if (help) { Jim_SetResultString(interp, "Usage: ", -1); /* subcmd */ add_cmd_usage(interp, ct, argv[0]); return &dummy_subcmd; } /* Check the number of args */ if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { Jim_SetResultString(interp, "wrong # args: should be \"", -1); /* subcmd */ add_cmd_usage(interp, ct, argv[0]); Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); return 0; } /* Good command */ return ct; }
static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_table, Jim_Obj *subcmd) { Jim_SetResultString(interp, "wrong # args: should be \"", -1); add_cmd_usage(interp, command_table, subcmd); Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); }
const char* es_tcl_last_result(es_Interp *interp) { return Jim_GetString(Jim_GetResult(interp), NULL); }
static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { const char *hdlfmt = "aio.unknown%ld"; const char *socktypes[] = { "unix", "unix.server", "dgram", "dgram.server", "stream", "stream.server", "pipe", NULL }; enum { SOCK_UNIX, SOCK_UNIX_SERVER, SOCK_DGRAM_CLIENT, SOCK_DGRAM_SERVER, SOCK_STREAM_CLIENT, SOCK_STREAM_SERVER, SOCK_STREAM_PIPE, SOCK_DGRAM6_CLIENT, SOCK_DGRAM6_SERVER, SOCK_STREAM6_CLIENT, SOCK_STREAM6_SERVER, }; int socktype; int sock; const char *hostportarg = NULL; int res; int on = 1; const char *mode = "r+"; int family = PF_INET; Jim_Obj *argv0 = argv[0]; int ipv6 = 0; if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-ipv6")) { if (!IPV6) { Jim_SetResultString(interp, "ipv6 not supported", -1); return JIM_ERR; } ipv6 = 1; family = PF_INET6; } argc -= ipv6; argv += ipv6; if (argc < 2) { wrongargs: Jim_WrongNumArgs(interp, 1, &argv0, "?-ipv6? type ?address?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type", JIM_ERRMSG) != JIM_OK) return JIM_ERR; Jim_SetEmptyResult(interp); hdlfmt = "aio.sock%ld"; if (argc > 2) { hostportarg = Jim_String(argv[2]); } switch (socktype) { case SOCK_DGRAM_CLIENT: if (argc == 2) { /* No address, so an unconnected dgram socket */ sock = socket(family, SOCK_DGRAM, 0); if (sock < 0) { JimAioSetError(interp, NULL); return JIM_ERR; } break; } /* fall through */ case SOCK_STREAM_CLIENT: { union sockaddr_any sa; int salen; if (argc != 3) { goto wrongargs; } if (ipv6) { if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) { return JIM_ERR; } } else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) { return JIM_ERR; } sock = socket(family, (socktype == SOCK_DGRAM_CLIENT) ? SOCK_DGRAM : SOCK_STREAM, 0); if (sock < 0) { JimAioSetError(interp, NULL); return JIM_ERR; } res = connect(sock, &sa.sa, salen); if (res) { JimAioSetError(interp, argv[2]); close(sock); return JIM_ERR; } } break; case SOCK_STREAM_SERVER: case SOCK_DGRAM_SERVER: { union sockaddr_any sa; int salen; if (argc != 3) { goto wrongargs; } if (ipv6) { if (JimParseIPv6Address(interp, hostportarg, &sa, &salen) != JIM_OK) { return JIM_ERR; } } else if (JimParseIpAddress(interp, hostportarg, &sa, &salen) != JIM_OK) { return JIM_ERR; } sock = socket(family, (socktype == SOCK_DGRAM_SERVER) ? SOCK_DGRAM : SOCK_STREAM, 0); if (sock < 0) { JimAioSetError(interp, NULL); return JIM_ERR; } /* Enable address reuse */ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); res = bind(sock, &sa.sa, salen); if (res) { JimAioSetError(interp, argv[2]); close(sock); return JIM_ERR; } if (socktype == SOCK_STREAM_SERVER) { res = listen(sock, 5); if (res) { JimAioSetError(interp, NULL); close(sock); return JIM_ERR; } } hdlfmt = "aio.socksrv%ld"; } break; #ifdef HAVE_SYS_UN_H case SOCK_UNIX: { struct sockaddr_un sa; socklen_t len; if (argc != 3 || ipv6) { goto wrongargs; } if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) { JimAioSetError(interp, argv[2]); return JIM_ERR; } family = PF_UNIX; sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { JimAioSetError(interp, NULL); return JIM_ERR; } len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family); res = connect(sock, (struct sockaddr *)&sa, len); if (res) { JimAioSetError(interp, argv[2]); close(sock); return JIM_ERR; } hdlfmt = "aio.sockunix%ld"; break; } case SOCK_UNIX_SERVER: { struct sockaddr_un sa; socklen_t len; if (argc != 3 || ipv6) { goto wrongargs; } if (JimParseDomainAddress(interp, hostportarg, &sa) != JIM_OK) { JimAioSetError(interp, argv[2]); return JIM_ERR; } family = PF_UNIX; sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { JimAioSetError(interp, NULL); return JIM_ERR; } len = strlen(sa.sun_path) + 1 + sizeof(sa.sun_family); res = bind(sock, (struct sockaddr *)&sa, len); if (res) { JimAioSetError(interp, argv[2]); close(sock); return JIM_ERR; } res = listen(sock, 5); if (res) { JimAioSetError(interp, NULL); close(sock); return JIM_ERR; } hdlfmt = "aio.sockunixsrv%ld"; break; } #endif #ifdef HAVE_PIPE case SOCK_STREAM_PIPE: { int p[2]; if (argc != 2 || ipv6) { goto wrongargs; } if (pipe(p) < 0) { JimAioSetError(interp, NULL); return JIM_ERR; } if (JimMakeChannel(interp, NULL, p[0], argv[1], "aio.pipe%ld", 0, "r") == JIM_OK) { Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); if (JimMakeChannel(interp, NULL, p[1], argv[1], "aio.pipe%ld", 0, "w") == JIM_OK) { Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); Jim_SetResult(interp, objPtr); return JIM_OK; } } /* Can only be here if fdopen() failed */ close(p[0]); close(p[1]); JimAioSetError(interp, NULL); return JIM_ERR; } break; #endif default: Jim_SetResultString(interp, "Unsupported socket type", -1); return JIM_ERR; } return JimMakeChannel(interp, NULL, sock, argv[1], hdlfmt, family, mode); }
/* * The main [exec] command */ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { fdtype outputId; /* File id for output pipe. -1 * means command overrode. */ fdtype errorId; /* File id for temporary file * containing error output. */ pidtype *pidPtr; int numPids, result; /* * See if the command is to be run in background; if so, create * the command, detach it, and return. */ if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) { Jim_Obj *listObj; int i; argc--; numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); if (numPids < 0) { return JIM_ERR; } /* The return value is a list of the pids */ listObj = Jim_NewListObj(interp, NULL, 0); for (i = 0; i < numPids; i++) { Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i])); } Jim_SetResult(interp, listObj); JimDetachPids(interp, numPids, pidPtr); Jim_Free(pidPtr); return JIM_OK; } /* * Create the command's pipeline. */ numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, &outputId, &errorId); if (numPids < 0) { return JIM_ERR; } /* * Read the child's output (if any) and put it into the result. */ Jim_SetResultString(interp, "", 0); result = JIM_OK; if (outputId != JIM_BAD_FD) { result = JimAppendStreamToString(interp, outputId, Jim_GetResult(interp)); if (result < 0) { Jim_SetResultErrno(interp, "error reading from output pipe"); } } if (JimCleanupChildren(interp, numPids, pidPtr, errorId) != JIM_OK) { result = JIM_ERR; } return result; }