#include #include #include #include #include #include #include "metasets.h" #include "tennis.h" #define SITEMS 7 #define GITEMS 5 #define PITEMS 6 #define STRSIZE 4096 /* malloc size, for exstrbuf() */ /* macros to bump PVL pointer, skipping */ /* (comments) or (comments or quotes) */ #define skipcomt(x) x++;if(((*x=='/')&&(*(x+1)=='*')))t_skipit(); #define skipcmqt(x) x++;if(((*x=='/')&&(*(x+1)=='*'))||(*x=='"'))t_skipit(); struct setdscr setdscr[MAXST]; /* THE definition for setdscr struct array */ /* Official declaration is in tennis.h */ /* short setkey; short holding 2 chars */ /* short dummy; /* int setname; strbuf index */ /* int setext; index */ /* int setlen,gamecnt; /* int gamename[MAXGM]; index */ /* int gamepnt[MAXGM]; /* int gametext[MAXGM]; index */ /* int pointnm[MAXGM][MAXPT]; index */ /* int pointpnt[MAXGM][MAXPT]; /* int pointyp[MAXGM][MAXPT]; index */ /* int pointext[MAXGM][MAXPT]; index */ /* } setdscr[MAXST]; */ static struct setdscr *sp; static char *setitem[SITEMS]= {"BEGIN_GROUP","END_GROUP","setkey","setname","setext","setlen","gamecnt"}; static char *gameitem[GITEMS]= {"BEGIN_GROUP","END_GROUP","gamename","gamepnt","gametext"}; static char *pointitem[PITEMS]= {"BEGIN_GROUP","END_GROUP","pointnm","pointpnt","pointyp","pointext"}; static char *pvc; /* pvcursor ptr. */ static int ngame,npoint; static char item[100]; size_t istr= 0; /* strbuf[] index */ size_t istrmax; /* max. allocated for istr */ char *strbuf; /* strbuf start addr. */ int nsetdscr= 0; /* # of setdscr entries */ int t_getstr(); char *t_findbegin(), *t_nextitem(); extern int setcount[]; /* --------------------------------------------------------------------- */ /* t_setparse(sptr,nset) * Internal routine to parse ascii for setdscr parameters. * sptr= pointer to start of in-memory acsii. * nset= setdscr[] index for new entry. */ t_setparse(sptr,nset) /* process set description */ char *sptr; int nset;{ char *p; short key; int i; ngame= 0; npoint= 0; sp= &setdscr[nset]; /* sp -> setdscr entry */ t_findbegin(sptr); /* parse data in array and */ t_doset(); /* store in setdscr entry */ return(t_setkeymap(sp->setkey,nset)); /* put nset in keymap array */ } /* --------------------------------------------------------------------- */ /* t_findbegin(p) * Find "BEGIN_GROUP" for start of set description (PVL format). * Switch to pvc pointer (PVCursor). */ char *t_findbegin(p) char *p;{ pvc= p-1; do{ skipcmqt(pvc); } while(strncmp(pvc,"BEGIN_GROUP",11)); return(pvc); } /* --------------------------------------------------------------------- */ /* t_doset() * Process set parameter data */ t_doset(){ /* search for selected items and store parameters */ int i,n; /* in corresponding setdscr structure elements */ char *p; do{ t_nextitem(); for(n=0;nsetkey); p[0]= strbuf[i]; /* put chars into short key */ p[1]= strbuf[i+1]; break; case 3: sp->setname= t_getstr(); break; case 4: sp->setext= t_getstr(); break; case 5: sp->setlen= t_getval(); break; case 6: sp->gamecnt= t_getval(); break; default: break; } } while(n != 1); } /* --------------------------------------------------------------------- */ /* t_dogame() * Process game parameter data */ t_dogame(){ int n; npoint= 0; /* reset for this game */ do{ t_nextitem(); for(n=0;ngamename[ngame]= t_getstr(); break; case 3: sp->gamepnt[ngame]= t_getval(); break; case 4: sp->gametext[ngame]= t_getstr(); break; default: break; } } while(n != 1); ngame++; } /* --------------------------------------------------------------------- */ /* t_dopoint() * Process point parameter data */ t_dopoint(){ int n; do{ t_nextitem(); for(n=0;npointnm[ngame][npoint]= t_getstr(); break; case 3: sp->pointpnt[ngame][npoint]= t_getval(); break; case 4: sp->pointyp[ngame][npoint]= t_getstr(); break; case 5: sp->pointext[ngame][npoint]= t_getstr(); break; default: break; } } while(n != 1); npoint++; } /* --------------------------------------------------------------------- */ /* t_nextitem() * Pick up the lead item of the next "line". * -> Ignore comments and quotes, skip to next ';', then to 1st alpha. */ char *t_nextitem(){ char *p; int n; do{ skipcmqt(pvc); } while(*pvc != ';'); do{ skipcmqt(pvc); } while(!isalpha(*pvc)); n= 0; p= pvc; /* collect item chars and end with null */ while((!isspace(*p))&&(*p != '=')) item[n++]= *p++; item[n]= 0; return(item); } /* --------------------------------------------------------------------- */ /* t_getsrt() * Get parameter string following '=' and store in strbuf. * Ignore comments (skipcomt) or comments/quotes (skipcmqt), * as is relevant. String may or may not be in '"'s. * Return strbuf offset to start of string. * pvc left before ';' */ int t_getstr(){ size_t istr0; istr0= istr; /* save strbuf index */ do{ skipcmqt(pvc); } while(*pvc != '='); do{ skipcomt(pvc); } while(isspace(*pvc)); if(*pvc == '"'){ /* string has quote delim.? */ pvc++; while((*pvc!='"')||(*(pvc-1)=='\\')){ /* ignore \" */ if(istr >= istrmax) ts_exstrbuf(); /* test limit */ strbuf[istr++]= *pvc++; /* store char */ } } else{ /* no quote => no spaces */ while((*pvc!=';')&&(!isspace(*pvc))){ if(istr >= istrmax) ts_exstrbuf(); strbuf[istr++]= *pvc++; } pvc--; /* leave cursor before ';' */ } if(istr >= istrmax) ts_exstrbuf(); /* test limit */ strbuf[istr++]= 0; /* terminate string */ return((int)istr0); /* + return index */ } /* --------------------------------------------------------------------- */ /* t_getval() * Get parameter value following '=' and return the value. * pvc left at val */ int t_getval(){ do{ skipcmqt(pvc); } while(*pvc != '='); do{ skipcomt(pvc); } while(isspace(*pvc)); return(atoi(pvc)); } /* --------------------------------------------------------------------- */ /* t_skipit() * Skip comment or quoted string. Leave pvc pointer at end / or " * Called from skipcmqt/skipcomt macros */ t_skipit(){ if(*pvc == '/') do{ for(pvc++; *pvc != '/'; pvc++); } while(*(pvc-1) != '*'); else do{ for(pvc++; *pvc != '"'; pvc++); } while(*(pvc-1) == '\\'); /* ignore \" */ } /* --------------------------------------------------------------------- */ /* ts_exstrbuf() * Allocate original/extra storage space for strbuf */ ts_exstrbuf(){ static first= 1; if(first){ istrmax= (size_t)STRSIZE; if((strbuf= (char*)malloc(istrmax)) == NULL) t_err("exstrbuf: malloc"); first= 0; } else{ istrmax += (size_t)STRSIZE; if((strbuf= (char*)realloc(strbuf,istrmax)) == NULL) t_err("exstrbuf: realloc"); } } /* --------------------------------------------------------------------- */ /* t_request(promt,str) * Request information from user. Print 'promt' message and store * ascii reply in array at 'str' pointer. */ int t_request(promt,str) /* read string from stdin */ char *promt, *str;{ /* store in array at *str */ char c; fprintf(stderr,"%s",promt); /* print prompt message */ while(isspace(c=getchar())); /* skip white space */ if(c==EOF) *str= '\0'; /* NULL */ else{ ungetc(c,stdin); /* push back 1st char */ gets(str); /* store string */ } return(0); } /* ---------------------------------------------------------------------- */ /* t_keyerr() * Print error message + key chars. No exit */ t_keyerr(ps,pc) char *ps,*pc;{ int i; fprintf(stderr,"%s ",ps); for(i=0;i<2;i++) if(isprint(pc[i])) fprintf(stderr,"(%c)",pc[i]); else fprintf(stderr,"(x%x)",0377&pc[i]); fprintf(stderr,"\n"); } /* ---------------------------------------------------------------------- */ /* t_err(p) * Print error message 'p' and terminate execution. */ t_err(p) /* fatal error */ char *p;{ fprintf(stderr,"%s error\n",p); exit(1); } /* --------------------------------------------------------------------- */