Initrequests implemented with callback support.
[ir-tcl-moved-to-github.git] / tclmain.c
1 /*
2  * IR toolkit for tcl/tk
3  * (c) Index Data 1995
4  *
5  * $Id: tclmain.c,v 1.2 1995-03-08 07:28:37 adam Exp $
6  */
7
8 #include <sys/time.h>
9 #include <sys/types.h>
10 #include <assert.h>
11 #include <unistd.h>
12
13 #include <tcl.h>
14
15 #include "ir-tcl.h"
16
17 static char *fileName = NULL;
18
19 static fd_set fdset_tcl;
20
21 void tcl_mainloop (Tcl_Interp *interp);
22
23 int Tcl_AppInit (Tcl_Interp *interp)
24 {
25     if (Tcl_Init(interp) == TCL_ERROR)
26         return TCL_ERROR;
27     if (ir_tcl_init(interp) == TCL_ERROR)
28         return TCL_ERROR;
29     return TCL_OK;
30 }
31
32 int main (int argc, char **argv)
33 {
34     Tcl_Interp *interp;
35     int code;
36
37     interp = Tcl_CreateInterp();
38
39     if (argc != 2)
40     {
41         fprintf (stderr, "Script file expected\n");
42         exit (1);
43     }
44     fileName = argv[1];
45     if (fileName == NULL)
46     {
47         fprintf (stderr, "No filename specified\n");
48         exit (1);
49     }
50     if (Tcl_AppInit(interp) != TCL_OK) {
51         fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result);
52     }
53     code = Tcl_EvalFile (interp, fileName);
54     if (*interp->result != 0)
55         printf ("%s\n", interp->result);
56     if (code != TCL_OK)
57         exit (1);
58     tcl_mainloop (interp);
59     exit (0);
60 }
61
62 struct callback {
63     void (*handle)(void *p);
64     void *obj;
65 };
66
67 #define MAX_CALLBACK 20
68
69 struct callback callback_table[MAX_CALLBACK];
70
71 void tcl_mainloop (Tcl_Interp *interp)
72 {
73     int i;
74     int res;
75     int count;
76     char input_buf[256];
77     Tcl_DString command;
78
79     for (i=0; i<MAX_CALLBACK; i++)
80         callback_table[i].handle = NULL;
81     Tcl_DStringInit (&command);
82     printf ("[TCL]"); fflush (stdout);
83     while (1)
84     {
85         FD_ZERO (&fdset_tcl);
86         FD_SET (0, &fdset_tcl);
87         for (i=3; i<MAX_CALLBACK; i++)
88             if (callback_table[i].handle)
89                 FD_SET (i, &fdset_tcl);
90         if ((res = select(MAX_CALLBACK+1, &fdset_tcl, 0, 0, 0)) < 0)
91         {
92             perror("select");
93             exit(1);
94         }
95         if (!res)
96             continue;
97         for (i=3; i<MAX_CALLBACK; i++)
98             if (FD_ISSET (i, &fdset_tcl))
99             {
100                 assert (callback_table[i].handle);
101                 (*callback_table[i].handle) (callback_table[i].obj);
102             }
103         if (FD_ISSET(0, &fdset_tcl))
104         {
105             count = read (0, input_buf, 256);
106             if (count <= 0)
107                 exit (0);
108             Tcl_DStringAppend (&command, input_buf, count);
109             if (Tcl_CommandComplete (Tcl_DStringValue (&command)))
110             {
111                 int code = Tcl_Eval (interp, Tcl_DStringValue (&command));
112                 Tcl_DStringFree (&command);
113                 printf ("[RES:%s]\n", interp->result);
114                 printf ("[TCL]"); fflush (stdout);
115             }
116         }
117     }
118 }
119
120 void ir_select_add (int fd, void *obj)
121 {
122     callback_table[fd].obj = obj;
123     callback_table[fd].handle = ir_select_proc;
124 }
125
126 void ir_select_remove (int fd, void *obj)
127 {
128     callback_table[fd].handle = NULL;
129 }