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