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