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