Work on delete of objects.
[ir-tcl-moved-to-github.git] / tclmain.c
1 /*
2  * IR toolkit for tcl/tk
3  * (c) Index Data 1995
4  * See the file LICENSE for details.
5  * Sebastian Hammer, Adam Dickmeiss
6  *
7  * $Log: tclmain.c,v $
8  * Revision 1.6  1995-05-29 08:44:28  adam
9  * Work on delete of objects.
10  *
11  * Revision 1.5  1995/03/20  08:53:30  adam
12  * Event loop in tclmain.c rewritten. New method searchStatus.
13  *
14  * Revision 1.4  1995/03/17  07:50:31  adam
15  * Headers have changed a little.
16  *
17  */
18
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <assert.h>
22 #include <unistd.h>
23
24 #include <tcl.h>
25
26 #include "ir-tcl.h"
27
28 static char *fileName = NULL;
29
30 /* select(2) callbacks */
31 struct callback {
32     void (*r_handle)(void *p);
33     void (*w_handle)(void *p);
34     void (*x_handle)(void *p);
35     void *obj;
36 };
37 #define MAX_CALLBACK 200
38
39 static struct callback callback_table[MAX_CALLBACK];
40 static int max_fd = 3;            /* don't worry: it will grow... */
41
42 void tcl_mainloop (Tcl_Interp *interp, int interactive);
43
44 int Tcl_AppInit (Tcl_Interp *interp)
45 {
46     if (Tcl_Init(interp) == TCL_ERROR)
47         return TCL_ERROR;
48     if (ir_tcl_init(interp) == TCL_ERROR)
49         return TCL_ERROR;
50     return TCL_OK;
51 }
52
53 int main (int argc, char **argv)
54 {
55     Tcl_Interp *interp;
56     int code;
57     int i;
58
59     interp = Tcl_CreateInterp();
60     Tcl_SetVar (interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
61     if (argc == 2)
62         fileName = argv[1];
63
64     if (Tcl_AppInit(interp) != TCL_OK) {
65         fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result);
66     }
67     for (i=0; i<MAX_CALLBACK; i++)
68     {
69         callback_table[i].r_handle = NULL;
70         callback_table[i].w_handle = NULL;
71         callback_table[i].x_handle = NULL;
72     }
73     if (fileName)
74     {
75         code = Tcl_EvalFile (interp, fileName);
76         if (*interp->result != 0)
77             printf ("%s\n", interp->result);
78         if (code != TCL_OK)
79             exit (1);
80         tcl_mainloop (interp, 0);
81     }
82     else
83     {
84         Tcl_SetVar (interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
85         tcl_mainloop (interp, 1);
86     }
87     exit (0);
88 }
89
90 void tcl_mainloop (Tcl_Interp *interp, int interactive)
91 {
92     int i;
93     int res;
94     Tcl_DString command;
95     static fd_set fdset_tcl_r;
96     static fd_set fdset_tcl_w;
97     static fd_set fdset_tcl_x;
98     int min_fd;
99
100     min_fd = interactive ? 3 : 0;
101     if (interactive)
102     {
103         Tcl_DStringInit (&command);
104         printf ("[TCL]"); fflush (stdout);
105     }
106     while (1)
107     {
108         FD_ZERO (&fdset_tcl_r);
109         FD_ZERO (&fdset_tcl_w);
110         FD_ZERO (&fdset_tcl_x);
111         if (interactive)
112             FD_SET (0, &fdset_tcl_r);
113         for (res=0, i=min_fd; i<=max_fd; i++)
114         {
115             if (callback_table[i].w_handle)
116             {
117                 FD_SET (i, &fdset_tcl_w);
118                 res++;
119             }
120             if (callback_table[i].r_handle)
121             {
122                 FD_SET (i, &fdset_tcl_r);
123                 res++;
124             }
125             if (callback_table[i].x_handle)
126             {
127                 FD_SET (i, &fdset_tcl_x);
128                 res++;
129             }
130         }
131         if (!interactive && !res)
132             return;
133         if ((res = select(max_fd+1, &fdset_tcl_r, &fdset_tcl_w, 
134                           &fdset_tcl_x, 0)) < 0)
135         {
136             perror("select");
137             exit(1);
138         }
139         if (!res)
140             continue;
141         for (i=min_fd; i<=max_fd; i++)
142         {
143             if (FD_ISSET (i, &fdset_tcl_r))
144             {
145                 assert (callback_table[i].r_handle);
146                 (*callback_table[i].r_handle) (callback_table[i].obj);
147             }
148             if (FD_ISSET (i, &fdset_tcl_w))
149             {
150                 assert (callback_table[i].w_handle);
151                 (*callback_table[i].w_handle) (callback_table[i].obj);
152             }
153             if (FD_ISSET (i, &fdset_tcl_x))
154             {
155                 assert (callback_table[i].x_handle);
156                 (*callback_table[i].x_handle) (callback_table[i].obj);
157             }
158         }
159         if (interactive && FD_ISSET(0, &fdset_tcl_r))
160         {
161             char input_buf[256];
162             int count = read (0, input_buf, 256);
163
164             if (count <= 0)
165                 exit (0);
166             Tcl_DStringAppend (&command, input_buf, count);
167             if (Tcl_CommandComplete (Tcl_DStringValue (&command)))
168             {
169                 int code = Tcl_Eval (interp, Tcl_DStringValue (&command));
170                 Tcl_DStringFree (&command);
171                 if (code)
172                     printf ("[ERR:%s]\n", interp->result);
173                 else
174                     printf ("[RES:%s]\n", interp->result);
175                 printf ("[TCL]"); fflush (stdout);
176             }
177         }
178     }
179 }
180
181 void ir_select_add (int fd, void *obj)
182 {
183     callback_table[fd].obj = obj;
184     callback_table[fd].r_handle = ir_select_read;
185     callback_table[fd].w_handle = NULL;
186     callback_table[fd].x_handle = NULL;
187     if (fd > max_fd)
188         max_fd = fd;
189 }
190
191 void ir_select_add_write (int fd, void *obj)
192 {
193     callback_table[fd].w_handle = ir_select_write;
194     if (fd > max_fd)
195         max_fd = fd;
196 }
197
198 void ir_select_remove_write (int fd, void *obj)
199 {
200     callback_table[fd].w_handle = NULL;
201 }
202
203 void ir_select_remove (int fd, void *obj)
204 {
205     callback_table[fd].r_handle = NULL;
206     callback_table[fd].w_handle = NULL;
207     callback_table[fd].x_handle = NULL;
208 }