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