1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11 
12 
13 #include <stdarg.h>
14 #include "dxlP.h"
15 #include "dxl.h"
16 
17 enum DXLExecuteCtl {
18         DXLEXECUTEONCE,
19         DXLEXECUTEONCHANGE,
20         DXLENDEXECUTION,
21         DXLENDEXECUTEONCHANGE
22 };
23 typedef enum DXLExecuteCtl DXLExecuteCtlEnum;
24 
25 #define BGbeginMSG "BG:  begin"
26 #define BGendMSG   "BG:  end"
27 #define FGbeginMSG "begin "
28 #define FGendMSG    NULL
29 #define INTRstopMSG "stop"
30 
_dxl_EndBG(DXLConnection * c,const char * msg,void * data)31 static void _dxl_EndBG(DXLConnection *c, const char *msg, void *data)
32 {
33     c->isExecuting --;
34 }
35 
_dxl_BeginBG(DXLConnection * c,const char * msg,void * data)36 static void _dxl_BeginBG(DXLConnection *c, const char *msg, void *data)
37 {
38     c->isExecuting ++;
39 }
40 
_dxl_CompleteExecute(DXLConnection * c,const char * msg,void * data)41 static void _dxl_CompleteExecute(DXLConnection *c, const char *msg, void *data)
42 {
43     int packetId = (int)(long)data;
44     c->isExecuting--;
45     _dxl_RemoveSystemHandler(c,PACK_COMPLETE,packetId,
46 			FGendMSG, _dxl_CompleteExecute);
47 }
48 
_dxl_INTRstop(DXLConnection * c,const char * msg,void * data)49 static void _dxl_INTRstop(DXLConnection *c, const char *msg, void *data)
50 {
51     c->isExecuting = 0;
52     _dxl_RemoveSystemHandler(c,PACK_INTERRUPT,-1,INTRstopMSG, _dxl_INTRstop);
53 }
_dxl_ManageExecuteHandlers(DXLConnection * conn,int install,int foreground,int packetId)54 static DXLError _dxl_ManageExecuteHandlers(DXLConnection *conn, int install,
55 				int foreground, int packetId)
56 {
57     if (conn->dxuiConnected)
58 	return ERROR;
59 
60     if (foreground) {
61 	if (install) {
62 	    if (!_dxl_SetSystemHandler(conn, PACK_COMPLETE,packetId, FGendMSG,
63 			(DXLMessageHandler)_dxl_CompleteExecute, (void*)packetId))
64 		return ERROR;
65 	} else {
66 	    /*
67 	     * FIXME: we should really use the correct packetId here
68 	     */
69 	    if (!_dxl_RemoveSystemHandler(conn,PACK_COMPLETE,-1, FGendMSG,
70 					_dxl_CompleteExecute))
71 		return ERROR;
72 	}
73 
74     } else {
75 	if (install) {
76 	    if (!_dxl_SetSystemHandlerString(conn, PACK_INTERRUPT,INTRstopMSG,
77 			(DXLMessageHandler)_dxl_INTRstop, (void*)0))
78 		return ERROR;
79 	} else {
80 		;	/* Don't bother removing them.
81 			 * Re-installs don't cause memory to be used up
82 			 * and it doesn't hurt to leave them installed.
83 			 */
84 	}
85 
86     }
87     return OK;
88 
89 }
90 
91 static DXLError
DXLExecuteCtl(DXLConnection * conn,DXLExecuteCtlEnum ectl,char * name,char ** args)92 DXLExecuteCtl(DXLConnection *conn, DXLExecuteCtlEnum ectl, char *name, char **args)
93 {
94    int i, sts = ERROR;
95    const char *cmd = NULL;
96    char namestr[1024];
97 
98    if (name)
99        sprintf(namestr, "%s(\n", name);
100    else
101        sprintf(namestr, "main(\n");
102 
103    if (args)
104    {
105        for (i = 0; args[i]; i++)
106        {
107 	   strcat(namestr, args[i]);
108 	   if (args[i+1])
109 	       strcat(namestr, ",");
110        }
111    }
112 
113    strcat(namestr, ");\n");
114 
115    switch (ectl) {
116 	case DXLEXECUTEONCE:
117 	    if (conn->dxuiConnected) {
118 		cmd = "execute once";
119 	    } else {
120 		int packetId;
121 		/*
122 		if (conn->debugMessaging && conn->isExecuting)
123 		    _DXLError(conn, "already executing");
124 		*/
125 		/* FIXME: handle other program names */
126 		packetId = DXLSendPacket(conn,PACK_FOREGROUND,namestr);
127 		if (packetId >= 0)
128 		    sts = _dxl_ManageExecuteHandlers(conn,1,1,packetId);
129 		conn->isExecuting++;
130 	    }
131 	    break;
132 	case DXLEXECUTEONCHANGE:
133 	    if (conn->dxuiConnected) {
134 		cmd = "execute onchange";
135 	    } else {
136 		int packetId;
137 		packetId = DXLSendPacket(conn,PACK_BACKGROUND,namestr);
138 		sts = (packetId >= 0);
139 		if (sts)
140 		{
141 		    _dxl_SetSystemHandler(conn, PACK_INFO, -1, BGbeginMSG,
142 			    (DXLMessageHandler)_dxl_BeginBG, (void*) NULL);
143 		    _dxl_SetSystemHandler(conn, PACK_INFO, -1, BGendMSG,
144 			    (DXLMessageHandler)_dxl_EndBG, (void*) NULL);
145 		    if (sts)
146 			DXLExecuteCtl(conn, DXLEXECUTEONCE,name,args);
147 		    if (sts)
148 			sts = _dxl_ManageExecuteHandlers(conn,1,0,-1);
149 		}
150 	    }
151 	    break;
152 	case DXLENDEXECUTION:
153 	    if (conn->dxuiConnected) {
154 		cmd = "execute end";
155 	    } else {
156 		sts = DXLSendPacket(conn,PACK_INTERRUPT,NULL) >= 0;
157 		if (sts)
158 		    sts = DXLSendImmediate(conn,"sync") >= 0;
159 		_dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGbeginMSG, _dxl_BeginBG);
160 		_dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGendMSG, _dxl_EndBG);
161 	    }
162 	    break;
163 	case DXLENDEXECUTEONCHANGE:
164 	    if (conn->dxuiConnected) {
165 		cmd = "execute endEOC";
166 	    } else {
167 		_dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGbeginMSG, _dxl_BeginBG);
168 		_dxl_RemoveSystemHandler(conn, PACK_INFO, -1, FGendMSG, _dxl_EndBG);
169 		sts = DXLSendPacket(conn,PACK_INTERRUPT,NULL) >= 0;
170 		if (sts)
171 		    sts = DXLSendImmediate(conn,"sync") >= 0;
172 	    }
173 	    break;
174     }
175 
176    if (cmd)
177 	return DXLSend(conn, cmd);
178    else
179 	return sts;
180 }
181 
182 DXLError
DXLExecuteOnce(DXLConnection * conn)183 DXLExecuteOnce(DXLConnection *conn)
184 {
185     return DXLExecuteCtl(conn, DXLEXECUTEONCE,NULL, NULL);
186 }
187 
188 DXLError
DXLExecuteOnChange(DXLConnection * conn)189 DXLExecuteOnChange(DXLConnection *conn)
190 {
191     return DXLExecuteCtl(conn, DXLEXECUTEONCHANGE,NULL, NULL);
192 }
193 
194 DXLError
exDXLExecuteOnceNamed(DXLConnection * conn,char * name)195 exDXLExecuteOnceNamed(DXLConnection *conn, char *name)
196 {
197     return DXLExecuteCtl(conn, DXLEXECUTEONCE, name, NULL);
198 }
199 
200 DXLError
exDXLExecuteOnChangeNamed(DXLConnection * conn,char * name)201 exDXLExecuteOnChangeNamed(DXLConnection *conn, char *name)
202 {
203     return DXLExecuteCtl(conn, DXLEXECUTEONCHANGE, name, NULL);
204 }
205 
206 DXLError
DXLEndExecution(DXLConnection * conn)207 DXLEndExecution(DXLConnection *conn)
208 {
209     return DXLExecuteCtl(conn, DXLENDEXECUTION, NULL, NULL);
210 }
211 
212 DXLError
DXLEndExecuteOnChange(DXLConnection * conn)213 DXLEndExecuteOnChange(DXLConnection *conn)
214 {
215     return DXLExecuteCtl(conn, DXLENDEXECUTEONCHANGE, NULL, NULL);
216 }
217 
218 DXLError
exDXLExecuteOnceNamedWithArgsV(DXLConnection * conn,char * name,char ** args)219 exDXLExecuteOnceNamedWithArgsV(DXLConnection *conn, char *name, char **args)
220 {
221     return DXLExecuteCtl(conn, DXLEXECUTEONCE, name, args);
222 }
223 
224 DXLError
exDXLExecuteOnceNamedWithArgs(DXLConnection * conn,char * name,...)225 exDXLExecuteOnceNamedWithArgs(DXLConnection *conn, char *name, ...)
226 {
227     int i;
228     char *args[100];
229     va_list arg;
230 
231     va_start(arg, name);
232     for (i = 0; i < 100; i++)
233 	if ((args[i] = va_arg(arg, char *)) == NULL)
234 	    break;
235 
236     return exDXLExecuteOnceNamedWithArgsV(conn, name, args);
237 }
238 
239 DXLError
exDXLExecuteOnChangeNamedWithArgsV(DXLConnection * conn,char * name,char ** args)240 exDXLExecuteOnChangeNamedWithArgsV(DXLConnection *conn, char *name, char **args)
241 {
242     return DXLExecuteCtl(conn, DXLEXECUTEONCHANGE, name, args);
243 }
244 
245 DXLError
exDXLExecuteOnChangeNamedWithArgs(DXLConnection * conn,char * name,...)246 exDXLExecuteOnChangeNamedWithArgs(DXLConnection *conn, char *name, ...)
247 {
248     int i;
249     char *args[100];
250     va_list arg;
251 
252     va_start(arg, name);
253     for (i = 0; i < 100; i++)
254 	if ((args[i] = va_arg(arg, char *)) == NULL)
255 	    break;
256 
257     return exDXLExecuteOnChangeNamedWithArgsV(conn, name, args);
258 }
259 
260 DXLError
DXLGetExecutionStatus(DXLConnection * conn,int * execStatus)261 DXLGetExecutionStatus(DXLConnection *conn, int *execStatus)
262 {
263     if (conn->dxuiConnected) {
264         char buf[100];
265         int sts = DXLQuery(conn, "query execution", sizeof(buf), buf);
266         if (! sts)
267             return ERROR;
268         if (1 != sscanf(buf, "execution state: %d", execStatus))
269             return ERROR;
270     } else {
271         /* FIXME: make sure the begin/end execution handlers are installed */
272         *execStatus = (conn->isExecuting != 0);
273     }
274     return OK;
275 }
276 
277