BDE
ReplayProject Report
91.592 Software Engineering
Sathyanarayan Jaganathan
(Spring 2002)
Computer Science Department
University of Massachusetts,
Lowell
Table of contents
|
Page |
|
|
2 2 2 |
|
|
2 3 3 3 |
|
|
4 4 |
|
|
4 5 |
|
|
6 7 8 |
|
|
11 |
|
|
11 |
|
Appendix A |
12 |
This section describes the new features added to implement replay in BDE using keypress callback.
Replay in BDE needs a replay file (‘logfile.txt’) that contains the list of commands to modify the database and snapshot of the initial database. The snapshot is stored as ‘logfileDB1.dat’. Replay file can be specified at command line; this loads the respective snapshot file and opens first graph in BDE canvas. Replay can also be initiated by clicking ‘Start Replay’ in the menu.
BDE also accepts a database snapshot file at its command line. This opens a graph select dialog box, and displays a user selected graph.
This version of BDE uses a ‘keypress callback’, the user can step through each command in the replay file by pressing ‘s’ button.
Replay implementation in BDE, needed some considerable changes to pr_log.c file generated by Chgen version 12. A new function replay_log with a different state model and more BDE and X-11 specific statements replaces the function in pr_log.c, which was more Gen and database dependent.
replay_log is a BDE specific function in bdeReplay.cc, which makes database updations similar to pr_replay in pr_log.c. The new function has three states. At any time the function will be in one of these three states.
State 0:
In this state, the function opens the file ‘<logfile>.txt’ and verifies if the first line is ‘SR’. It switches to State 1 only when it finds an ‘SR’ token in the first line.
State 1:
The function reads a line from ‘<logfile>.txt’ and parses the line. It executes the command on the database, if the command is valid. For every valid command, the display list is updated and the canvas is redrawn.
State 2:
The function reaches this state at the end of ‘<logfile>.txt’. In this state the replay file is closed and an appropriate value is returned.
Replay in BDE can be initiated in two ways. The first method is to specify the replay file at the command line. The other method is covered in the next subsection. In the former, respective database snapshot file (<logfile>DB1.dat) is loaded to the database and the first graph in the snapshot file is displayed on the canvas. The default selection of the first graph can be changed to user selection by "# define SELECT_REPLAY_GRAPH 1" in fileio.cc.
Replay can be started by pressing ‘Start Replay’ button in the menu. This displays a file selection dialog box. The files that are displayed in the file selection box are filtered to have ‘txt’ extension. After user selects a replay file, the respective database snapshot is loaded to the memory resident database and displayed on the canvas.
After initializing replay in BDE, next step is to step through the commands in the replay file. Stepping is done by pressing ‘s’ button in the keyboard. A keypress callback is triggered when user presses any key, which in turn calls replay_log function if the key pressed is ‘s’. The keypress callback handler calls replay_log only when the value of ReplayReady variable is 1. Replay stepping is also implemented using other callbacks. The source code and testing for other callbacks are in the folder ‘/usr/proj3/case/02s592’.
Discussion and analysis of replay implementation in BDE, revealed the use of more BDE specific statements and functions during the replay process. Since chgen code is more database dependent, a new file with application specific code and database operations was added to BDE (bdeReplay.cc).
Replay_log is called by the keypress callback handler which is in file fileio.cc. If the function reads a valid command from the replay file that changes the contents of the database, it deletes the display list of BDE and rebuilds the display list to have the contents of the current graph and calls Redraw function to redraw the canvas.
This section describes the BDE user interface for replay using keypress callback.
Screen shots for replay in BDE


