/************************************************************************/ /* File : pr_log.c */ /* Schema : ../schema/94sbde_schema.sch */ /* Chgen Version : Chgen V 12 - Sathya */ /************************************************************************/ #include #include #include #include #include #include #include #include "94sbde_schema.h" /* hcg_logfile[NAMELENGTH] defined where #ifdef MAIN (in bde/src/fileio.cc)*/ /**********************************************************************/ /* Function prototypes */ /**********************************************************************/ #ifdef __STDC__ extern void mystrcpy(char *, const char *, int, int); extern int lut_insert_element(lut_st *, char *); #else strcpy(); extern int lut_insert_element(); #endif /* in pr_load.c: */ extern void hcg_parse(char*, char*, int*); extern int lut_insert_element(lut_st*, char*); extern int find_view_idx(char*); extern int find_tbl_idx(const char*); /* added const 2k20829 - RJL */ extern void hcg_read_next(void); extern void pr_init (char*, char*); extern void pr_load (char*, char*); extern void pr_free(void); extern void do_pr_add( char *viewname, char *tbl_abbrv, hcg_ptr tbl_ptr); extern int meets_view(int, int, hcg_key); /* in pr_delete.c: macro pr_delete and pr_del() */ extern void pr_del(int); /* arg1=XX.idx; REQUIRES valid XXcurr ptr */ /* In bdeReplay.cc */ /* #ifdef BDELOG */ #ifdef GENLOG extern /*"C"*/ int replay_log(void); #endif /* in pr_dump.c: */ extern void pr_dump (char*, char*, int, char*); /* from : */ int unlink(const char*); int close(int); /* fwd ref: */ int mysleep(struct timeval *); void HAverify(void); /* buffers for replay_log */ char temp_tbl[HCG_KEY_SIZE+1]; char temp_field[NAMELENGTH+1]; char temp_newval[BUFSIZE+1]; char temp_newkey[HCG_KEY_SIZE+1]; char viewname[NAMELENGTH]; hcg_key HG_pkey; char *logfile; FILE *logfile_fp; char token[BUFSIZE]; int idx; int near_realtime; int replayState; int replayStatus; #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; /************************************************************************/ /* Global variables */ /************************************************************************/ static struct timeval timestamp; static int time_flag = -1; /**************************************************************************** * * * trivial function for signal handler * ***************************************************************************/ static void func(int signo) { return; } /************************************************************/ /* Function: log_sleep */ /* */ /* This function is used to pause the execution based on */ /* a parameter indicatings the number of milliseconds of */ /* the desired pause */ /* */ /* Arguments: mseconds - integer of the number of sleep */ /* milliseconds. */ /************************************************************/ #ifdef __STDC__ int log_sleep(int milliseconds) #else int log_sleep(milliseconds) int milliseconds; #endif /* __STDC__ */ { struct timeval t; int status; if (milliseconds < 0) { fprintf(stderr, "%s: %d: log_sleep: milliseconds must be >= 0\n", __FILE__,__LINE__); return -1; } t.tv_sec = milliseconds/1000; t.tv_usec = (milliseconds % 1000)*1000; status = mysleep(&t); if (status < 0) { fprintf(stderr, "%s: %d: log_sleep: mysleep failed with status %d\n", __FILE__,__LINE__,status); return -1; } return 0; } /**************************************************************************** * mysleep * * This routine blocks until the amount of time specified in the timeval * * referred to be t has elapsed. The method used is to set an interval * * timer and to wait until the signal is delivered with a sigpause. * * side effects: * * The SIGALRM handler is reset for the duration of the call, * * When the interval timer expires, A SIGALRM is delivered to the process * * * * preconditions: * * t is not null * * t refers to a timeval struct * * t->tv_sec >= 0 * * t->tv_usec >= 0 * * t->tv_usec < 1*10^6 * * * * postcondition: * * if the return value of mysleep is 0, then * * time = time' + t->tv_sec + t->tv_usec * * * * returns: 0 if no errors occurred, -1 otherwise * ***************************************************************************/ int mysleep(struct timeval *t) { struct sigaction newact, oldact; sigset_t newmask, oldmask, zeromask; struct itimerval tv1, tv2; /* validate arg */ if (t == NULL) { fprintf(stderr, "%s: %d: mysleep: bad argument\n", __FILE__,__LINE__); return -1; } /* don't wait if no time specified */ if (t->tv_sec == 0 && t->tv_usec == 0) { return 0; } /* block signals */ sigemptyset(&newmask); sigemptyset(&zeromask); sigaddset(&newmask, SIGALRM); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) { perror("sigprocmask"); fprintf(stderr, "%s: %d: mysleep: sigprocmask failed\n", __FILE__,__LINE__); return -1; } /* set handler */ newact.sa_handler = func; sigemptyset(&newact.sa_mask); newact.sa_flags = 0; if (sigaction(SIGALRM, &newact, &oldact) < 0) { perror("sigaction"); fprintf(stderr, "%s: %d: mysleep: sigaction failed\n", __FILE__, __LINE__); return -1; } /* set interval timer */ tv2.it_value.tv_sec = t->tv_sec; tv2.it_value.tv_usec = t->tv_usec; tv2.it_interval.tv_sec = 0; tv2.it_interval.tv_usec = 0; if (setitimer(ITIMER_REAL, &tv2, &tv1) < 0) { fprintf(stderr, "%s: %d: mysleep: setitimer failed\n", __FILE__, __LINE__); return -1; } if (tv1.it_value.tv_sec > 0 || tv1.it_value.tv_usec > 0) { fprintf(stderr, "%s: %d: mysleep: interval timer is already set!\n", __FILE__,__LINE__); return -1; } /* sleep until signal delivered */ if (sigsuspend(&zeromask) != -1) { fprintf(stderr, "%s: %d: mysleep: sigsuspend didn't return -1\n", __FILE__, __LINE__); return -1; } /* reset signal mask */ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) { perror("sigprocmask"); fprintf(stderr, "%s: %d: mysleep: sigprocmask failed\n", __FILE__, __LINE__); return -1; } /* reset signal handler */ if (sigaction(SIGALRM, &oldact, NULL) < 0 ) { perror("sigaction"); fprintf(stderr, "%s: %d: mysleep: sigaction failed\n", __FILE__, __LINE__); return -1; } return 0; } /* end mysleep */ /******************************************************************************/ /* time_initialize */ /* Sets the timestamp global with the current time and clear the time_flag */ /******************************************************************************/ void time_initialize() { struct timezone t; gettimeofday(×tamp, &t); time_flag = 0; } int get_delta_tee(struct timeval *t) { struct timeval now, delta; struct timezone tz; if (!t) { fprintf(stderr, "%s: %d: get_delta_tee: t is null\n",__FILE__, __LINE__); return -1; } if (gettimeofday(&now, &tz) < 0) { perror("gettimeofday"); fprintf(stderr, "%s: %d: gettimeofday failed\n", __FILE__, __LINE__); return -1; } if (time_flag != 0) { /* the first time through report elapsed time of zero, and initialize */ t->tv_sec = 0; t->tv_usec = 0; time_initialize(); return 0; } if (now.tv_usec < timestamp.tv_usec) { if (now.tv_sec <= 0) { fprintf(stderr, "%s: %d: get_delta_tee: bad tv_sec value\n", __FILE__, __LINE__); return -1; } delta.tv_sec = now.tv_sec - 1; delta.tv_usec = now.tv_usec + 1000000; } else { delta.tv_sec = now.tv_sec; delta.tv_usec = now.tv_usec; } t->tv_sec = delta.tv_sec - timestamp.tv_sec; t->tv_usec = delta.tv_usec - timestamp.tv_usec; timestamp.tv_sec = now.tv_sec; timestamp.tv_usec = now.tv_usec; return 0; } /* end get_delta_tee */ /********************************************************** * Function: timeval2millisec(int *, struct timeval *) * * * * This function converts the time in the timeval struct * * into the equiv number of milliseconds, and places the * * result in the first argument. * * On success it returns 0, -1 otherwise * *********************************************************/ static int timeval2millisec(int *millisec, const struct timeval *t) { int temp; if (!millisec || !t) { fprintf(stderr, "%s: %d: timeval2millisec: bad argument\n", __FILE__, __LINE__); return -1; } temp = t->tv_sec*1000; temp = temp + t->tv_usec/1000; *millisec = (int) temp; return 0; } /**********************************************************/ /* Function: logstr() */ /* Arguments: text - contains the string to be printed */ /* to the log file. */ /* */ /* This function writes the text string to the logfile */ /* if logging is active */ /* */ /**********************************************************/ void logstr(char text[BUFSIZE]) { if (hcg_log == 1) fprintf(hcg_logfileptr, "%s", text); } /**********************************************************/ /* Function: logwait() */ /* Arguments: none */ /* */ /* This function calculates the wait time based on the */ /* value of setitimer. */ /* waitTime = initial_val_of_itimer - cur_val_of_itimer */ /* Writes the waitTime to the log file and re-initializes*/ /* the value of the itimer. */ /* */ /**********************************************************/ void logwait(void) { struct timeval tv; char text[BUFSIZE]; int waitTime; if (hcg_log == 1) { get_delta_tee(&tv); if (timeval2millisec(&waitTime, &tv) < 0) { fprintf(stderr, "%s: %d: logwait: timeval2millisec failed\n",__FILE__,__LINE__); return; } sprintf(text,"WA %d\n", waitTime); logstr(text); } } /********************************************************************************/ /* Function : pr_startlog */ /* */ /* Abstract : This function is used to start a logging session. */ /* It opens a logfile and dumps a current copy of the database */ /* */ /* Created by : B. Rideout */ /* */ /* Creation Date : 4/24/96 */ /* */ /* Modified : */ /* */ /********************************************************************************/ int pr_startlog (char* file_name, char* viewname) { static char rcsid[] = ""; char DB1string[10] = "DB1.dat"; char logfileDB1_name[NAMELENGTH]; char temp_file_name[NAMELENGTH]="\0"; int i; /* check that pr_init has been called - if not, return without starting log*/ if (!hcg_initialized) { printf("Error: pr_startlog() called when database is not yet initialized.\n"); return (-1); } /* check that viewname is valid - if not, return without starting log*/ if (!find_view_idx(viewname)) { printf("Error: view %s passed to pr_startlog is not defined.\n",viewname); return (-2); } /* check that logging is off - if not, return without starting log*/ if (hcg_log != 0 ) { if (hcg_log == 1 ) { printf("Error: pr_startlog called when logging was not off.\n"); return (-3); } else if ( hcg_log == 2) printf("Error: pr_startlog called when logging was not off.\n"); } /* Check that file_name is not null */ if (!strcmp(file_name, "\0")) { printf("Error: log file name null; logging not on.\n"); return (-4); } /* set global hcg_logfile to file name of log file (w/out extention) */ for (i = strlen(file_name); ((i>=0) && (file_name[i]!= '.')); /* no period found yet */ (i--)); /* (i = namelength before type extension, i == -1 if no tpye ext.) */ if (i<0) /* no extension */ strcpy (hcg_logfile, file_name); else /* remove extension */ strncpy (hcg_logfile, file_name, (i)); strcpy (temp_file_name, hcg_logfile); strcat (temp_file_name, ".txt"); /* check that logfile opened - if not, return without starting log*/ if ((hcg_logfileptr=fopen(temp_file_name, "w")) == NULL) { printf("Error: pr_startlog() cannot open %s\n", file_name); return (-3); } /* Call pr_dump to save a current version of the database */ /* Database saved to name of log file + "DB1" */ strcat (strcpy(logfileDB1_name, hcg_logfile), DB1string); pr_dump (viewname, logfileDB1_name, FALSE, "w" ); /* Initiate logging by setting global hcg_log = 1 */ hcg_log = 1; /* Log call to pr_startlog as first record */ logstr("SR\n"); /* Set timer info - to be done */ time_initialize(); return (0); } /* End pr_startlog */ /********************************************************************************/ /* Function : pr_stoplog */ /* */ /* Abstract : This function is used to stop a logging session. */ /* It optionally dumps a current copy of the database and closes */ /* the logfile */ /* */ /* Created by : B. Rideout */ /* */ /* Creation Date : 4/26/96 */ /* */ /* Modified : */ /* */ /********************************************************************************/ int pr_stoplog (char* viewname, int dump_flag) { char DB2string[10] = "DB2.dat"; char logfileDB2_name[NAMELENGTH]; /* check that logging is active - if not, return without stopping log*/ if (!hcg_log) { printf("Error: pr_stoplog() called when logging not active.\n"); return (-1); } /* check that viewname is valid - if not, return without starting log*/ if (!find_view_idx(viewname)) { printf("Error: view %s passed to pr_startlog is not defined.\n",viewname); return (-2); } /* 4/24/96 - other error checking functions to be added */ /* Generate Wait statement */ logwait(); /* Log pr_stoplog */ logstr("SP\n"); /* Terminate logging by setting global hcg_log = 0 */ hcg_log =0; /* Call pr_dump to save a current version of the database if dump_flag set */ /* Database saved to name of log file + "DB2" */ if (dump_flag) { strcat (strcpy(logfileDB2_name, hcg_logfile), DB2string); pr_dump (viewname, logfileDB2_name, FALSE, "w" ); } fclose(hcg_logfileptr); return (0); } /* End pr_stoplog */ /************************************************************/ /* Function: log_parselogdata */ /* */ /* This function is used to parse the data in logdata.txt */ /* (to which pr_log appended all files in pr_init's arg2) */ /* & create temporary files that contain the data of the */ /* original data files. It initializes char* newlist with */ /* new temp* filenames separated by spaces. These files */ /* will be read and deleted before replaying the logfile. */ /* The return value indicates success=0, or failure <0. */ /* */ /* Arguments: newlist - updated list of temp* filenames. */ /* */ /* Preconditions: Added by RJL 030809: */ /* File logdata.txt must exist with data TBscanned */ /* Datafile lines: field 1 cannot be "LogDataFile " */ /* newlist must not exceed BUFSIZE bytes in length */ /* filenames must not exceed NAMELENGTH bytes */ /* (BUFSIZE=256, NAMELENGTH=30 in bde's schema.h) */ /* */ /* (Non-local file names cannot be prefixed by 'temp' */ /* until path prefixes are deleted - RJL 030810.) */ /* */ /* returns: 0 - success */ /* <0 - failure */ /* -3 - open file failure */ /* -5 - invalid file format */ /************************************************************/ int log_parselogdata(char * newlist) { char datafile[NAMELENGTH],token[BUFSIZE]; char tempfname[NAMELENGTH],tempnewlist[BUFSIZE]; FILE *data_fp, *temp_fp; int idx; /* open logdata.txt */ strcpy(datafile,"logdata.txt"); if ((data_fp = fopen(datafile, "r")) ==NULL) { printf("Failed to open file logdata.txt\n"); return(-3); } hcg_ascii_fp = data_fp; hcg_read_next(); /* read first line to hcg_buffer[BUFSIZE] */ assert(strlen(hcg_buffer) <= BUFSIZE); /* else buffer overflow */ idx = 0; /* running index in line buffer */ hcg_parse(hcg_buffer,token,&idx); if (strcmp(token,"LogDataFile") != 0) { printf("File logdata.txt: Invalid format \n"); return(-5); } hcg_parse(hcg_buffer,token,&idx); /* get filename */ tempnewlist[0] = '\0'; while (!feof(data_fp)) { /* open temp file */ sprintf(tempfname,"temp%s",token); if ((temp_fp = fopen(tempfname, "w")) == NULL) { printf("fopen(%s, \"w\" failed \n", tempfname); return(-3); /* fail to open file */ } strcat(tempnewlist,tempfname); strcat(tempnewlist," \0"); hcg_read_next(); /* read next line in data file */ idx = 0; hcg_parse(hcg_buffer,token,&idx); while (!feof(data_fp) && (strcmp(token,"LogDataFile") != 0)) { /* write buffer in temp file */ fprintf(temp_fp,"%s\n",hcg_buffer); hcg_read_next(); assert(strlen(hcg_buffer) <= BUFSIZE); /* else buffer overflow */ idx = 0; hcg_parse(hcg_buffer,token,&idx); } /* end loop to copy lines until next "LogDataFile" token */ fclose(temp_fp); hcg_parse(hcg_buffer,token,&idx); /* get filename */ } fclose(data_fp); assert(strlen(tempnewlist) <= BUFSIZE); strcpy(newlist,tempnewlist); return(0); } /* end log_parselogdata */ /************************************************************/ /* Function: del_tempfiles */ /* */ /* This function is used to delete the temporary files that */ /* were created during the replay session. */ /* */ /* Arguments: filelist - list of files separated by commas */ /************************************************************/ void del_tempfiles(char *filelist) { int idx = 0; char token[BUFSIZE]; while (idx < strlen(filelist)) { hcg_parse(filelist,token,&idx); dprints("Unlinked %s.\n",token); unlink(token); } } /************************************************************/ /* Function: log_do_add */ /* log_do_ SHOULD be renamed log_replay_ etc.-RJL 031019 */ /* */ /* This function is used to do the add given the viewname */ /* the tablename and a string of the additional information */ /* */ /* Arguments: view - the viewname */ /* tablename - the tablename of the record to */ /* be added. */ /* theRest - a string of the additional info */ /* of the record to be added */ /* Returns: 0 - success */ /* <0 - error with the add */ /* */ /* Genlog 96s523 */ /************************************************************/ int log_do_add(char *view, char *tablename, char *theRest) { int status = 0; /* the return status of the function */ int idx = 0; /* parsing temp index */ int tbl_encoding; struct FO *FO_elt; struct GD *GD_elt; struct HG *HG_elt; struct HN *HN_elt; struct HA *HA_elt; struct HL *HL_elt; struct HP *HP_elt; struct HI *HI_elt; struct CG *CG_elt; struct GX *GX_elt; if (!find_tbl_idx(tablename)) /* updates hcg_tbl_idx */ { fprintf(stderr, "%s: %d: log_do_add: unknown table (%s) found in log\n", __FILE__, __LINE__, tablename); return (status = -1); } tbl_encoding = encoding(hcg_table_seq_list[hcg_tbl_idx].ttabbrev); /* global hcg_tbl_idx is set by find_tbl_idx */ /* the following switch statement is adapted from the one in pr_parse */ switch( tbl_encoding ) { case 0: /* encoding of FO */ FO_elt = pr_create(FO); if (!FO_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); mystrcpy(FO_elt->xfont, hcg_t, 50, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(FO_elt->psfontname, hcg_t, 50, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(FO_elt->psfontsize, hcg_t, 2, 0); mystrcpy(FO_elt->bdefont, theRest+idx, 15, 0); pr_add(view, FO, FO_elt); break; case 1: /* encoding of GD */ GD_elt = pr_create(GD); if (!GD_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); mystrcpy(GD_elt->shape, hcg_t, 10, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GD_elt, width, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GD_elt, height, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); mystrcpy(GD_elt->hsegpattern, hcg_t, 4, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(GD_elt->txtfont, hcg_t, 25, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(GD_elt->location, hcg_t, 10, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(GD_elt->justify, hcg_t, 10, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GD_elt, gcwidth, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GD_elt, gcheight, (float) atof(hcg_t)); pr_add(view, GD, GD_elt); break; case 2: /* encoding of HG */ HG_elt = pr_create(HG); if (!HG_elt) { fprintf(stderr, "%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); mystrcpy(HG_elt->FSid, hcg_t, 8, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HG_elt->HNid, hcg_t, 8, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HG_elt->HGauthor, hcg_t, 12, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HG_elt->HGcreated, hcg_t, 12, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HG_elt->HGlastmod, hcg_t, 12, 0); mystrcpy(HG_elt->HGtitle, theRest+idx, 60, 1); pr_add(view, HG, HG_elt); break; case 3: /* encoding of HN */ HN_elt = pr_create(HN); if (!HN_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); HN_elt->HGid = hcg_k; hcg_parse(theRest, hcg_t, &idx); mystrcpy(HN_elt->FSid, hcg_t, 8, 0); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HN_elt->shape, hcg_t, 1, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HN_elt, centerx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HN_elt, centery, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HN_elt, width, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HN_elt, height, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HN_elt->txtfont, hcg_t, 25, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HN_elt, txtoffsetx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HN_elt, txtoffsety, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HN_elt, txtwidth, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HN_elt, txtheight, atoi(hcg_t)); mystrcpy(HN_elt->nodename, theRest+idx, 20, 1); pr_add(view, HN, HN_elt); break; case 4: /* encoding of HA */ HA_elt = pr_create(HA); if (!HA_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); HA_elt->HNid = hcg_k; hcg_parse(theRest, hcg_t, &idx); mystrcpy(HA_elt->DAid, hcg_t, 8, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HA_elt, txtoffsetx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HA_elt, txtoffsety, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HA_elt, HAorigin, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HA_elt, txtwidth, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HA_elt, txtheight, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HA_elt->txtfont, hcg_t, 25, 0); mystrcpy(HA_elt->hlabel, theRest+idx, 60, 1); pr_add(view, HA, HA_elt); break; case 5: /* encoding of HL */ HL_elt = pr_create(HL); if (!HL_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); HL_elt->HNid1 = hcg_k; hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); HL_elt->HNid2 = hcg_k; hcg_parse(theRest, hcg_t, &idx); pr_set_int(HL_elt, HPcount, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HL_elt, allvisible, atoi(hcg_t)); pr_add(view, HL, HL_elt); break; case 6: /* encoding of HP */ HP_elt = pr_create(HP); if (!HP_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); HP_elt->HLid = hcg_k; hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HP_elt, HPx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HP_elt, HPy, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HP_elt, is_visible, atoi(hcg_t)); mystrcpy(HP_elt->hsegpattern, theRest+idx, 4, 0); pr_add(view, HP, HP_elt); break; case 7: /* encoding of HI */ HI_elt = pr_create(HI); if (!HI_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); HI_elt->HLid = hcg_k; hcg_parse(theRest, hcg_t, &idx); mystrcpy(HI_elt->DIid, hcg_t, 8, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HI_elt, HIorigin, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HI_elt, tbeginx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(HI_elt, tbeginy, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HI_elt, txtwidth, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(HI_elt, txtheight, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); mystrcpy(HI_elt->txtfont, hcg_t, 25, 0); mystrcpy(HI_elt->hlabel, theRest+idx, 40, 1); pr_add(view, HI, HI_elt); break; case 8: /* encoding of CG */ CG_elt = pr_create(CG); if (!CG_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); CG_elt->HGid = hcg_k; hcg_parse(theRest, hcg_t, &idx); pr_set_flt(CG_elt, CGcenterx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(CG_elt, CGcentery, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(CG_elt, CGwidth, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(CG_elt, CGheight, (float) atof(hcg_t)); pr_add(view, CG, CG_elt); break; case 9: /* encoding of GX */ GX_elt = pr_create(GX); if (!GX_elt) { fprintf(stderr,"%s: %d: log_do_add: pr_create failed\n", __FILE__, __LINE__); return (status = -1); } hcg_parse(theRest, hcg_t, &idx); encode(hcg_t, &hcg_k); GX_elt->CGid = hcg_k; hcg_parse(theRest, hcg_t, &idx); mystrcpy(GX_elt->DAid, hcg_t, 8, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GX_elt, GXorigin, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); mystrcpy(GX_elt->txtfont, hcg_t, 25, 0); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GX_elt, txtoffsetx, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_flt(GX_elt, txtoffsety, (float) atof(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(GX_elt, txtwidth, atoi(hcg_t)); hcg_parse(theRest, hcg_t, &idx); pr_set_int(GX_elt, txtheight, atoi(hcg_t)); mystrcpy(GX_elt->grphcaption, theRest+idx, 128, 1); pr_add(view, GX, GX_elt); break; } return 0; } /* end log_do_add i(i.e., _replay_ */ /************************************************************/ /* Function: convert2temp */ /* */ /* This function is used to convert an inputted string of */ /* datfiles separated by spaces to the filenames with the */ /* prefix 'temp'. Returns the string of altered names. */ /* */ /* Arguments: instr - string of size BUFSIZE that */ /* containts the string to add the */ /* temp infront of each word */ /* out - string that will place the */ /* altered string. */ /* Preconditions: */ /* instr must be a string of size BUFSIZE */ /* out must be a string of size BUFSIZE */ /************************************************************/ void convert2temp(char instr[BUFSIZE],char out[BUFSIZE]) { char token[BUFSIZE]; char outstr[BUFSIZE]; int idx = 0; if (strlen(instr)==0) { strcpy(out,"\0"); return; } /* get first token in string instr */ hcg_parse(instr,token,&idx); sprintf(outstr,"temp%s",token); /* get the rest of the tokens in the string instr */ hcg_parse(instr,token,&idx); while (idx < strlen(instr)) { char temp[BUFSIZE]; sprintf(temp," temp%s",token); strcat(outstr,temp); hcg_parse(instr,token,&idx); } strcpy(out,outstr); return; } /************************************************************/ /* Function: log_do_delete (log_replay_delete - RJL) */ /* */ /* This function is used to delete a record given the pkey. */ /* */ /* Arguments: pkeychar - char string of the primary key. */ /************************************************************/ /* RJL note 031021: find_tbl_idx puts a table type code in tbl_idx. * pr_delete(XX) really deletes a row of the table 'type' * with integer code XX##_idx. * It works via this macro call: #define pr_delete(tbl) pr_del(tbl##_idx) */ void log_do_delete(const char pkeychar[HCG_KEY_SIZE+1]) { long unsigned temp_id; int tbl_encoding; find_tbl_idx(pkeychar); /* updates hcg_tbl_idx */ if(encode(pkeychar,&hcg_k) ==1) { dprints("Found DL with pkey %s.\n",pkeychar); tbl_encoding = encoding(hcg_table_seq_list[hcg_tbl_idx].ttabbrev); switch(tbl_encoding) { case 0: /* FO table */ pr_find(FO, FOid, hcg_k); if (FOcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(FO); break; case 1: /* GD table */ pr_find(GD, GDid, hcg_k); if (GDcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(GD); break; case 2: /* HG table */ pr_find(HG, HGid, hcg_k); if (HGcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(HG); break; case 3: /* HN table */ pr_find(HN, HNid, hcg_k); if (HNcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(HN); break; case 4: /* HA table */ pr_find(HA, HAid, hcg_k); if (HAcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(HA); break; case 5: /* HL table */ pr_find(HL, HLid, hcg_k); if (HLcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(HL); break; case 6: /* HP table */ pr_find(HP, HPid, hcg_k); if (HPcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(HP); break; case 7: /* HI table */ pr_find(HI, HIid, hcg_k); if (HIcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(HI); break; case 8: /* CG table */ pr_find(CG, CGid, hcg_k); if (CGcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(CG); break; case 9: /* GX table */ pr_find(GX, GXid, hcg_k); if (GXcurr == NULL) printf("log_delete: %s not found.\n", pkeychar); else pr_delete(GX); break; } /* end switch */ } /* end if decode */ } /************************************************************/ /* Function: log_do_set_int */ /* */ /* This function is used to set the value of an int field. */ /* */ /* Created by : Rob Rassmann */ /* */ /* Creation Date : 12/12/98 */ /* */ /* Arguments: pkeychar - char string of the primary key. */ /* fieldname - char string of the changing field. */ /* newval - int value to be set. */ /************************************************************/ void log_do_set_int(const char pkeychar[HCG_KEY_SIZE+1],const char fieldname[NAMELENGTH+1],const int newval) { char pkey[HCG_KEY_SIZE+1]; int tbl_encoding/*, fld_encoding*/; strcpy(pkey,pkeychar); find_tbl_idx(pkey); if (encode(pkey,&hcg_k) == 1) /* updates hcg_k to unsigned long pkeycode */ { dprints("Found DL with pkey %s.\n", pkeychar); tbl_encoding = encoding(hcg_table_seq_list[hcg_tbl_idx].ttabbrev); switch(tbl_encoding) { case 0: /* FO table */ pr_find(FO, FOid, hcg_k); if (FOcurr == NULL) printf("log_do_set_int pkey %s not found.\n", pkeychar); else{ /* no int fields */ } break; case 1: /* GD table */ pr_find(GD, GDid, hcg_k); if (GDcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ /* no int fields */ } break; case 2: /* HG table */ pr_find(HG, HGid, hcg_k); if (HGcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ } break; case 3: /* HN table */ pr_find(HN, HNid, hcg_k); if (HNcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"txtwidth")==0) HNcurr->txtwidth = newval; else if(strcmp(fieldname,"txtheight")==0) HNcurr->txtheight = newval; /* POSITION and SHAPE are floats */ } break; case 4: /* HA table */ pr_find(HA, HAid, hcg_k); if (HAcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"txtwidth")==0) HAcurr->txtwidth = newval; else if(strcmp(fieldname,"txtheight")==0) HAcurr->txtheight = newval; } break; case 5: /* HL table */ pr_find(HL, HLid, hcg_k); if (HLcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HPcount")==0) HLcurr->HPcount = newval; else if(strcmp(fieldname,"allvisible")==0) HLcurr->allvisible = newval; } break; case 6: /* HP table */ pr_find(HP, HPid, hcg_k); if (HPcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"is_visible")==0) HPcurr->is_visible = newval; } break; case 7: /* HI table */ pr_find(HI, HIid, hcg_k); if (HIcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"txtwidth")==0) HIcurr->txtwidth = newval; else if(strcmp(fieldname,"txtheight")==0) HIcurr->txtheight = newval; } break; case 8: /* CG table */ pr_find(CG, CGid, hcg_k); if (CGcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ } break; case 9: /* GX table */ pr_find(GX, GXid, hcg_k); if (GXcurr == NULL) printf("log_do_set_int %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"txtwidth")==0) GXcurr->txtwidth = newval; else if(strcmp(fieldname,"txtheight")==0) GXcurr->txtheight = newval; } break; default: assert(hcg_k = NULL); /* print error and exit */ break; }; /* end switch */ } /* end if encode */ else dprints("log_do_set_int: failed to encode pkey %s\n", pkey); } /* end log_do_set_int */ /************************************************************/ /* Function: log_do_set_flt */ /* */ /* This function is used to set the value of an float field.*/ /* */ /* Created by : Rob Rassmann */ /* */ /* Creation Date : 12/12/98 */ /* */ /* Arguments: pkeychar - char string of the primary key. */ /* fieldname - char string of the changing field. */ /* newval - flt value to be set. */ /************************************************************/ void log_do_set_flt(const char pkeychar[HCG_KEY_SIZE+1],const char fieldname[NAMELENGTH+1],const float newval) { char pkey[HCG_KEY_SIZE+1]; int tbl_encoding/*, fld_encoding*/; strcpy(pkey,pkeychar); find_tbl_idx(pkeychar); if(encode(pkey,&hcg_k) ==1) { dprints("Found DL with pkey %s.\n",pkeychar); tbl_encoding = encoding(hcg_table_seq_list[hcg_tbl_idx].ttabbrev); switch(tbl_encoding) { case 0: /* FO table */ pr_find(FO, FOid, hcg_k); if (FOcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ } break; case 1: /* GD table */ pr_find(GD, GDid, hcg_k); if (GDcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"width")==0) GDcurr->width = newval; else if(strcmp(fieldname,"height")==0) GDcurr->height = newval; else if(strcmp(fieldname,"gcwidth")==0) GDcurr->gcwidth = newval; else if(strcmp(fieldname,"gcheight")==0) GDcurr->gcheight = newval; } break; case 2: /* HG table */ pr_find(HG, HGid, hcg_k); if (HGcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ } break; case 3: /* HN table */ pr_find(HN, HNid, hcg_k); if (HNcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"centerx")==0) HNcurr->centerx = newval; else if(strcmp(fieldname,"centery")==0) HNcurr->centery = newval; else if(strcmp(fieldname,"width")==0) HNcurr->width = newval; else if(strcmp(fieldname,"height")==0) HNcurr->height = newval; else if(strcmp(fieldname,"txtoffsetx")==0) HNcurr->txtoffsetx = newval; else if(strcmp(fieldname,"txtoffsety")==0) HNcurr->txtoffsety = newval; } break; case 4: /* HA table */ pr_find(HA, HAid, hcg_k); if (HAcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"txtoffsetx")==0) HAcurr->txtoffsetx = newval; else if(strcmp(fieldname,"txtoffsety")==0) HAcurr->txtoffsety = newval; else if(strcmp(fieldname,"HAorigin")==0) HAcurr->HAorigin = newval; } break; case 5: /* HL table */ pr_find(HL, HLid, hcg_k); if (HLcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ } break; case 6: /* HP table */ pr_find(HP, HPid, hcg_k); if (HPcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HPx")==0) HPcurr->HPx = newval; else if(strcmp(fieldname,"HPy")==0) HPcurr->HPy = newval; } break; case 7: /* HI table */ pr_find(HI, HIid, hcg_k); if (HIcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HIorigin")==0) HIcurr->HIorigin = newval; else if(strcmp(fieldname,"tbeginx")==0) HIcurr->tbeginx = newval; else if(strcmp(fieldname,"tbeginy")==0) HIcurr->tbeginy = newval; } break; case 8: /* CG table */ pr_find(CG, CGid, hcg_k); if (CGcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"CGcenterx")==0) CGcurr->CGcenterx = newval; else if(strcmp(fieldname,"CGcentery")==0) CGcurr->CGcentery = newval; else if(strcmp(fieldname,"CGwidth")==0) CGcurr->CGwidth = newval; else if(strcmp(fieldname,"CGheight")==0) CGcurr->CGheight = newval; } break; case 9: /* GX table */ pr_find(GX, GXid, hcg_k); if (GXcurr == NULL) printf("log_do_set_flt %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"GXorigin")==0) GXcurr->GXorigin = newval; else if(strcmp(fieldname,"txtoffsetx")==0) GXcurr->txtoffsetx = newval; else if(strcmp(fieldname,"txtoffsety")==0) GXcurr->txtoffsety = newval; } break; } /* end switch */ } /* end if decode */ } /************************************************************/ /* Function: log_do_set_key */ /* */ /* This function is used to set the value of an key field. */ /* */ /* Created by : Rob Rassmann */ /* */ /* Creation Date : 12/12/98 */ /* */ /* Arguments: pkeychar - char string of the primary key. */ /* fieldname - char string of the changing field. */ /* newval - char string key value to be set.*/ /************************************************************/ void log_do_set_key(const char pkeychar[HCG_KEY_SIZE+1],const char fieldname[NAMELENGTH+1],const char newval[HCG_KEY_SIZE+1]) { char pkey[HCG_KEY_SIZE+1]; int tbl_encoding/*, fld_encoding*/; hcg_key new_key; strcpy(pkey,pkeychar); find_tbl_idx(pkeychar); if(encode(pkey,&hcg_k) ==1) { dprints("Found DL with pkey %s.\n",pkeychar); if(encode(fieldname,&new_key) ==1) { dprints("Found DL with key %s.\n",fieldname); tbl_encoding = encoding(hcg_table_seq_list[hcg_tbl_idx].ttabbrev); switch(tbl_encoding) { case 0: /* FO table */ pr_find(FO, FOid, hcg_k); if (FOcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"FOid")==0) FOcurr->FOid = new_key; } break; case 1: /* GD table */ pr_find(GD, GDid, hcg_k); if (GDcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"GDid")==0) GDcurr->GDid = new_key; } break; case 2: /* HG table */ pr_find(HG, HGid, hcg_k); if (HGcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HGid")==0) HGcurr->HGid = new_key; } break; case 3: /* HN table */ pr_find(HN, HNid, hcg_k); if (HNcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HNid")==0) HNcurr->HNid = new_key; else if(strcmp(fieldname,"HGid")==0) HNcurr->HGid = new_key; } break; case 4: /* HA table */ pr_find(HA, HAid, hcg_k); if (HAcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HAid")==0) HAcurr->HAid = new_key; else if(strcmp(fieldname,"HNid")==0) HAcurr->HNid = new_key; } break; case 5: /* HL table */ pr_find(HL, HLid, hcg_k); if (HLcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HLid")==0) HLcurr->HLid = new_key; else if(strcmp(fieldname,"HNid1")==0) HLcurr->HNid1 = new_key; else if(strcmp(fieldname,"HNid2")==0) HLcurr->HNid2 = new_key; } break; case 6: /* HP table */ pr_find(HP, HPid, hcg_k); if (HPcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HPid")==0) HPcurr->HPid = new_key; else if(strcmp(fieldname,"HLid")==0) HPcurr->HLid = new_key; } break; case 7: /* HI table */ pr_find(HI, HIid, hcg_k); if (HIcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"HIid")==0) HIcurr->HIid = new_key; else if(strcmp(fieldname,"HLid")==0) HIcurr->HLid = new_key; } break; case 8: /* CG table */ pr_find(CG, CGid, hcg_k); if (CGcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"CGid")==0) CGcurr->CGid = new_key; else if(strcmp(fieldname,"HGid")==0) CGcurr->HGid = new_key; } break; case 9: /* GX table */ pr_find(GX, GXid, hcg_k); if (GXcurr == NULL) printf("log_do_set_key %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"GXid")==0) GXcurr->GXid = new_key; else if(strcmp(fieldname,"CGid")==0) GXcurr->CGid = new_key; } break; } /* end switch */ } /* end if decode of fieldname */ } /* end if decode of pkey */ } /************************************************************/ /* Function: log_do_set_str */ /* */ /* This function is used to set the value of an string field.*/ /* */ /* Created by : Rob Rassmann */ /* */ /* Creation Date : 12/12/98 */ /* */ /* Arguments: pkeychar - char string of the primary key. */ /* fieldname - char string of the changing field. */ /* newval - char string value to be set. */ /************************************************************/ void log_do_set_str(const char pkeychar[HCG_KEY_SIZE+1],const char fieldname[NAMELENGTH+1],const char newval[BUFSIZE+1]) { char pkey[HCG_KEY_SIZE+1]; int tbl_encoding/*, fld_encoding*/; strcpy(pkey,pkeychar); find_tbl_idx(pkeychar); if(encode(pkey,&hcg_k) ==1) { dprints("Found DL with pkey %s.\n",pkeychar); tbl_encoding = encoding(hcg_table_seq_list[hcg_tbl_idx].ttabbrev); switch(tbl_encoding) { case 0: /* FO table */ pr_find(FO, FOid, hcg_k); if (FOcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"xfont")==0) strcpy(FOcurr->xfont,newval); else if(strcmp(fieldname,"psfontname")==0) strcpy(FOcurr->psfontname,newval); else if(strcmp(fieldname,"psfontsize")==0) strcpy(FOcurr->psfontsize,newval); else if(strcmp(fieldname,"bdefont")==0) strcpy(FOcurr->bdefont,newval); } break; case 1: /* GD table */ pr_find(GD, GDid, hcg_k); if (GDcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"shape")==0) strcpy(GDcurr->shape,newval); else if(strcmp(fieldname,"hsegpattern")==0) strcpy(GDcurr->hsegpattern,newval); else if(strcmp(fieldname,"txtfont")==0) strcpy(GDcurr->txtfont,newval); else if(strcmp(fieldname,"location")==0) strcpy(GDcurr->location,newval); else if(strcmp(fieldname,"justify")==0) strcpy(GDcurr->justify,newval); } break; case 2: /* HG table */ pr_find(HG, HGid, hcg_k); if (HGcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"FSid")==0) strcpy(HGcurr->FSid,newval); else if(strcmp(fieldname,"HNid")==0) strcpy(HGcurr->HNid,newval); else if(strcmp(fieldname,"HGauthor")==0) strcpy(HGcurr->HGauthor,newval); else if(strcmp(fieldname,"HGcreated")==0) strcpy(HGcurr->HGcreated,newval); else if(strcmp(fieldname,"HGlastmod")==0) strcpy(HGcurr->HGlastmod,newval); } break; case 3: /* HN table */ pr_find(HN, HNid, hcg_k); if (HNcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"FSid")==0) strcpy(HNcurr->FSid,newval); else if(strcmp(fieldname,"shape")==0) strcpy(HNcurr->shape,newval); else if(strcmp(fieldname,"txtfont")==0) strcpy(HNcurr->txtfont,newval); } break; case 4: /* HA table */ pr_find(HA, HAid, hcg_k); if (HAcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"DAid")==0) strcpy(HAcurr->DAid,newval); else if(strcmp(fieldname,"txtfont")==0) strcpy(HAcurr->txtfont,newval); } break; case 5: /* HL table */ pr_find(HL, HLid, hcg_k); if (HLcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ } break; case 6: /* HP table */ pr_find(HP, HPid, hcg_k); if (HPcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"hsegpattern")==0) strcpy(HPcurr->hsegpattern,newval); } break; case 7: /* HI table */ pr_find(HI, HIid, hcg_k); if (HIcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"DIid")==0) strcpy(HIcurr->DIid,newval); else if(strcmp(fieldname,"txtfont")==0) strcpy(HIcurr->txtfont,newval); } break; case 8: /* CG table */ pr_find(CG, CGid, hcg_k); if (CGcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ } break; case 9: /* GX table */ pr_find(GX, GXid, hcg_k); if (GXcurr == NULL) printf("log_do_set_str %s not found.\n", pkeychar); else{ if(strcmp(fieldname,"DAid")==0) strcpy(GXcurr->DAid,newval); else if(strcmp(fieldname,"txtfont")==0) strcpy(GXcurr->txtfont,newval); } break; } /* end switch */ } /* end if decode */ } /* end log_do_set_type */ /************************************************************/ /* Function: encode_token */ /* */ /* This function is imported from bdeReplay.cc */ /* */ /************************************************************/ /* This could be an STL map function if available in 'C". */ replayCode encode_token( char *token ) /* convert token to command */ { int tokenlength = strlen(token); assert(tokenlength == 2 || tokenlength == 10); if ( tokenlength == 10 ) { if (strcmp(token, "PR_SET_INT") == 0) return SetIntCmd; else if (strcmp(token, "PR_SET_FLT") == 0) return SetFltCmd; else if (strcmp(token, "PR_SET_KEY") == 0) return SetKeyCmd; else if (strcmp(token, "PR_SET_STR") == 0) return SetStrCmd; } else { if (tokenlength == 2) { if (strcmp(token, "WA") == 0) return WaitCmd; else if (strcmp(token, "DL") == 0) return DeleteCmd; else if (strcmp(token, "SR") == 0) return StartCmd; else if (strcmp(token, "FR") == 0) return FreeCmd; else if (strcmp(token, "IN") == 0) return InitCmd; else if (strcmp(token, "LD") == 0) return LoadCmd; else if (strcmp(token, "SP") == 0) return StopCmd; else if (strcmp(token, "VN") == 0) return ViewNameCmd; } else return AddRowCmd; } return -1; /* can't reach here - avoids warning:reach end of non-void fcn */ } /*end encode_token*/ /************************************************************/ /* Function:do_command */ /* */ /* This function is command interpreter for replay logfile */ /* */ /************************************************************/ /* It is application-independent and completely chgen-produced. */ /* TBD? Update MVstate/RFLAG+ to trigger updatedisplaylist and ReDraw? */ int do_command( char *hcg_buffer, char *token, int idx) { extern FILE * logfile_fp; char temp[BUFSIZE]; int totMsec; int temp_newint; float temp_newflt; char temp_newstr[BUFSIZE+1]; char datalist[BUFSIZE]; char tempdatalist[BUFSIZE]; char logviewname[NAMELENGTH]; char datafile[NAMELENGTH]; char newdatafile[NAMELENGTH]; char temppkey[BUFSIZE]; char *addlist; idx = 0; hcg_parse(hcg_buffer,token,&idx); command = encode_token(token); dprintsd("Token =%s, Command = %d\n", token, command); switch((int)command) { case WaitCmd: /* get the wait times */ hcg_parse(hcg_buffer,temp,&idx); /* convert seconds and milliseconds to milliseconds */ totMsec = atoi(temp); dprintd("Found WA with total milliseconds %d.\n", totMsec); if ((near_realtime ==1) && (totMsec > 0)) log_sleep(totMsec); break; case DeleteCmd: hcg_parse(hcg_buffer,temp_newkey,&idx); assert(strlen(temp_newkey) == HCG_KEY_SIZE); log_do_delete(temp_newkey); break; case SetIntCmd: // int temp_newint; hcg_parse(hcg_buffer,temp_tbl,&idx); hcg_parse(hcg_buffer,temp_field,&idx); hcg_parse(hcg_buffer,temp_newval,&idx); temp_newint = atoi(temp_newval); log_do_set_int(temp_tbl,temp_field,temp_newint); break; case SetFltCmd: //float temp_newflt; hcg_parse(hcg_buffer,temp_tbl,&idx); hcg_parse(hcg_buffer,temp_field,&idx); hcg_parse(hcg_buffer,temp_newval,&idx); temp_newflt = atof(temp_newval); log_do_set_flt(temp_tbl,temp_field,temp_newflt); break; case SetKeyCmd: hcg_parse(hcg_buffer,temp_tbl,&idx); hcg_parse(hcg_buffer,temp_field,&idx); hcg_parse(hcg_buffer,temp_newkey,&idx); log_do_set_key(temp_tbl,temp_field,temp_newkey); break; case SetStrCmd: hcg_parse(hcg_buffer,temp_tbl,&idx); hcg_parse(hcg_buffer,temp_field,&idx); hcg_parse(hcg_buffer,temp_newstr,&idx); log_do_set_str(temp_tbl,temp_field,temp_newstr); break; case InitCmd: hcg_parse(hcg_buffer,viewname,&idx); hcg_parse(hcg_buffer,temp,&idx); strcpy(datalist,strstr(hcg_buffer, temp)); convert2temp(datalist,tempdatalist); dprintss("Found IN with viewname %s, datalist=%s.\n",viewname,temp); pr_init(viewname,tempdatalist); hcg_ascii_fp = logfile_fp; /* reset the file pointer */ break; case LoadCmd: hcg_parse(hcg_buffer,logviewname,&idx); hcg_parse(hcg_buffer,datafile,&idx); sprintf(newdatafile,"temp%s",datafile); dprintss("Found LD: viewname:%s,datafile:%s.\n",logviewname, newdatafile); pr_load(logviewname,newdatafile); hcg_ascii_fp = logfile_fp; break; case FreeCmd: dprint("Found FR.\n"); pr_free(); break; case ViewNameCmd: hcg_parse(hcg_buffer,viewname,&idx); dprints("Found VN with viewname %s.\n",viewname); strcpy(hcg_viewname,viewname); break; case StopCmd: dprint("Found SP\n"); replayState = STATE2; break; case AddRowCmd: default: if (strlen(token)!= HCG_KEY_SIZE) printf("Logfile: unknown command '%s' - ignored\n", token); else strcpy(temppkey,token); hcg_parse(hcg_buffer,temp, &idx); addlist = (char *)strstr(hcg_buffer, temp); if (find_tbl_idx(temppkey)==0) { dprints("Unknown pkey %s: skipping \n", token); } else { dprintss("Found Add with pkey %s, rest %s.\n",temppkey,addlist); log_do_add(hcg_viewname,hcg_table_seq_list[hcg_tbl_idx]. ttabbrev,addlist); } hcg_parse(hcg_buffer,datafile,&idx); /*a garble may be a bug here - RJL 031022*/ break; // AddRow is the default case } // end switch(command) return (command); /* needed for second switch(command) which is in */ /* bdeReplay's replay_log byt may not be needed. */ } /*end do_command */ /************************************************************/ /* Function: pr_replay */ /* */ /* This function is used to replay a logged session based on*/ /* a log file. It will destroy the current database, */ /* restore the DB from the start of the log session, */ /* and reproduce the DB modifications in the logfile. */ /* */ /* Arguments: view - the viewname of the log session */ /* logfile - the name of the logfile to replay */ /* near_realtime - a boolean flag indicating if */ /* the replay should approx realtime */ /* 0 - no near_realtime playback */ /* 1 - playback in near-realtime */ /* take_endsnapshot - a boolean flag indicating if the */ /* database should be dumped at the */ /* end of the replay. */ /* 0 - do not take the end DB snapshot */ /* 1 - take the end DB snapshot */ /* */ /* Preconditions (added by RJL 030809) */ /* (name without extension) cannot include "." */ /* DB1.dat exists to initialize database */ /* logdata.txt must contain "LogDataFile\n" plus data */ /* for each file copy that pr_init will scan. */ /* pr_load sets hcg_log = 0 and returns retval. */ /* Is this BAD if retval = -4? */ /* */ /* Return values: */ /* 0 - success */ /* -1 - Replay error - null view name */ /* -2 - Replay error - null log file */ /* -3 - Replay error - unable to open file */ /* -4 - Replay error - log session in progress */ /* -5 - Replay error - incorrect log file format */ /* */ /************************************************************/ int pr_replay(char *view, char logfile[NAMELENGTH], int near_realtime, int take_endsnapshot) { /*unused: FILE *log_fp;*/ char filelist[BUFSIZE], tempfilelist[BUFSIZE], tempvar[BUFSIZE], logfiledb[NAMELENGTH]; int retval; filelist[0] = '\0'; #ifdef DEBUG printf("pr_replay:BUFSIZE=%i, NAMELENGTH=%i, filelist=\n\t%s\n", BUFSIZE, NAMELENGTH, filelist); #endif assert( near_realtime == 0 || near_realtime == 1); /* range constraint pre-condition - should be an enumeration */ if (hcg_log ==1 ) { printf("Error: pr_replay invalid - logging in progress\n"); return(-4); } /* TBD: Allow "SR" command AFTER loading valid data? */ /* Why? - replay already permits pr_adding rows after "SR". */ /* set replay to be on & save logfilename*/ hcg_log = 2; strcpy(hcg_logfile,logfile); //hcg_logfile scope? /* validate the arguments */ if (view == NULL) { printf("pr_replay error: null view name\n"); hcg_log = 0; return(-1); } if (logfile == NULL) { printf("pr_replay error: null log file\n"); hcg_log = 0; return(-2); } /* free the existing database */ if (hcg_initialized) { pr_free(); } strtok(logfile,"."); /* assumes exactly one period */ /* generate checkpoint file name by appending "DB1" */ sprintf(logfiledb,"%sDB1.dat",logfile); /*Pre-condition: infile logdata.txt MUST exist here - RJL 030809 */ retval = log_parselogdata(tempfilelist); if (retval != 0) return(retval); /* Why quit now? - RJL 040404 */ sprintf(filelist, "%s %s", tempfilelist, logfiledb); dprints("pr_replay: filelist to pr_init: \n\t%s\n\n", filelist); /* initialize & load the database */ pr_init("../lib/bdetest.viewdefs", tempfilelist); /* get stats from tempfilelist and logfiledb: RJL 030809*/ pr_load(view,logfiledb); retval = 0; /* unless replay_log returns another value */ #ifdef GENLOG retval = replay_log(); /* compiled only #ifdef GENLOG */ /* NB: CLIENT must have a stub for this, which is an */ /* application-specific part of replaying the logfile */ /* bdeReplay.cc contains a work-completion function after replay_log. */ /* take final snapshot */ if (take_endsnapshot==1) { sprintf(tempvar,"%sDB3.dat",logfile); pr_dump(view, tempvar,0,"w"); dprints("endSnapshot is in file %sDB3.dat\n", logfile); } #endif if (hcg_log == 2) hcg_log = 0; /* replay is finished; normal editing resumes. */ /* TBD: allow logging during replay and both afterward - RJL 030807 */ return (retval); } // end pr_replay