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