Replay file: mylog.txt
Database snapshot: mylogDB1.dat
SR
VN 94sbdeview
/* DL HA000001 */
HA000002 HN000011 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E
DL HA000001
HA000003 HN000012 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E
DL HA000002
HA000004 HN000012 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N
DL HA000003
HA000005 HN000013 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N
DL HA000004
HA000006 HN000014 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N
DL HA000005
HA000007 HN000015 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N
DL HA000006
HA000008 HN000016 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N
DL HA000007
HA000009 HN000016 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W
DL HA000008
HA000010 HN000017 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W
DL HA000009
HA000011 HN000018 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W
DL HA000010
HA000012 HN000019 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W
DL HA000011
HA000013 HN000004 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W
DL HA000012
HA000014 HN000004 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S
DL HA000013
HA000015 HN000005 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S
DL HA000014
HA000016 HN000006 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S
DL HA000015
HA000017 HN000007 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S
DL HA000016
HA000018 HN000008 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S
DL HA000017
HA000019 HN000008 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E
DL HA000018
HA000020 HN000009 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E
DL HA000019
HA000021 HN000010 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E
DL HA000020
SP
HG000001 FS010000 HN010000 LECHNER 19FEB02/2224 19FEB02/2224 ringPath.dat
HN000004 HG000001 FS010000 R 60.0000 60.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000005 HG000001 FS010000 R 60.0000 110.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000006 HG000001 FS010000 R 60.0000 160.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000007 HG000001 FS010000 R 60.0000 210.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000008 HG000001 FS010000 R 60.0000 260.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000009 HG000001 FS010000 R 110.0000 260.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000010 HG000001 FS010000 R 160.0000 260.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000011 HG000001 FS010000 R 210.0000 260.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000012 HG000001 FS010000 R 260.0000 260.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000013 HG000001 FS010000 R 260.0000 210.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000014 HG000001 FS010000 R 260.0000 160.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000015 HG000001 FS010000 R 260.0000 110.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000016 HG000001 FS010000 R 260.0000 60.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000017 HG000001 FS010000 R 210.0000 60.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000018 HG000001 FS010000 R 160.0000 60.0000 48.0000 48.0000 Fixed 11.0000 11.0000 30 13
HN000019 HG000001 FS010000 R 110.0000 60.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HN000020 HG000001 FS010000 R 59.0000 59.0000 49.0000 49.0000 Fixed 0.0000 0.0000 0 0
HA000001 HN000010 DA010009 8.0000 -4.0000 0.0000 37 16 *helvetica-bold-r*140* E
CG000001 HG000001 370.0000 25.0000 50.0000 0.0000
CG000002 HG000001 509.0000 80.0000 416.0000 56.0000
CG000003 HG000001 515.0000 243.0000 422.0000 66.0000
GX000001 CG000001 DA010009 0.0000 *helvetica-bold-r*140* 36.0000 -6.0000 72 13 ringPath.dat
GX000002 CG000002 DA010009 0.0000 *helvetica-bold-r*140* 181.0000 10.0000 331 21 ringPath.dat: Closed Path for Hominid Navigation Test
GX000003 CG000002 DA010009 0.0000 *helvetica-bold-r*140* 181.0000 -12.0000 304 21 Created 020219; last changed 020522 as mylogDB1.dat
GX000004 CG000003 DA010009 0.0000 *helvetica-bold-r*140* 203.0000 16.0000 246 16 Nodes HN000000 thru HN000003 were removed.
GX000005 CG000003 DA010009 0.0000 *helvetica-bold-r*140* 202.2534 -1.0000 218 16 Nodes 4 to 20 proceed clockwise from upper left corner.
GX000006 CG000003 DA010009 0.0000 *helvetica-bold-r*140* 202.2534 -17.0000 218 16 Manual edits were made to this file - RJL
Script started on Thu May 23 15:46:12 2002
%pwd
/usr/proj3/case/gen/ver_12/sjaganat/Test/bde/test
%../executables/alpha/bde.exe mylog.txt
Using GENV12
Warning: Cannot convert string "-*-Menu-Medium-R-Normal--*-120-*-*-P-*-ISO8859-1" to type FontStruct
Replay file : mylog.txt | Click Options -> Start Replay to start replay
GD defaults file not specified. Using BDE defaults
SCnode 0x11 17
dostate: selected.getstate = 0x11 = 17
Using default viewdefs: ../lib/bdetest.viewdefs
Warning: unknown table /* found in scanned datafile ../lib/fonts.dat, ignored.
Warning: unknown table /* found in scanned datafile ../lib/fonts.dat, ignored.
Warning: unknown table found in scanned datafile ../lib/fonts.dat, ignored.
Warning: unknown table found in scanned datafile ../lib/fonts.dat, ignored.
Warning: unknown table () found in datafile, ignored.
Replay Ready : 1Token=SR, Command = 6
Found SR
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=VN, Command = 11
Found VN with viewname 94sbdeview.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=/*, Command = -1
Logfile: unknown command '/*' - ignored
Unknown pkey /*: skipping
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000002, Command = 12
Found Add with pkey HA000002, rest HN000011 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000001.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000003, Command = 12
Found Add with pkey HA000003, rest HN000012 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000002.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000004, Command = 12
Found Add with pkey HA000004, rest HN000012 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000003.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000005, Command = 12
Found Add with pkey HA000005, rest HN000013 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000004.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000006, Command = 12
Found Add with pkey HA000006, rest HN000014 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000005.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000007, Command = 12
Found Add with pkey HA000007, rest HN000015 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000006.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000008, Command = 12
Found Add with pkey HA000008, rest HN000016 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* N .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000007.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000009, Command = 12
Found Add with pkey HA000009, rest HN000016 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000008.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000010, Command = 12
Found Add with pkey HA000010, rest HN000017 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000009.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000011, Command = 12
Found Add with pkey HA000011, rest HN000018 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000010.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000012, Command = 12
Found Add with pkey HA000012, rest HN000019 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000011.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000013, Command = 12
Found Add with pkey HA000013, rest HN000004 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* W .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000012.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000014, Command = 12
Found Add with pkey HA000014, rest HN000004 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000013.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000015, Command = 12
Found Add with pkey HA000015, rest HN000005 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000014.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000016, Command = 12
Found Add with pkey HA000016, rest HN000006 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000015.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000017, Command = 12
Found Add with pkey HA000017, rest HN000007 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000016.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000018, Command = 12
Found Add with pkey HA000018, rest HN000008 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* S .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000017.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000019, Command = 12
Found Add with pkey HA000019, rest HN000008 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000018.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000020, Command = 12
Found Add with pkey HA000020, rest HN000009 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000019.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=HA000021, Command = 12
Found Add with pkey HA000021, rest HN000010 DA010009 0.0000 0.0000 0.0000 0 0 *helvetica-bold-r*140* E .
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=DL, Command = 5
Found DL with pkey HA000020.
Fileio.cc:replay_Log returns: replayStatus = 1
Replay Ready : 1Token=SP, Command = 10
Found SP
Fileio.cc:replay_Log returns: replayStatus = 2
Replay Ready : 0Fileio.cc:replay_Log returns: replayStatus = 536852704
Replay Ready : 0Fileio.cc:replay_Log returns: replayStatus = 536852704
%exit
exit
script done on Thu May 23 15:47:21 2002
The X Toolkit Cookbook
Paul E. Kimball
Genlog Project
M. Murphy, D. Nelson, B. Rideout.
Chgen V11 Final Report
Prof. R. J. Lechner, Joseph S. Karner, Keith B. Spinney.
Appendix A
Code changes to BDE
/***********************************************************/
/* File : bdeReplay.cc */
/* Description : */
/* Created by : 02s592 */
/* Routines : replay_log */
/* updatedisplaylist */
/* Uses: encode_token and do_command in pr_log.c */
/***********************************************************/
/* TBD: CHeck if ReDraw is a callback wrapper or the real stuff -RJL */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "94sbde_schema.h"
#include "bde.h"
#include "prototype.h" // no longer declares replay_log-RJL 020501
#include "graph.h" //class i'faces; #includes state.h
///////////// X/Xt/Motif include files ////////////////////
// RJL: Why do we need <X11*.h>in bdeReplay.cc?
// replay_log is called FROM the Xt callback routine in fileio.cc
//#include <X11/StringDefs.h>
//#include <X11/Xlib.h>
//#include <X11/Intrinsic.h>
//#include <Xm/Xm.h>
extern "C" {
/* in pr_load.c: */
void hcg_parse(char*, char*, int*);
extern char* viewname; /* view --> viewname - RJL 020501 */
/* in pr_log.c: */
void hcg_read_next(void);
extern hcg_key HG_pkey;
extern char *logfile;
extern FILE* logfile_fp;
extern char token[BUFSIZE];
extern int near_realtime;
extern int take_endsnapshot;
extern int replayState;
extern int replayStatus;
extern int idx;
} /* extern "C" */
// replayState values: (should be enum'd)
#define STATE0 0
#define STATE1 1
#define STATE2 2
// enumeration of command names as integers:
typedef
enum {SetIntCmd,SetFltCmd,SetKeyCmd,SetStrCmd,WaitCmd,DeleteCmd,
StartCmd,FreeCmd,InitCmd,LoadCmd,StopCmd,ViewNameCmd,AddRowCmd}
replayCode;
replayCode command; // for switch(command)
extern "C" {
replayCode do_command(char*, char*, int*);
}
// macros to avoid scattered #ifdefs below
// depend on argcount after format string
//ERROR: `#' operator should be followed by a macro argument name
// when tried to #define dprintf wraped in #ifdef DEBUG - RJL 020430
#define dprintf(string)\
printf(string);
#define dprintf1arg(string,arg1)\
printf(string, arg1);
#define dprintf2args(string,arg1,arg2)\
printf(string, arg1, arg2);
void updatedisplaylist(struct HG *cHG) /* updates HGcurr - RJL*/
/* updatedisplaylist regenerates the graph object list of HN/CG/HL ptrs
* after a database update or HG-row selection;
* it supplies input data for ReDraw.
* The caller is responsible for updating cHG - RJL 020427
*/
{
node *lastnode;
hlink *lastlink;
caption *lastcaption; // last caption Added by 94FBDE
HGcurr = cHG; // added 020427 - RJL (else why pass this argument?)
(void) new graph(HGcurr);
child_loop(HG,HN,HNid,HGid) // depends on HGcurr!
{
lastnode = new node(HNcurr);
child_loop(HN,HL,HLid1,HNid1)
{
lastlink = new hlink(HLcurr);
}
}
child_loop(HG,CG,CGid,HGid) // Added by 94FBDE
{
lastcaption = new caption(CGcurr);
}
} // end updatedisplaylist
void encode_token(char *token, int *command)
/* encode_token converts first token on a logfile line to an int arg
* for use as a switch(command) argument.
* Move this to pr_log.c where chgen can produce it - RJL 020427
*/
{
int tokenlength = strlen(token);
if (tokenlength==10) {
if (strcmp(token,"PR_SET_INT") == 0) *command = SetIntCmd;
else if (strcmp(token,"PR_SET_FLT") == 0) *command = SetFltCmd;
else if (strcmp(token,"PR_SET_KEY") == 0) *command = SetKeyCmd;
else if (strcmp(token,"PR_SET_STR") == 0) *command = SetStrCmd;
}
else if (tokenlength==2) { //ordered by decreasing frrequency
if (strcmp(token,"WA") == 0) *command = WaitCmd;
else if (strcmp(token,"DL") == 0) *command = DeleteCmd;
else if (strcmp(token,"FR") == 0) *command = FreeCmd;
else if (strcmp(token,"IN") == 0) *command = InitCmd;
else if (strcmp(token,"LD") == 0) *command = LoadCmd;
else if (strcmp(token,"SP") == 0) *command = StopCmd;
else if (strcmp(token,"VN") == 0) *command = ViewNameCmd;
else if (strcmp(token,"SR") == 0) *command = StartCmd; /* Sathya */
}
else if (tokenlength != HCG_KEY_SIZE) // pkey, 8 or 12 bytes
{
printf("Logfile: unknown command '%s' - ignored\n", token);
}
else //expect table row to be pr_added */
{
*command = AddRowCmd; // default
};
dprintf2args("Token=%s, Command = %d\n", token, *command);
}
// end encode_token
/************************************************************/
/* Function:replay_log */
/* */
/* This is the callback function to parse one logfile line */
/* and execute the action of the log entry. */
/* The arguments are saved by pr_replay for reference here */
/* Arguments: logfile - logfile to replay */
/* near_realtime - flag indicates to */
/* replay in near realtime */
/* 0 = not real time */
/* 1 = real time */
/* Return values: */
/* 0 - success parsing and replay */
/* -3 - cannot open file */
/* -5 - logfile doesn't start with line "SR" */
/* -7 - logfile doesn't end with line "SP" */
/* "SR" is a precondition if pr_load delegates to pr_replay.*/
/* "SP" is a post-condition that is not fatal */
/* fopen success is a pre-condition - pr_load already tried.*/
/* Effects: */
/* hcg_buffer - altered */
/* hcg_ascii_fp - altered */
/* hcg_t - altered */
/* value of database may be altered based on commamnds in */
/* the format of the data file. If no SP was found, */
/* replay_log will exit [with no change? - RJL] */
/************************************************************/
/******************************************************************
* Design Notes from RJL - 020429: a problem here is that most of the code
* below can be auto-generated by genv12; only the state machine and
* updatedisplaylist and ReDraw calls are bde-specific.
* The rest depends only on schema.h. and chgen can handle it.
*
* Therefore I refactored out some code and moved it to pr_util.
* THis includes the Level 2 command interpreter.
* Level 1: switch(state) as below;
* Level 2: encode(token, &command) and switch(command);
* encode_token() enumerates the commands for inner switch cases.
*
* The last 5 lines of each command case block
* were common to most but not all commands; I factored them out
* under one of two switch(command) blocks for selective action.
* SOme lines below call other pr_util library functions
* generated in pr_log.c by chgen.
*************************************************************
*/
extern "C" int replay_log(void);
int replay_log(void) // RJL: void
{
//This belongs in pr_replay - RJL 020427
assert((near_realtime == 1) || (near_realtime ==0));
// Valid command values depend on replayState:
switch(replayState) {
case STATE0:
/* re-open the log file and go to STATE1 or STATE2 */
if ((logfile_fp = fopen(logfile, "r")) ==NULL) {
hcg_log = 0;
return(-3);
}
hcg_ascii_fp = logfile_fp;
hcg_read_next(); /* read first line of log file */
assert(!feof(hcg_ascii_fp)); // pre-condition
idx = 0;
hcg_parse(hcg_buffer,token,&idx);
encode_token(token, (int*)&command);
assert(command == StartCmd); /* Sathya */
//command "SR" is a pre-condition (verified by pr_load)
//so no need for switch(command)
dprintf("Found SR\n");
// Move read_next and feof test to start of State1:
replayState = STATE1; // GO TO STATE 1
break; // STATE0 /* Sathya - Break not needed to go to state1*/
// if (!feof(hcg_ascii_fp)) replayState = STATE1;
case STATE1:
hcg_read_next(); // get first command
if (feof(hcg_ascii_fp)) {
replayState = STATE2; // empty logfile
break;
}
command = do_command(hcg_buffer, token, &idx);
switch(command) {
case SetFltCmd:
case SetIntCmd:
case SetKeyCmd:
case SetStrCmd:
case AddRowCmd:
case DeleteCmd:
clearObjects();
HG_pkey = HGcurr->HGid;
updatedisplaylist(HGcurr);
ReDraw();
break;
case WaitCmd: case StartCmd: case FreeCmd: case InitCmd:
case LoadCmd: case StopCmd: case ViewNameCmd:
break;
} // end 2nd switch(command)
break; // end STATE1
case STATE2:
//Valid command is "SP"; absence is non-fatal;,
idx = 0;
hcg_read_next();
if (feof(hcg_ascii_fp)) {
fclose(logfile_fp);
replayStatus = -7; /* successful completion of log parsing */
}
hcg_parse(hcg_buffer,token,&idx);
encode_token(token, (int*) &command); // RJL 020427
if (strcmp(token,"SP") == 0) {
replayStatus= 0; /* successful completion of log parsing */
fclose(logfile_fp);
}
else {
fclose(logfile_fp);
replayStatus = -9; /* log file has stuff after the SP entry */
}
if (take_endsnapshot==1) { /* take final snapshot */
char* tempvar;
sprintf(tempvar,"%sDB3.dat",logfile);
pr_dump(viewname, tempvar,0,"w"); //view->viewname RJL 020501
}
break; // end of STATE2
default:
printf("Illegal value %d for replayState\n", replayState);
break;
} // end switch(replayState)
return replayState; /* returns to X11 not pr_replay - RJL */
} // end replay_log
/////////////////////////////////////////////////////////////////////
//
// Name : init.cc
//
// Description : Motif and bde intitialization routine
//
// Created by : 93fbde
//
// Routines : init_leftmenu
// init_menubar
// createNodeDialog
// create_load_dialogbox
// create_saveas_dialogbox
// create_exit_dialogbox
// initClasses
// changeCanvasCursor
// load_defaults
// donew
// dostate
//
// Edit history :
// <Revision history truncated>
//
/////////////////////////////////////////////////////////////////////
#ifndef lint
static char rcsid[] =
"$Id: init.cc,v 1.5.2.4 2002/05/02 03:10:13 lechner Exp $";
#endif
#ifndef String_REDEFINE_NOT_NEEDED /* redefine X11 String type-name */
#define String X_String_t
#endif
#ifndef String_REDEFINE_NOT_NEEDED
#undef String
#endif
////////////////// Include files ///////////////////////////////////
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include "bde.h"
#include "menus.h"
#include "graph.h"
#include "defs.h"
#include "loaddefaults.h"
#include "prototype.h"
///////////////// Macro defines ////////////////////////////////////
#define black rootscreen -> black_pixel
#define white rootscreen -> white_pixel
///////////////// External variables, Functions ///////////////////
extern Widget toplevel, valuemenu;
extern char globalfontname[51];
extern char *filedefault;
extern XFontStruct *gcfont;
extern void createMsgBox(void);
extern int currentArrow, // 96subde: fjara, ianandak
currentWidth,
currentPattern,
currentFit,
restyling;
extern char *logfile;
extern void Keypress(Widget w, XtPointer input, XEvent *event, Boolean *continue_dispatch);
extern void CreateHGDialogBox( char *);
extern char *current_filename;
extern void Replay_LoadGraph(char *infile);
extern int replayState;
///////////////// Program Widgets ////////////////////////////////
Widget canvas; //DrawingArea Widget
Widget exitbde; //PushButton Widget
Widget filenamebox, mesgboxtitle; //Label Widgets
Widget leftmenu; //BulletinBoard Widget
Widget menubar; //MenuBar Widget
Widget sw; //Scrolled Widget
Widget txtwidget;
Widget topform; //Form Widget
Widget textDialog;
Widget graphCaptionDialog;
Widget textbox; //Message box Widget
//////////////// Local subroutines/functions ////////////////////////////////
static int ChkInvalidCmdLineOptions( int, char ** );
//////////////// Global variables ////////////////////////////////
Cursor arrow, movehand, addcross, dot, textCursor;
Cursor pirate, question; /* added by BDE4 */
XFontStruct *font1;
XmFontList fontlist;
int ReplayReady, Opengraph = 0;
Display *display;
int displayWidth, displayHeight;
/*--------------------- Command Line Options -------------------------------*/
typedef struct APP_DATA /* Application's data */
{
String gd_defaults; /* graph defaults file */
String viewdefs; /* view definitions file */
} APP_DATA, *P_APP_DATA;
/* Command line options specific to this application */
static XrmOptionDescRec options[] = {
{ "-d", "*gd_defaults", XrmoptionSepArg, NULL },
{ "-v", "*viewdefs", XrmoptionSepArg, NULL },
};
/* Resources specific to this application (default values) */
/* logdata.txt conflicts with LogDataFile keyword list */
/* I changed this default to logdata_out.txt - RJL 020506 */
static XtResource resources[] = {
{ "gd_defaults", "GD_defaults", XtRString, sizeof(String),
XtOffset( P_APP_DATA, gd_defaults ), XtRString, (String) NULL },
{ "viewdefs", "Viewdefs", XtRString, sizeof(String),
XtOffset( P_APP_DATA, viewdefs ), XtRString, (String) NULL },
};
/*---------------------------------------------------------------------------*/
//bde aborts BEFORE this brkpnt at init.cc:253 - 2k0911 4PM
/////////////////////// INIT (Initialize) /////////////////////////
void init(unsigned int argc, char **argv)
{
//////////////// Local variables /////////////////////////////////
XtAppContext app;
XmString fiLe, edit, conf, help;
Screen *rootscreen;
int depth;
APP_DATA data;
int error;
XmString file_label;
String fallbacks[] = {
//"*fontList:-*-courier-bold-r-*--12-*=tag1",
"bde.form*resizable: false",
"bde.form.leftmenu*resizePolicy: XmRESIZE_NONE",
"bde.form.leftmenu*highlightThickness: 0",
"bde.form.filetitle.labelString: Untitled\n",
"bde.form.mesgboxtitle.labelString: Messages",
"bde.form.leftmenu.classboxframe.classbox*selectColor: red",
"bde.form.leftmenu.actionboxframe.actionbox*selectColor: red",
"bde.form.scrollwindow.height: 570",
"bde.form.scrollwindow.width: 650",
"bde.form.scrollwindow.canvas.height: 550",
"bde.form.scrollwindow.canvas.width: 740",
"bde.form.scrollwindow.canvas.background: white",
//this is a temporary fix to get around a bug in OSF Motif 1.2
"bde*button_5*labelString: Exit BDE",
"bde.height: 730",
"bde.width: 930",
NULL};
currentArrow = 1; // default arrow style (head). 96subde: fjara, ianandak
currentWidth = 1; // default segment width (medium). 96subde: fjara, ianandak
currentPattern = 0; // default line pattern (solid). 96subde: fjara, ianandak
currentFit = 0;
restyling = 0;
toplevel = XtVaAppInitialize(&app, "bde", options, XtNumber( options ),
(int *)&argc, argv, fallbacks, NULL);
/* when opening display, any command line options not
recognized are left in argv and argc. Program name
is always left in argv regardless */
if ( ( error = ChkInvalidCmdLineOptions( argc, argv )) == 0 )
{
/* get values for graph defaults and viewdefs
filenames */
XtGetApplicationResources( toplevel, &data, resources,
XtNumber( resources ), NULL, 0 );
font1 = XLoadQueryFont(XtDisplay(toplevel), "-*-courier-bold-r-*--18-*");
fontlist = XmFontListCreate(font1, "tag1");
//////////////// Basic X Stuff ///////////////////////////////////
display = XtDisplay(toplevel);
rootscreen = XtScreen(toplevel);
depth = DisplayPlanes(display, 0);
displayWidth = DisplayWidth(display, DefaultScreen(display));
displayHeight = DisplayHeight(display, DefaultScreen(display));
#ifdef DEBUG
XSynchronize(display, True);
#endif
//////////////// Cursors ////////////////////////////////////////
arrow = XCreateFontCursor(display, XC_top_left_arrow);
movehand = XCreateFontCursor(display, XC_hand2);
addcross = XCreateFontCursor(display, XC_cross);
dot = XCreateFontCursor(display, XC_dot);
textCursor = XCreateFontCursor(display, XC_xterm);
pirate = XCreateFontCursor(display, XC_pirate);
question = XCreateFontCursor(display, XC_question_arrow);
//////////////// Main Form Widget ////////////////////////////////
topform = XtVaCreateManagedWidget( "form", xmFormWidgetClass,
toplevel, NULL);
////////////////////////// menubar /////////////////////////////
fiLe = XmStringCreateSimple("File");
edit = XmStringCreateSimple("Edit");
conf = XmStringCreateSimple("Options");
help = XmStringCreateSimple("Help");
menubar = XmVaCreateSimpleMenuBar(topform,"menubar",
XmVaCASCADEBUTTON, fiLe, 'F',
XmVaCASCADEBUTTON, edit, 'E',
XmVaCASCADEBUTTON, conf, 'O',
XmVaCASCADEBUTTON, help, 'H',
XmNleftAttachment, XmATTACH_FORM,
XmNtopAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
XmStringFree(fiLe);
XmStringFree(edit);
XmStringFree(conf);
XmStringFree(help);
////////////// Initialize Child widgets for menubar /////////
init_menubar();
//////////////// Leftmenu (Replaces bde1 Blockmenu //////////////
leftmenu = XtVaCreateManagedWidget("leftmenu",
xmRowColumnWidgetClass, topform,
XmNpacking, XmPACK_TIGHT,
XmNorientation, XmVERTICAL,
XmNfontList, fontlist,
XmNspacing, 20,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, menubar,
XmNbottomAttachment, XmATTACH_FORM,
XmNwidth, 250,
XmNheight, 600, // 96subde fjara, ianandak
XmNresizeHeight, False, // 96subde fjara, ianandak
XmNleftOffset, 5,
XmNtopOffset, 40,
NULL);
////////////// Initialize Child widgets for Leftmenu //////////
init_leftmenu();
////////////// File Name Label Widget ////////////////////////
file_label = XmStringCreateLtoR( "Untitled\n",XmSTRING_DEFAULT_CHARSET );
filenamebox = XtVaCreateManagedWidget( "filetitle",
xmLabelWidgetClass, topform,
XmNlabelString, file_label,
XmNfontList, fontlist,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, leftmenu,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, menubar,
XmNrightAttachment, XmATTACH_FORM,
NULL);
XmStringFree( file_label );
////////////// Scrolled Window for canvas ////////////////////
sw = XtVaCreateManagedWidget( "scrollwindow",
xmScrolledWindowWidgetClass, topform,
XmNleftWidget, leftmenu,
XmNleftAttachment, XmATTACH_WIDGET,
XmNtopWidget, filenamebox,
XmNtopAttachment, XmATTACH_WIDGET,
XmNscrollingPolicy, XmAUTOMATIC,
XmNrightAttachment, XmATTACH_FORM,
XmNscrollBarDisplayPolicy, XmAUTOMATIC,
XmNscrollBarPlacement, XmBOTTOM_RIGHT,
XmNscrolledWindowMarginHeight, 0,
XmNscrolledWindowMarginWidth, 0,
XmNvisualPolicy, XmVARIABLE,
NULL);
////////////////////// Canvas ///////////////////////////////
canvas = XtVaCreateManagedWidget( "canvas",
xmDrawingAreaWidgetClass, sw,
NULL);
//Typecasted callback to remove compiler errors due to mismatch with
//XtAddCallback prototype functions. - 99s523 rgantyal,vdhamoda
XtAddCallback(canvas, XmNexposeCallback,
(void (*)(_WidgetRec *, void *, void *))docanvasexposure,
NULL);
//////////////////// Messagebox Title Label ///////////////////
createMsgBox();
//////////////////// Canvas Callbacks /////////////////////////
XtAddEventHandler(canvas, ButtonPressMask, FALSE, dobuttonevent,
(XtPointer)BUTTON_DOWN_EVENT);
XtAddEventHandler(canvas, ButtonMotionMask, FALSE, dobuttonevent,
(XtPointer)BUTTON_MOVED_EVENT);
XtAddEventHandler(canvas, ButtonReleaseMask, FALSE, dobuttonevent,
(XtPointer)BUTTON_UP_EVENT);
/************************** Sathya ******************************/
XtAddEventHandler(canvas, KeyPressMask|KeyReleaseMask, False, Keypress, NULL);
// mt - casted above statements
////////////////////// Text Dialog ////////////////////////////
textDialog = createTextDialog(toplevel, 20);
graphCaptionDialog = createTextDialog(toplevel, 128);
//////// Create Node Dialog (What the hell is this ???) ///////
createNodeDialog(sw);
//////// Create both load and saveas dialogboxes //////////////
////////////////// Pop them up when called for /////////////////
create_load_dialogbox();
create_saveas_dialogbox();
create_exit_dialogbox();
//////////////////// Initialize Images, GC's //////////////////
initClasses();
XtRealizeWidget(toplevel);
//////////////////// Initialize Cursor ////////////////////////
changeCanvasCursor(arrow);
////////////// Load single graph defaults row read only ///////////
load_defaults( data.gd_defaults );
//TBD: This load should be done by pr_load from a GD.dat file - RJL 95/3/15
// If this fails, now does the default behavior in fileio.cc get invoked?
/*** BDE replay modifications by Sathya - Begin ***/
if ( Opengraph == 1 && ReplayReady == 0 )
CreateHGDialogBox(current_filename);
if ( Opengraph == 1 && ReplayReady == 2 )
{
replayState = 0;
Replay_LoadGraph( logfile );
ReplayReady = 1;
}
XmProcessTraversal(canvas, XmTRAVERSE_CURRENT);
/*** BDE replay modifications by Sathya - End ***/
XtAppMainLoop(app);
}
} // end init()?
/*************************************************************************
*
* Function Name: ChkInvalidCmdLineOptions
*
* Description:
* This function checks to see if the user specified any invalid
* command line options. And if so, displays the correct command
* line usage information.
*
* Inputs:
* argc (int): the number of command line arguments
* left after parsing by XtAppInitialize
* argv (char **): the command line options remaining after parsing
* by XtVaAppInitialize. The name of the program
* will always be left in argv.
*
* Returns:
* The number of invalid command line options
*
****************************************************************************/
static int ChkInvalidCmdLineOptions( int argc, char **argv )
{
int i;
static int errs = 0;
extern int create_replay_dialogbox();
char *temp_str, temp_infile[100];
/* first argument is program name - skip it */
for ( i = 1; i < argc; i++ )
{
if ( *argv[i] == '-' )
{
if ( !errs++ ) /* do first time through */
fprintf( stderr, "%s: command line option unknown:\n", argv[0] );
fprintf( stderr, "\toption: %s\n", argv[i] );
}
}
// Modifications by Sathya - begin
if ( argc != 2 ) /* Replay file not specified*/
{
ReplayReady = 0;
printf("Replay file not specified, Click Options -> Start Replay to start replay\n");
}
else
{
strcpy(temp_infile, argv[1]);
if ((temp_str = strtok (temp_infile, ".")) != NULL )
{
temp_str = strtok ((char *)NULL, ".");
if (strcmp( temp_str, "txt") == 0 )
{
printf("Replay file : %s | Click Options -> Start Replay to start replay\n", argv[1]);
ReplayReady = 2;
logfile = argv[1];
Opengraph = 1;
}
else
{
ReplayReady = 0;
if (strcmp(temp_str, "dat") == 0)
{
Opengraph = 1;
current_filename = strdup( argv[1] );
}
}
}
}
// Modifications by Sathya - end
/* if invalid command line options specified, display
correct command line usage */
if ( errs )
{
fprintf( stderr,
"Usage: %s [-d graph defaults file] [-v viewdefs file] [log file]\n",
argv[0] );
fprintf( stderr,
"%s also understands all standard Xt command line options.\n",
argv[0] );
}
return( errs );
} // end ChkInvalid-etc.
/////////////////////////////////////////////////////////////////////////
// Name: fileio.cc
//
// Description : This program deals with all kind of i/o, using pr utils.
//
// Created by : Unknown.
//
// Routines : create_load_dialogbox()
// create_savedas_dialogbox()
// dosaveas()
// real_saveas()
// cancel_saveas()
// doload()
// real_load()
// cancel_load()
// DoNewGraph()
//
// Edit history:
//
// <revision history truncated>
//
///////////////////////////////////////////////////////////////////////////////
<only new code additions are shown>
/*********************************************************************
* Function : Keypress
*
* Description: Callback routine for Keypress - Calls replay_log
* function if the key pressed is 's' and
* ReplayReady is 1.
*
* Created by : Sathya
********************************************************************/
void Keypress(Widget w, XtPointer input, XEvent *event,
Boolean *continue_dispatch)
{
KeySym keysym;
Modifiers dummy;
int replayStatus;
extern int ReplayReady;
if(event -> type == KeyPress)
{
XtTranslateKeycode(XtDisplay(w), event->xkey.keycode,
event-> xkey.state, &dummy, &keysym);
printf("Replay Ready : %d", ReplayReady);
if ( (strcmp (XKeysymToString(keysym), "s") == 0) && (ReplayReady == 1) )
if ( (replayStatus = replay_log()) == STATE2 )
ReplayReady = 0;
#ifdef DEBUG
printf("Fileio.cc:replay_Log returns: replayStatus = %d\n",
replayStatus);
#endif
}
}
/**************************************************************************
* Function : create_replay_dialogbox
*
* Description: Initializes the dialog box to be displayed for
* selecting a replay file (<logfile>.txt).
*
* Created by: Sathya
***************************************************************************/
int create_replay_dialogbox()
{
XmString dirMask ;
Arg args[10] ;
int arg_count ;
void real_replay(Widget,caddr_t, XmFileSelectionBoxCallbackStruct*);
void cancel_load(Widget,caddr_t, XmFileSelectionBoxCallbackStruct*) ;
dirMask = XmStringLtoRCreate ("./*.txt", XmSTRING_DEFAULT_CHARSET);
firstArg(XmNdirMask, dirMask);
fileselectbox = XmCreateFileSelectionDialog(toplevel ,"File",args,arg_count );
help_load = XmFileSelectionBoxGetChild(fileselectbox,XmDIALOG_HELP_BUTTON) ;
XtSetSensitive (help_load, False);
XtAddCallback(fileselectbox,XmNokCallback,
(void (*)(_WidgetRec *, void *, void *))real_replay,
NULL);
XtAddCallback(fileselectbox,XmNcancelCallback,
(void (*)(_WidgetRec *, void *, void *))cancel_load,
NULL);
return (0);
}
/***************************************************************************
* Function : real_replay
*
* Description: Callback function - Triggered when the user selects a
* replay file. It clears the current graph in the canvas
* and calls Replay_LoadGraph.
*
* Created by: Sathya
****************************************************************************/
void real_replay(Widget ww ,caddr_t b,
XmFileSelectionBoxCallbackStruct *call_data )
{
void filenamemessage(char*);
char *filename;
char *error_msg;
void help_dialog(char*) ;
void Replay_LoadGraph(char *infile);
origgen = gen;
/* get filename specified and unmanage file selection box */
XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename );
XtUnmanageChild(fileselectbox);
/* check status of filep */
if ( ( error_msg = GetFileStatus( filename, "r" ) ) != (char *) NULL )
{
help_dialog( error_msg );
XtFree( error_msg );
}
else
{
clearObjects();
hcg_initialized = 0 ;
ReDraw();
pr_free();
if ( current_filename != (char *) NULL )
free( current_filename );
current_filename = strdup( filename );
Replay_LoadGraph(current_filename);
}
if ( filename != (char *) NULL )
XtFree( filename );
} // end real_replay
/**************************************************************************
* Function : Replay_LoadGraph
*
* Arguments : Replay logfile, <logfile>.txt
*
* Description : Displays the graph selection box if SELECT_REPLAY_GRAPH
* is 1, else it selects the first graph in the
* <logfile>DB1.dat file.
*
* created by: Sathya
***************************************************************************/
void Replay_LoadGraph(char *infile)
{
#define SELECT_REPLAY_GRAPH 0
hcg_key temp_key;
extern char *logfile;
char* datfile;
char* temp_name;
temp_name = (char *) (malloc(sizeof(char) * 100));
datfile = (char *) (malloc(sizeof(char) * 100));
strcpy(temp_name, infile);
strtok(temp_name,".");
sprintf(datfile,"%sDB1.dat",temp_name);
current_filename = strdup( datfile );
if ( SELECT_REPLAY_GRAPH )
CreateHGDialogBox(datfile);
else
{
hcg_initialized = 0;
pr_init( GetBDEViewDefsFile(), GetBDEDatFileList(datfile) );
pr_load("94sbdeview",datfile);
table_loop("94sbdeview", HG)
{
break;
}
if (HGcurr == NULL)
printf("Error opening the default(First) graph\n");
else
{
HG_pkey = temp_key;
updatedisplaylist(HGcurr);
ReDraw();
SetStateOfGraphExistence( 1 );
XtSetSensitive( leftmenu, True );
UpdateTitleOfBDEWindow( current_filename, HGcurr->HGtitle );
}
}
logfile = infile;