Event loop in tclmain.c rewritten. New method searchStatus.
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 20 Mar 1995 08:53:22 +0000 (08:53 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 20 Mar 1995 08:53:22 +0000 (08:53 +0000)
ir-tcl.c
ir-tcl.h
iterate.tcl [new file with mode: 0644]
tclmain.c

index 19bed8c..baaf68d 100644 (file)
--- a/ir-tcl.c
+++ b/ir-tcl.c
@@ -1,9 +1,13 @@
 /*
  * IR toolkit for tcl/tk
  * (c) Index Data 1995
+ * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: ir-tcl.c,v $
- * Revision 1.13  1995-03-17 18:26:17  adam
+ * Revision 1.14  1995-03-20 08:53:22  adam
+ * Event loop in tclmain.c rewritten. New method searchStatus.
+ *
+ * Revision 1.13  1995/03/17  18:26:17  adam
  * Non-blocking i/o used now. Database names popup as cascade items.
  *
  * Revision 1.12  1995/03/17  15:45:00  adam
@@ -116,6 +120,7 @@ typedef struct IRRecordList_ {
 
 typedef struct IRSetObj_ {
     IRObj *parent;
+    int searchStatus;
     int resultCount;
     int start;
     int number;
@@ -598,8 +603,9 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp,
 
     if (argc < 3)
     {
-        interp->result = "wrong # args";
-        return TCL_ERROR;
+        for (i=0; i<p->num_databaseNames; i++)
+            Tcl_AppendElement (interp, p->databaseNames[i]);
+        return TCL_OK;
     }
     if (p->databaseNames)
     {
@@ -656,7 +662,7 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp,
     { 0, "init",                    do_init_request },
     { 0, "disconnect",              do_disconnect },
     { 0, "callback",                do_callback },
-    { 0, "databaseNames",           do_databaseNames},
+    { 1, "databaseNames",           do_databaseNames},
     { 1, "query",                   do_query },
     { 0, NULL, NULL}
     };
@@ -857,6 +863,18 @@ static int do_resultCount (void *o, Tcl_Interp *interp,
 }
 
 /*
+ * do_searchStatus: Get search status (after search response)
+ */
+static int do_searchStatus (void *o, Tcl_Interp *interp,
+                           int argc, char **argv)
+{
+    IRSetObj *obj = o;
+
+    sprintf (interp->result, "%d", obj->searchStatus);
+    return TCL_OK;
+}
+
+/*
  * do_numberOfRecordsReturned: Get number of records returned
  */
 static int do_numberOfRecordsReturned (void *o, Tcl_Interp *interp,
@@ -1196,6 +1214,7 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp,
 {
     static IRMethod tab[] = {
     { 0, "search",                  do_search },
+    { 0, "searchStatus",            do_searchStatus },
     { 0, "resultCount",             do_resultCount },
     { 0, "numberOfRecordsReturned", do_numberOfRecordsReturned },
     { 0, "present",                 do_present },
@@ -1258,12 +1277,14 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs)
     IRSetObj *obj = p->child;
 
     if (obj)
+    {
+        obj->searchStatus = searchrs->searchStatus ? 1 : 0;
         obj->resultCount = *searchrs->resultCount;
-    if (searchrs->searchStatus)
-        printf("Search was a success.\n");
+        printf ("Search response %d, %d hits\n", 
+                 obj->searchStatus, obj->resultCount);
+    }
     else
-        printf("Search was a bloomin' failure.\n");
-    printf("Number of hits: %d\n", *searchrs->resultCount);
+        printf ("Search response, no object!\n");
 }
 
 static void ir_initResponse (void *obj, Z_InitResponse *initrs)
index 42ee0d1..0bc452e 100644 (file)
--- a/ir-tcl.h
+++ b/ir-tcl.h
@@ -1,9 +1,13 @@
 /*
  * IR toolkit for tcl/tk
  * (c) Index Data 1995
+ * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: ir-tcl.h,v $
- * Revision 1.4  1995-03-17 18:26:18  adam
+ * Revision 1.5  1995-03-20 08:53:27  adam
+ * Event loop in tclmain.c rewritten. New method searchStatus.
+ *
+ * Revision 1.4  1995/03/17  18:26:18  adam
  * Non-blocking i/o used now. Database names popup as cascade items.
  *
  * Revision 1.3  1995/03/17  07:50:28  adam
diff --git a/iterate.tcl b/iterate.tcl
new file mode 100644 (file)
index 0000000..b04d101
--- /dev/null
@@ -0,0 +1,28 @@
+# $Id: iterate.tcl,v 1.1 1995-03-20 08:53:28 adam Exp $
+#
+# Small test script which searches for adam ...
+proc init-response {} {
+    global count
+
+    set count 0
+    puts "In init-response"
+    z callback {search-response}
+    z.1 search adam
+}
+
+proc search-response {} {
+    global count
+
+    incr count
+    puts "In search-response $count"
+    z callback {search-response}
+    z.1 search adam
+}
+
+ir z
+ir-set z.1
+z databaseNames DEM
+z connect localhost:9999
+z callback {init-response}
+z init
+
index c782cf4..7e5ae24 100644 (file)
--- a/tclmain.c
+++ b/tclmain.c
@@ -1,9 +1,13 @@
 /*
  * IR toolkit for tcl/tk
  * (c) Index Data 1995
+ * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: tclmain.c,v $
- * Revision 1.4  1995-03-17 07:50:31  adam
+ * Revision 1.5  1995-03-20 08:53:30  adam
+ * Event loop in tclmain.c rewritten. New method searchStatus.
+ *
+ * Revision 1.4  1995/03/17  07:50:31  adam
  * Headers have changed a little.
  *
  */
 
 static char *fileName = NULL;
 
-static fd_set fdset_tcl;
+/* select(2) callbacks */
+struct callback {
+    void (*r_handle)(void *p);
+    void (*w_handle)(void *p);
+    void (*x_handle)(void *p);
+    void *obj;
+};
+#define MAX_CALLBACK 200
+
+static struct callback callback_table[MAX_CALLBACK];
+static int max_fd = 3;            /* don't worry: it will grow... */
 
-void tcl_mainloop (Tcl_Interp *interp);
+void tcl_mainloop (Tcl_Interp *interp, int interactive);
 
 int Tcl_AppInit (Tcl_Interp *interp)
 {
@@ -36,6 +50,7 @@ int main (int argc, char **argv)
 {
     Tcl_Interp *interp;
     int code;
+    int i;
 
     interp = Tcl_CreateInterp();
     Tcl_SetVar (interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
@@ -45,6 +60,12 @@ int main (int argc, char **argv)
     if (Tcl_AppInit(interp) != TCL_OK) {
         fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result);
     }
+    for (i=0; i<MAX_CALLBACK; i++)
+    {
+        callback_table[i].r_handle = NULL;
+        callback_table[i].w_handle = NULL;
+        callback_table[i].x_handle = NULL;
+    }
     if (fileName)
     {
         code = Tcl_EvalFile (interp, fileName);
@@ -52,56 +73,90 @@ int main (int argc, char **argv)
             printf ("%s\n", interp->result);
         if (code != TCL_OK)
             exit (1);
+        tcl_mainloop (interp, 0);
+    }
+    else
+    {
+        Tcl_SetVar (interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
+        tcl_mainloop (interp, 1);
     }
-    Tcl_SetVar (interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
-    tcl_mainloop (interp);
     exit (0);
 }
 
-struct callback {
-    void (*handle)(void *p);
-    void *obj;
-};
-
-#define MAX_CALLBACK 20
-
-struct callback callback_table[MAX_CALLBACK];
-
-void tcl_mainloop (Tcl_Interp *interp)
+void tcl_mainloop (Tcl_Interp *interp, int interactive)
 {
     int i;
     int res;
-    int count;
-    char input_buf[256];
     Tcl_DString command;
+    static fd_set fdset_tcl_r;
+    static fd_set fdset_tcl_w;
+    static fd_set fdset_tcl_x;
+    int min_fd;
 
-    for (i=0; i<MAX_CALLBACK; i++)
-        callback_table[i].handle = NULL;
-    Tcl_DStringInit (&command);
-    printf ("[TCL]"); fflush (stdout);
+    min_fd = interactive ? 3 : 0;
+    if (interactive)
+    {
+        Tcl_DStringInit (&command);
+        printf ("[TCL]"); fflush (stdout);
+    }
     while (1)
     {
-        FD_ZERO (&fdset_tcl);
-        FD_SET (0, &fdset_tcl);
-        for (i=3; i<MAX_CALLBACK; i++)
-            if (callback_table[i].handle)
-                FD_SET (i, &fdset_tcl);
-        if ((res = select(MAX_CALLBACK+1, &fdset_tcl, 0, 0, 0)) < 0)
+        FD_ZERO (&fdset_tcl_r);
+        FD_ZERO (&fdset_tcl_w);
+        FD_ZERO (&fdset_tcl_x);
+        if (interactive)
+            FD_SET (0, &fdset_tcl_r);
+        for (res=0, i=min_fd; i<=max_fd; i++)
+        {
+            if (callback_table[i].w_handle)
+            {
+                FD_SET (i, &fdset_tcl_w);
+                res++;
+            }
+            if (callback_table[i].r_handle)
+            {
+                FD_SET (i, &fdset_tcl_r);
+                res++;
+            }
+            if (callback_table[i].x_handle)
+            {
+                FD_SET (i, &fdset_tcl_x);
+                res++;
+            }
+        }
+        if (!interactive && !res)
+            return;
+        if ((res = select(max_fd+1, &fdset_tcl_r, &fdset_tcl_w, 
+                          &fdset_tcl_x, 0)) < 0)
         {
             perror("select");
             exit(1);
         }
         if (!res)
             continue;
-        for (i=3; i<MAX_CALLBACK; i++)
-            if (FD_ISSET (i, &fdset_tcl))
+        for (i=min_fd; i<=max_fd; i++)
+        {
+            if (FD_ISSET (i, &fdset_tcl_r))
+            {
+                assert (callback_table[i].r_handle);
+                (*callback_table[i].r_handle) (callback_table[i].obj);
+            }
+            if (FD_ISSET (i, &fdset_tcl_w))
             {
-                assert (callback_table[i].handle);
-                (*callback_table[i].handle) (callback_table[i].obj);
+                assert (callback_table[i].w_handle);
+                (*callback_table[i].w_handle) (callback_table[i].obj);
             }
-        if (FD_ISSET(0, &fdset_tcl))
+            if (FD_ISSET (i, &fdset_tcl_x))
+            {
+                assert (callback_table[i].x_handle);
+                (*callback_table[i].x_handle) (callback_table[i].obj);
+            }
+        }
+        if (interactive && FD_ISSET(0, &fdset_tcl_r))
         {
-            count = read (0, input_buf, 256);
+            char input_buf[256];
+            int count = read (0, input_buf, 256);
+
             if (count <= 0)
                 exit (0);
             Tcl_DStringAppend (&command, input_buf, count);
@@ -122,10 +177,28 @@ void tcl_mainloop (Tcl_Interp *interp)
 void ir_select_add (int fd, void *obj)
 {
     callback_table[fd].obj = obj;
-    callback_table[fd].handle = ir_select_proc;
+    callback_table[fd].r_handle = ir_select_read;
+    callback_table[fd].w_handle = NULL;
+    callback_table[fd].x_handle = NULL;
+    if (fd > max_fd)
+        max_fd = fd;
+}
+
+void ir_select_add_write (int fd, void *obj)
+{
+    callback_table[fd].w_handle = ir_select_write;
+    if (fd > max_fd)
+        max_fd = fd;
+}
+
+void ir_select_remove_write (int fd, void *obj)
+{
+    callback_table[fd].w_handle = NULL;
 }
 
 void ir_select_remove (int fd, void *obj)
 {
-    callback_table[fd].handle = NULL;
+    callback_table[fd].r_handle = NULL;
+    callback_table[fd].w_handle = NULL;
+    callback_table[fd].x_handle = NULL;
 }