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