#include #include #include #include #include #include #include "metasets.h" #include "tennis.h" #define BLANK ((' '<<8)|' ') /* 2 space chars */ #define MAXNSRC 16 /* srcname size */ #define MAXVBUF (outputbfsiz-BOMLEN-EOMLEN-24) /* max buf size available */ /* for variable set text */ #define TAPE 1 /* device id's */ #define DISK 2 #define PIPE 4 #define istape (outype==TAPE) #define isdisk (outype==DISK) #define ispipe (outype==PIPE) static char c_ofile[NAMLEN]; /* output name/unit # */ static int prompt= 1; /* request prompt */ static int ounit= -1; /* output file descriptor */ static int recseq= 0; /* match seq. # */ static int outype= 0; /* holds output dev. id */ static char tourname[80]; /* requested from operator */ char *opointer; /* output buffer pointer */ int tennis_step= 0; /* flag to step opointer */ char *inputbuff= NULL; /* input buffer addr */ int inputbfsiz= IBUFLEN; /* input buffer size */ char *outputbuff= NULL; /* output buffer addr */ int outputbfsiz= OBUFLEN; /* output buffer size */ int setcount[MAXCNT]; /* setcount for endtourney */ int setinitp[MAXST]; /* strbuf indices -> filename stings */ int tennis_dual= 0; /* to flag dual I/O */ int firstmetas= 1; /* flag meta processing */ char *t_putset(); extern int t_request(); extern char *strbuf; extern size_t istr,istrmax; extern int nsetdscr; /* extern int mtwrite(),mtweof(),mtrew(),mtclose(); */ /* ------------------------------------------------------------------- */ /* put_set(key) * User interface to putset. Tests key for valid user set. * Returns pointer to start of 1st game for new set. */ char *put_set(key) /* user routine, check key for */ short key;{ /* alpha chars or T_END */ char *kp; kp= (char*)&key; if((isalpha(*kp) && isalpha(*(kp+1))) || (key == T_END)) return(t_putset(key)); else return(NULL); } /* ------------------------------------------------------------------- */ /* t_putset(key) * Internal routine. Handles metasets, tests output buffer for room, * advances opointer for new set, terminates run for T_END flag. */ char *t_putset(key) short key;{ static frstputset= 1; char *p,*lookahead; short okey; int n,iset; for(;;){ /* THIS SECTION FOR NO GETSET/ PUTSET ONLY ***** */ if(frstputset && !tennis_dual){ /* 1st putset call ? */ frstputset= 0; t_bufalloc(1); /* allocate buffer */ opointer= outputbuff; /* init ptr. */ t_initkeymap(); /* init maps */ recseq= 0; if(t_begtourney() < 0) /* output set 0[ */ return(NULL); t_obflush(); ts_outsetdscr(); /* output sets 0! */ ts_outsrcsav(); /* output sets 0$ */ tennis_step= 0; /* ***** */ } if(tennis_step){ p= (char*)&okey; *p= *opointer; /* pick up key chars */ *(p+1)= *(opointer+1); iset= t_keymap(okey); /* advance opointer to */ if(iset >= 0) /* start of next set */ opointer += setdscr[iset].setlen; /* user set */ else{ t_keyerr("putset: no setlen, key",p); exit(1); } } else tennis_step= 1; /* default state after this */ if(key == T_END){ /* end of tourney ? */ t_endtourney(); ts_oclose(ounit); firstmetas= 1; /* reset getset for new OUTPUT */ frstputset= 1; /* ditto putset */ nsetdscr= 0; /* reset for new output if any */ ounit= -1; return(NULL); } iset= t_keymap(key); /* see if set fits */ if(iset < 0){ t_keyerr("putset: no iset index, key",(char*)&key); exit(1); } lookahead= opointer+setdscr[iset].setlen; if(lookahead > outputbuff+outputbfsiz-EOMLEN) t_obflush(); /* if not, flush buffer */ p= (char*)&key; *opointer= *p; /* store key */ *(opointer+1)= *(p+1); *(opointer+2)= ' '; *(opointer+3)= ' '; n= USRCNT+iset; /* inc setcount */ if(n >= MAXCNT) n= MAXCNT-1; setcount[n]++; return(opointer+setdscr[iset].gamepnt[0]); /* ptr to 1st game */ } } /* ------------------------------------------------------------------- */ /* set_init(p) * User routine to effect output of new set descriptors. Stores names * of set descriptor files for later processing on 1st put_set() call. */ set_init(p) /* p -> string with filename for PVL dscr */ char *p;{ if(nsetdscr >= MAXST) /* nsetdscr = # new user sets */ t_err("set_init: nsetdscr >= MAXST"); setinitp[nsetdscr++]= t_savstr(p); /* save string + store index */ } /* --------------------------------------------------------------------- */ /* set_outfile(fname,tname) * User routine to set the name of the output file * and the identifying name of the tourney. * Will prevent prompting to the terminal. */ set_outfile(fname,tname) char *fname, *tname;{ strcpy(c_ofile,fname); strcpy(tourname,tname); prompt= 0; /* suppress prompt */ if(t_getoutput() < 0) t_err("set_outfile:\n cannot create output file"); t_bufalloc(1); /* alloc buffer */ } /* ------------------------------------------------------------------- */ /* set_bufsize() * User routine to set input and output buffer sizes. */ set_bufsize(input,output) int input,output;{ inputbfsiz= input; outputbfsiz= output; } /* ------------------------------------------------------------------- */ /* t_bufalloc(iostate) * Malloc buffer space for I/O and set buffer addresses. * iostate indicates calling routine. * (single buffers only at this stage) */ t_bufalloc(iostate) int iostate;{ if(iostate == 0){ /* call from getset */ if(inputbuff == NULL){ if((inputbuff= (char*)malloc(inputbfsiz)) == NULL) t_err("bufalloc: malloc input"); } if(tennis_dual && (outputbuff==NULL)){ if((outputbuff= (char*)malloc(outputbfsiz)) == NULL) t_err("bufalloc: malloc output"); } } else{ /* call from putset */ if(outputbuff == NULL){ if((outputbuff= (char*)malloc(outputbfsiz)) == NULL) t_err("bufalloc: malloc output"); } } } /* ------------------------------------------------------------------- */ /* start of set 0[ */ char trnydscr[150]= "\ 0[ ]S[syBOT;\n\ BEGIN_GROUP = trnydscr;\n\ bfsz = 32768;\n\ cmptyp = DEC;\n\ cmpos = LTRX4.2;\n\ cmpnm = jaguar.larc.nasa.gov;\n"; /* library path name, if any, should be entered here, and the line in tourdata() below should be modified for the file date: t_put2item("lb",libname,NULL) -> t_put2item("lb",libname,libname) */ static char libname[80]= "/localsys/LocalLib/libtennis.a"; static int srcname[MAXNSRC]; /* from setnmsav(), setsrcsav() */ static int srcnum= 2; /* srcname entries */ static char isotime[24],skiptm[24]; /* ------------------------------------------------------------------- */ /* t_begtourney() * Internal routine to output 0[ metaset. * Requests new output and tourney's ID. */ t_begtourney(){ if(prompt){ while(ounit < 0){ t_request("output filename\n? ",c_ofile); if(t_getoutput() < 0) return(-1); /* -> putset returns NULL */ } t_request("identifying name of tourney (dataset)\n? ",tourname); } t_begmatch(); /* start of tourney */ setcount[BTCNT0]++; t_tourdata(); /* construct set 0[ */ /* t_obflush(); do this elsewhere if wanted * flush outputbuff */ return(0); } /* ------------------------------------------------------------------- */ /* t_endtourney() * Outputs 0] metaset. Effected on receipt of put_set(T_END) call. */ t_endtourney(){ t_obflush(); /* flush outputbuff */ setcount[ETCNT0]++; /* 0] count */ setcount[OBFCNT]++; /* fold in last buf */ t_tourcounts(); /* tour. set counts */ t_obflush(); /* + final flush */ } /* ------------------------------------------------------------------- */ /* t_begmatch() * Outputs [[ metaset. Called internally. Leaves opointer in * advanced position. */ t_begmatch(){ /* begin of match */ static char bor[14]= "[[ ]S[syBOR"; /* key + synch */ strncpy(outputbuff,bor,12); recseq++; sprintf(outputbuff+12,"%12d",recseq); /* match seq no. */ opointer= outputbuff+BOMLEN; /* adv. op for next set */ } /* ------------------------------------------------------------------- */ /* t_endmatch() * Outputs ]] metaset. Called internally. Leaves opointer in * advanced position. */ t_endmatch(){ /* end of match */ static char eor[14]= "]] ]S[syEOR"; /* key + sync */ int reclen; strncpy(opointer,eor,12); reclen= (int)(opointer-outputbuff+EOMLEN); /* match size */ sprintf(opointer+12,"%12d",reclen); opointer += EOMLEN; /* adv. op for write */ } /* ------------------------------------------------------------------- */ /* t_obflush() * Flushes the output buffer, with appropriate ]] and [[ metasets. * Advances opointer. */ t_obflush(){ /* outputbuff flush + handles end/begmatch */ t_endmatch(); /* ends at current opointer */ ts_write(ounit); t_begmatch(); /* advances opointer for next set */ } /* ------------------------------------------------------------------- */ /* t_tourdata() * Writes 0[ metaset data into output buffer. */ t_tourdata(){ char *opend; int n; opend= opointer+BOTLEN; /* save end pointer */ strcpy(opointer,trnydscr); opointer += strlen(trnydscr); t_put2item("tr",tourname,NULL); t_put2item("lb",libname,libname); n= srcname[0]; t_put2item("mn",&strbuf[n],&strbuf[n]); /* main.c */ n= srcname[1]; t_put2item("oth",&strbuf[n],&strbuf[n]); /* other.c */ sprintf(opointer,"skiptm\t= %s;\n",skiptm); opointer += 11 +strlen(skiptm); sprintf(opointer,"END_GROUP = trnydscr;\n"); opointer += 22; while(opointer < opend) *opointer++ = ' '; /* fill to end */ } /* ------------------------------------------------------------------- */ /* t_put2item(lab,nam,pf) * Writes names and dates to buffer. Lab= label, nam= name, * pf= name or NULL (see ts_time below). */ /* eg: lbnm = /usr/lib/lib.tennis;\n */ t_put2item(lab,nam,pf) /* lbdt = 1991-24-92T12:00:00;\n */ char *lab,*nam,*pf;{ sprintf(opointer,"%snm\t= %s;\n",lab,nam); opointer += 7 +strlen(lab)+strlen(nam); ts_time(pf); sprintf(opointer,"%sdt\t= %s;\n",lab,isotime); opointer += 7 +strlen(lab)+strlen(isotime); } /* ------------------------------------------------------------------- */ /* ts_time(pf) * Writes time into isotime array. File time for pf= filename, or * exectution time for pf= NULL */ /* convert atime:"Sun Sep 16 01:03:52 1985\n" */ ts_time(pf) /* to isotime:'1985-09-16T01:03:52' */ char *pf;{ struct stat sbuf; /* p = NULL ptr -> execution time */ int tval,mon; /* else -> file modification time */ struct tm *itime,*localtime(); char *p,*atime,*ctime(); if(pf == NULL) tval= time(0); /* get current time */ else{ stat(pf,&sbuf); /* get file stat */ tval= sbuf.st_mtime; /* last mod. time */ } itime= localtime(&tval); /* pick up month */ mon= itime->tm_mon+1; atime= ctime(&tval); /* atime string */ p= isotime; strncpy(p,&atime[20],4); /* year */ p[4]= '-'; p[5]= mon/10+'0'; /* month 1-12 */ p[6]= mon%10+'0'; p[7]='-'; strncpy(&p[8],&atime[8],11); /* dayTtime */ p[10]= 'T'; if(p[8] == ' ') p[8]= '0'; /* space in day? */ } /* ------------------------------------------------------------------- */ /* setnmsav(mainp,otherp) * User routine to effect output of 0$ metasets. Saves source filenames * for later output by putset() call. File times will be written in 0[ * metaset. Requires input of two names (may be the same). */ setnmsav(mainp,otherp) char *mainp,*otherp;{ srcname[0]= t_savstr(mainp); srcname[1]= t_savstr(otherp); } /* ------------------------------------------------------------------- */ /* setsrcsav(mainp,otherp) * User routine to effect output of 0$ metasets for additions files. */ setsrcsav(sp) char *sp;{ if(srcnum > MAXNSRC) fprintf(stderr,"setsrcsav: %s, array full\n",sp); else{ srcname[srcnum]= t_savstr(sp); srcnum++; } } /* --------------------------------------------------------------------- */ /* t_savstr(p) * Internal routine to save strings in strbuf, the system allocated * memory buffer. Returns offset of start of string in buffer. */ int t_savstr(p) /* save string in strbuf */ char *p;{ size_t istr0; istr0= istr; /* save string start index */ while(*p){ if(istr >= istrmax) ts_exstrbuf(); strbuf[istr++]= *p++; /* store string in strbuf */ } if(istr >= istrmax) ts_exstrbuf(); strbuf[istr++]= 0; /* terminate string */ return((int)istr0); /* + return index */ } /* --------------------------------------------------------------------- */ static int seqno,ncpf; /* for variable size set */ /* --------------------------------------------------------------------- */ /* ts_outsetdscr() * Routine to output 0! metaset for each setinit() entry. Called at start * of 1st putset() call. Reads in given set descriptor file, parses data * for new setdscr[] entry, then copies data to output buffer. * Large set descriptor files will be broken into a sequence of variable * size 0! metasets. (These may not yet be available for translation back * by subsequent getset().) */ ts_outsetdscr(){ struct stat sbuf; char *p,*tbuf; int id,n,ns; int index,nset; for(nset=0;nset MAXVBUF) /* bigger than whole buffer ? */ while(ns){ t_obflush(); n= (ns >= MAXVBUF)? MAXVBUF: ns; t_setext(p,n); setcount[SDCNT0]++; ns -= n; p += n; seqno++; } else{ /* room left in buffer ? */ if(opointer+ns+24 > outputbuff+outputbfsiz-EOMLEN) t_obflush(); t_setext(p,ns); /* output data */ setcount[SDCNT0]++; } free((void*)tbuf); /* free memory */ #if !defined(VAX) close(id); /* close file */ #else rms_close(id); #endif } /* HOLD OFF final flush, not wanted for dual I/O */ /* t_obflush(); /* flush again when all 0!'s done */ } /* --------------------------------------------------------------------- */ /* t_setext(p,n) * Constructs 1st game of variable size metaset 0!, then copies file * text into 2nd game. p= start of text, n= size of text. */ t_setext(p,n) char *p; int n;{ static char set0[14]= "0! ]$[B"; /* key + synch */ strncpy(opointer,set0,8); sprintf(opointer+8,"%4d",seqno); /* seqno. */ sprintf(opointer+12,"%4d",ncpf); /* ncpf */ sprintf(opointer+16,"%8d",n); /* texlng */ opointer += 24; strncpy(opointer,p,n); /* text */ opointer += n; } /* --------------------------------------------------------------------- */ /* ts_outsrcsav() * Outputs 0$ metasets, variable size, from source files specified * in the srcname[] array. Srcname has previously been set by the user * calls setnmsav() and setsrcsav(). */ ts_outsrcsav(){ /* output sets 0$ for files in srcsav[] */ struct stat sbuf; char *p; int in,id,n,ns; for(in= 0;in MAXVBUF) /* bigger than whole buffer ? */ while(ns){ t_obflush(); n= (ns >= MAXVBUF)? MAXVBUF: ns; t_setfile(id,n); setcount[SSCNT0]++; ns -= n; seqno++; } else{ /* room left in buffer ? */ if(opointer+ns+24 > outputbuff+outputbfsiz-EOMLEN) t_obflush(); t_setfile(id,ns); /* output data */ setcount[SSCNT0]++; } #if !defined(VAX) close(id); /* close file */ #else rms_close(id); #endif } /* HOLD OFF final flush, not wanted for dual I/O */ /* t_obflush(); /* flush again when all 0$'s done */ } /* --------------------------------------------------------------------- */ /* t_setfile(p,n) * Constructs 1st game of variable size metaset 0$, then copies file * text into 2nd game. id= system file id, n= size of text. * Similar to setext(), except copies directly from file (no parsing). */ t_setfile(id,n) /* construct set 0$ in outputbuff */ int id,n;{ static char set0[14]= "0$ ]$[B"; /* key + synch */ char *txp; strncpy(opointer,set0,8); sprintf(opointer+8,"%4d",seqno); /* seqno. */ sprintf(opointer+12,"%4d",ncpf); /* ncpf */ txp = opointer+16; /* save for texlng */ opointer += 24; #if !defined(VAX) n= read(id,opointer,n); /* text */ #else n= rms_read(id,opointer,n); /* text */ #endif if(n < 0) t_err("t_setfile: read error"); sprintf(txp,"%8d",n); /* texlng */ opointer += n; } /* --------------------------------------------------------------------- */ /* t_tourcounts() * Writes 0] metaset data into output buffer. */ t_tourcounts(){ static char eot[14]= "0] ]S[syEOT"; /* key + sync */ static char *keys= "0[0!0$0]n[n!n$n]"; /* meta keys */ char *p; int imax,iset; int i,n; p= opointer; strncpy(p,eot,12); sprintf(p+12,"%12d",setcount[0]); /* match count */ p += 24; for(i=1;i