DEFINEPHASE now takes 3 params instead of 1
[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.14  1996/02/23 17:51:11  tamches
6  * DEFINEPHASE now takes 3 params instead of 1
7  *
8  * Revision 1.13  1996/02/11 21:25:09  tamches
9  * added param to start-phase
10  *
11  * Revision 1.12  1996/01/26 22:02:00  newhall
12  * added myphasename, myphasestartT, myphasehandle
13  *
14  * Revision 1.11  1996/01/19  20:56:29  newhall
15  * changes due to visiLib interface changes
16  *
17  * Revision 1.10  1996/01/17 18:32:34  newhall
18  * changes due to new visiLib
19  *
20  * Revision 1.9  1995/11/17  17:30:32  newhall
21  * added Dg metriclabel, Dg metricavelabel, and Dg metricsumlabel commands
22  * changed the Dg start command so that it doesn't take any arguments
23  *
24  * Revision 1.8  1995/11/12  23:30:49  newhall
25  * added Dg_Exited
26  *
27  * Revision 1.7  1995/02/26  02:02:02  newhall
28  * added callback functions for new visiLib phase info.
29  *
30  * Revision 1.6  1994/11/08  00:20:26  tamches
31  * removed blt-ish influences
32  * sped up processing of new data callbacks
33  * very close now to dg2.C of barchart
34  *
35  * Revision 1.5  1994/09/30  21:03:07  newhall
36  * removed call to StartVisi
37  *
38  * Revision 1.4  1994/09/25  02:07:47  newhall
39  * changed arguments to GetMetsRes
40  *
41  * Revision 1.3  1994/08/05  20:17:10  rbi
42  * Update for new version of libvisi.a
43  *
44  * Revision 1.2  1994/06/14  18:57:47  rbi
45  * Updated layout and added curve validation callback.
46  *
47  * Revision 1.1  1994/05/31  21:05:47  rbi
48  * Initial version of tclVisi and tabVis
49  *
50  */
51 #include <stdlib.h>
52 #include <iostream.h>
53 #include <tcl.h>
54 #include <tk.h>
55 #include "visi/h/visualization.h"
56
57 extern Tcl_Interp *MainInterp;
58
59 void my_visi_callback(void* , int* , long unsigned int* ) {
60     if (-1 == visi_callback())
61        exit(1);
62 }
63
64 int Dg_Add(int) {
65    // Gets called by visi lib when it detects new METRICS and/or RESOURCES
66
67    const int retval = Tcl_Eval(MainInterp, "DgConfigCallback");
68    if (retval == TCL_ERROR)
69       cerr << MainInterp->result << endl;
70
71    return retval;
72 }
73
74 int Dg_Data(int lastBucket) {
75    // New data has arrived.
76    // We are passed the bucket number.  We can grab data for all current
77    // metric/resource pairs and do something.
78
79    // Here, we just invoke the tcl script "DgDataCallback", passing lastBucket
80
81    char buffer[100];
82    sprintf(buffer, "DgDataCallback %d", lastBucket);
83    const int retval = Tcl_Eval(MainInterp, buffer);
84    if (retval == TCL_ERROR)
85       cerr << MainInterp->result << endl;
86
87    return retval;
88 }
89
90 int Dg_Fold(int) {
91    const int retval=Tcl_Eval(MainInterp, "DgFoldCallback");
92    if (retval == TCL_ERROR)
93       cerr << MainInterp->result << endl;
94
95    return retval;
96 }
97
98 int Dg_Invalid(int) {
99    const int retval=Tcl_Eval(MainInterp, "DgInvalidCallback");
100    if (retval == TCL_ERROR)
101       cerr << MainInterp->result << endl;
102
103    return retval;
104 }
105
106 int Dg_PhaseStart(int which) {
107    char buffer[100];
108    sprintf(buffer, "DgPhaseStartCallback %d", which);
109    const int retval = Tcl_Eval(MainInterp, buffer);
110    if (retval == TCL_ERROR)
111       cerr << MainInterp->result << endl;
112
113   return retval;
114 }
115
116 int Dg_PhaseEnd(int which) {
117    char buffer[100];
118    sprintf(buffer, "DgPhaseEndCallback %d", which);
119    const int retval = Tcl_Eval(MainInterp, buffer);
120    if (retval == TCL_ERROR)
121       cerr << MainInterp->result << endl;
122
123   return retval;
124 }
125
126 int Dg_PhaseData(int) {
127    const int retval=Tcl_Eval(MainInterp, "DgPhaseDataCallback");
128    if (retval == TCL_ERROR)
129       cerr << MainInterp->result << endl;
130
131   return retval;
132 }
133
134 int Dg_Exited(int) {
135    const int retval=Tcl_Eval(MainInterp, "DgParadynExitedCallback");
136    if (retval == TCL_ERROR){
137       // cerr << MainInterp->result << endl;
138       exit(-1);
139    }
140
141   return retval;
142 }
143
144 #define   AGGREGATE        0
145 #define   BINWIDTH         1
146 #define   METRICNAME       2
147 #define   METRICUNITS      3
148 #define   NUMBINS          4
149 #define   NUMMETRICS       5
150 #define   NUMRESOURCES     6
151 #define   DEFINEPHASE      7
152 #define   RESOURCENAME     8
153 #define   STARTSTREAM      9
154 #define   STOPSTREAM       10
155 #define   DGSUM            11
156 #define   DGVALID          12
157 #define   DGENABLED        13
158 #define   VALUE            14
159 #define   CMDERROR         15
160 #define   LASTBUCKET       16
161 #define   FIRSTBUCKET      17
162 #define   NUMPHASES        18
163 #define   PHASENAME        19
164 #define   PHASESTARTTIME   20
165 #define   PHASEENDTIME     21
166 #define   MYPHASENAME      22
167 #define   MYPHASESTARTTIME 23
168 #define   MYPHASEHANDLE    24
169 #define   METRICAVELAB     25
170 #define   METRICSUMLAB     26
171
172 struct cmdTabEntry {
173    char *cmdname;
174    int index;
175    int numargs;
176 };
177
178 static struct cmdTabEntry Dg_Cmds[] = {
179   {"average",      AGGREGATE,       2},
180   {"binwidth",     BINWIDTH,        0},
181   {"firstbucket",  FIRSTBUCKET,     2},
182   {"lastbucket",   LASTBUCKET,      2},
183   {"metricname",   METRICNAME,      1},
184   {"metriclabel",  METRICUNITS,     1},
185   {"numbins",      NUMBINS,         0},
186   {"nummetrics",   NUMMETRICS,      0},
187   {"numresources", NUMRESOURCES,    0},
188   {"phase",        DEFINEPHASE,     3},
189   {"resourcename", RESOURCENAME,    1},
190   {"start",        STARTSTREAM,     2},
191   {"stop",         STOPSTREAM,      2},
192   {"sum",          DGSUM,           2},
193   {"valid",        DGVALID,         2},
194   {"enabled",      DGENABLED,       2},
195   {"value",        VALUE,           3},
196   {"phasename",    PHASENAME,       1},
197   {"phasestartT",  PHASESTARTTIME,  1},
198   {"phaseendT",    PHASEENDTIME,    1},
199   {"myphasename",  MYPHASENAME,     0},
200   {"myphasestartT", MYPHASESTARTTIME, 0},
201   {"myphasehandle", MYPHASEHANDLE,  0},
202   {"numphases",     NUMPHASES,      0},
203   {"metricavelabel",  METRICAVELAB, 1},
204   {"metricsumlabel",  METRICSUMLAB, 1},
205   {NULL,           CMDERROR,        0}
206 };
207
208 int findCommand(Tcl_Interp *interp, 
209                 int argc, char *argv[]) {
210   if (argc == 0) {
211     sprintf(interp->result, "USAGE: Dg <option> [args...]\n");
212     return CMDERROR;
213   }
214   for (cmdTabEntry *C = Dg_Cmds; C->cmdname; C++) {
215     if (strcmp(argv[0], C->cmdname) == 0) {
216       if ((argc-1) == C->numargs) 
217         return C->index; // successful parsing
218
219       sprintf(interp->result, 
220               "%s: wrong number of args (%d). Should be %d\n",
221               argv[0], argc-1, C->numargs);
222       return CMDERROR;
223     }
224   }
225
226   sprintf(interp->result, "unknown option (%s)\n", argv[0]);
227   return CMDERROR;
228 }
229
230 int Dg_TclCommand(ClientData,
231                   Tcl_Interp *interp, 
232                   int argc, 
233                   char *argv[]) {
234   const int cmdDex = findCommand(interp, argc-1, argv+1);
235   if (cmdDex == CMDERROR)
236      return TCL_ERROR;
237
238   int m, r, buck;
239
240   switch(cmdDex) {
241   case AGGREGATE:   
242     m = atoi(argv[2]);
243     r = atoi(argv[3]);
244     sprintf(interp->result,"%g", visi_AverageValue(m,r));
245     return TCL_OK;
246
247   case BINWIDTH:     
248     sprintf(interp->result, "%g", visi_BucketWidth());
249     return TCL_OK;
250
251   case FIRSTBUCKET:
252     m = atoi(argv[2]);
253     r = atoi(argv[3]);
254     sprintf(interp->result,"%d", visi_FirstValidBucket(m,r)); 
255     return TCL_OK;
256
257   case LASTBUCKET:
258     m = atoi(argv[2]);
259     r = atoi(argv[3]);
260     sprintf(interp->result,"%d", visi_LastBucketFilled(m,r));
261     return TCL_OK;
262
263   case METRICNAME:  
264     m = atoi(argv[2]);
265     sprintf(interp->result, "%s", visi_MetricName(m));
266     return TCL_OK;
267
268   case METRICUNITS:  
269     m = atoi(argv[2]);
270     sprintf(interp->result, "%s", visi_MetricLabel(m));
271     return TCL_OK;
272
273   case NUMBINS:     
274     sprintf(interp->result, "%d", visi_NumBuckets());
275     return TCL_OK;
276
277   case NUMMETRICS:  
278     sprintf(interp->result, "%d", visi_NumMetrics());
279     return TCL_OK;
280
281   case NUMRESOURCES:
282     sprintf(interp->result, "%d", visi_NumResources());
283     return TCL_OK;
284
285   case DEFINEPHASE: {
286     // argv[2] --> phase name (currently unused!)
287     // argv[3] --> with perf consult (boolean value)
288     // argv[4] --> with visis (boolean value)
289
290     int withPerfConsult = 0;
291     int withVisis = 0;
292     (void)Tcl_GetBoolean(interp, argv[3], &withPerfConsult);
293     (void)Tcl_GetBoolean(interp, argv[4], &withVisis);
294
295     visi_DefinePhase(NULL, (bool)withPerfConsult, (bool)withVisis);
296        // let paradyn pick the phase's name
297     return TCL_OK;
298   }
299
300   case RESOURCENAME:
301     r = atoi(argv[2]);
302     sprintf(interp->result, "%s", visi_ResourceName(r));
303     return TCL_OK;
304
305   case STARTSTREAM:       
306     visi_GetMetsRes(argv[2], atoi(argv[3]));
307     return TCL_OK;
308
309   case STOPSTREAM:
310     m = atoi(argv[2]);
311     r = atoi(argv[3]);
312     visi_StopMetRes(m, r);
313     return TCL_OK;
314
315   case DGSUM:         
316     m = atoi(argv[2]);
317     r = atoi(argv[3]);
318     sprintf(interp->result,"%g", visi_SumValue(m,r));
319     return TCL_OK;
320
321   case DGVALID:
322     m = atoi(argv[2]);
323     r = atoi(argv[3]);
324     sprintf(interp->result, "%d", visi_Valid(m,r));
325     return TCL_OK;
326
327   case DGENABLED:
328     m = atoi(argv[2]);
329     r = atoi(argv[3]);
330     sprintf(interp->result, "%d", visi_Enabled(m,r));
331     return TCL_OK;
332
333   case VALUE:       
334     m = atoi(argv[2]);
335     r = atoi(argv[3]);
336     buck = atoi(argv[4]);
337     sprintf(interp->result,"%g", visi_DataValue(m,r,buck));
338     return TCL_OK;
339
340   case NUMPHASES:
341     sprintf(interp->result, "%d", visi_NumPhases());
342     return TCL_OK;
343
344   case PHASENAME:
345     m = atoi(argv[2]);
346     sprintf(interp->result, "%s", visi_GetPhaseName(m));
347     return TCL_OK;
348
349   case PHASESTARTTIME:
350     m = atoi(argv[2]);
351     sprintf(interp->result, "%f", visi_GetPhaseStartTime(m));
352     return TCL_OK;
353
354   case PHASEENDTIME:
355     m = atoi(argv[2]);
356     sprintf(interp->result, "%f", visi_GetPhaseEndTime(m));
357     return TCL_OK;
358
359   case MYPHASENAME:
360     sprintf(interp->result, "%s", visi_GetMyPhaseName());
361     return TCL_OK;
362
363   case MYPHASESTARTTIME:
364     sprintf(interp->result, "%f", visi_GetStartTime());
365     return TCL_OK;
366
367   case MYPHASEHANDLE:
368     sprintf(interp->result, "%d", visi_GetMyPhaseHandle());
369     return TCL_OK;
370
371
372
373   case METRICAVELAB:
374     m = atoi(argv[2]);
375     sprintf(interp->result, "%s", visi_MetricAveLabel(m));
376     return TCL_OK;
377
378   case METRICSUMLAB:
379     m = atoi(argv[2]);
380     sprintf(interp->result, "%s", visi_MetricSumLabel(m));
381     return TCL_OK;
382    
383   }
384
385   sprintf(interp->result, "Internal error (func findCommand)\n");
386   return TCL_ERROR;
387 }
388
389 int Dg_Init(Tcl_Interp *interp) {
390    int fd=visi_Init();
391    if (fd < 0) {
392       cerr << "tclVisi: could not initialize visilib" << endl;
393       exit(-1);
394    }
395
396   (void) visi_RegistrationCallback(ADDMETRICSRESOURCES,Dg_Add); 
397   (void) visi_RegistrationCallback(DATAVALUES,Dg_Data); 
398   (void) visi_RegistrationCallback(FOLD,Dg_Fold); 
399   (void) visi_RegistrationCallback(INVALIDMETRICSRESOURCES,Dg_Invalid);
400   (void) visi_RegistrationCallback(PHASESTART,Dg_PhaseStart);
401   (void) visi_RegistrationCallback(PHASEEND,Dg_PhaseEnd);
402   (void) visi_RegistrationCallback(PHASEDATA,Dg_PhaseData);
403   (void) visi_RegistrationCallback(PARADYNEXITED,Dg_Exited);
404
405   Tcl_CreateCommand(interp, "Dg", Dg_TclCommand, 
406                     (ClientData *) NULL,(Tcl_CmdDeleteProc *) NULL);
407  
408   // Arrange for my_visi_callback() to be called whenever data is waiting
409   // to be read off of descriptor "fd".  Extremely important! [tcl book
410   // page 357]
411   Tk_CreateFileHandler(fd, TK_READABLE, (Tk_FileProc *) my_visi_callback, 0);
412
413   return TCL_OK;
414 }
415
416