aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2016-03-25 18:09:56 +1000
committerSteve Bennett <steveb@workware.net.au>2025-03-13 10:26:16 +1000
commit15477c68e844200114bb3e13d895b7897b482864 (patch)
treeadd7c619d76390ebe46a964d431c911374f02bf1
parent54c9f51c15e7cbb3e2a62e04b1ad87402cb41486 (diff)
downloadjimtcl-15477c68e844200114bb3e13d895b7897b482864.zip
jimtcl-15477c68e844200114bb3e13d895b7897b482864.tar.gz
jimtcl-15477c68e844200114bb3e13d895b7897b482864.tar.bz2
eventloop: Add support for vwait script
An additional arg to vwait is now supported: vwait ?-signal? var ?script? If the script is given it is evaluated on every event. If the script returns a break or error code, the vwait terminates. This approach makes it easier to avoid using global variables to control the eventloop. Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim-eventloop.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/jim-eventloop.c b/jim-eventloop.c
index fa5631f..a3880ad 100644
--- a/jim-eventloop.c
+++ b/jim-eventloop.c
@@ -564,19 +564,24 @@ static void JimELAssocDataDeleProc(Jim_Interp *interp, void *data)
static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp);
- Jim_Obj *oldValue;
+ Jim_Obj *oldValue = NULL;
+ Jim_Obj *scriptObjPtr = NULL;
int rc;
int signal = 0;
- if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-signal")) {
+ if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-signal")) {
signal++;
}
- if (argc - signal != 2) {
+ if (argc - signal == 3) {
+ scriptObjPtr = argv[2 + signal];
+ }
+ else if (argc - signal != 2) {
return JIM_USAGE;
}
oldValue = Jim_GetGlobalVariable(interp, argv[1 + signal], JIM_NONE);
+
if (oldValue) {
Jim_IncrRefCount(oldValue);
}
@@ -590,6 +595,8 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
eventLoop->suppress_bgerror = 0;
while ((rc = Jim_ProcessEvents(interp, JIM_ALL_EVENTS)) >= 0) {
+ Jim_Obj *currValue;
+
if (signal && interp->sigmask) {
/* vwait -signal and handled signals were received, so transfer them
* to ignored signals so that 'signal check -clear' will return them.
@@ -602,7 +609,7 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
interp->sigmask = 0;
break;
}
- Jim_Obj *currValue;
+
currValue = Jim_GetGlobalVariable(interp, argv[1 + signal], JIM_NONE);
/* Stop the loop if the vwait-ed variable changed value,
* or if was unset and now is set (or the contrary)
@@ -614,6 +621,16 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_CheckSignal(interp)) {
break;
}
+ if (scriptObjPtr) {
+ /* Stop the loop if a provided script returns BREAK or ERR */
+ int retval = Jim_EvalObj(interp, scriptObjPtr);
+ if (retval == JIM_ERR || retval == JIM_BREAK) {
+ if (retval == JIM_ERR) {
+ rc = -2;
+ }
+ break;
+ }
+ }
}
if (oldValue)
Jim_DecrRefCount(interp, oldValue);
@@ -785,7 +802,7 @@ int Jim_eventloopInit(Jim_Interp *interp)
Jim_SetAssocData(interp, "eventloop", JimELAssocDataDeleProc, eventLoop);
- Jim_RegisterCmd(interp, "vwait", "?-signal? name", 1, 2, JimELVwaitCommand, NULL, eventLoop, 0);
+ Jim_RegisterCmd(interp, "vwait", "?-signal? name ?script?", 1, 3, JimELVwaitCommand, NULL, eventLoop, 0);
Jim_RegisterCmd(interp, "update", "?idletasks?", 0, 1, JimELUpdateCommand, NULL, eventLoop, 0);
Jim_RegisterCmd(interp, "after", "option ?arg ...?", 1, -1, JimELAfterCommand, NULL, eventLoop, 0);