static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int i; int len; Jim_Obj *listObj = argv[1]; Jim_Obj *dictObj; len = Jim_ListLength(interp, listObj); if (len % 2) { Jim_SetResultString(interp, "list must have an even number of elements", -1); return JIM_ERR; } dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); if (!dictObj) { /* Doesn't exist, so just set the list directly */ return Jim_SetVariable(interp, argv[0], listObj); } if (Jim_IsShared(dictObj)) { dictObj = Jim_DuplicateObj(interp, dictObj); } for (i = 0; i < len; i += 2) { Jim_Obj *nameObj; Jim_Obj *valueObj; Jim_ListIndex(interp, listObj, i, &nameObj, JIM_NONE); Jim_ListIndex(interp, listObj, i + 1, &valueObj, JIM_NONE); Jim_DictAddElement(interp, dictObj, nameObj, valueObj); } return Jim_SetVariable(interp, argv[0], dictObj); }
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb) { /* Just use a list to store the data */ Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); AppendStatElement(interp, listObj, "dev", sb->st_dev); AppendStatElement(interp, listObj, "ino", sb->st_ino); AppendStatElement(interp, listObj, "mode", sb->st_mode); AppendStatElement(interp, listObj, "nlink", sb->st_nlink); AppendStatElement(interp, listObj, "uid", sb->st_uid); AppendStatElement(interp, listObj, "gid", sb->st_gid); AppendStatElement(interp, listObj, "size", sb->st_size); AppendStatElement(interp, listObj, "atime", sb->st_atime); AppendStatElement(interp, listObj, "mtime", sb->st_mtime); AppendStatElement(interp, listObj, "ctime", sb->st_ctime); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1)); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1)); /* Was a variable specified? */ if (varName) { Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE); if (objPtr) { if (Jim_DictSize(interp, objPtr) < 0) { /* This message matches the one from Tcl */ Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName); Jim_FreeNewObj(interp, listObj); return JIM_ERR; } if (Jim_IsShared(objPtr)) objPtr = Jim_DuplicateObj(interp, objPtr); /* Just cheat here and append as a list and convert to a dict */ Jim_ListAppendList(interp, objPtr, listObj); Jim_DictSize(interp, objPtr); Jim_InvalidateStringRep(objPtr); Jim_FreeNewObj(interp, listObj); listObj = objPtr; } Jim_SetVariable(interp, varName, listObj); } /* And also return the value */ Jim_SetResult(interp, listObj); return JIM_OK; }
/* 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; }