#include #include #include #include #include "mp.h" #include "struct.h" #define MAXCOLUMNS 10 extern int debug; extern char *getwrd(); extern void trch(); extern int same(), numeric(); struct Plot *GetStructPlot(); /*************************************************************************** * GetDat finds numeric data in a text file and stores it in arrays. * * GetDat reads a text file whose handle is pointed to by 'fp'. In * this file are expected to be lines containing "words" [of arbitrary * length, delimited by blanks, tabs, or commas.] In each line, the first * word will be pointed to by 'wp[0]'; the user thinks of this * word as being in column 1. 'wp[1]' will point to the next word, * etc. GetDat is primarily interested in those words which look like * numbers. * * The user has assigned column numbers to the variables x, y, and e. * She wants GetDat to find all the lines which contain numbers in those * columns and save the numbers in the arrays 'x[]', 'y[]', 'e[]'. * Further, successive lines which contain numbers in the columns of * interest are to be treated as a list [possibly delimited by lines * which don't contain numbers in the columns of interest.] * Finally, the number of lists and the numbers of lines * in each list are to be saved in the data structure pointed to by the * argument 'Pict'. * * Special handling: If the column associated with 'x[]' is given as 0, * the 'x[]' array is to be filled as if the x-columns of each list * contained [0,1,2...]. If the column associated with 'e[]' is 0, the * 'e[]' array is not to be filled at all. * * Lines which begin with "*SCALFACT*" contain scale factors by which * collected data is to be multiplied. Scale factor columns map to data * columns after the keyword "*SCALFACT*" is discarded. * * Lines which begin with "*TITLE*", "*XLABEL*", and "*YLABEL*" are * interpreted as text to be stored in the structure pointed to by * 'Pict'. The keyword "*...*" and the blanks, tabs, or commas following * it are discarded. * *************************************/ #define COLUMN_OK(z) (z<0 ? TRUE : numeric(wp[z])) #define LINE_IS_DATA (COLUMN_OK(xcol) && COLUMN_OK(ycol) && COLUMN_OK(ecol)) #define DATA(z) (fact[(z)]*atoFFP(wp[(z)])) #define PLOT_OPENED (Plot->NPts && !PlotClosed) FFP fact[MAXCOLUMNS]; /* SCALE FACTORS */ short maxcol; /* LARGEST OF ARGS: XCOL, YCOL, ECOL */ char title[80], xlabel[80], ylabel[80]; /********************************************/ void GetDat(fp, xcol, ycol, ecol, terse, Pict) FILE *fp; int xcol, ycol, ecol; /* column numbers to be inspected */ int terse; /* false => echo non-numeric lines to stdout */ struct Pict *Pict; /* contains info for plotting this data */ { short i, PlotClosed = FALSE, Continued = FALSE; short xcoord = 0; char cbuf[100], *cb, *wp[MAXCOLUMNS]; struct Plot *Plot, *PrevPlot; FFP *x, *y, *e; /*** INITIALIZE ***/ /* TRANSLATE from user column numbers to array indices, FIND max */ xcol--; ycol--; ecol--; maxcol = max(xcol,max(ycol,ecol)); if (debug) printf("GetDat: x, y, e columns: %d,%d,%d\n",xcol,ycol,ecol); for (i=0; i<=maxcol; i++) fact[i] = 1.; /* init scale factors */ Pict->NPlt = 0; Pict->Plot = GetStructPlot(); Plot = Pict->Plot; x = Plot->x; y = Plot->y; e = Plot->e; /*** GET DATA ***/ /* FIND list(s) of numbers in file, GET numbers in x,y(,e) arrays */ while (cb = fgets(cbuf,100,fp)) { trch('\n',0,cb); trch('\t',' ',cbuf); trch(',',' ',cbuf); if (!KeyWord(cb,Pict)) { for (i=0; i<=maxcol; i++) wp[i] = getwrd(&cb); if (LINE_IS_DATA) { if (PlotClosed) { /* allocate, link, SET UP FOR NEW PLOT */ Plot->NextPlot = GetStructPlot(); Plot = Plot->NextPlot; x = Plot->x; y = Plot->y; e = Plot->e; PlotClosed = FALSE; xcoord = 0; } else if (Plot->NPts == MAXPOINTS) { /* allocate, link, SET UP FOR CONTINUATION OF CURRENT PLOT */ Continued = TRUE; PrevPlot = Plot; Plot->NextPlot = GetStructPlot(); Plot = Plot->NextPlot; x = Plot->x; y = Plot->y; e = Plot->e; } else if (Continued) {PrevPlot->Continued = TRUE; Continued = FALSE;} /*** PAYLOAD ***/ /* STORE data in arrays, COUNT points */ *(x++) = ( xcol>=0 ? DATA(xcol) : (FFP)(xcoord++)); *(y++) = DATA(ycol); if (ecol>=0) *(e++) = DATA(ecol); Plot->NPts++; if (debug) { printf("GetDat: x=%f, y=%f", *(x-1), *(y-1)); if (ecol>=0) printf(", e=%f", *(e-1)); printf("\n"); } } else { /* line does not contain plottable data */ if (!terse) printf("%s\n",cbuf); if (PLOT_OPENED) { Pict->NPlt++; PlotClosed = TRUE; } } } } if (PLOT_OPENED) Pict->NPlt++; return; } /******************/ int KeyWord(cb,Pict) char *cb; struct Pict *Pict; { short i; if (same(cb,"*",1)) { if (same(cb,"*SCALFACT*",10)) { (void)getwrd(&cb); for (i=0; i<=maxcol; i++) { if (debug) printf("scalfact >%s<\n", cb); fact[i] = atoFFP(getwrd(&cb)); if (debug) printf("scalfact %f\n", fact[i]); } return (TRUE); } else if (same(cb,"*TITLE*",7)) { (void)getwrd(&cb); (void)strcpy(title,cb); Pict->Title = title; return (TRUE); } else if (same(cb,"*XLABEL*",8)) { (void)getwrd(&cb); (void)strcpy(xlabel,cb); Pict->XLabel = xlabel; return (TRUE); } else if (same(cb,"*YLABEL*",8)) { (void)getwrd(&cb); (void)strcpy(ylabel,cb); Pict->YLabel = ylabel; return (TRUE); } } return (FALSE); } /*************************************************************************/ struct Remember *Key=NULL; struct Plot *GetStructPlot() { struct Plot *P; P = (struct Plot *)AllocRemember(&Key,sizeof(struct Plot),MEMF_CLEAR); P->x = (FFP *)AllocRemember(&Key,MAXPOINTS * sizeof(FFP),MEMF_CLEAR); P->y = (FFP *)AllocRemember(&Key,MAXPOINTS * sizeof(FFP),MEMF_CLEAR); P->e = (FFP *)AllocRemember(&Key,MAXPOINTS * sizeof(FFP),MEMF_CLEAR); P->xp = (short *)AllocRemember(&Key,MAXPOINTS * sizeof(short),MEMF_CLEAR); P->yp = (short *)AllocRemember(&Key,MAXPOINTS * sizeof(short),MEMF_CLEAR); P->ep = (short *)AllocRemember(&Key,MAXPOINTS * sizeof(short),MEMF_CLEAR); P->Reg = (struct PlotRegion *) AllocRemember(&Key,sizeof(struct PlotRegion),MEMF_CLEAR); if (debug) { printf("GetStructPlot: Plot=%d\n",P); printf("...Plot->x=%d, ->y=%d, ->e=%d\n",P->x,P->y,P->e); printf("...Plot->xp=%d, ->yp=%d, ->ep=%d\n",P->xp,P->yp,P->ep); printf("...Plot->Reg=%d\n",P->Reg); } return(P); } /*******************/ void FreeStructPlot() { FreeRemember(&Key,TRUE); }