added Dg_Exited
[dyninst.git] / visiClients / tclVisi / src / DGclient.C
1 /*
2  *  DGclient.C -- Code for the visi<->tcl interface.
3  *    
4  * $Log: DGclient.C,v $
5  * Revision 1.8  1995/11/12 23:30:49  newhall
6  * added Dg_Exited
7  *
8  * Revision 1.7  1995/02/26  02:02:02  newhall
9  * added callback functions for new visiLib phase info.
10  *
11  * Revision 1.6  1994/11/08  00:20:26  tamches
12  * removed blt-ish influences
13  * sped up processing of new data callbacks
14  * very close now to dg2.C of barchart
15  *
16  * Revision 1.5  1994/09/30  21:03:07  newhall
17  * removed call to StartVisi
18  *
19  * Revision 1.4  1994/09/25  02:07:47  newhall
20  * changed arguments to GetMetsRes
21  *
22  * Revision 1.3  1994/08/05  20:17:10  rbi
23  * Update for new version of libvisi.a
24  *
25  * Revision 1.2  1994/06/14  18:57:47  rbi
26  * Updated layout and added curve validation callback.
27  *
28  * Revision 1.1  1994/05/31  21:05:47  rbi
29  * Initial version of tclVisi and tabVis
30  *
31  */
32 #include <stdlib.h>
33 #include <iostream.h>
34 #include <tcl.h>
35 #include <tk.h>
36 #include "../../../visi/h/visualization.h"
37
38 extern Tcl_Interp *MainInterp;
39
40 void my_visi_callback(void* arg0, int* arg1, long unsigned int* arg2) {
41     if (-1 == visi_callback())
42        exit(1);
43 }
44
45 int Dg_Add(int dummy) {
46    // Gets called by visi lib when it detects new METRICS and/or RESOURCES
47
48    const int retval = Tcl_Eval(MainInterp, "DgConfigCallback");
49    if (retval == TCL_ERROR)
50       cerr << MainInterp->result << endl;
51
52    return retval;
53 }
54
55 int Dg_Data(int lastBucket) {
56    // New data has arrived.
57    // We are passed the bucket number.  We can grab data for all current
58    // metric/resource pairs and do something.
59
60    // Here, we just invoke the tcl script "DgDataCallback", passing lastBucket
61
62    char buffer[100];
63    sprintf(buffer, "DgDataCallback %d", lastBucket);
64    const int retval = Tcl_Eval(MainInterp, buffer);
65    if (retval == TCL_ERROR)
66       cerr << MainInterp->result << endl;
67
68    return retval;
69 }
70
71 int Dg_Fold(int dummy) {
72    const int retval=Tcl_Eval(MainInterp, "DgFoldCallback");
73    if (retval == TCL_ERROR)
74       cerr << MainInterp->result << endl;
75
76    return retval;
77 }
78
79 int Dg_Invalid(int dummy) {
80    const int retval=Tcl_Eval(MainInterp, "DgInvalidCallback");
81    if (retval == TCL_ERROR)
82       cerr << MainInterp->result << endl;
83
84    return retval;
85 }
86
87 int Dg_PhaseStart(int which) {
88    char buffer[100];
89    sprintf(buffer, "DgPhaseStartCallback %d", which);
90    const int retval = Tcl_Eval(MainInterp, buffer);
91    if (retval == TCL_ERROR)
92       cerr << MainInterp->result << endl;
93
94   return retval;
95 }
96
97 int Dg_PhaseEnd(int which) {
98    char buffer[100];
99    sprintf(buffer, "DgPhaseEndCallback %d", which);
100    const int retval = Tcl_Eval(MainInterp, buffer);
101    if (retval == TCL_ERROR)
102       cerr << MainInterp->result << endl;
103
104   return retval;
105 }
106
107 int Dg_PhaseData(int dummy) {
108    const int retval=Tcl_Eval(MainInterp, "DgPhaseDataCallback");
109    if (retval == TCL_ERROR)
110       cerr << MainInterp->result << endl;
111
112   return retval;
113 }
114
115 int Dg_Exited(int dummy) {
116    const int retval=Tcl_Eval(MainInterp, "DgParadynExitedCallback");
117    if (retval == TCL_ERROR){
118       // cerr << MainInterp->result << endl;
119       exit(-1);
120    }
121
122   return retval;
123 }
124
125 #define   AGGREGATE        0
126 #define   BINWIDTH         1
127 #define   FOLDMETHOD       2
128 #define   METRICNAME       3
129 #define   METRICUNITS      4
130 #define   NUMBINS          5
131 #define   NUMMETRICS       6
132 #define   NUMRESOURCES     7
133 #define   DEFINEPHASE      8
134 #define   RESOURCENAME     9
135 #define   STARTSTREAM      10
136 #define   STOPSTREAM       11
137 #define   DGSUM            12
138 #define   DGVALID          13
139 #define   DGENABLED        14
140 #define   VALUE            15
141 #define   CMDERROR         16
142 #define   LASTBUCKET       17
143 #define   FIRSTBUCKET      18
144 #define   NUMPHASES        19
145 #define   PHASENAME        20
146 #define   PHASESTARTTIME   21
147 #define   PHASEENDTIME     22
148
149 struct cmdTabEntry {
150    char *cmdname;
151    int index;
152    int numargs;
153 };
154
155 static struct cmdTabEntry Dg_Cmds[] = {
156   {"aggregate",    AGGREGATE,       2},
157   {"binwidth",     BINWIDTH,        0},
158   {"firstbucket",  FIRSTBUCKET,     2},
159   {"foldmethod",   FOLDMETHOD,      2},
160   {"lastbucket",   LASTBUCKET,      2},
161   {"metricname",   METRICNAME,      1},
162   {"metricunits",  METRICUNITS,     1},
163   {"numbins",      NUMBINS,         0},
164   {"nummetrics",   NUMMETRICS,      0},
165   {"numresources", NUMRESOURCES,    0},
166   {"phase",        DEFINEPHASE,     0},
167   {"resourcename", RESOURCENAME,    1},
168   {"start",        STARTSTREAM,     2},
169   {"stop",         STOPSTREAM,      2},
170   {"sum",          DGSUM,           2},
171   {"valid",        DGVALID,         2},
172   {"enabled",      DGENABLED,       2},
173   {"value",        VALUE,           3},
174   {"phasename",    PHASENAME,       1},
175   {"phasestartT",  PHASESTARTTIME,  1},
176   {"phaseendT",    PHASEENDTIME,    1},
177   {"numphases",    NUMPHASES,       0},
178   {NULL,           CMDERROR,        0}
179 };
180
181 int findCommand(Tcl_Interp *interp, 
182                 int argc, char *argv[]) {
183   if (argc == 0) {
184     sprintf(interp->result, "USAGE: Dg <option> [args...]\n");
185     return CMDERROR;
186   }
187   for (cmdTabEntry *C = Dg_Cmds; C->cmdname; C++) {
188     if (strcmp(argv[0], C->cmdname) == 0) {
189       if ((argc-1) == C->numargs) 
190         return C->index; // successful parsing
191
192       sprintf(interp->result, 
193               "%s: wrong number of args (%d). Should be %d\n",
194               argv[0], argc-1, C->numargs);
195       return CMDERROR;
196     }
197   }
198
199   sprintf(interp->result, "unknown option (%s)\n", argv[0]);
200   return CMDERROR;
201 }
202
203 int Dg_TclCommand(ClientData clientData,
204                   Tcl_Interp *interp, 
205                   int argc, 
206                   char *argv[]) {
207   const int cmdDex = findCommand(interp, argc-1, argv+1);
208   if (cmdDex == CMDERROR)
209      return TCL_ERROR;
210
211   int m, r, buck;
212   PhaseInfo *p;
213
214   switch(cmdDex) {
215   case AGGREGATE:   
216     m = atoi(argv[2]);
217     r = atoi(argv[3]);
218     sprintf(interp->result,"%g", dataGrid.AggregateValue(m,r));
219     return TCL_OK;
220
221   case BINWIDTH:     
222     sprintf(interp->result, "%g", dataGrid.BinWidth());
223     return TCL_OK;
224
225   case FIRSTBUCKET:
226     m = atoi(argv[2]);
227     r = atoi(argv[3]);
228     sprintf(interp->result,"%d", dataGrid[m][r].FirstValidBucket()); 
229     return TCL_OK;
230
231   case FOLDMETHOD:
232     m = atoi(argv[2]);
233     sprintf(interp->result,"%d", dataGrid.FoldMethod(m));
234     return TCL_OK;
235
236   case LASTBUCKET:
237     m = atoi(argv[2]);
238     r = atoi(argv[3]);
239     sprintf(interp->result,"%d", dataGrid[m][r].LastBucketFilled());
240     return TCL_OK;
241
242   case METRICNAME:  
243     m = atoi(argv[2]);
244     sprintf(interp->result, "%s", dataGrid.MetricName(m));
245     return TCL_OK;
246
247   case METRICUNITS:  
248     m = atoi(argv[2]);
249     sprintf(interp->result, "%s", dataGrid.MetricUnits(m));
250     return TCL_OK;
251
252   case NUMBINS:     
253     sprintf(interp->result, "%d", dataGrid.NumBins());
254     return TCL_OK;
255
256   case NUMMETRICS:  
257     sprintf(interp->result, "%d", dataGrid.NumMetrics());
258     return TCL_OK;
259
260   case NUMRESOURCES:
261     sprintf(interp->result, "%d", dataGrid.NumResources());
262     return TCL_OK;
263
264   case DEFINEPHASE:       
265     // DefinePhase(atof(argv[2]), argv[3]);
266     DefinePhase(-1.0, NULL);
267     return TCL_OK;
268
269   case RESOURCENAME:
270     r = atoi(argv[2]);
271     sprintf(interp->result, "%s", dataGrid.ResourceName(r));
272     return TCL_OK;
273
274   case STARTSTREAM:       
275     // GetMetsRes(argv[2], argv[3], 0); 
276 //    GetMetsRes((char *)NULL,0, 0); 
277     GetMetsRes(argv[2], atoi(argv[3]), 0); // 0-->histogram (1-->scalar)
278                                            // argv[3] is num
279     return TCL_OK;
280
281   case STOPSTREAM:
282     m = atoi(argv[2]);
283     r = atoi(argv[3]);
284     StopMetRes(m, r);
285     return TCL_OK;
286
287   case DGSUM:         
288     m = atoi(argv[2]);
289     r = atoi(argv[3]);
290     sprintf(interp->result,"%g", dataGrid.SumValue(m,r));
291     return TCL_OK;
292
293   case DGVALID:
294     m = atoi(argv[2]);
295     r = atoi(argv[3]);
296     sprintf(interp->result, "%d", dataGrid.Valid(m,r));
297     return TCL_OK;
298
299   case DGENABLED:
300     m = atoi(argv[2]);
301     r = atoi(argv[3]);
302     sprintf(interp->result, "%d", dataGrid[m][r].Enabled());
303     return TCL_OK;
304
305   case VALUE:       
306     m = atoi(argv[2]);
307     r = atoi(argv[3]);
308     buck = atoi(argv[4]);
309     sprintf(interp->result,"%g", dataGrid[m][r].Value(buck));
310     return TCL_OK;
311
312   case NUMPHASES:
313     sprintf(interp->result, "%d", dataGrid.NumPhases());
314     return TCL_OK;
315
316   case PHASENAME:
317     m = atoi(argv[2]);
318     p = dataGrid.GetPhaseInfo(m);
319     sprintf(interp->result, "%s", p->getName());
320     return TCL_OK;
321
322   case PHASESTARTTIME:
323     m = atoi(argv[2]);
324     p = dataGrid.GetPhaseInfo(m);
325     sprintf(interp->result, "%f", p->getStartTime());
326     return TCL_OK;
327
328   case PHASEENDTIME:
329     m = atoi(argv[2]);
330     p = dataGrid.GetPhaseInfo(m);
331     sprintf(interp->result, "%f", p->getEndTime());
332     return TCL_OK;
333
334   }
335
336   sprintf(interp->result, "Internal error (func findCommand)\n");
337   return TCL_ERROR;
338 }
339
340 int Dg_Init(Tcl_Interp *interp) {
341    int fd=VisiInit();
342    if (fd < 0) {
343       cerr << "tclVisi: could not initialize visilib" << endl;
344       exit(-1);
345    }
346
347   (void) RegistrationCallback(ADDMETRICSRESOURCES,Dg_Add); 
348   (void) RegistrationCallback(DATAVALUES,Dg_Data); 
349   (void) RegistrationCallback(FOLD,Dg_Fold); 
350   (void) RegistrationCallback(INVALIDMETRICSRESOURCES,Dg_Invalid);
351   (void) RegistrationCallback(PHASESTART,Dg_PhaseStart);
352   (void) RegistrationCallback(PHASEEND,Dg_PhaseEnd);
353   (void) RegistrationCallback(PHASEDATA,Dg_PhaseData);
354   (void) RegistrationCallback(PARADYNEXITED,Dg_Exited);
355
356   Tcl_CreateCommand(interp, "Dg", Dg_TclCommand, 
357                     (ClientData *) NULL,(Tcl_CmdDeleteProc *) NULL);
358  
359   // Arrange for my_visi_callback() to be called whenever data is waiting
360   // to be read off of descriptor "fd".  Extremely important! [tcl book
361   // page 357]
362   Tk_CreateFileHandler(fd, TK_READABLE, (Tk_FileProc *) my_visi_callback, 0);
363
364   return TCL_OK;
365 }
366
367