changes due to new visiLib
[dyninst.git] / visiClients / barchart / dg2.C
1 // dg2.C
2 // customized (for barchart) version of DGclient.C in tclVisi directory
3
4 /* $Log: dg2.C,v $
5 /* Revision 1.14  1996/01/17 18:31:14  newhall
6 /* changes due to new visiLib
7 /*
8  * Revision 1.13  1996/01/10 21:11:15  tamches
9  * added METRICAVEUNITS, METRICSUMUNITS
10  *
11  * Revision 1.12  1995/11/29 00:40:07  tamches
12  * removed myTclEval
13  *
14  * Revision 1.11  1995/11/17 17:39:32  newhall
15  * changed Dg start command, and call to GetMetsRes
16  *
17  * Revision 1.10  1995/11/17  17:32:27  newhall
18  * changed Dg start command to take no arguments, replaced call to MetricUnits
19  * with call to MetricLabel
20  *
21  * Revision 1.9  1995/09/22  19:23:41  tamches
22  * removed warnings under g++ 2.7.0
23  *
24  * Revision 1.8  1995/08/06  22:11:48  tamches
25  * removed some warnings by using myTclEval
26  *
27  * Revision 1.7  1995/02/26  02:01:48  newhall
28  * added callback functions for new visiLib phase info.
29  *
30  * Revision 1.6  1994/11/06  10:24:04  tamches
31  * minor cleanups (especially commenting)
32  *
33  * Revision 1.5  1994/10/11  21:59:47  tamches
34  * Removed extra StartVisi() bug.
35  * Implemented dataGrid[][].Enabled()
36  *
37  * Revision 1.4  1994/10/10  23:08:47  tamches
38  * preliminary changes on the way to swapping the x and y axes
39  *
40  * Revision 1.3  1994/10/10  14:36:18  tamches
41  * fixed some resizing bugs
42  *
43  * Revision 1.2  1994/09/29  20:05:39  tamches
44  * minor cvs fixes
45  *
46  * Revision 1.1  1994/09/29  19:52:25  tamches
47  * initial implementation.
48  * This is a modified version of DGclient.C (tclVisi/src), specially
49  * tuned for the barchart program.
50  *
51 */
52
53 // An updated version of DGClient.C for barchart2.C
54 // Contains several **deletions** to remove blt_barchart influences
55
56 #include <stdlib.h> // exit()
57 #include <iostream.h>
58
59 #include "tcl.h"
60 #include "tk.h"
61 #include "tkTools.h" // myTclEval()
62
63 #include "dg2.h"
64 #include "visi/h/visualization.h"
65 #include "barChartTcl.h"
66 #include "barChart.h"
67
68 void my_visi_callback(void*, int*, long unsigned int*) {
69    if (visi_callback() == -1)
70       exit(0);
71 }
72
73 int Dg2AddMetricsCallback(int) {
74    myTclEval(MainInterp, "DgConfigCallback");
75
76    // if necessary, the tcl program will call xAxisHasChanged and/or
77    // yAxisHasChanged, which are commands we implement in barChart.C.
78    // We take action then.
79
80    return TCL_OK;
81 }
82
83 int Dg2Fold(int) {
84    myTclEval(MainInterp, "DgFoldCallback");
85    return TCL_OK;
86 }
87
88 int Dg2InvalidMetricsOrResources(int) {
89    myTclEval(MainInterp, "DgInvalidCallback");
90    return TCL_OK;
91 }
92
93 int Dg2PhaseNameCallback(int) {
94    myTclEval(MainInterp, "DgPhaseCallback");
95    return TCL_OK;
96 }
97
98 #define   AGGREGATE        0
99 #define   BINWIDTH         1
100 #define   FOLDMETHOD       2
101 #define   METRICNAME       3
102 #define   METRICUNITS      4
103 #define   METRICAVEUNITS   5
104 #define   METRICSUMUNITS   6
105 #define   NUMBINS          7
106 #define   NUMMETRICS       8
107 #define   NUMRESOURCES     9
108 #define   DEFINEPHASE      10
109 #define   RESOURCENAME     11
110 #define   STARTSTREAM      12
111 #define   STOPSTREAM       13
112 #define   DGSUM            14
113 #define   DGVALID          15
114 #define   DGENABLED        16
115 #define   VALUE            17
116 #define   CMDERROR         18
117 #define   LASTBUCKET       19
118 #define   FIRSTBUCKET      20
119
120 struct cmdTabEntry {
121    const char *cmdname;
122    int index;
123    int numargs;
124 };
125
126 static struct cmdTabEntry Dg_Cmds[] = {
127   {"aggregate",    AGGREGATE,       2},
128   {"binwidth",     BINWIDTH,        0},
129   {"firstbucket",  FIRSTBUCKET,     2},
130   {"foldmethod",   FOLDMETHOD,      2},
131   {"lastbucket",   LASTBUCKET,      2},
132   {"metricname",   METRICNAME,      1},
133   {"metricunits",  METRICUNITS,     1},
134   {"metricaveunits", METRICAVEUNITS,1},
135   {"metricsumunits", METRICSUMUNITS,1},
136   {"numbins",      NUMBINS,         0},
137   {"nummetrics",   NUMMETRICS,      0},
138   {"numresources", NUMRESOURCES,    0},
139   {"phase",        DEFINEPHASE,     3},
140   {"resourcename", RESOURCENAME,    1},
141   {"start",        STARTSTREAM,     0},
142   {"stop",         STOPSTREAM,      2},
143   {"sum",          DGSUM,           2},
144   {"valid",        DGVALID,         2},
145   {"enabled",      DGENABLED,       2},
146   {"value",        VALUE,           3},
147   {NULL,           CMDERROR,        0}
148 };
149
150 int findCommand(Tcl_Interp *interp, 
151                        int argc, 
152                        char *argv[]) {
153
154   if (argc == 0) {
155      sprintf(interp->result, "USAGE: Dg <option> [args...]\n");
156      return CMDERROR;
157   }
158
159   for (cmdTabEntry *C = Dg_Cmds; C->cmdname!=NULL; C++) {
160      if (strcmp(argv[0], C->cmdname) == 0) {
161         if (argc-1 == C->numargs) 
162            return C->index; // successful parsing
163
164         sprintf(interp->result, 
165               "%s: wrong number of args (%d). Should be %d\n",
166               argv[0], argc-1, C->numargs);
167         return CMDERROR;
168      }
169   }
170
171   sprintf(interp->result, "unknown option (%s)\n", argv[0]);
172   return CMDERROR;
173 }
174
175 int Dg_TclCommand(ClientData,
176                   Tcl_Interp *interp, 
177                   int argc, char *argv[]) {
178   // entrypoint to the tcl "Dg" command we've installed
179   // all the sprintf()'s are rather slow...
180
181   // parse the arguments, using global vrble Dg_Cmds[] to tell what's what.
182   int cmdDex = findCommand(interp, argc-1, argv+1);
183   if (cmdDex == CMDERROR)
184     return TCL_ERROR;
185
186   int m, r, buck; // metric number, resource number, bucket number
187
188   switch(cmdDex) {
189   case AGGREGATE:   
190     m = atoi(argv[2]);
191     r = atoi(argv[3]);
192     sprintf(interp->result,"%g", visi_AverageValue(m,r));
193     return TCL_OK;
194
195   case BINWIDTH:     
196     sprintf(interp->result, "%g", visi_BucketWidth());
197     return TCL_OK;
198
199   case FIRSTBUCKET:
200     m = atoi(argv[2]);
201     r = atoi(argv[3]);
202     sprintf(interp->result,"%d", visi_FirstValidBucket(m,r)); 
203     return TCL_OK;
204
205   case LASTBUCKET:
206     m = atoi(argv[2]);
207     r = atoi(argv[3]);
208     sprintf(interp->result,"%d", visi_LastBucketFilled(m,r));
209     return TCL_OK;
210
211   case METRICNAME:  
212     m = atoi(argv[2]);
213     strcpy(interp->result, visi_MetricName(m));
214     return TCL_OK;
215
216   case METRICUNITS:  
217     m = atoi(argv[2]);
218     strcpy(interp->result, visi_MetricLabel(m));
219     return TCL_OK;
220
221   case METRICAVEUNITS:  
222     m = atoi(argv[2]);
223     strcpy(interp->result, visi_MetricAveLabel(m));
224     return TCL_OK;
225
226   case METRICSUMUNITS:  
227     m = atoi(argv[2]);
228     strcpy(interp->result, visi_MetricSumLabel(m));
229     return TCL_OK;
230
231   case NUMBINS:     
232     sprintf(interp->result, "%d", visi_NumBuckets());
233     return TCL_OK;
234
235   case NUMMETRICS:  
236     sprintf(interp->result, "%d", visi_NumMetrics());
237     return TCL_OK;
238
239   case NUMRESOURCES:
240     sprintf(interp->result, "%d", visi_NumResources());
241     return TCL_OK;
242
243   case DEFINEPHASE:       
244     visi_DefinePhase(-1.0,NULL);
245     return TCL_OK;
246
247   case RESOURCENAME:
248     r = atoi(argv[2]);
249     strcpy(interp->result, visi_ResourceName(r));
250     return TCL_OK;
251
252   case STARTSTREAM:       
253     visi_GetMetsRes(); 
254     return TCL_OK;
255
256   case STOPSTREAM:
257     m = atoi(argv[2]);
258     r = atoi(argv[3]);
259     visi_StopMetRes(m, r);
260     return TCL_OK;
261
262   case DGSUM:         
263     m = atoi(argv[2]);
264     r = atoi(argv[3]);
265     sprintf(interp->result,"%g", visi_SumValue(m,r));
266     return TCL_OK;
267
268   case DGVALID:
269     m = atoi(argv[2]);
270     r = atoi(argv[3]);
271     sprintf(interp->result, "%d", visi_Valid(m,r));
272     return TCL_OK;
273
274   case DGENABLED:
275     m = atoi(argv[2]);
276     r = atoi(argv[3]);
277     sprintf(interp->result, "%d", visi_Enabled(m,r));
278 //    sprintf(interp->result, "%d", Enabled(m,r));
279     return TCL_OK;
280
281   case VALUE:       
282     m = atoi(argv[2]);
283     r = atoi(argv[3]);
284     buck = atoi(argv[4]);
285     sprintf(interp->result,"%g", visi_DataValue(m,r,buck));
286     return TCL_OK;
287   }
288
289   sprintf(interp->result, "Internal error (func findCommand)\n");
290   return TCL_ERROR;
291 }
292
293 void (*UsersNewDataCallbackRoutine)(int firstBucket, int lastBucket);
294    // we will call this routine for you when we get a new-data callback
295    // from the visi lib (first, we do a bit of processing for you, such
296    // as determining what the range is buckets you haven't seen yet is).
297
298 int Dg2_Init(Tcl_Interp *interp) {
299    // initialize with the visi lib
300    int fd = visi_Init();
301    if (fd < 0) {
302       cerr << "Dg2_Init() -- could not initialize with the visi lib" << endl;
303       exit(5);
304    }
305
306    // Register C++ Callback routines with the visi lib when
307    // certain events happen.  The most important (performance-wise)
308    // is the DATAVALUES callback, which signals the arrival of
309    // new barchart data.  We must process this callback very quickly,
310    // in order to perturb the system as little as possible.
311
312    if (visi_RegistrationCallback(ADDMETRICSRESOURCES,Dg2AddMetricsCallback)!=0)
313       panic("Dg2_Init() -- couldn't install ADDMETRICSRESOURCES callback");
314
315    if (visi_RegistrationCallback(FOLD, Dg2Fold) != 0)
316       panic("Dg2_Init() -- couldn't install FOLD callback");
317
318    if (visi_RegistrationCallback(INVALIDMETRICSRESOURCES, Dg2InvalidMetricsOrResources) != 0)
319       panic("Dg2_Init() -- couldn't install INVALID callback");
320
321    if (visi_RegistrationCallback(PHASESTART, Dg2PhaseNameCallback) != 0)
322       panic("Dg2_Init() -- couldn't install PHASENAME callback");
323
324    if (visi_RegistrationCallback(DATAVALUES, Dg2NewDataCallback) != 0)
325       panic("Dg2_Init() -- couldn't install DATAVALUES callback");
326
327    // install "Dg" as a new tcl command; Dg_TclCommand() will be invoked when
328    // a tcl script calls Dg
329    Tcl_CreateCommand(interp, "Dg", Dg_TclCommand, 
330                     (ClientData *) NULL,(Tcl_CmdDeleteProc *) NULL);
331  
332    // Arrange for my_visi_callback() to be called whenever data is waiting
333    // to be read off of descriptor "fd".  Extremely important! [tcl book
334    // page 357]
335    Tk_CreateFileHandler(fd, TK_READABLE, (Tk_FileProc *) my_visi_callback, 0);
336
337    return TCL_OK;
338 }