removed DEFINEPHASE
[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.16  1996/02/23 17:48:06  tamches
6 /* removed DEFINEPHASE
7 /*
8  * Revision 1.15  1996/01/19 20:56:06  newhall
9  * changes due to visiLib interface changes
10  *
11  * Revision 1.14  1996/01/17 18:31:14  newhall
12  * changes due to new visiLib
13  *
14  * Revision 1.13  1996/01/10 21:11:15  tamches
15  * added METRICAVEUNITS, METRICSUMUNITS
16  *
17  * Revision 1.12  1995/11/29 00:40:07  tamches
18  * removed myTclEval
19  *
20  * Revision 1.11  1995/11/17 17:39:32  newhall
21  * changed Dg start command, and call to GetMetsRes
22  *
23  * Revision 1.10  1995/11/17  17:32:27  newhall
24  * changed Dg start command to take no arguments, replaced call to MetricUnits
25  * with call to MetricLabel
26  *
27  * Revision 1.9  1995/09/22  19:23:41  tamches
28  * removed warnings under g++ 2.7.0
29  *
30  * Revision 1.8  1995/08/06  22:11:48  tamches
31  * removed some warnings by using myTclEval
32  *
33  * Revision 1.7  1995/02/26  02:01:48  newhall
34  * added callback functions for new visiLib phase info.
35  *
36  * Revision 1.6  1994/11/06  10:24:04  tamches
37  * minor cleanups (especially commenting)
38  *
39  * Revision 1.5  1994/10/11  21:59:47  tamches
40  * Removed extra StartVisi() bug.
41  * Implemented dataGrid[][].Enabled()
42  *
43  * Revision 1.4  1994/10/10  23:08:47  tamches
44  * preliminary changes on the way to swapping the x and y axes
45  *
46  * Revision 1.3  1994/10/10  14:36:18  tamches
47  * fixed some resizing bugs
48  *
49  * Revision 1.2  1994/09/29  20:05:39  tamches
50  * minor cvs fixes
51  *
52  * Revision 1.1  1994/09/29  19:52:25  tamches
53  * initial implementation.
54  * This is a modified version of DGclient.C (tclVisi/src), specially
55  * tuned for the barchart program.
56  *
57 */
58
59 // An updated version of DGClient.C for barchart2.C
60 // Contains several **deletions** to remove blt_barchart influences
61
62 #include <stdlib.h> // exit()
63 #include <iostream.h>
64
65 #include "tcl.h"
66 #include "tk.h"
67 #include "tkTools.h" // myTclEval()
68
69 #include "dg2.h"
70 #include "visi/h/visualization.h"
71 #include "barChartTcl.h"
72 #include "barChart.h"
73
74 void my_visi_callback(void*, int*, long unsigned int*) {
75    if (visi_callback() == -1)
76       exit(0);
77 }
78
79 int Dg2AddMetricsCallback(int) {
80    myTclEval(MainInterp, "DgConfigCallback");
81
82    // if necessary, the tcl program will call xAxisHasChanged and/or
83    // yAxisHasChanged, which are commands we implement in barChart.C.
84    // We take action then.
85
86    return TCL_OK;
87 }
88
89 int Dg2Fold(int) {
90    myTclEval(MainInterp, "DgFoldCallback");
91    return TCL_OK;
92 }
93
94 int Dg2InvalidMetricsOrResources(int) {
95    myTclEval(MainInterp, "DgInvalidCallback");
96    return TCL_OK;
97 }
98
99 int Dg2PhaseNameCallback(int) {
100    myTclEval(MainInterp, "DgPhaseCallback");
101    return TCL_OK;
102 }
103
104 #define   AGGREGATE        0
105 #define   BINWIDTH         1
106 #define   FOLDMETHOD       2
107 #define   METRICNAME       3
108 #define   METRICUNITS      4
109 #define   METRICAVEUNITS   5
110 #define   METRICSUMUNITS   6
111 #define   NUMBINS          7
112 #define   NUMMETRICS       8
113 #define   NUMRESOURCES     9
114 #define   RESOURCENAME     10
115 #define   STARTSTREAM      11
116 #define   STOPSTREAM       12
117 #define   DGSUM            13
118 #define   DGVALID          14
119 #define   DGENABLED        15
120 #define   VALUE            16
121 #define   CMDERROR         17
122 #define   LASTBUCKET       18
123 #define   FIRSTBUCKET      19
124
125 struct cmdTabEntry {
126    const char *cmdname;
127    int index;
128    int numargs;
129 };
130
131 static struct cmdTabEntry Dg_Cmds[] = {
132   {"aggregate",    AGGREGATE,       2},
133   {"binwidth",     BINWIDTH,        0},
134   {"firstbucket",  FIRSTBUCKET,     2},
135   {"foldmethod",   FOLDMETHOD,      2},
136   {"lastbucket",   LASTBUCKET,      2},
137   {"metricname",   METRICNAME,      1},
138   {"metricunits",  METRICUNITS,     1},
139   {"metricaveunits", METRICAVEUNITS,1},
140   {"metricsumunits", METRICSUMUNITS,1},
141   {"numbins",      NUMBINS,         0},
142   {"nummetrics",   NUMMETRICS,      0},
143   {"numresources", NUMRESOURCES,    0},
144   {"resourcename", RESOURCENAME,    1},
145   {"start",        STARTSTREAM,     2},
146   {"stop",         STOPSTREAM,      2},
147   {"sum",          DGSUM,           2},
148   {"valid",        DGVALID,         2},
149   {"enabled",      DGENABLED,       2},
150   {"value",        VALUE,           3},
151   {NULL,           CMDERROR,        0}
152 };
153
154 int findCommand(Tcl_Interp *interp, 
155                        int argc, 
156                        char *argv[]) {
157
158   if (argc == 0) {
159      sprintf(interp->result, "USAGE: Dg <option> [args...]\n");
160      return CMDERROR;
161   }
162
163   for (cmdTabEntry *C = Dg_Cmds; C->cmdname!=NULL; C++) {
164      if (strcmp(argv[0], C->cmdname) == 0) {
165         if (argc-1 == C->numargs) 
166            return C->index; // successful parsing
167
168         sprintf(interp->result, 
169               "%s: wrong number of args (%d). Should be %d\n",
170               argv[0], argc-1, C->numargs);
171         return CMDERROR;
172      }
173   }
174
175   sprintf(interp->result, "unknown option (%s)\n", argv[0]);
176   return CMDERROR;
177 }
178
179 int Dg_TclCommand(ClientData,
180                   Tcl_Interp *interp, 
181                   int argc, char *argv[]) {
182   // entrypoint to the tcl "Dg" command we've installed
183   // all the sprintf()'s are rather slow...
184
185   // parse the arguments, using global vrble Dg_Cmds[] to tell what's what.
186   int cmdDex = findCommand(interp, argc-1, argv+1);
187   if (cmdDex == CMDERROR)
188     return TCL_ERROR;
189
190   int m, r, buck; // metric number, resource number, bucket number
191
192   switch(cmdDex) {
193   case AGGREGATE:   
194     m = atoi(argv[2]);
195     r = atoi(argv[3]);
196     sprintf(interp->result,"%g", visi_AverageValue(m,r));
197     return TCL_OK;
198
199   case BINWIDTH:     
200     sprintf(interp->result, "%g", visi_BucketWidth());
201     return TCL_OK;
202
203   case FIRSTBUCKET:
204     m = atoi(argv[2]);
205     r = atoi(argv[3]);
206     sprintf(interp->result,"%d", visi_FirstValidBucket(m,r)); 
207     return TCL_OK;
208
209   case LASTBUCKET:
210     m = atoi(argv[2]);
211     r = atoi(argv[3]);
212     sprintf(interp->result,"%d", visi_LastBucketFilled(m,r));
213     return TCL_OK;
214
215   case METRICNAME:  
216     m = atoi(argv[2]);
217     strcpy(interp->result, visi_MetricName(m));
218     return TCL_OK;
219
220   case METRICUNITS:  
221     m = atoi(argv[2]);
222     strcpy(interp->result, visi_MetricLabel(m));
223     return TCL_OK;
224
225   case METRICAVEUNITS:  
226     m = atoi(argv[2]);
227     strcpy(interp->result, visi_MetricAveLabel(m));
228     return TCL_OK;
229
230   case METRICSUMUNITS:  
231     m = atoi(argv[2]);
232     strcpy(interp->result, visi_MetricSumLabel(m));
233     return TCL_OK;
234
235   case NUMBINS:     
236     sprintf(interp->result, "%d", visi_NumBuckets());
237     return TCL_OK;
238
239   case NUMMETRICS:  
240     sprintf(interp->result, "%d", visi_NumMetrics());
241     return TCL_OK;
242
243   case NUMRESOURCES:
244     sprintf(interp->result, "%d", visi_NumResources());
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(argv[2],0); 
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 }