aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jim-aio.c137
-rw-r--r--jim-bio.c273
-rw-r--r--jim-load.c16
-rw-r--r--jim-package.c72
-rw-r--r--jim-posix.c294
-rw-r--r--jim-signal.c492
-rw-r--r--jim.c649
-rw-r--r--jim.h21
8 files changed, 1256 insertions, 698 deletions
diff --git a/jim-aio.c b/jim-aio.c
index ae78440..6604b85 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -117,15 +117,15 @@ static void JimAioDelProc(Jim_Interp *interp, void *privData)
if (!af->OpenFlags == AIO_FDOPEN) // fp = fdopen(fd) !!
close(af->fd);
if (af->rEvent) { // remove existing EventHandlers
- Jim_DeleteFileHandler(interp,af->fp);
- Jim_DecrRefCount(interp,af->rEvent);
+ Jim_DeleteFileHandler(interp,af->fp);
+ Jim_DecrRefCount(interp,af->rEvent);
}
if (af->wEvent) {
- Jim_DeleteFileHandler(interp,af->fp);
+ Jim_DeleteFileHandler(interp,af->fp);
Jim_DecrRefCount(interp,af->wEvent);
}
if (af->eEvent) {
- Jim_DeleteFileHandler(interp,af->fp);
+ Jim_DeleteFileHandler(interp,af->fp);
Jim_DecrRefCount(interp,af->eEvent);
}
Jim_Free(af);
@@ -154,7 +154,7 @@ static int JimAioHandlerCommand(Jim_Interp *interp, int argc,
OPT_FLUSH, OPT_EOF,
OPT_NDELAY,
OPT_READABLE, OPT_WRITABLE, OPT_EXCEPTION,
- OPT_ACCEPT
+ OPT_ACCEPT,
};
if (argc < 2) {
@@ -451,9 +451,7 @@ static int JimAioHandlerCommand(Jim_Interp *interp, int argc,
return JIM_ERR;
}
} else if (option == OPT_ACCEPT) {
- int ret;
- ret = JimAioAcceptHelper(interp,af);
- return (ret);
+ return JimAioAcceptHelper(interp,af);
}
return JIM_OK;
}
@@ -465,12 +463,12 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc,
AioFile *af;
char buf[AIO_CMD_LEN];
const char *mode = "r";
- Jim_Obj *objPtr;
long fileId;
const char *options[] = {"input", "output", "error", NULL};
enum {OPT_INPUT, OPT_OUTPUT, OPT_ERROR};
int OpenFlags = 0;
int modeLen;
+ const char *cmdname = buf;
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 1, argv, "filename ?mode?");
@@ -486,9 +484,9 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc,
return JIM_ERR;
OpenFlags |= AIO_KEEPOPEN;
switch (option) {
- case OPT_INPUT: fp = stdin; break;
- case OPT_OUTPUT: fp = stdout; break;
- case OPT_ERROR: fp = stderr; break;
+ case OPT_INPUT: fp = stdin; cmdname = "stdin"; break;
+ case OPT_OUTPUT: fp = stdout; cmdname = "stdout"; break;
+ case OPT_ERROR: fp = stderr; cmdname = "stderr"; break;
default: fp = NULL; Jim_Panic(interp,"default reached in JimAioOpenCommand()");
break;
}
@@ -498,14 +496,10 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc,
JimAioSetError(interp);
return JIM_ERR;
}
+ /* Get the next file id */
+ fileId = Jim_GetId(interp);
+ sprintf(buf, "aio.handle%ld", fileId);
}
- /* Get the next file id */
- if (Jim_EvalGlobal(interp,
- "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
- return JIM_ERR;
- objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
- if (objPtr == NULL) return JIM_ERR;
- if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
/* Create the file command */
af = Jim_Alloc(sizeof(*af));
@@ -516,9 +510,8 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc,
af->rEvent = NULL;
af->wEvent = NULL;
af->eEvent = NULL;
- sprintf(buf, "aio.handle%ld", fileId);
- Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc);
- Jim_SetResultString(interp, buf, -1);
+ Jim_CreateCommand(interp, cmdname, JimAioHandlerCommand, af, JimAioDelProc);
+ Jim_SetResultString(interp, cmdname, -1);
return JIM_OK;
}
@@ -528,8 +521,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc,
FILE *fp;
AioFile *af;
char buf[AIO_CMD_LEN];
- char *hdlfmt = "unknown";
- Jim_Obj *objPtr;
+ char *hdlfmt = "aio.unknown%ld";
long fileId;
const char *socktypes[] = {
"file",
@@ -641,12 +633,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc,
return JIM_ERR;
}
/* Get the next file id */
- if (Jim_EvalGlobal(interp,
- "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
- return JIM_ERR;
- objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
- if (objPtr == NULL) return JIM_ERR;
- if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
+ fileId = Jim_GetId(interp);
/* Create the file command */
af = Jim_Alloc(sizeof(*af));
@@ -669,19 +656,13 @@ static int JimAioAcceptHelper(Jim_Interp *interp, AioFile *serv_af )
int addrlen = sizeof(struct sockaddr_in);
AioFile *af;
char buf[AIO_CMD_LEN];
- Jim_Obj *objPtr;
long fileId;
sock = accept(serv_af->fd,(struct sockaddr*)&serv_af->sa,&addrlen);
if (sock < 0)
return JIM_ERR;
/* Get the next file id */
- if (Jim_EvalGlobal(interp,
- "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
- return JIM_ERR;
- objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
- if (objPtr == NULL) return JIM_ERR;
- if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
+ fileId = Jim_GetId(interp);
/* Create the file command */
af = Jim_Alloc(sizeof(*af));
@@ -698,6 +679,79 @@ static int JimAioAcceptHelper(Jim_Interp *interp, AioFile *serv_af )
return JIM_OK;
}
+FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
+{
+ Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
+
+ if (cmdPtr && cmdPtr->cmdProc == JimAioHandlerCommand) {
+ return ((AioFile *)cmdPtr->privData)->fp;
+ }
+ return NULL;
+}
+
+#ifdef JIM_TCL_COMPAT
+static int JimAioTclCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj **newargv = Jim_Alloc(sizeof(Jim_Obj*)*argc);
+ int ret;
+ int i;
+
+ /* cmd channel ?args? */
+ newargv[0] = argv[1];
+ newargv[1] = argv[0];
+
+ for (i = 2; i < argc; i++) {
+ newargv[i] = argv[i];
+ }
+
+ ret = Jim_EvalObjVector(interp, argc, newargv);
+
+ Jim_Free(newargv);
+
+ return ret;
+}
+
+static int JimAioPutsCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *newargv[4];
+
+ int off = 1;
+
+ /* "puts" */
+ newargv[off++] = argv[0];
+
+ /* puts ?-nonewline? ?channel? msg */
+ if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nonewline")) {
+ newargv[off++] = argv[1];
+ argv++;
+ argc--;
+ }
+
+ if (argc == 2) {
+ /* Missing channel, so use stdout */
+ newargv[0] = Jim_NewStringObj(interp, "stdout", -1);
+ newargv[off++] = argv[1];
+ }
+ else {
+ newargv[0] = argv[1];
+ newargv[off++] = argv[2];
+ }
+ return Jim_EvalObjVector(interp, off, newargv);
+}
+
+static void JimAioTclCompat(Jim_Interp *interp)
+{
+ static const char *tclcmds[] = { "read", "gets", "flush", "close", "eof", "seek", "tell", 0};
+ int i;
+
+ for (i = 0; tclcmds[i]; i++) {
+ Jim_CreateCommand(interp, tclcmds[i], JimAioTclCmd, NULL, NULL);
+ }
+ Jim_CreateCommand(interp, "puts", JimAioPutsCmd, NULL, NULL);
+ Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
+}
+#endif
+
int
Jim_aioInit(Jim_Interp *interp)
{
@@ -705,6 +759,15 @@ Jim_aioInit(Jim_Interp *interp)
return JIM_ERR;
Jim_CreateCommand(interp, "aio.open", JimAioOpenCommand, NULL, NULL);
Jim_CreateCommand(interp, "aio.socket", JimAioSockCommand, NULL, NULL);
+
+ /* Takeover stdin, stdout and stderr */
+ Jim_EvalGlobal(interp,
+ "aio.open standard input; aio.open standard output; aio.open standard error");
+
+#ifdef JIM_TCL_COMPAT
+ JimAioTclCompat(interp);
+#endif
+
return JIM_OK;
}
diff --git a/jim-bio.c b/jim-bio.c
new file mode 100644
index 0000000..93696e1
--- /dev/null
+++ b/jim-bio.c
@@ -0,0 +1,273 @@
+/*
+ * jim-bio.c
+ *
+ * Implements the bio command for binary I/O
+ *
+ * bio read ?-hex? fd var length
+ *
+ * Reads 'length' bytes of binary data from 'fd' and stores an encoded string
+ * in 'var' so that the string contains no internal null characters.
+ *
+ * Returns the number of (original) chars read, which may be short if EOF is reached.
+ *
+ * bio write ?-hex? fd encoded
+ *
+ * Writes the binary-encoded string 'encoded' to 'fd'
+ *
+ * Returns the number of chars written (if no error)
+ *
+ * For the default binary encoding:
+ * - 0x00 -> 0x01, 0x30
+ * - 0x01 -> 0x01, 0x31
+ *
+ * Alternatively, if -hex is specified, the data is read and written as ascii hex
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <jim.h>
+#include <jim-subcmd.h>
+
+static int hex2char(const char *hex)
+{
+ int value;
+ value = (hex[0] >= 'A' ? ((hex[0] & 0xdf) - 'A') + 10 : (hex[0] - '0'));
+ value *= 16;
+ value += (hex[1] >= 'A' ? ((hex[1] & 0xdf) - 'A') + 10 : (hex[1] - '0'));
+ return value;
+}
+
+static void char2hex(int c, char hex[2])
+{
+ hex[1] = (c & 0x0F) >= 0x0A ? (c & 0x0F) + 'A' - 10 : (c & 0x0F) + '0';
+ c /= 16;
+ hex[0] = (c & 0x0F) >= 0x0A ? (c & 0x0F) + 'A' - 10 : (c & 0x0F) + '0';
+}
+
+/**
+ * Modelled on Jim_ReadCmd
+ *
+ */
+static int bio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ char buf[130];
+ int count = 0;
+ long len;
+ int hex = 0;
+ int total = 0;
+ FILE *fh;
+
+ if (Jim_CompareStringImmediate(interp, argv[0], "-hex")) {
+ hex++;
+ argv++;
+ argc--;
+ }
+ else if (argc == 4) {
+ return -1;
+ }
+
+ fh = Jim_AioFilehandle(interp, argv[0]);
+
+ if (!fh) {
+ return JIM_ERR;
+ }
+
+ if (Jim_GetLong(interp, argv[2], &len) != JIM_OK) {
+ return JIM_ERR;
+ }
+
+ Jim_Obj *result = Jim_NewStringObj(interp, "", 0);
+
+ /* Read one char at a time, escaping 0x00 and 0xFF as necessary */
+ while (len > 0) {
+ int ch = fgetc(fh);
+ if (ch == EOF) {
+ break;
+ }
+ total++;
+
+ if (hex) {
+ char2hex(ch, buf + count);
+ count += 2;
+ }
+ else {
+ if (ch == 0 || ch == 1) {
+ buf[count++] = 1;
+ ch = ch + '0';
+ }
+ buf[count++] = ch;
+ }
+
+ /* Allow space for the null termination, plus escaping of one char */
+ if (count >= sizeof(buf) - 2) {
+ /* Buffer is full, so append it */
+ Jim_AppendString(interp, result, buf, count);
+
+ count = 0;
+ }
+ len--;
+ }
+
+ if (ferror(fh)) {
+ Jim_SetResultString(interp, "error during read", -1);
+ clearerr(fh);
+ return JIM_ERR;
+ }
+
+ Jim_AppendString(interp, result, buf, count);
+
+ if (Jim_SetVariable(interp, argv[1], result) != JIM_OK) {
+ return JIM_ERR;
+ }
+
+ Jim_SetResultInt(interp, total);
+
+ return JIM_OK;
+}
+
+#if 0
+static int bio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ OpenFile *infilePtr;
+ OpenFile *outfilePtr;
+ int count = 0;
+ int maxlen = 0;
+
+ if (TclGetOpenFile(interp, argv[0], &infilePtr) != JIM_OK) {
+ return TCL_ERROR;
+ }
+ if (!infilePtr->readable) {
+ Jim_AppendResult(interp, "\"", argv[0],
+ "\" wasn't opened for reading", (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (TclGetOpenFile(interp, argv[1], &outfilePtr) != JIM_OK) {
+ return TCL_ERROR;
+ }
+ if (!outfilePtr->writable) {
+ Jim_AppendResult(interp, "\"", argv[1],
+ "\" wasn't opened for writing", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (argc == 3) {
+ if (Jim_GetInt(interp, argv[2], &maxlen) != JIM_OK) {
+ return TCL_ERROR;
+ }
+ }
+
+ while (maxlen == 0 || count < maxlen) {
+ int ch = fgetc(infilePtr->f);
+ if (ch == EOF || fputc(ch, outfilePtr->f) == EOF) {
+ break;
+ }
+ count++;
+ }
+
+ if (ferror(infilePtr->f)) {
+ Jim_AppendResult(interp, "error reading \"", argv[0], "\": ", Jim_UnixError(interp), 0);
+ clearerr(infilePtr->f);
+ return TCL_ERROR;
+ }
+
+ if (ferror(outfilePtr->f)) {
+ Jim_AppendResult(interp, "error writing \"", argv[0], "\": ", Jim_UnixError(interp), 0);
+ clearerr(outfilePtr->f);
+ return TCL_ERROR;
+ }
+
+ Jim_SetIntResult(interp, count);
+
+ return JIM_OK;
+}
+#endif
+
+static int bio_cmd_write(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ FILE *fh;
+ const char *pt;
+ int hex = 0;
+ long total = 0;
+
+
+ if (Jim_CompareStringImmediate(interp, argv[0], "-hex")) {
+ hex++;
+ argv++;
+ argc--;
+ }
+ else if (argc == 3) {
+ return -1;
+ }
+
+ fh = Jim_AioFilehandle(interp, argv[0]);
+
+ for (pt = Jim_GetString(argv[1], NULL); *pt; pt++) {
+ int ch;
+
+ if (hex) {
+ ch = hex2char(pt);
+ pt++;
+ }
+ else {
+ ch = *pt;
+ if (ch == 1) {
+ pt++;
+ ch = *pt - '0';
+ }
+ }
+ if (fputc(ch, fh) == EOF) {
+ break;
+ }
+ total++;
+ }
+
+ if (ferror(fh)) {
+ Jim_SetResultString(interp, "error during write", -1);
+ clearerr(fh);
+ return JIM_ERR;
+ }
+
+ Jim_SetResultInt(interp, total);
+
+ return JIM_OK;
+}
+
+static const jim_subcmd_type command_table[] = {
+ { .cmd = "read",
+ .function = bio_cmd_read,
+ .args = "?-hex? fd var numbytes",
+ .minargs = 3,
+ .maxargs = 4,
+ .description = "Read binary bytes as an encoded string"
+ },
+ { .cmd = "write",
+ .function = bio_cmd_write,
+ .args = "?-hex? fd buf",
+ .minargs = 2,
+ .maxargs = 3,
+ .description = "Write an encoded string as binary bytes"
+ },
+#if 0
+ { .cmd = "copy",
+ .function = bio_cmd_copy,
+ .args = "fromfd tofd ?bytes?",
+ .minargs = 2,
+ .maxargs = 3,
+ .description = "Read from one fd and write to another"
+ },
+#endif
+ { 0 }
+};
+
+int
+Jim_bioInit(Jim_Interp *interp)
+{
+ if (Jim_PackageProvide(interp, "bio", "1.0", JIM_ERRMSG) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_CreateCommand(interp, "bio", Jim_SubCmdProc, (void *)command_table, NULL);
+ return JIM_OK;
+}
diff --git a/jim-load.c b/jim-load.c
index 8572405..ebd6b63 100644
--- a/jim-load.c
+++ b/jim-load.c
@@ -116,3 +116,19 @@ int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
}
#endif/* JIM_DYNLIB */
+/* [load] */
+static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "libaryFile");
+ return JIM_ERR;
+ }
+ return Jim_LoadLibrary(interp, Jim_GetString(argv[1], NULL));
+}
+
+int Jim_loadInit(Jim_Interp *interp)
+{
+ Jim_CreateCommand(interp, "load", Jim_LoadCoreCommand, NULL, NULL);
+ return JIM_OK;
+}
diff --git a/jim-package.c b/jim-package.c
index 48976c0..4474381 100644
--- a/jim-package.c
+++ b/jim-package.c
@@ -28,6 +28,24 @@ int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver,
return JIM_OK;
}
+static int Jim_PackageList(Jim_Interp *interp)
+{
+ Jim_HashTableIterator *htiter;
+ Jim_HashEntry *he;
+ Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
+
+ htiter = Jim_GetHashTableIterator(&interp->packages);
+ while ((he = Jim_NextHashEntry(htiter)) != NULL) {
+ Jim_ListAppendElement(interp, listObjPtr,
+ Jim_NewStringObj(interp, he->key, -1));
+ }
+ Jim_FreeHashTableIterator(htiter);
+
+ Jim_SetResult(interp, listObjPtr);
+
+ return JIM_OK;
+}
+
static char *JimFindPackage(Jim_Interp *interp, char **prefixes,
int prefixc, const char *pkgName)
{
@@ -135,3 +153,57 @@ const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
}
}
+/* [package] */
+int Jim_PackageCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int option;
+ const char *options[] = {
+ "require", "provide", "list", NULL
+ };
+ enum {OPT_REQUIRE, OPT_PROVIDE, OPT_LIST};
+
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?");
+ return JIM_ERR;
+ }
+ if (Jim_GetEnum(interp, argv[1], options, &option, "option",
+ JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+
+ if (option == OPT_REQUIRE) {
+ int exact = 0;
+ const char *ver;
+
+ if (Jim_CompareStringImmediate(interp, argv[2], "-exact")) {
+ exact = 1;
+ argv++;
+ argc--;
+ }
+ if (argc != 3 && argc != 4) {
+ Jim_WrongNumArgs(interp, 2, argv, "?-exact? package ?version?");
+ return JIM_ERR;
+ }
+ ver = Jim_PackageRequire(interp, Jim_GetString(argv[2], NULL),
+ argc == 4 ? Jim_GetString(argv[3], NULL) : "",
+ JIM_ERRMSG);
+ if (ver == NULL)
+ return JIM_ERR_ADDSTACK;
+ Jim_SetResultString(interp, ver, -1);
+ } else if (option == OPT_PROVIDE) {
+ if (argc != 4) {
+ Jim_WrongNumArgs(interp, 2, argv, "package version");
+ return JIM_ERR;
+ }
+ return Jim_PackageProvide(interp, Jim_GetString(argv[2], NULL),
+ Jim_GetString(argv[3], NULL), JIM_ERRMSG);
+ } else if (option == OPT_LIST) {
+ return Jim_PackageList(interp);
+ }
+ return JIM_OK;
+}
+
+int Jim_packageInit(Jim_Interp *interp)
+{
+ Jim_CreateCommand(interp, "package", Jim_PackageCoreCommand, NULL, NULL);
+ return JIM_OK;
+}
diff --git a/jim-posix.c b/jim-posix.c
index f280f3e..9a81a55 100644
--- a/jim-posix.c
+++ b/jim-posix.c
@@ -50,21 +50,6 @@ static int Jim_PosixForkCommand(Jim_Interp *interp, int argc,
return JIM_OK;
}
-static int Jim_PosixSleepCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- long longValue;
-
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 1, argv, "?seconds?");
- return JIM_ERR;
- }
- if (Jim_GetLong(interp, argv[1], &longValue) != JIM_OK)
- return JIM_ERR;
- sleep(longValue);
- return JIM_OK;
-}
-
static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
{
@@ -103,292 +88,13 @@ static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc,
return JIM_OK;
}
-static int Jim_PosixSethostnameCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- const char *hostname;
- int len;
-
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 1, argv, "hostname");
- return JIM_ERR;
- }
- hostname = Jim_GetString(argv[1], &len);
- if (sethostname(hostname, len) == -1) {
- Jim_PosixSetError(interp);
- return JIM_ERR;
- }
- return JIM_OK;
-}
-// added Commands, some linux specific
-
-// uses POSIX.1b
-#define S_NS 1000000000
-#define S_US 1000000
-#define MSNS 1000000
-#define USNS 1000
-#define NSNS 1
-
-static int Jim_LinuxUSleepCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- int mult = NSNS ;
- double floatValue ;
- const char *units ;
- long long delay ;
- int len ;
- struct timespec tv;
-
- switch (argc) {
- case 3:
- units = Jim_GetString(argv[2], &len);
- if (units == NULL)
- return JIM_ERR;
- switch (*units) {
- case 's': mult = S_NS; break;
- case 'm': mult = MSNS; break;
- case 'u': mult = USNS; break;
- case 'n': mult = NSNS; break;
- default:
- Jim_WrongNumArgs(interp, 1, argv, "arg3: ms us ns or empty");
- return JIM_ERR;
- }
- // fallthrough
- case 2: if (Jim_GetDouble(interp, argv[1], &floatValue) != JIM_OK)
- return JIM_ERR;
- delay = (long long)(floatValue * mult);
- break;
- default:
- Jim_WrongNumArgs(interp, 1, argv, "?useconds?");
- return JIM_ERR;
- }
- tv.tv_sec = delay / S_NS;
- tv.tv_nsec = delay % S_NS;
- fprintf(stderr,"delay: %lld mult: %d sec: %ld ns: %ld\n", delay, mult, tv.tv_sec,tv.tv_nsec );
- nanosleep(&tv,NULL);
- return JIM_OK;
-}
-
-static int Jim_PointInTimeCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- struct timezone tz = { 0, 0 };
- double pit ;
- struct timeval tv;
-
- gettimeofday(&tv,&tz);
- pit = (double)tv.tv_usec;
- pit /= (double)S_US;
- pit +=(double)tv.tv_sec;
-
- Jim_SetResult(interp, Jim_NewDoubleObj(interp, pit));
- return JIM_OK;
-}
-
-static int Jim_PointInTimeJulianCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- struct timezone tz = { 0, 0 };
- double pit ;
- struct timeval tv;
-
- gettimeofday(&tv,&tz);
- pit = (double)tv.tv_usec;
- pit /= (double)S_US;
- pit += (double)tv.tv_sec;
- pit /= (double)( 60 * 60 * 24 );
- pit += 2440587.5;
-
- Jim_SetResult(interp, Jim_NewDoubleObj(interp, pit));
- return JIM_OK;
-}
-
-#if 0
-// signal stuff
-// signal <signame>
-
- static const char *signames[] = {
- "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
- "SIGABRT", "SIGFPE", "SIGKILL", "SIGSEGV",
- "SIGPIPE", "SIGALRM", "SIGTERM",
- "SIGUSR1", "SIGUSR2",
- "SIGCHLD", "SIGCONT", "SIGSTOP",
- "SIGTSTP", "SIGTTIN" "SIGTTOU",
- "SIGBUS",
-#ifdef SIGPOLL
- "SIGPOLL",
-#endif
- "SIGPROF", "SIGSYS",
- "SIGTRAP", "SIGURG", "SIGVTALRM", "SIGXCPU",
- "SIGXFSZ",
- "SIGIOT",
-#ifdef SIGEMT
- "SIGEMT",
-#endif
- "SIGSTKFLT", "SIGIO",
- "SIGCLD", "SIGPWR",
-#ifdef SIGINFO
- "SIGINFO",
-#endif
-#ifdef SIGLOST
- "SIGLOST",
-#endif
- "SIGWINCH", "SIGUNUSED",
- "SIGRT32", "SIGRT33", "SIGRT34", "SIGRT35",
- "SIGRT36", "SIGRT37", "SIGRT38", "SIGRT39",
- NULL
- } ;
-static int signums[] = {
- SIGHUP, SIGINT, SIGQUIT, SIGILL,
- SIGABRT, SIGFPE, SIGKILL, SIGSEGV,
- SIGPIPE, SIGALRM, SIGTERM,
- SIGUSR1, SIGUSR2,
- SIGCHLD, SIGCONT, SIGSTOP,
- SIGTSTP, SIGTTIN, SIGTTOU,
- SIGBUS,
-#ifdef SIGPOLL
- SIGPOLL,
-#endif
- SIGPROF, SIGSYS,
- SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU,
- SIGXFSZ,
- SIGIOT,
-#ifdef SIGEMT
- SIGEMT,
-#endif
- SIGSTKFLT, SIGIO,
- SIGCLD, SIGPWR,
-#ifdef SIGINFO
- SIGINFO,
-#endif
-#ifdef SIGLOST
- SIGLOST,
-#endif
- SIGWINCH, SIGUNUSED,
-#ifdef SIGRT
- SIGRT32, SIGRT33, SIGRT34, SIGRT35,
- SIGRT36, SIGRT37, SIGRT38, SIGRT39,
-#endif
- 0
- } ;
-
-#if 0
-enum {
- HUP, INT, QUIT, ILL,
- ABRT, FPE, KILL, SEGV,
- PIPE, ALRM, TERM,
- USR1, USR2,
- CHLD, CONT, STOP,
- TSTP, TTIN, TTOU,
- BUS, POLL, PROF, SYS,
- TRAP, URG, VTALRM, XCPU,
- XFSZ,
- IOT,
-#ifdef SIGEMT
- EMT,
-#endif
- STKFLT, IO,
- CLD, PWR,
-#ifdef SIGINFO
- INFO,
-#endif
-#ifdef SIGLOST
- LOST,
-#endif
- WINCH, UNUSED,
-#ifdef SIGRT
- RT32, RT33, RT34, RT35,
- RT36, RT37, RT38, RT39,
-#endif
- ISEND
- } ;
-#endif
-#endif
-
-static void Jim_Posix_SigHandler(int signal)
-{
-#if 0
- int i;
- for (i=0; i<sizeof(signums)/sizeof(*signums) && (signums[i] != signal);i++) ;
-#endif
- //fprintf(stderr,"signal %d %s\n", signal,signames[i]);
- fprintf(stderr,"signal %d\n", signal);
-}
-
-typedef void (*sighandler_t)(int);
-
-static int Jim_PosixSignalCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- int sig;
- int signum;
- sighandler_t lastaction;
- sighandler_t nextaction = SIG_DFL;
- const char *op;
- int strlen = 0;
-
- if (argc < 2) {
- Jim_WrongNumArgs(interp, 1, argv, "signame ?action ...?");
- return JIM_ERR;
- }
- if (Jim_GetEnum(interp, argv[1], signames, &sig, "Signal Names",
- JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
-
- signum = signums[sig];
-
- switch (argc) {
- case 3:
- if (op = Jim_GetString(argv[2], &strlen),strlen == 0) {
- return JIM_ERR;
- }
- if (strcmp("default",op) == 0) {
- nextaction = SIG_DFL;
- } else if (strcmp("ignore",op) == 0) {
- nextaction = SIG_IGN;
- } else if (strcmp("debug",op) == 0) {
- nextaction = Jim_Posix_SigHandler;
- } else {
- // this is the place to insert a script! UK
- }
- // fall through to query case:
- case 2:
- lastaction = signal(signum, nextaction);
- if (argc==2)
- signal(signum, lastaction);
- if (lastaction == SIG_ERR) {
- return JIM_ERR;
- }
- if (lastaction == SIG_DFL) {
- Jim_SetResultString(interp, "default", -1);
- return JIM_OK;
- }
- if (lastaction == SIG_IGN) {
- Jim_SetResultString(interp, "ignore", -1);
- return JIM_OK;
- }
- Jim_SetResultString(interp, "function", -1);
- return JIM_OK;
- }
-
- return JIM_OK;
-}
-
-
-
// end added
int Jim_posixInit(Jim_Interp *interp)
{
if (Jim_PackageProvide(interp, "posix", "1.0", JIM_ERRMSG) != JIM_OK)
return JIM_ERR;
Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL);
- Jim_CreateCommand(interp, "os.sleep", Jim_PosixSleepCommand, NULL, NULL);
Jim_CreateCommand(interp, "os.getids", Jim_PosixGetidsCommand, NULL, NULL);
Jim_CreateCommand(interp, "os.gethostname", Jim_PosixGethostnameCommand, NULL, NULL);
- Jim_CreateCommand(interp, "os.sethostname", Jim_PosixSethostnameCommand, NULL, NULL);
- Jim_CreateCommand(interp, "os.usleep", Jim_LinuxUSleepCommand, NULL, NULL);
- Jim_CreateCommand(interp, "os.signal", Jim_PosixSignalCommand, NULL, NULL);
- Jim_CreateCommand(interp, "pit", Jim_PointInTimeCommand, NULL, NULL);
- Jim_CreateCommand(interp, "Jpit", Jim_PointInTimeJulianCommand, NULL, NULL);
return JIM_OK;
}
diff --git a/jim-signal.c b/jim-signal.c
new file mode 100644
index 0000000..1d21d59
--- /dev/null
+++ b/jim-signal.c
@@ -0,0 +1,492 @@
+/*
+ * jim-signal.c
+ *
+ */
+
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "jim.h"
+#include "jim-subcmd.h"
+
+#define MAX_SIGNALS 32
+
+static int *sigloc;
+static unsigned long sigsblocked;
+static struct sigaction *sa_old;
+static int signal_handling[MAX_SIGNALS];
+
+static void signal_handler(int sig)
+{
+ /* We just remember which signal occurred. Jim_Eval() will
+ * notice this as soon as it can and throw an error
+ */
+ *sigloc = sig;
+}
+
+static void signal_ignorer(int sig)
+{
+ /* We just remember which signals occurred */
+ sigsblocked |= (1 << sig);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SignalId --
+ *
+ * Return a textual identifier for a signal number.
+ *
+ * Results:
+ * This procedure returns a machine-readable textual identifier
+ * that corresponds to sig. The identifier is the same as the
+ * #define name in signal.h.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *Jim_SignalId(int sig)
+{
+ switch (sig) {
+#ifdef SIGABRT
+ case SIGABRT: return "SIGABRT";
+#endif
+#ifdef SIGALRM
+ case SIGALRM: return "SIGALRM";
+#endif
+#ifdef SIGBUS
+ case SIGBUS: return "SIGBUS";
+#endif
+#ifdef SIGCHLD
+ case SIGCHLD: return "SIGCHLD";
+#endif
+#if defined(SIGCLD) && (!defined(SIGCHLD) || (SIGCLD != SIGCHLD))
+ case SIGCLD: return "SIGCLD";
+#endif
+#ifdef SIGCONT
+ case SIGCONT: return "SIGCONT";
+#endif
+#if defined(SIGEMT) && (!defined(SIGXCPU) || (SIGEMT != SIGXCPU))
+ case SIGEMT: return "SIGEMT";
+#endif
+#ifdef SIGFPE
+ case SIGFPE: return "SIGFPE";
+#endif
+#ifdef SIGHUP
+ case SIGHUP: return "SIGHUP";
+#endif
+#ifdef SIGILL
+ case SIGILL: return "SIGILL";
+#endif
+#ifdef SIGINT
+ case SIGINT: return "SIGINT";
+#endif
+#ifdef SIGIO
+ case SIGIO: return "SIGIO";
+#endif
+#if defined(SIGIOT) && (!defined(SIGABRT) || (SIGIOT != SIGABRT))
+ case SIGIOT: return "SIGIOT";
+#endif
+#ifdef SIGKILL
+ case SIGKILL: return "SIGKILL";
+#endif
+#if defined(SIGLOST) && (!defined(SIGIOT) || (SIGLOST != SIGIOT)) && (!defined(SIGURG) || (SIGLOST != SIGURG))
+ case SIGLOST: return "SIGLOST";
+#endif
+#ifdef SIGPIPE
+ case SIGPIPE: return "SIGPIPE";
+#endif
+#if defined(SIGPOLL) && (!defined(SIGIO) || (SIGPOLL != SIGIO))
+ case SIGPOLL: return "SIGPOLL";
+#endif
+#ifdef SIGPROF
+ case SIGPROF: return "SIGPROF";
+#endif
+#if defined(SIGPWR) && (!defined(SIGXFSZ) || (SIGPWR != SIGXFSZ))
+ case SIGPWR: return "SIGPWR";
+#endif
+#ifdef SIGQUIT
+ case SIGQUIT: return "SIGQUIT";
+#endif
+#ifdef SIGSEGV
+ case SIGSEGV: return "SIGSEGV";
+#endif
+#ifdef SIGSTOP
+ case SIGSTOP: return "SIGSTOP";
+#endif
+#ifdef SIGSYS
+ case SIGSYS: return "SIGSYS";
+#endif
+#ifdef SIGTERM
+ case SIGTERM: return "SIGTERM";
+#endif
+#ifdef SIGTRAP
+ case SIGTRAP: return "SIGTRAP";
+#endif
+#ifdef SIGTSTP
+ case SIGTSTP: return "SIGTSTP";
+#endif
+#ifdef SIGTTIN
+ case SIGTTIN: return "SIGTTIN";
+#endif
+#ifdef SIGTTOU
+ case SIGTTOU: return "SIGTTOU";
+#endif
+#if defined(SIGURG) && (!defined(SIGIO) || (SIGURG != SIGIO))
+ case SIGURG: return "SIGURG";
+#endif
+#ifdef SIGUSR1
+ case SIGUSR1: return "SIGUSR1";
+#endif
+#ifdef SIGUSR2
+ case SIGUSR2: return "SIGUSR2";
+#endif
+#ifdef SIGVTALRM
+ case SIGVTALRM: return "SIGVTALRM";
+#endif
+#ifdef SIGWINCH
+ case SIGWINCH: return "SIGWINCH";
+#endif
+#ifdef SIGXCPU
+ case SIGXCPU: return "SIGXCPU";
+#endif
+#ifdef SIGXFSZ
+ case SIGXFSZ: return "SIGXFSZ";
+#endif
+#ifdef SIGINFO
+ case SIGINFO: return "SIGINFO";
+#endif
+ }
+ return "unknown signal";
+}
+
+/**
+ * Given the name of a signal, returns the signal value if found,
+ * or returns -1 (and sets an error) if not found.
+ * We accept -SIGINT, SIGINT, INT or any lowercase version or a number,
+ * either positive or negative.
+ */
+static int
+find_signal_by_name(Jim_Interp *interp, const char *name)
+{
+ int i;
+ const char *pt = name;
+
+ /* Remove optional - and SIG from the front of the name */
+ if (*pt == '-') {
+ pt++;
+ }
+ if (strncasecmp(name, "sig", 3) == 0) {
+ pt += 3;
+ }
+ if (isdigit(pt[0])) {
+ i = atoi(pt);
+ if (i > 0 && i < MAX_SIGNALS) {
+ return i;
+ }
+ }
+ else {
+ for (i = 1; i < MAX_SIGNALS; i++) {
+ /* Jim_SignalId() returns names such as SIGINT, and
+ * returns "unknown signal id" if unknown, so this will work
+ */
+ if (strcasecmp(Jim_SignalId(i) + 3, pt) == 0) {
+ return i;
+ }
+ }
+ }
+ Jim_SetResultString(interp, "unknown signal ", -1);
+ Jim_AppendString(interp, Jim_GetResult(interp), name, -1);
+
+ return -1;
+}
+
+#define SIGNAL_ACTION_HANDLE 1
+#define SIGNAL_ACTION_IGNORE -1
+#define SIGNAL_ACTION_DEFAULT 0
+
+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 (signal_handling[i] == action) {
+ /* Add signal name to the list */
+ Jim_ListAppendElement(interp, Jim_GetResult(interp),
+ Jim_NewStringObj(interp, Jim_SignalId(i), -1));
+ }
+ }
+ return JIM_OK;
+ }
+
+ /* Make sure we know where to store the signals which occur */
+ if (!sigloc) {
+ sigloc = &interp->signal;
+ }
+
+ /* Catch all the signals we care about */
+ if (action != SIGNAL_ACTION_DEFAULT) {
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ 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_GetString(argv[i], NULL));
+ if (sig < 0) {
+ return JIM_ERR;
+ }
+ if (action != signal_handling[sig]) {
+ /* Need to change the action for this signal */
+ switch (action) {
+ case SIGNAL_ACTION_HANDLE:
+ case SIGNAL_ACTION_IGNORE:
+ if (signal_handling[sig] == 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);
+ }
+ }
+ signal_handling[sig] = action;
+ }
+ }
+
+ return JIM_OK;
+}
+
+static int signal_cmd_handle(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ return do_signal_cmd(interp, SIGNAL_ACTION_HANDLE, argc, argv);
+}
+
+static int signal_cmd_ignore(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ return do_signal_cmd(interp, SIGNAL_ACTION_IGNORE, argc, argv);
+}
+
+static int signal_cmd_default(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ return do_signal_cmd(interp, SIGNAL_ACTION_DEFAULT, argc, argv);
+}
+
+static int signal_cmd_throw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int sig = SIGINT;
+ if (argc == 1) {
+ if ((sig = find_signal_by_name(interp, Jim_GetString(argv[0], NULL))) < 0) {
+ return JIM_ERR;
+ }
+ }
+
+ /* Just set the signal */
+ interp->signal = sig;
+
+#if 1
+ /* Set the canonical name of the signal as the result */
+ Jim_SetResultString(interp, Jim_SignalId(sig), -1);
+#endif
+
+ /* And simply say we caught the signal */
+ return JIM_SIGNAL;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Jim_SignalCmd --
+ * Implements the TCL signal command:
+ * signal handle|ignore|default|throw ?signals ...?
+ * signal throw signal
+ *
+ * Specifies which signals are handled by Tcl code.
+ * If the one of the given signals is caught, it causes a JIM_SIGNAL
+ * exception to be thrown which can be caught by catch.
+ *
+ * Use 'signal ignore' to ignore the signal(s)
+ * Use 'signal default' to go back to the default behaviour
+ * Use 'signal throw signal' to raise the given signal
+ *
+ * If no arguments are given, returns the list of signals which are being handled
+ *
+ * Results:
+ * Standard TCL results.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static const jim_subcmd_type signal_command_table[] = {
+ { .cmd = "handle",
+ .args = "?signals ...?",
+ .function = signal_cmd_handle,
+ .minargs = 0,
+ .maxargs = -1,
+ .description = "Lists handled signals, or adds to handled signals"
+ },
+ { .cmd = "ignore",
+ .args = "?signals ...?",
+ .function = signal_cmd_ignore,
+ .minargs = 0,
+ .maxargs = -1,
+ .description = "Lists ignored signals, or adds to ignored signals"
+ },
+ { .cmd = "default",
+ .args = "?signals ...?",
+ .function = signal_cmd_default,
+ .minargs = 0,
+ .maxargs = -1,
+ .description = "Lists defaulted signals, or adds to defaulted signals"
+ },
+ { .cmd = "throw",
+ .args = "?signal?",
+ .function = signal_cmd_throw,
+ .minargs = 0,
+ .maxargs = 1,
+ .description = "Raises the given signal (default SIGINT)"
+ },
+ { 0 }
+};
+
+static int Jim_AlarmCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int ret;
+
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "seconds");
+ return JIM_ERR;
+ }
+ else {
+#ifdef HAVE_UALARM
+ double t;
+
+ ret = Jim_GetDouble(interp, argv[1], &t);
+ if (ret == JIM_OK) {
+ if (t < 10) {
+ ualarm(t * 1e6, 0);
+ }
+ else {
+ alarm(t);
+ }
+ }
+#else
+ long t;
+
+ ret = Jim_GetLong (interp, argv[1], &t);
+ if (ret == JIM_OK) {
+ alarm(t);
+ }
+#endif
+ }
+
+ return ret;
+}
+
+static int Jim_SleepCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int ret;
+
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "seconds");
+ return JIM_ERR;
+ }
+ else {
+ double t;
+
+ ret = Jim_GetDouble(interp, argv[1], &t);
+ if (ret == JIM_OK) {
+ if (t < 10) {
+ usleep(t * 1e6);
+ }
+ else {
+ sleep(t);
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int Jim_KillCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int sig;
+ long pid;
+ Jim_Obj *pidObj;
+ const char *signame;
+
+ if (argc != 2 && argc != 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "?SIG|-0? pid");
+ return JIM_ERR;
+ }
+
+ if (argc == 2) {
+ signame = "SIGTERM";
+ pidObj = argv[1];
+ }
+ else {
+ signame = Jim_GetString(argv[1], NULL);
+ pidObj = argv[2];
+ }
+
+ /* Special 'kill -0 pid' to determine if a pid exists */
+ if (strcmp(signame, "-0") == 0 || strcmp(signame, "0") == 0) {
+ sig = 0;
+ }
+ else {
+ sig = find_signal_by_name(interp, signame);
+ if (sig < 0) {
+ return JIM_ERR;
+ }
+ }
+
+ if (Jim_GetLong(interp, pidObj, &pid) != JIM_OK) {
+ return JIM_ERR;
+ }
+
+ if (kill(pid, sig) == 0) {
+ return JIM_OK;
+ }
+
+ Jim_SetResultString(interp, "kill: Failed to deliver signal", -1);
+ return JIM_ERR;
+}
+
+int Jim_signalInit(Jim_Interp *interp)
+{
+ if (Jim_PackageProvide(interp, "signal", "1.0", JIM_ERRMSG) != JIM_OK) {
+ return JIM_ERR;
+ }
+ /* Teach the jim core how to convert signal values to names */
+ interp->signal_to_name = Jim_SignalId;
+
+ Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, NULL);
+ Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0);
+ Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0);
+
+ /* Sleep is slightly dubious here */
+ Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0);
+ return JIM_OK;
+}
diff --git a/jim.c b/jim.c
index 001c903..1a3f1f1 100644
--- a/jim.c
+++ b/jim.c
@@ -113,33 +113,6 @@ static Jim_HashTableType JimVariablesHashTableType;
* Utility functions
* ---------------------------------------------------------------------------*/
-static char *
-jim_vasprintf( const char *fmt, va_list ap )
-{
-#ifndef HAVE_VASPRINTF
- /* yucky way */
-static char buf[2048];
- vsnprintf( buf, sizeof(buf), fmt, ap );
- /* garentee termination */
- buf[sizeof(buf)-1] = 0;
-#else
- char *buf;
- vasprintf( &buf, fmt, ap );
-#endif
- return buf;
-}
-
-static void
-jim_vasprintf_done( void *buf )
-{
-#ifndef HAVE_VASPRINTF
- (void)(buf);
-#else
- free(buf);
-#endif
-}
-
-
/*
* Convert a string to a jim_wide INTEGER.
* This function originates from BSD.
@@ -515,9 +488,9 @@ void Jim_Panic(Jim_Interp *interp, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- /*
- * Send it here first.. Assuming STDIO still works
- */
+ /*
+ * Send it here first.. Assuming STDIO still works
+ */
fprintf(stderr, JIM_NL "JIM INTERPRETER PANIC: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, JIM_NL JIM_NL);
@@ -538,10 +511,6 @@ void Jim_Panic(Jim_Interp *interp, const char *fmt, ...)
}
#endif
- fprintf(stderr, JIM_NL "JIM INTERPRETER PANIC: ");
- vfprintf(stderr, fmt, ap );
- fprintf(stderr, JIM_NL JIM_NL );
-
abort();
}
@@ -560,9 +529,10 @@ void Jim_Panic(Jim_Interp *interp, const char *fmt, ...)
void *Jim_Alloc(int size)
{
- /* We allocate zero length arrayes, etc. to use a single orthogonal codepath */
- if (size==0)
- size=1;
+ /* We allocate zero length arrayes, etc. to use a single orthogonal codepath */
+ if (size==0) {
+ size = 1;
+ }
void *p = malloc(size);
if (p == NULL)
Jim_Panic(NULL,"malloc: Out of memory");
@@ -575,9 +545,10 @@ void Jim_Free(void *ptr) {
void *Jim_Realloc(void *ptr, int size)
{
- /* We allocate zero length arrayes, etc. to use a single orthogonal codepath */
- if (size==0)
- size=1;
+ /* We allocate zero length arrayes, etc. to use a single orthogonal codepath */
+ if (size==0) {
+ size = 1;
+ }
void *p = realloc(ptr, size);
if (p == NULL)
Jim_Panic(NULL,"realloc: Out of memory");
@@ -990,6 +961,7 @@ static void JimStringKeyValCopyHTValDestructor(void *privdata, void *val)
Jim_Free((void*)val); /* ATTENTION: const cast */
}
+#if 0
static Jim_HashTableType JimStringCopyHashTableType = {
JimStringCopyHTHashFunction, /* hash function */
JimStringCopyHTKeyDup, /* key dup */
@@ -998,6 +970,7 @@ static Jim_HashTableType JimStringCopyHashTableType = {
JimStringCopyHTKeyDestructor, /* key destructor */
NULL /* val destructor */
};
+#endif
/* This is like StringCopy but does not auto-duplicate the key.
* It's used for intepreter's shared strings. */
@@ -2048,22 +2021,6 @@ void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str,
StringAppendString(objPtr, str, len);
}
-void Jim_AppendString_sprintf( Jim_Interp *interp, Jim_Obj *objPtr, const char *fmt, ... )
-{
- char *buf;
- va_list ap;
-
- va_start( ap, fmt );
- buf = jim_vasprintf( fmt, ap );
- va_end(ap);
-
- if( buf ){
- Jim_AppendString( interp, objPtr, buf, -1 );
- jim_vasprintf_done(buf);
- }
-}
-
-
void Jim_AppendObj(Jim_Interp *interp, Jim_Obj *objPtr,
Jim_Obj *appendObjPtr)
{
@@ -2309,27 +2266,26 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
Jim_Obj *resObjPtr;
- fmt = Jim_GetString(fmtObjPtr, &fmtLen);
- _fmt = fmt;
+ _fmt = fmt = Jim_GetString(fmtObjPtr, &fmtLen);
resObjPtr = Jim_NewStringObj(interp, "", 0);
while (fmtLen) {
const char *p = fmt;
char spec[2], c;
jim_wide wideValue;
- double doubleValue;
- /* we cheat and use Sprintf()! */
- char fmt_str[100];
- char *cp;
- int width;
- int ljust;
- int zpad;
- int spad;
- int altfm;
- int forceplus;
- int prec;
- int inprec;
- int haveprec;
- int accum;
+ double doubleValue;
+ /* we cheat and use Sprintf()! */
+ char fmt_str[100];
+ char *cp;
+ int width;
+ int ljust;
+ int zpad;
+ int spad;
+ int altfm;
+ int forceplus;
+ int prec;
+ int inprec;
+ int haveprec;
+ int accum;
while (*fmt != '%' && fmtLen) {
fmt++; fmtLen--;
@@ -2338,226 +2294,225 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
if (fmtLen == 0)
break;
fmt++; fmtLen--; /* skip '%' */
- zpad = 0;
- spad = 0;
- width = -1;
- ljust = 0;
- altfm = 0;
- forceplus = 0;
- inprec = 0;
- haveprec = 0;
- prec = -1; /* not found yet */
+ zpad = 0;
+ spad = 0;
+ width = -1;
+ ljust = 0;
+ altfm = 0;
+ forceplus = 0;
+ inprec = 0;
+ haveprec = 0;
+ prec = -1; /* not found yet */
next_fmt:
- if( fmtLen <= 0 ){
- break;
- }
- switch( *fmt ){
- /* terminals */
+ if( fmtLen <= 0 ){
+ break;
+ }
+ switch( *fmt ){
+ /* terminals */
case 'b': /* binary - not all printfs() do this */
- case 's': /* string */
- case 'i': /* integer */
- case 'd': /* decimal */
- case 'x': /* hex */
- case 'X': /* CAP hex */
- case 'c': /* char */
- case 'o': /* octal */
- case 'u': /* unsigned */
- case 'f': /* float */
- break;
-
- /* non-terminals */
- case '0': /* zero pad */
- zpad = 1;
- fmt++; fmtLen--;
- goto next_fmt;
- break;
- case '+':
- forceplus = 1;
- fmt++; fmtLen--;
- goto next_fmt;
- break;
- case ' ': /* sign space */
- spad = 1;
- fmt++; fmtLen--;
- goto next_fmt;
- break;
- case '-':
- ljust = 1;
- fmt++; fmtLen--;
- goto next_fmt;
- break;
- case '#':
- altfm = 1;
- fmt++; fmtLen--;
- goto next_fmt;
-
- case '.':
- inprec = 1;
- fmt++; fmtLen--;
- goto next_fmt;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- accum = 0;
- while( isdigit(*fmt) && (fmtLen > 0) ){
- accum = (accum * 10) + (*fmt - '0');
- fmt++; fmtLen--;
- }
- if( inprec ){
- haveprec = 1;
- prec = accum;
- } else {
- width = accum;
- }
- goto next_fmt;
- case '*':
- /* suck up the next item as an integer */
- fmt++; fmtLen--;
- objc--;
- if( objc <= 0 ){
- goto not_enough_args;
- }
- if( Jim_GetWide(interp,objv[0],&wideValue )== JIM_ERR ){
- Jim_FreeNewObj(interp, resObjPtr );
- return NULL;
- }
- if( inprec ){
- haveprec = 1;
- prec = wideValue;
- if( prec < 0 ){
- /* man 3 printf says */
- /* if prec is negative, it is zero */
- prec = 0;
- }
- } else {
- width = wideValue;
- if( width < 0 ){
- ljust = 1;
- width = -width;
- }
- }
- objv++;
- goto next_fmt;
- break;
- }
-
-
- if (*fmt != '%') {
+ case 's': /* string */
+ case 'i': /* integer */
+ case 'd': /* decimal */
+ case 'x': /* hex */
+ case 'X': /* CAP hex */
+ case 'c': /* char */
+ case 'o': /* octal */
+ case 'u': /* unsigned */
+ case 'f': /* float */
+ break;
+
+ /* non-terminals */
+ case '0': /* zero pad */
+ zpad = 1;
+ fmt++; fmtLen--;
+ goto next_fmt;
+ break;
+ case '+':
+ forceplus = 1;
+ fmt++; fmtLen--;
+ goto next_fmt;
+ break;
+ case ' ': /* sign space */
+ spad = 1;
+ fmt++; fmtLen--;
+ goto next_fmt;
+ break;
+ case '-':
+ ljust = 1;
+ fmt++; fmtLen--;
+ goto next_fmt;
+ break;
+ case '#':
+ altfm = 1;
+ fmt++; fmtLen--;
+ goto next_fmt;
+
+ case '.':
+ inprec = 1;
+ fmt++; fmtLen--;
+ goto next_fmt;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ accum = 0;
+ while( isdigit(*fmt) && (fmtLen > 0) ){
+ accum = (accum * 10) + (*fmt - '0');
+ fmt++; fmtLen--;
+ }
+ if( inprec ){
+ haveprec = 1;
+ prec = accum;
+ } else {
+ width = accum;
+ }
+ goto next_fmt;
+ case '*':
+ /* suck up the next item as an integer */
+ fmt++; fmtLen--;
+ objc--;
+ if( objc <= 0 ){
+ goto not_enough_args;
+ }
+ if( Jim_GetWide(interp,objv[0],&wideValue )== JIM_ERR ){
+ Jim_FreeNewObj(interp, resObjPtr );
+ return NULL;
+ }
+ if( inprec ){
+ haveprec = 1;
+ prec = wideValue;
+ if( prec < 0 ){
+ /* man 3 printf says */
+ /* if prec is negative, it is zero */
+ prec = 0;
+ }
+ } else {
+ width = wideValue;
+ if( width < 0 ){
+ ljust = 1;
+ width = -width;
+ }
+ }
+ objv++;
+ goto next_fmt;
+ break;
+ }
+
+
+ if (*fmt != '%') {
if (objc == 0) {
- not_enough_args:
+ not_enough_args:
Jim_FreeNewObj(interp, resObjPtr);
- Jim_SetResultString(interp,
- "not enough arguments for all format specifiers", -1);
+ Jim_SetResultString(interp, "not enough arguments for all format specifiers", -1);
return NULL;
} else {
objc--;
}
}
-
- /*
- * Create the formatter
- * cause we cheat and use sprintf()
- */
- cp = fmt_str;
- *cp++ = '%';
- if( altfm ){
- *cp++ = '#';
- }
- if( forceplus ){
- *cp++ = '+';
- } else if( spad ){
- /* PLUS overrides */
- *cp++ = ' ';
- }
- if( ljust ){
- *cp++ = '-';
- }
- if( zpad ){
- *cp++ = '0';
- }
- if( width > 0 ){
- sprintf( cp, "%d", width );
- /* skip ahead */
- cp = strchr(cp,0);
- }
- /* did we find a period? */
- if( inprec ){
- /* then add it */
- *cp++ = '.';
- /* did something occur after the period? */
- if( haveprec ){
- sprintf( cp, "%d", prec );
- }
- cp = strchr(cp,0);
- }
- *cp = 0;
-
- /* here we do the work */
- /* actually - we make sprintf() do it for us */
+
+ /*
+ * Create the formatter
+ * cause we cheat and use sprintf()
+ */
+ cp = fmt_str;
+ *cp++ = '%';
+ if( altfm ){
+ *cp++ = '#';
+ }
+ if( forceplus ){
+ *cp++ = '+';
+ } else if( spad ){
+ /* PLUS overrides */
+ *cp++ = ' ';
+ }
+ if( ljust ){
+ *cp++ = '-';
+ }
+ if( zpad ){
+ *cp++ = '0';
+ }
+ if( width > 0 ){
+ sprintf( cp, "%d", width );
+ /* skip ahead */
+ cp = strchr(cp,0);
+ }
+ /* did we find a period? */
+ if( inprec ){
+ /* then add it */
+ *cp++ = '.';
+ /* did something occur after the period? */
+ if( haveprec ){
+ sprintf( cp, "%d", prec );
+ }
+ cp = strchr(cp,0);
+ }
+ *cp = 0;
+
+ /* here we do the work */
+ /* actually - we make sprintf() do it for us */
switch(*fmt) {
case 's':
- *cp++ = 's';
- *cp = 0;
- /* BUG: we do not handled embeded NULLs */
- snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, Jim_GetString( objv[0], NULL ));
+ *cp++ = 's';
+ *cp = 0;
+ /* BUG: we do not handled embeded NULLs */
+ snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, Jim_GetString( objv[0], NULL ));
break;
case 'c':
- *cp++ = 'c';
- *cp = 0;
+ *cp++ = 'c';
+ *cp = 0;
if (Jim_GetWide(interp, objv[0], &wideValue) == JIM_ERR) {
Jim_FreeNewObj(interp, resObjPtr);
return NULL;
}
c = (char) wideValue;
- snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, c );
+ snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, c );
+ break;
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'e':
+ case 'E':
+ *cp++ = *fmt;
+ *cp = 0;
+ if( Jim_GetDouble( interp, objv[0], &doubleValue ) == JIM_ERR ){
+ Jim_FreeNewObj( interp, resObjPtr );
+ return NULL;
+ }
+ snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, doubleValue );
break;
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- case 'e':
- case 'E':
- *cp++ = *fmt;
- *cp = 0;
- if( Jim_GetDouble( interp, objv[0], &doubleValue ) == JIM_ERR ){
- Jim_FreeNewObj( interp, resObjPtr );
- return NULL;
- }
- snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, doubleValue );
- break;
case 'b':
case 'd':
case 'o':
- case 'i':
- case 'u':
- case 'x':
- case 'X':
- /* jim widevaluse are 64bit */
- if( sizeof(jim_wide) == sizeof(long long) ){
- *cp++ = 'l';
- *cp++ = 'l';
- } else {
- *cp++ = 'l';
- }
- *cp++ = *fmt;
- *cp = 0;
+ case 'i':
+ case 'u':
+ case 'x':
+ case 'X':
+ /* jim widevaluse are 64bit */
+ if( sizeof(jim_wide) == sizeof(long long) ){
+ *cp++ = 'l';
+ *cp++ = 'l';
+ } else {
+ *cp++ = 'l';
+ }
+ *cp++ = *fmt;
+ *cp = 0;
if (Jim_GetWide(interp, objv[0], &wideValue) == JIM_ERR) {
Jim_FreeNewObj(interp, resObjPtr);
return NULL;
}
- snprintf(sprintf_buf, JIM_MAX_FMT, fmt_str, wideValue );
+ snprintf(sprintf_buf, JIM_MAX_FMT, fmt_str, wideValue );
break;
case '%':
- sprintf_buf[0] = '%';
- sprintf_buf[1] = 0;
- objv--; /* undo the objv++ below */
+ sprintf_buf[0] = '%';
+ sprintf_buf[1] = 0;
+ objv--; /* undo the objv++ below */
break;
default:
spec[0] = *fmt; spec[1] = '\0';
@@ -2567,16 +2522,16 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
"bad field specifier \"", spec, "\"", NULL);
return NULL;
}
- /* force terminate */
+ /* force terminate */
#if 0
- printf("FMT was: %s\n", fmt_str );
- printf("RES was: |%s|\n", sprintf_buf );
+ printf("FMT was: %s\n", fmt_str );
+ printf("RES was: |%s|\n", sprintf_buf );
#endif
-
- sprintf_buf[ JIM_MAX_FMT - 1] = 0;
- Jim_AppendString( interp, resObjPtr, sprintf_buf, strlen(sprintf_buf) );
- /* next obj */
- objv++;
+
+ sprintf_buf[ JIM_MAX_FMT - 1] = 0;
+ Jim_AppendString( interp, resObjPtr, sprintf_buf, strlen(sprintf_buf) );
+ /* next obj */
+ objv++;
fmt++;
fmtLen--;
}
@@ -2586,10 +2541,10 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
int objc, Jim_Obj *const *objv)
{
- char *sprintf_buf=malloc(JIM_MAX_FMT);
- Jim_Obj *t=Jim_FormatString_Inner(interp, fmtObjPtr, objc, objv, sprintf_buf);
- free(sprintf_buf);
- return t;
+ char *sprintf_buf=malloc(JIM_MAX_FMT);
+ Jim_Obj *t=Jim_FormatString_Inner(interp, fmtObjPtr, objc, objv, sprintf_buf);
+ free(sprintf_buf);
+ return t;
}
/* -----------------------------------------------------------------------------
@@ -4432,7 +4387,6 @@ Jim_Interp *Jim_CreateInterp(void)
Jim_InitHashTable(&i->references, &JimReferencesHashTableType, i);
Jim_InitHashTable(&i->sharedStrings, &JimSharedStringsHashTableType,
NULL);
- Jim_InitHashTable(&i->stub, &JimStringCopyHashTableType, NULL);
Jim_InitHashTable(&i->assocData, &JimAssocDataHashTableType, i);
Jim_InitHashTable(&i->packages, &JimStringKeyValCopyHashTableType, NULL);
i->framePtr = i->topFramePtr = JimCreateCallFrame(i);
@@ -4476,7 +4430,6 @@ void Jim_FreeInterp(Jim_Interp *i)
Jim_Free((void*)i->scriptFileName);
Jim_FreeHashTable(&i->commands);
Jim_FreeHashTable(&i->references);
- Jim_FreeHashTable(&i->stub);
Jim_FreeHashTable(&i->assocData);
Jim_FreeHashTable(&i->packages);
Jim_Free(i->prngState);
@@ -5274,8 +5227,6 @@ static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj)
Jim_Obj *compare_script = Jim_DuplicateObj(sort_interp, sort_command);
long ret = 0;
- //fprintf(stderr, "ListSortCommand: lhsObj=%s, rhsObj=%s\n", Jim_GetString(*lhsObj, NULL), Jim_GetString(*rhsObj, NULL));
-
/* We have already had an error, so just compare pointers */
if (sort_result != JIM_OK) {
return (long)lhsObj - (long)rhsObj;
@@ -6378,7 +6329,7 @@ int JimParseExprNumber(struct JimParserCtx *pc)
if ((*pc->p == 'x') || (*pc->p == 'X')) {
allowhex = 1;
allowdot = 0;
- }
+ }
if (*pc->p == '.')
allowdot = 0;
pc->p++; pc->len--;
@@ -7978,6 +7929,7 @@ int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
/* Decr refcount of arguments and return the retcode */
for (i = 0; i < objc; i++)
Jim_DecrRefCount(interp, objv[i]);
+
return retcode;
}
@@ -8199,8 +8151,9 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
break;
case JIM_TT_CMD:
retcode = Jim_EvalObj(interp, token[i].objPtr);
- if (retcode != JIM_OK)
+ if (retcode != JIM_OK) {
goto err;
+ }
argv[j] = Jim_GetResult(interp);
break;
default:
@@ -8274,6 +8227,10 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
token[i-argc*2].linenr);
}
}
+ if (interp->signal_level && interp->signal) {
+ /* Check for a signal after each command */
+ retcode = JIM_SIGNAL;
+ }
if (retcode != JIM_OK) {
i -= argc*2; /* point to the command name. */
goto err;
@@ -8437,13 +8394,13 @@ int Jim_Eval_Named(Jim_Interp *interp, const char *script, const char *filename,
int retval;
Jim_Obj *scriptObjPtr;
- scriptObjPtr = Jim_NewStringObj(interp, script, -1);
+ scriptObjPtr = Jim_NewStringObj(interp, script, -1);
Jim_IncrRefCount(scriptObjPtr);
- if( filename ){
- JimSetSourceInfo( interp, scriptObjPtr, filename, lineno );
- }
+ if( filename ){
+ JimSetSourceInfo( interp, scriptObjPtr, filename, lineno );
+ }
retval = Jim_EvalObj(interp, scriptObjPtr);
Jim_DecrRefCount(interp, scriptObjPtr);
@@ -8452,7 +8409,7 @@ int Jim_Eval_Named(Jim_Interp *interp, const char *script, const char *filename,
int Jim_Eval(Jim_Interp *interp, const char *script)
{
- return Jim_Eval_Named( interp, script, NULL, 0 );
+ return Jim_Eval_Named( interp, script, NULL, 0 );
}
@@ -8498,6 +8455,7 @@ int Jim_EvalObjBackground(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
return retval;
}
+/* REVISIT: Just load the file with a single malloc/fread then Jim_EvalObj() */
int Jim_EvalFile(Jim_Interp *interp, const char *filename)
{
char *prg = NULL;
@@ -8507,15 +8465,15 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename)
Jim_Obj *scriptObjPtr;
if ((fp = fopen(filename, "r")) == NULL) {
- const int cwd_len=2048;
- char *cwd=malloc(cwd_len);
+ const int cwd_len=2048;
+ char *cwd=malloc(cwd_len);
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- getcwd( cwd, cwd_len );
+ getcwd( cwd, cwd_len );
Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Error loading script \"", filename, "\"",
- " cwd: ", cwd,
- " err: ", strerror(errno), NULL);
- free(cwd);
+ "Error loading script \"", filename, "\"",
+ " cwd: ", cwd,
+ " err: ", strerror(errno), NULL);
+ free(cwd);
return JIM_ERR;
}
buflen = 1024;
@@ -8525,12 +8483,10 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename)
maxlen = totread+buflen+1;
prg = Jim_Realloc(prg, maxlen);
}
- /* do not use Jim_fread() - this is really a file */
if ((nread = fread(prg+totread, 1, buflen, fp)) == 0) break;
totread += nread;
}
prg[totread] = '\0';
- /* do not use Jim_fclose() - this is really a file */
fclose(fp);
scriptObjPtr = Jim_NewStringObjNoAlloc(interp, prg, totread);
@@ -9682,8 +9638,8 @@ static int Jim_IfCoreCommand(Jim_Interp *interp, int argc,
return Jim_EvalObj(interp, argv[current]);
/* Ok: no else-clause follows */
if (++current >= argc) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- return JIM_OK;
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ return JIM_OK;
}
falsebody = current++;
if (Jim_CompareStringImmediate(interp, argv[falsebody],
@@ -10795,12 +10751,44 @@ static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
{
int exitCode = 0;
+ int sig = 0;
- if (argc != 2 && argc != 3) {
- Jim_WrongNumArgs(interp, 1, argv, "script ?varName?");
+ if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-signal")) {
+ sig++;
+ }
+
+ if (argc - sig != 2 && argc - sig != 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "?-signal? script ?varName?");
return JIM_ERR;
}
+ argc -= sig;
+ argv += sig;
+
+ interp->signal_level += sig;
exitCode = Jim_EvalObj(interp, argv[1]);
+ interp->signal_level -= sig;
+
+
+ /* If we get TCL_SIGNAL without the -signal parameter,
+ * just pass it through to be caught at a higher level
+ */
+ if (exitCode == JIM_SIGNAL && !sig) {
+ return exitCode;
+ }
+
+ if (sig) {
+ if (exitCode == JIM_SIGNAL && interp->signal_level == 0) {
+ /* Yes, catch the signal at this level */
+ if (interp->signal_to_name) {
+ Jim_SetResultString(interp, interp->signal_to_name(interp->signal), -1);
+ }
+ else {
+ Jim_SetResultInt(interp, interp->signal);
+ }
+ interp->signal = 0;
+ }
+ }
+
if (argc == 3) {
if (Jim_SetVariable(interp, argv[2], Jim_GetResult(interp))
!= JIM_OK)
@@ -10996,17 +10984,6 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc,
return JIM_OK;
}
-/* [load] */
-static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- if (argc < 2) {
- Jim_WrongNumArgs(interp, 1, argv, "libaryFile");
- return JIM_ERR;
- }
- return Jim_LoadLibrary(interp, Jim_GetString(argv[1], NULL));
-}
-
/* [subst] */
static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
@@ -11536,54 +11513,6 @@ static int Jim_RandCoreCommand(Jim_Interp *interp, int argc,
}
}
-/* [package] */
-static int Jim_PackageCoreCommand(Jim_Interp *interp, int argc,
- Jim_Obj *const *argv)
-{
- int option;
- const char *options[] = {
- "require", "provide", NULL
- };
- enum {OPT_REQUIRE, OPT_PROVIDE};
-
- if (argc < 2) {
- Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?");
- return JIM_ERR;
- }
- if (Jim_GetEnum(interp, argv[1], options, &option, "option",
- JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
-
- if (option == OPT_REQUIRE) {
- int exact = 0;
- const char *ver;
-
- if (Jim_CompareStringImmediate(interp, argv[2], "-exact")) {
- exact = 1;
- argv++;
- argc--;
- }
- if (argc != 3 && argc != 4) {
- Jim_WrongNumArgs(interp, 2, argv, "?-exact? package ?version?");
- return JIM_ERR;
- }
- ver = Jim_PackageRequire(interp, Jim_GetString(argv[2], NULL),
- argc == 4 ? Jim_GetString(argv[3], NULL) : "",
- JIM_ERRMSG);
- if (ver == NULL)
- return JIM_ERR_ADDSTACK;
- Jim_SetResultString(interp, ver, -1);
- } else if (option == OPT_PROVIDE) {
- if (argc != 4) {
- Jim_WrongNumArgs(interp, 2, argv, "package version");
- return JIM_ERR;
- }
- return Jim_PackageProvide(interp, Jim_GetString(argv[2], NULL),
- Jim_GetString(argv[3], NULL), JIM_ERRMSG);
- }
- return JIM_OK;
-}
-
static struct {
const char *name;
Jim_CmdProc cmdProc;
@@ -11632,7 +11561,6 @@ static struct {
{"collect", Jim_CollectCoreCommand},
{"rename", Jim_RenameCoreCommand},
{"dict", Jim_DictCoreCommand},
- {"load", Jim_LoadCoreCommand},
{"subst", Jim_SubstCoreCommand},
{"info", Jim_InfoCoreCommand},
{"split", Jim_SplitCoreCommand},
@@ -11646,7 +11574,6 @@ static struct {
{"lreverse", Jim_LreverseCoreCommand},
{"range", Jim_RangeCoreCommand},
{"rand", Jim_RandCoreCommand},
- {"package", Jim_PackageCoreCommand},
{"tailcall", Jim_TailcallCoreCommand},
{NULL, NULL},
};
diff --git a/jim.h b/jim.h
index 6f06229..c6d7fa3 100644
--- a/jim.h
+++ b/jim.h
@@ -141,9 +141,10 @@ extern "C" {
#define JIM_RETURN 2
#define JIM_BREAK 3
#define JIM_CONTINUE 4
-#define JIM_EVAL 5
-#define JIM_EXIT 6
-#define JIM_ERR_ADDSTACK 7
+#define JIM_SIGNAL 5
+#define JIM_EVAL 6
+#define JIM_EXIT 7
+#define JIM_ERR_ADDSTACK 8
#define JIM_MAX_NESTING_DEPTH 10000 /* default max nesting depth */
/* Some function get an integer argument with flags to change
@@ -477,6 +478,10 @@ typedef struct Jim_Interp {
int maxNestingDepth; /* Used for infinite loop detection. */
int returnCode; /* Completion code to return on JIM_RETURN. */
int exitCode; /* Code to return to the OS on JIM_EXIT. */
+ int signal; /* A caught signal, or 0 if none */
+ int signal_level; /* A nesting level of catch -signal */
+ long id; /* Hold unique id for various purposes */
+ const char *(*signal_to_name)(int sig); /* Returns a name for the signal number */
Jim_CallFrame *framePtr; /* Pointer to the current call frame */
Jim_CallFrame *topFramePtr; /* toplevel/global frame pointer. */
struct Jim_HashTable commands; /* Commands hash table */
@@ -510,9 +515,6 @@ typedef struct Jim_Interp {
a command. It is set to what the user specified
via Jim_CreateCommand(). */
- struct Jim_HashTable stub; /* Stub hash table to export API */
- /* Jim_GetApi() function pointer, used to bootstrap the STUB table */
- int (*getApiFuncPtr)(struct Jim_Interp *, const char *, void *);
struct Jim_CallFrame *freeFramesList; /* list of CallFrame structures. */
struct Jim_HashTable assocData; /* per-interp storage for use by packages */
Jim_PrngState *prngState; /* per interpreter Random Number Gen. state. */
@@ -539,6 +541,9 @@ typedef struct Jim_Interp {
(i)->result = _resultObjPtr_; \
} while(0)
+/* Use this for filehandles, etc. which need a unique id */
+#define Jim_GetId(i) (++(i)->id)
+
/* Reference structure. The interpreter pointer is held within privdata member in HashTable */
#define JIM_REFERENCE_TAGLEN 7 /* The tag is fixed-length, because the reference
string representation must be fixed length. */
@@ -824,6 +829,10 @@ int Jim_StringToWide(const char *str, jim_wide *widePtr, int base);
/* jim-load.c */
int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName);
+
+/* jim-aio.c */
+FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command);
+
#ifdef __cplusplus
}
#endif