Removed lines and list as synonyms of list in MARC extractron.
[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.13  1995-08-28 12:21:22  adam
9  * Removed lines and list as synonyms of list in MARC extractron.
10  * Configure searches also for tk4.0 / tcl7.4.
11  *
12  * Revision 1.12  1995/08/28  11:07:16  adam
13  * Minor changes.
14  *
15  * Revision 1.11  1995/08/03  13:23:02  adam
16  * Request queue.
17  *
18  * Revision 1.10  1995/06/30  12:39:28  adam
19  * Bug fix: loadFile didn't set record type.
20  * The MARC routines are a little less strict in the interpretation.
21  * Script display.tcl replaces the old marc.tcl.
22  * New interactive script: shell.tcl.
23  *
24  * Revision 1.9  1995/06/26  10:20:20  adam
25  * ir-tk works like wish.
26  *
27  * Revision 1.8  1995/06/21  15:16:44  adam
28  * More work on configuration.
29  *
30  * Revision 1.7  1995/06/21  11:04:54  adam
31  * Uses GNU autoconf 2.3.
32  * Install procedure implemented.
33  * boook bitmaps moved to sub directory bitmaps.
34  *
35  * Revision 1.6  1995/05/29  08:44:28  adam
36  * Work on delete of objects.
37  *
38  * Revision 1.5  1995/03/20  08:53:30  adam
39  * Event loop in tclmain.c rewritten. New method searchStatus.
40  *
41  * Revision 1.4  1995/03/17  07:50:31  adam
42  * Headers have changed a little.
43  *
44  */
45
46 #include <unistd.h>
47 #include <sys/time.h>
48 #include <sys/types.h>
49 #ifdef _AIX
50 #include <sys/select.h>
51 #endif
52 #include <assert.h>
53
54 #include <tcl.h>
55 #include <log.h>
56 #include "ir-tcl.h"
57
58 static char *fileName = NULL;
59
60 /* select(2) callbacks */
61 struct callback {
62     void (*r_handle)(ClientData);
63     void (*w_handle)(ClientData);
64     void (*x_handle)(ClientData);
65     void *obj;
66 };
67 #define MAX_CALLBACK 200
68
69 static struct callback callback_table[MAX_CALLBACK];
70 static int max_fd = 3;            /* don't worry: it will grow... */
71
72 void tcl_mainloop (Tcl_Interp *interp, int interactive);
73
74 int Tcl_AppInit (Tcl_Interp *interp)
75 {
76     if (Tcl_Init(interp) == TCL_ERROR)
77         return TCL_ERROR;
78     if (ir_tcl_init(interp) == TCL_ERROR)
79         return TCL_ERROR;
80     return TCL_OK;
81 }
82
83 int main (int argc, char **argv)
84 {
85     Tcl_Interp *interp;
86     int code;
87     int i;
88
89     interp = Tcl_CreateInterp();
90     Tcl_SetVar (interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
91     if (argc == 2)
92         fileName = argv[1];
93
94     if (Tcl_AppInit(interp) != TCL_OK) {
95         fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result);
96     }
97     for (i=0; i<MAX_CALLBACK; i++)
98     {
99         callback_table[i].r_handle = NULL;
100         callback_table[i].w_handle = NULL;
101         callback_table[i].x_handle = NULL;
102     }
103     if (fileName)
104     {
105         code = Tcl_EvalFile (interp, fileName);
106         if (*interp->result != 0)
107             printf ("%s\n", interp->result);
108         if (code != TCL_OK)
109             exit (1);
110         tcl_mainloop (interp, 0);
111     }
112     else if (isatty(0))
113     {
114
115         Tcl_SetVar (interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
116         tcl_mainloop (interp, 1);
117     }
118     else
119     {
120         Tcl_DString command;
121         char input_buf[1024];
122         int count;
123
124         printf ("xx\n");
125         Tcl_DStringInit (&command);
126         while (fgets (input_buf, 1024, stdin))
127         {
128             count = strlen(input_buf);
129             Tcl_DStringAppend (&command, input_buf, count);
130             if (Tcl_CommandComplete (Tcl_DStringValue (&command)))
131             {
132                 int code = Tcl_Eval (interp, Tcl_DStringValue (&command));
133                 Tcl_DStringFree (&command);
134                 if (code)
135                     printf ("Error: %s\n", interp->result);
136             }
137         }
138         tcl_mainloop (interp, 0);
139     }
140     exit (0);
141 }
142
143 void tcl_mainloop (Tcl_Interp *interp, int interactive)
144 {
145     int i;
146     int res;
147     Tcl_DString command;
148     static fd_set fdset_tcl_r;
149     static fd_set fdset_tcl_w;
150     static fd_set fdset_tcl_x;
151     int min_fd;
152
153     min_fd = interactive ? 3 : 0;
154     if (interactive)
155     {
156         Tcl_DStringInit (&command);
157         printf ("%% "); fflush (stdout);
158     }
159     while (1)
160     {
161         FD_ZERO (&fdset_tcl_r);
162         FD_ZERO (&fdset_tcl_w);
163         FD_ZERO (&fdset_tcl_x);
164         if (interactive)
165             FD_SET (0, &fdset_tcl_r);
166         for (res=0, i=min_fd; i<=max_fd; i++)
167         {
168             if (callback_table[i].w_handle)
169             {
170                 FD_SET (i, &fdset_tcl_w);
171                 res++;
172             }
173             if (callback_table[i].r_handle)
174             {
175                 FD_SET (i, &fdset_tcl_r);
176                 res++;
177             }
178             if (callback_table[i].x_handle)
179             {
180                 FD_SET (i, &fdset_tcl_x);
181                 res++;
182             }
183         }
184         if (!interactive && !res)
185             return;
186         if ((res = select(max_fd+1, &fdset_tcl_r, &fdset_tcl_w, 
187                           &fdset_tcl_x, 0)) < 0)
188         {
189             perror("select");
190             exit(1);
191         }
192         if (!res)
193             continue;
194         for (i=min_fd; i<=max_fd; i++)
195         {
196             if (FD_ISSET (i, &fdset_tcl_r))
197             {
198                 assert (callback_table[i].r_handle);
199                 (*callback_table[i].r_handle) (callback_table[i].obj);
200             }
201             if (FD_ISSET (i, &fdset_tcl_w))
202             {
203                 assert (callback_table[i].w_handle);
204                 (*callback_table[i].w_handle) (callback_table[i].obj);
205             }
206             if (FD_ISSET (i, &fdset_tcl_x))
207             {
208                 assert (callback_table[i].x_handle);
209                 (*callback_table[i].x_handle) (callback_table[i].obj);
210             }
211         }
212         if (interactive && FD_ISSET(0, &fdset_tcl_r))
213         {
214             char input_buf[1024];
215             int count = read (0, input_buf, 1024);
216
217             if (count <= 0)
218                 exit (0);
219             Tcl_DStringAppend (&command, input_buf, count);
220             if (Tcl_CommandComplete (Tcl_DStringValue (&command)))
221             {
222                 int code = Tcl_Eval (interp, Tcl_DStringValue (&command));
223                 Tcl_DStringFree (&command);
224                 if (code)
225                     printf ("Error: %s\n", interp->result);
226                 else if (*interp->result)
227                     printf ("%s\n", interp->result);
228                 printf ("%% "); fflush (stdout);
229             }
230         }
231     }
232 }
233
234 void ir_select_add (int fd, void *obj)
235 {
236     callback_table[fd].obj = obj;
237     callback_table[fd].r_handle = ir_select_read;
238     callback_table[fd].w_handle = NULL;
239     callback_table[fd].x_handle = NULL;
240     if (fd > max_fd)
241         max_fd = fd;
242 }
243
244 void ir_select_add_write (int fd, void *obj)
245 {
246     callback_table[fd].w_handle = ir_select_write;
247     if (fd > max_fd)
248         max_fd = fd;
249 }
250
251 void ir_select_remove_write (int fd, void *obj)
252 {
253     callback_table[fd].w_handle = NULL;
254 }
255
256 void ir_select_remove (int fd, void *obj)
257 {
258     callback_table[fd].r_handle = NULL;
259     callback_table[fd].w_handle = NULL;
260     callback_table[fd].x_handle = NULL;
261 }