static int Win32_GetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) { JIM_NOTUSED(objc); JIM_NOTUSED(objv); Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)GetActiveWindow())); return JIM_OK; }
static int Win32_GetTickCount(Jim_Interp *interp, int objc, Jim_Obj *const *objv) { JIM_NOTUSED(objc); JIM_NOTUSED(objv); Jim_SetResult(interp, Jim_NewIntObj(interp, GetTickCount())); return JIM_OK; }
static int JimZlibCheckBufSize(Jim_Interp *interp, jim_wide bufsiz) { if ((bufsiz <= 0) || (bufsiz > INT_MAX)) { Jim_SetResultString(interp, "buffer size must be 0 to ", -1); Jim_AppendObj(interp, Jim_GetResult(interp), Jim_NewIntObj(interp, INT_MAX)); return JIM_ERR; } return JIM_OK; }
/* Poor man's implementation of exec with system() * The system() call *may* do command line redirection, etc. * The standard output is not available. * Can't redirect filehandles. */ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp); int i, j; int rc; /* Create a quoted command line */ for (i = 1; i < argc; i++) { int len; const char *arg = Jim_GetString(argv[i], &len); if (i > 1) { Jim_AppendString(interp, cmdlineObj, " ", 1); } if (strpbrk(arg, "\\\" ") == NULL) { /* No quoting required */ Jim_AppendString(interp, cmdlineObj, arg, len); continue; } Jim_AppendString(interp, cmdlineObj, "\"", 1); for (j = 0; j < len; j++) { if (arg[j] == '\\' || arg[j] == '"') { Jim_AppendString(interp, cmdlineObj, "\\", 1); } Jim_AppendString(interp, cmdlineObj, &arg[j], 1); } Jim_AppendString(interp, cmdlineObj, "\"", 1); } rc = system(Jim_String(cmdlineObj)); Jim_FreeNewObj(interp, cmdlineObj); if (rc) { Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, 0)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, rc)); Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); return JIM_ERR; } return JIM_OK; }
/* * Our function. */ static int CountCharsFunc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc != 2) { Jim_WrongNumArgs(interp, 1, argv, "string"); return (JIM_ERR); } Jim_SetResult(interp, Jim_NewIntObj(interp, Jim_Length(argv[1]))); return (JIM_OK); }
static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objv[8]; if (argc != 1) { Jim_WrongNumArgs(interp, 1, argv, ""); return JIM_ERR; } objv[0] = Jim_NewStringObj(interp, "uid", -1); objv[1] = Jim_NewIntObj(interp, getuid()); objv[2] = Jim_NewStringObj(interp, "euid", -1); objv[3] = Jim_NewIntObj(interp, geteuid()); objv[4] = Jim_NewStringObj(interp, "gid", -1); objv[5] = Jim_NewIntObj(interp, getgid()); objv[6] = Jim_NewStringObj(interp, "egid", -1); objv[7] = Jim_NewIntObj(interp, getegid()); Jim_SetResult(interp, Jim_NewListObj(interp, objv, 8)); return JIM_OK; }
static int Win32_GetCursor(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) { HCURSOR hCursor; JIM_NOTUSED(objc); JIM_NOTUSED(objv); hCursor = GetCursor(); Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)hCursor)); return JIM_OK; }
static LRESULT CALLBACK JimWin32WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int objc = 0, r; Jim_Obj *objv[16]; Jim_Interp *interp = (Jim_Interp *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (interp) { objv[objc++] = Jim_NewStringObj(interp, "WndProc", -1); switch (uMsg) { case WM_CREATE: //Jim_EvalObjVector(interp, objc, objv); break; case WM_COMMAND: objv[objc++] = Jim_NewIntObj(interp, HIWORD(wParam)); objv[objc++] = Jim_NewIntObj(interp, LOWORD(wParam)); objv[objc++] = Jim_NewIntObj(interp, lParam); r = Jim_EvalObjVector(interp, objc, objv); if (r == JIM_BREAK) return 0L; break; } } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { pid_t pid; JIM_NOTUSED(argv); if (argc != 1) { Jim_WrongNumArgs(interp, 1, argv, ""); return JIM_ERR; } if ((pid = fork()) == -1) { Jim_SetResultString(interp, strerror(errno), -1); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, (jim_wide)pid)); return JIM_OK; }
static int Win32_LoadLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv) { HMODULE hLib = NULL; if (objc != 2) { Jim_WrongNumArgs(interp, 1, objv, "path"); return JIM_ERR; } hLib = LoadLibraryA(Jim_String(objv[1])); if (hLib == NULL) { Jim_SetResult(interp, Win32ErrorObj(interp, "LoadLibrary", GetLastError())); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hLib)); return JIM_OK; }
static int Win32_SetCursor(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) { HCURSOR hCursor; int r = JIM_OK; if (objc != 2) { Jim_WrongNumArgs(interp, 1, objv, "hCursor"); return JIM_ERR; } r = Jim_GetLong(interp, objv[1], (long *)&hCursor); if (r == JIM_OK) { hCursor = SetCursor(hCursor); Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)hCursor)); } return r; }
static int zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { if (argc != 1) { Jim_WrongNumArgs(interp, 1, argv, "powerstatus"); return JIM_ERR; } cyg_uint32 status; ZY1000_PEEK(ZY1000_JTAG_BASE+0x10, status); Jim_SetResult(interp, Jim_NewIntObj(interp, (status&0x80)!=0)); return JIM_OK; }
static int ioutil_Jim_Command_peek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc != 2) { Jim_WrongNumArgs(interp, 1, argv, "peek ?address?"); return JIM_ERR; } long address; if (Jim_GetLong(interp, argv[1], &address) != JIM_OK) return JIM_ERR; int value = *((volatile int *) address); Jim_SetResult(interp, Jim_NewIntObj(interp, value)); return JIM_OK; }
static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap) { /* parse config or cget options */ while (goi->argc > 0) { Jim_SetEmptyResult(goi->interp); Jim_Nvp *n; int e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n); if (e != JIM_OK) { Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0); return e; } switch (n->value) { case JCFG_EVENT: e = jtag_tap_configure_event(goi, tap); if (e != JIM_OK) return e; break; case JCFG_IDCODE: if (goi->isconfigure) { Jim_SetResultFormatted(goi->interp, "not settable: %s", n->name); return JIM_ERR; } else { if (goi->argc != 0) { Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS"); return JIM_ERR; } } Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode)); break; default: Jim_SetResultFormatted(goi->interp, "unknown value: %s", n->name); return JIM_ERR; } } return JIM_OK; }
static int Win32_CreateWindow(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) { int r = JIM_ERR; HWND hwnd, hwndParent = HWND_DESKTOP; DWORD style = WS_VISIBLE | WS_OVERLAPPEDWINDOW; UINT id = 0; const char *class, *title; if (objc < 3 || objc > 5) { Jim_WrongNumArgs(interp, 1, objv, "class title ?parent? ?id?"); return JIM_ERR; } class = Jim_GetString(objv[1], NULL); title = Jim_GetString(objv[2], NULL); if (objc == 4) { if (Jim_GetLong(interp, objv[3], (long *)&hwndParent) != JIM_OK) return JIM_ERR; style = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; } if (objc == 5) { if (Jim_GetLong(interp, objv[4], (long *)&id) != JIM_OK) return JIM_ERR; } hwnd = CreateWindowA(class, title, style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndParent, (HMENU)id, g_hInstance, NULL); if (hwnd) { SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)interp); Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)hwnd)); r = JIM_OK; } else { Jim_SetResult(interp, Win32ErrorObj(interp, "CreateWindow", GetLastError())); r = JIM_ERR; } return r; }
static int jim_stacktrace_command(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { if (argc != 1) { return JIM_ERR; } Jim_Obj * stacktrace = Jim_DuplicateObj(interp, interp->stackTrace); /* insert actual error site at beginning of list*/ Jim_Obj *procname = Jim_NewStringObj(interp, "", -1); /* Uhhh... don't know this one. */ Jim_ListInsertElements(interp, stacktrace, 0, 1, &procname); Jim_Obj *filename = Jim_NewStringObj(interp, interp->errorFileName, -1); Jim_ListInsertElements(interp, stacktrace, 1, 1, &filename); Jim_Obj *line = Jim_NewIntObj(interp, interp->errorLine); Jim_ListInsertElements(interp, stacktrace, 2, 1, &line); Jim_SetResult(interp, stacktrace); return JIM_OK; }
static int Win32_GetModuleHandle(Jim_Interp *interp, int objc, Jim_Obj * const *objv) { HMODULE hModule = NULL; const char *name = NULL; if (objc < 1 || objc > 2) { Jim_WrongNumArgs(interp, 1, objv, "?name?"); return JIM_ERR; } if (objc == 2) name = Jim_String(objv[1]); hModule = GetModuleHandleA(name); if (hModule == NULL) { Jim_SetResult(interp, Win32ErrorObj(interp, "GetModuleHandle", GetLastError())); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hModule)); return JIM_OK; }
/* * Create error messages for unusual process exits. An * extra newline gets appended to each error message, but * it gets removed below (in the same fashion that an * extra newline in the command's output is removed). */ static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus) { Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); int rc = JIM_ERR; if (WIFEXITED(waitStatus)) { if (WEXITSTATUS(waitStatus) == 0) { Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1)); rc = JIM_OK; } else { Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus))); } } else { const char *type; const char *action; if (WIFSIGNALED(waitStatus)) { type = "CHILDKILLED"; action = "killed"; } else { type = "CHILDSUSP"; action = "suspended"; } Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1)); #ifdef jim_ext_signal Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus))); Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid)); Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1)); #else Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus))); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus))); #endif } Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); return rc; }
static int Win32_SetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) { HWND hwnd, old; int r = JIM_OK; if (objc != 2) { Jim_WrongNumArgs(interp, 1, objv, "windowHandle"); return JIM_ERR; } r = Jim_GetLong(interp, objv[1], (long *)&hwnd); if (r == JIM_OK) { old = SetActiveWindow(hwnd); if (old == NULL) { Jim_SetResult(interp, Win32ErrorObj(interp, "SetActiveWindow", GetLastError())); r = JIM_ERR; } else { Jim_SetResult(interp, Jim_NewIntObj(interp, (long)old)); } } return r; }
int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int opt_indices = 0; int opt_all = 0; int opt_inline = 0; regex_t *regex; int match, i, j; int offset = 0; regmatch_t *pmatch = NULL; int source_len; int result = JIM_OK; const char *pattern; const char *source_str; int num_matches = 0; int num_vars; Jim_Obj *resultListObj = NULL; int regcomp_flags = 0; int eflags = 0; int option; enum { OPT_INDICES, OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_INLINE, OPT_START, OPT_END }; static const char * const options[] = { "-indices", "-nocase", "-line", "-all", "-inline", "-start", "--", NULL }; if (argc < 3) { wrongNumArgs: Jim_WrongNumArgs(interp, 1, argv, "?-switch ...? exp string ?matchVar? ?subMatchVar ...?"); return JIM_ERR; } for (i = 1; i < argc; i++) { const char *opt = Jim_String(argv[i]); if (*opt != '-') { break; } if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { return JIM_ERR; } if (option == OPT_END) { i++; break; } switch (option) { case OPT_INDICES: opt_indices = 1; break; case OPT_NOCASE: regcomp_flags |= REG_ICASE; break; case OPT_LINE: regcomp_flags |= REG_NEWLINE; break; case OPT_ALL: opt_all = 1; break; case OPT_INLINE: opt_inline = 1; break; case OPT_START: if (++i == argc) { goto wrongNumArgs; } if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { return JIM_ERR; } break; } } if (argc - i < 2) { goto wrongNumArgs; } regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); if (!regex) { return JIM_ERR; } pattern = Jim_String(argv[i]); source_str = Jim_GetString(argv[i + 1], &source_len); num_vars = argc - i - 2; if (opt_inline) { if (num_vars) { Jim_SetResultString(interp, "regexp match variables not allowed when using -inline", -1); result = JIM_ERR; goto done; } num_vars = regex->re_nsub + 1; } pmatch = Jim_Alloc((num_vars + 1) * sizeof(*pmatch)); /* If an offset has been specified, adjust for that now. * If it points past the end of the string, point to the terminating null */ if (offset) { if (offset < 0) { offset += source_len + 1; } if (offset > source_len) { source_str += source_len; } else if (offset > 0) { source_str += offset; } eflags |= REG_NOTBOL; } if (opt_inline) { resultListObj = Jim_NewListObj(interp, NULL, 0); } next_match: match = regexec(regex, source_str, num_vars + 1, pmatch, eflags); if (match >= REG_BADPAT) { char buf[100]; regerror(match, regex, buf, sizeof(buf)); Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); result = JIM_ERR; goto done; } if (match == REG_NOMATCH) { goto done; } num_matches++; if (opt_all && !opt_inline) { /* Just count the number of matches, so skip the substitution h */ goto try_next_match; } /* * If additional variable names have been specified, return * index information in those variables. */ j = 0; for (i += 2; opt_inline ? j < num_vars : i < argc; i++, j++) { Jim_Obj *resultObj; if (opt_indices) { resultObj = Jim_NewListObj(interp, NULL, 0); } else { resultObj = Jim_NewStringObj(interp, "", 0); } if (pmatch[j].rm_so == -1) { if (opt_indices) { Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); } } else { int len = pmatch[j].rm_eo - pmatch[j].rm_so; if (opt_indices) { Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + pmatch[j].rm_so)); Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + pmatch[j].rm_so + len - 1)); } else { Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, len); } } if (opt_inline) { Jim_ListAppendElement(interp, resultListObj, resultObj); } else { /* And now set the result variable */ result = Jim_SetVariable(interp, argv[i], resultObj); if (result != JIM_OK) { Jim_FreeObj(interp, resultObj); break; } } } try_next_match: if (opt_all && (pattern[0] != '^' || (regcomp_flags & REG_NEWLINE)) && *source_str) { if (pmatch[0].rm_eo) { offset += pmatch[0].rm_eo; source_str += pmatch[0].rm_eo; } else { source_str++; offset++; } if (*source_str) { eflags = REG_NOTBOL; goto next_match; } } done: if (result == JIM_OK) { if (opt_inline) { Jim_SetResult(interp, resultListObj); } else { Jim_SetResultInt(interp, num_matches); } } Jim_Free(pmatch); return result; }
/* 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", "ndelay", "readable", "writable", "onexception", "accept", NULL }; enum {OPT_CLOSE, OPT_SEEK, OPT_TELL, OPT_GETS, OPT_READ, OPT_PUTS, OPT_FLUSH, OPT_EOF, OPT_NDELAY, OPT_READABLE, OPT_WRITABLE, OPT_EXCEPTION, OPT_ACCEPT }; 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-2] != '\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) && (errno != EAGAIN)) { /* 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; } else if (option == OPT_NDELAY) { #ifdef O_NDELAY int fmode = af->flags; if (argc == 3) { jim_wide wideValue; if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK) return JIM_ERR; switch (wideValue) { case 0: fmode &= ~O_NDELAY; break ; case 1: fmode |= O_NDELAY; break ; } fcntl(af->fd,F_SETFL,fmode); af->flags = fmode; } Jim_SetResult(interp, Jim_NewIntObj(interp, (fmode & O_NONBLOCK)?1:0)); return JIM_OK; #else return JIM_ERR; #endif } else if ( (option == OPT_READABLE) || (option == OPT_WRITABLE) || (option == OPT_EXCEPTION) ) { int mask = 0; Jim_Obj **scrListObjpp = NULL; Jim_Obj *listObj; const char *dummy = NULL; int scrlen = 0; if (!(Jim_CreateFileHandler && Jim_DeleteFileHandler)) { Jim_SetResultString(interp, "Eventloop not present ( or loaded too late ) !", -1); return JIM_ERR; } switch (option) { case OPT_READABLE: mask = JIM_EVENT_READABLE; scrListObjpp = &af->rEvent; if (argc == 4) mask |= JIM_EVENT_FEOF ; break; case OPT_WRITABLE: mask = JIM_EVENT_WRITABLE; scrListObjpp = &af->wEvent; break; case OPT_EXCEPTION: mask = JIM_EVENT_EXCEPTION; scrListObjpp = &af->eEvent; break; } switch (argc) { case 4: case 3: if (*scrListObjpp) { Jim_DeleteFileHandler(interp, af->fp); //,mask); Jim_DecrRefCount(interp, *scrListObjpp); *scrListObjpp = NULL; } if ( dummy = Jim_GetString(argv[2],&scrlen),(scrlen == 0)) { break; } else { *scrListObjpp = Jim_NewListObj(interp, NULL, 0); Jim_IncrRefCount(*scrListObjpp); // fprintf(stderr,"0 %p \n",*scrListObjpp); listObj = argv[2]; if (Jim_IsShared(listObj)) listObj = Jim_DuplicateObj(interp, listObj); // Jim_IncrRefCount(listObj); // fprintf(stderr,"script:\"%s\" argp: %p objp1: %p\n", Jim_GetString(argv[2], NULL),argv[2],listObj); // fprintf(stderr,"1"); Jim_ListAppendElement(interp,*scrListObjpp,listObj); // fprintf(stderr,"2"); if (mask & JIM_EVENT_FEOF) { listObj = argv[3]; if (Jim_IsShared(listObj)) listObj = Jim_DuplicateObj(interp, listObj); // Jim_IncrRefCount(listObj); // fprintf(stderr,"script:\"%s\" argp: %p objp2: %p\n", Jim_GetString(argv[3], NULL),argv[3],listObj); // fprintf(stderr,"3"); Jim_ListAppendElement(interp,*scrListObjpp,listObj); // fprintf(stderr,"4"); } // fprintf(stderr,"event readable fd: %d, script:\"%s\" objp3: %p\n",af->fd, Jim_GetString(argv[2], NULL),argv[2]); Jim_IncrRefCount(*scrListObjpp); // fprintf(stderr,"6 %p \n",Jim_CreateFileHandler); Jim_CreateFileHandler(interp, af->fp, mask, JimAioFileEventHandler, *scrListObjpp, JimAioFileEventFinalizer); // fprintf(stderr,"7"); } break; case 2: if (*scrListObjpp) Jim_SetResult(interp,*scrListObjpp); return JIM_OK; default: Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } } else if (option == OPT_ACCEPT) { int ret; fprintf(stderr,"ACCEPT\n"); ret = JimAioAcceptHelper(interp,af); fprintf(stderr,"ret %d\n",ret); return (ret); } return JIM_OK; }
/* Calls to [sqlite.open] create commands that are implemented by this * C command. */ static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { sqlite3 *db = Jim_CmdPrivData(interp); int option; static const char * const options[] = { "close", "query", "lastid", "changes", NULL }; enum { OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES }; if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite 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_String(argv[0])); return JIM_OK; } else if (option == OPT_QUERY) { /* QUERY */ Jim_Obj *objPtr, *rowsListPtr; sqlite3_stmt *stmt; const char *query, *tail; int columns, rows, len; int retcode = JIM_ERR; Jim_Obj *nullStrObj; if (argc >= 4 && Jim_CompareStringImmediate(interp, argv[2], "-null")) { nullStrObj = argv[3]; argv += 2; argc -= 2; } else { nullStrObj = Jim_NewEmptyStringObj(interp); } Jim_IncrRefCount(nullStrObj); if (argc < 3) { Jim_WrongNumArgs(interp, 2, argv, "query ?args?"); goto err; } objPtr = JimSqliteFormatQuery(interp, argv[2], argc - 3, argv + 3); if (objPtr == NULL) { return JIM_ERR; } query = Jim_GetString(objPtr, &len); Jim_IncrRefCount(objPtr); /* Compile the query into VM code */ if (sqlite3_prepare_v2(db, query, len, &stmt, &tail) != SQLITE_OK) { Jim_DecrRefCount(interp, objPtr); Jim_SetResultString(interp, sqlite3_errmsg(db), -1); goto err; } Jim_DecrRefCount(interp, objPtr); /* query no longer needed. */ /* Build a list of rows (that are lists in turn) */ rowsListPtr = Jim_NewListObj(interp, NULL, 0); Jim_IncrRefCount(rowsListPtr); rows = 0; columns = sqlite3_column_count(stmt); while (sqlite3_step(stmt) == SQLITE_ROW) { int i; objPtr = Jim_NewListObj(interp, NULL, 0); for (i = 0; i < columns; i++) { Jim_Obj *vObj = NULL; Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, sqlite3_column_name(stmt, i), -1)); switch (sqlite3_column_type(stmt, i)) { case SQLITE_NULL: vObj = nullStrObj; break; case SQLITE_INTEGER: vObj = Jim_NewIntObj(interp, sqlite3_column_int(stmt, i)); break; case SQLITE_FLOAT: vObj = Jim_NewDoubleObj(interp, sqlite3_column_double(stmt, i)); break; case SQLITE_TEXT: case SQLITE_BLOB: vObj = Jim_NewStringObj(interp, sqlite3_column_blob(stmt, i), sqlite3_column_bytes(stmt, i)); break; } Jim_ListAppendElement(interp, objPtr, vObj); } Jim_ListAppendElement(interp, rowsListPtr, objPtr); rows++; } /* Finalize */ if (sqlite3_finalize(stmt) != SQLITE_OK) { Jim_SetResultString(interp, sqlite3_errmsg(db), -1); } else { Jim_SetResult(interp, rowsListPtr); retcode = JIM_OK; } Jim_DecrRefCount(interp, rowsListPtr); err: Jim_DecrRefCount(interp, nullStrObj); return retcode; } else if (option == OPT_LASTID) { if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_last_insert_rowid(db))); return JIM_OK; } else if (option == OPT_CHANGES) { if (argc != 2) { Jim_WrongNumArgs(interp, 2, argv, ""); return JIM_ERR; } Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_changes(db))); return JIM_OK; } return JIM_OK; }
/* *---------------------------------------------------------------------- * * StoreStatData -- * * This is a utility procedure that breaks out the fields of a * "stat" structure and stores them in textual form into the * elements of an associative array. * * Results: * Returns a standard Tcl return value. If an error occurs then * a message is left in interp->result. * * Side effects: * Elements of the associative array given by "varName" are modified. * *---------------------------------------------------------------------- */ static void AppendStatElement(Jim_Interp *interp, Jim_Obj *listObj, const char *key, jim_wide value) { Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, key, -1)); Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value)); }
/* * 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; }
/* 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; }
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { struct command_context *context; struct target *target; struct arm *arm; int retval; context = current_command_context(interp); assert(context != NULL); target = get_current_target(context); if (target == NULL) { LOG_ERROR("%s: no current target", __func__); return JIM_ERR; } if (!target_was_examined(target)) { LOG_ERROR("%s: not yet examined", target_name(target)); return JIM_ERR; } arm = target_to_arm(target); if (!is_arm(arm)) { LOG_ERROR("%s: not an ARM", target_name(target)); return JIM_ERR; } if ((argc < 6) || (argc > 7)) { /* FIXME use the command name to verify # params... */ LOG_ERROR("%s: wrong number of arguments", __func__); return JIM_ERR; } int cpnum; uint32_t op1; uint32_t op2; uint32_t CRn; uint32_t CRm; uint32_t value; long l; /* NOTE: parameter sequence matches ARM instruction set usage: * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * The "rX" is necessarily omitted; it uses Tcl mechanisms. */ retval = Jim_GetLong(interp, argv[1], &l); if (retval != JIM_OK) return retval; if (l & ~0xf) { LOG_ERROR("%s: %s %d out of range", __func__, "coprocessor", (int) l); return JIM_ERR; } cpnum = l; retval = Jim_GetLong(interp, argv[2], &l); if (retval != JIM_OK) return retval; if (l & ~0x7) { LOG_ERROR("%s: %s %d out of range", __func__, "op1", (int) l); return JIM_ERR; } op1 = l; retval = Jim_GetLong(interp, argv[3], &l); if (retval != JIM_OK) return retval; if (l & ~0xf) { LOG_ERROR("%s: %s %d out of range", __func__, "CRn", (int) l); return JIM_ERR; } CRn = l; retval = Jim_GetLong(interp, argv[4], &l); if (retval != JIM_OK) return retval; if (l & ~0xf) { LOG_ERROR("%s: %s %d out of range", __func__, "CRm", (int) l); return JIM_ERR; } CRm = l; retval = Jim_GetLong(interp, argv[5], &l); if (retval != JIM_OK) return retval; if (l & ~0x7) { LOG_ERROR("%s: %s %d out of range", __func__, "op2", (int) l); return JIM_ERR; } op2 = l; value = 0; /* FIXME don't assume "mrc" vs "mcr" from the number of params; * that could easily be a typo! Check both... * * FIXME change the call syntax here ... simplest to just pass * the MRC() or MCR() instruction to be executed. That will also * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) * if that's ever needed. */ if (argc == 7) { retval = Jim_GetLong(interp, argv[6], &l); if (retval != JIM_OK) return retval; value = l; /* NOTE: parameters reordered! */ /* ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2) */ retval = arm->mcr(target, cpnum, op1, op2, CRn, CRm, value); if (retval != ERROR_OK) return JIM_ERR; } else { /* NOTE: parameters reordered! */ /* ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2) */ retval = arm->mrc(target, cpnum, op1, op2, CRn, CRm, &value); if (retval != ERROR_OK) return JIM_ERR; Jim_SetResult(interp, Jim_NewIntObj(interp, value)); } return JIM_OK; }
static int Win32_GetVersion(Jim_Interp *interp, int objc, Jim_Obj * const *objv) { Jim_SetResult(interp, Jim_NewIntObj(interp, GetVersion())); return JIM_OK; }
static int Win32_GetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv) { Jim_SetResult(interp, Jim_NewIntObj(interp, (ptrdiff_t)GetActiveWindow())); return JIM_OK; }
static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp); double ms = 0; jim_wide id; Jim_Obj *objPtr, *idObjPtr; static const char * const options[] = { "cancel", "info", "idle", NULL }; enum { AFTER_CANCEL, AFTER_INFO, AFTER_IDLE, AFTER_RESTART, AFTER_EXPIRE, AFTER_CREATE }; int option = AFTER_CREATE; if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "option ?arg ...?"); return JIM_ERR; } if (Jim_GetDouble(interp, argv[1], &ms) != JIM_OK) { if (Jim_GetEnum(interp, argv[1], options, &option, "argument", JIM_ERRMSG) != JIM_OK) { return JIM_ERR; } Jim_SetEmptyResult(interp); } else if (argc == 2) { /* Simply a sleep */ usleep(ms * 1000); return JIM_OK; } switch (option) { case AFTER_IDLE: if (argc < 3) { Jim_WrongNumArgs(interp, 2, argv, "script ?script ...?"); return JIM_ERR; } /* fall through */ case AFTER_CREATE: { Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2); Jim_IncrRefCount(scriptObj); id = Jim_CreateTimeHandler(interp, (jim_wide)(ms * 1000), JimAfterTimeHandler, scriptObj, JimAfterTimeEventFinalizer); objPtr = Jim_NewStringObj(interp, NULL, 0); Jim_AppendString(interp, objPtr, "after#", -1); idObjPtr = Jim_NewIntObj(interp, id); Jim_IncrRefCount(idObjPtr); Jim_AppendObj(interp, objPtr, idObjPtr); Jim_DecrRefCount(interp, idObjPtr); Jim_SetResult(interp, objPtr); return JIM_OK; } case AFTER_CANCEL: if (argc < 3) { Jim_WrongNumArgs(interp, 2, argv, "id|command"); return JIM_ERR; } else { jim_wide remain = 0; id = JimParseAfterId(argv[2]); if (id <= 0) { /* Not an event id, so search by script */ Jim_Obj *scriptObj = Jim_ConcatObj(interp, argc - 2, argv + 2); id = JimFindAfterByScript(eventLoop, scriptObj); Jim_FreeNewObj(interp, scriptObj); if (id <= 0) { /* Not found */ break; } } remain = Jim_DeleteTimeHandler(interp, id); if (remain >= 0) { Jim_SetResultInt(interp, remain); } } break; case AFTER_INFO: if (argc == 2) { Jim_TimeEvent *te = eventLoop->timeEventHead; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); char buf[30]; const char *fmt = "after#%" JIM_WIDE_MODIFIER; while (te) { snprintf(buf, sizeof(buf), fmt, te->id); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, buf, -1)); te = te->next; } Jim_SetResult(interp, listObj); } else if (argc == 3) { id = JimParseAfterId(argv[2]); if (id >= 0) { Jim_TimeEvent *e = JimFindTimeHandlerById(eventLoop, id); if (e && e->timeProc == JimAfterTimeHandler) { Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); Jim_ListAppendElement(interp, listObj, e->clientData); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, e->initialus ? "timer" : "idle", -1)); Jim_SetResult(interp, listObj); return JIM_OK; } } Jim_SetResultFormatted(interp, "event \"%#s\" doesn't exist", argv[2]); return JIM_ERR; } else { Jim_WrongNumArgs(interp, 2, argv, "?id?"); return JIM_ERR; } break; } return JIM_OK; }