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