1*48262Sbostic /*- 2*48262Sbostic * Copyright (c) 1991 The Regents of the University of California. 3*48262Sbostic * All rights reserved. 4*48262Sbostic * 5*48262Sbostic * %sccs.include.proprietary.c% 6*48262Sbostic */ 7*48262Sbostic 811779Ssam #ifndef lint 9*48262Sbostic char copyright[] = 10*48262Sbostic "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 11*48262Sbostic All rights reserved.\n"; 12*48262Sbostic #endif /* not lint */ 1311779Ssam 14*48262Sbostic #ifndef lint 15*48262Sbostic static char sccsid[] = "@(#)graph.c 4.3 (Berkeley) 04/17/91"; 16*48262Sbostic #endif /* not lint */ 17*48262Sbostic 1811778Ssam #include <stdio.h> 1911778Ssam #include <ctype.h> 2011778Ssam #include <math.h> 2111778Ssam #define INF HUGE 2211778Ssam #define F .25 2311778Ssam 2411778Ssam struct xy { 2511778Ssam int xlbf; /*flag:explicit lower bound*/ 2611778Ssam int xubf; /*flag:explicit upper bound*/ 2711778Ssam int xqf; /*flag:explicit quantum*/ 2811778Ssam double (*xf)(); /*transform function, e.g. log*/ 2911778Ssam float xa,xb; /*scaling coefficients*/ 3011778Ssam float xlb,xub; /*lower and upper bound*/ 3111778Ssam float xquant; /*quantum*/ 3211778Ssam float xoff; /*screen offset fraction*/ 3311778Ssam float xsize; /*screen fraction*/ 3411778Ssam int xbot,xtop; /*screen coords of border*/ 3511778Ssam float xmult; /*scaling constant*/ 3611778Ssam } xd,yd; 3711778Ssam struct val { 3811778Ssam float xv; 3911778Ssam float yv; 4011778Ssam int lblptr; 4111778Ssam } *xx; 4211778Ssam 4311778Ssam char *labs; 4411778Ssam int labsiz; 4511778Ssam 4611778Ssam int tick = 50; 4711778Ssam int top = 4000; 4811778Ssam int bot = 200; 4911778Ssam float absbot; 5011778Ssam int n; 5111778Ssam int erasf = 1; 5211778Ssam int gridf = 2; 5311778Ssam int symbf = 0; 5411778Ssam int absf = 0; 5511778Ssam int transf; 5611778Ssam int brkf; 5711778Ssam float dx; 5811778Ssam char *plotsymb; 5911778Ssam 6011778Ssam double atof(); 6111778Ssam #define BSIZ 80 6211778Ssam char labbuf[BSIZ]; 6311778Ssam char titlebuf[BSIZ]; 6411778Ssam 6511778Ssam char *modes[] = { 6611778Ssam "disconnected", 6711778Ssam "solid", 6811778Ssam "dotted", 6911778Ssam "dotdashed", 7011778Ssam "shortdashed", 7111778Ssam "longdashed" 7211778Ssam }; 7311778Ssam int mode = 1; 7411778Ssam char *realloc(); 7511778Ssam char *malloc(); 7611778Ssam 7711778Ssam double ident(x) 7811778Ssam double x; 7911778Ssam { 8011778Ssam return(x); 8111778Ssam } 8211778Ssam 8311778Ssam main(argc,argv) 8411778Ssam char *argv[]; 8511778Ssam { 8611778Ssam 8711778Ssam space(0,0,4096,4096); 8811778Ssam init(&xd); 8911778Ssam init(&yd); 9011778Ssam xd.xsize = yd.xsize = 1.; 9111778Ssam xx = (struct val *)malloc((unsigned)sizeof(struct val)); 9211778Ssam labs = malloc(1); 9311778Ssam labs[labsiz++] = 0; 9411778Ssam setopt(argc,argv); 9511778Ssam if(erasf) 9611778Ssam erase(); 9711778Ssam readin(); 9811778Ssam transpose(); 9911778Ssam scale(&xd,(struct val *)&xx->xv); 10011778Ssam scale(&yd,(struct val *)&xx->yv); 10111778Ssam axes(); 10211778Ssam title(); 10311778Ssam plot(); 10411778Ssam move(1,1); 10511778Ssam closevt(); 10611778Ssam return(0); 10711778Ssam } 10811778Ssam 10911778Ssam init(p) 11011778Ssam struct xy *p; 11111778Ssam { 11211778Ssam p->xf = ident; 11311778Ssam p->xmult = 1; 11411778Ssam } 11511778Ssam 11611778Ssam setopt(argc,argv) 11711778Ssam char *argv[]; 11811778Ssam { 11911778Ssam char *p1, *p2; 12011778Ssam float temp; 12111778Ssam 12211778Ssam xd.xlb = yd.xlb = INF; 12311778Ssam xd.xub = yd.xub = -INF; 12411778Ssam while(--argc > 0) { 12511778Ssam argv++; 12611778Ssam again: switch(argv[0][0]) { 12711778Ssam case '-': 12811778Ssam argv[0]++; 12911778Ssam goto again; 13011778Ssam case 'l': /* label for plot */ 13111778Ssam p1 = titlebuf; 13211778Ssam if (argc>=2) { 13311778Ssam argv++; 13411778Ssam argc--; 13511778Ssam p2 = argv[0]; 13611778Ssam while (*p1++ = *p2++); 13711778Ssam } 13811778Ssam break; 13911778Ssam 14011778Ssam case 'd': /*disconnected,obsolete option*/ 14111778Ssam case 'm': /*line mode*/ 14211778Ssam mode = 0; 14311778Ssam if(!numb(&temp,&argc,&argv)) 14411778Ssam break; 14511778Ssam if(temp>=sizeof(modes)/sizeof(*modes)) 14611778Ssam mode = 1; 14711778Ssam else if(temp>=0) 14811778Ssam mode = temp; 14911778Ssam break; 15011778Ssam 15111778Ssam case 'a': /*automatic abscissas*/ 15211778Ssam absf = 1; 15311778Ssam dx = 1; 15411778Ssam if(!numb(&dx,&argc,&argv)) 15511778Ssam break; 15611778Ssam if(numb(&absbot,&argc,&argv)) 15711778Ssam absf = 2; 15811778Ssam break; 15911778Ssam 16011778Ssam case 's': /*save screen, overlay plot*/ 16111778Ssam erasf = 0; 16211778Ssam break; 16311778Ssam 16411778Ssam case 'g': /*grid style 0 none, 1 ticks, 2 full*/ 16511778Ssam gridf = 0; 16611778Ssam if(!numb(&temp,&argc,&argv)) 16711778Ssam temp = argv[0][1]-'0'; /*for caompatibility*/ 16811778Ssam if(temp>=0&&temp<=2) 16911778Ssam gridf = temp; 17011778Ssam break; 17111778Ssam 17211778Ssam case 'c': /*character(s) for plotting*/ 17311778Ssam if(argc >= 2) { 17411778Ssam symbf = 1; 17511778Ssam plotsymb = argv[1]; 17611778Ssam argv++; 17711778Ssam argc--; 17811778Ssam } 17911778Ssam break; 18011778Ssam 18111778Ssam case 't': /*transpose*/ 18211778Ssam transf = 1; 18311778Ssam break; 18411778Ssam case 'b': /*breaks*/ 18511778Ssam brkf = 1; 18611778Ssam break; 18711778Ssam case 'x': /*x limits */ 18811778Ssam limread(&xd,&argc,&argv); 18911778Ssam break; 19011778Ssam case 'y': 19111778Ssam limread(&yd,&argc,&argv); 19211778Ssam break; 19311778Ssam case 'h': /*set height of plot */ 19411778Ssam if(!numb(&yd.xsize, &argc,&argv)) 19511778Ssam badarg(); 19611778Ssam break; 19711778Ssam case 'w': /*set width of plot */ 19811778Ssam if(!numb(&xd.xsize, &argc, &argv)) 19911778Ssam badarg(); 20011778Ssam break; 20111778Ssam case 'r': /* set offset to right */ 20211778Ssam if(!numb(&xd.xoff, &argc, &argv)) 20311778Ssam badarg(); 20411778Ssam break; 20511778Ssam case 'u': /*set offset up the screen*/ 20611778Ssam if(!numb(&yd.xoff,&argc,&argv)) 20711778Ssam badarg(); 20811778Ssam break; 20911778Ssam default: 21011778Ssam badarg(); 21111778Ssam } 21211778Ssam } 21311778Ssam } 21411778Ssam 21511778Ssam limread(p, argcp, argvp) 21611778Ssam register struct xy *p; 21711778Ssam int *argcp; 21811778Ssam char ***argvp; 21911778Ssam { 22011778Ssam if(*argcp>1 && (*argvp)[1][0]=='l') { 22111778Ssam (*argcp)--; 22211778Ssam (*argvp)++; 22311778Ssam p->xf = log10; 22411778Ssam } 22511778Ssam if(!numb(&p->xlb,argcp,argvp)) 22611778Ssam return; 22711778Ssam p->xlbf = 1; 22811778Ssam if(!numb(&p->xub,argcp,argvp)) 22911778Ssam return; 23011778Ssam p->xubf = 1; 23111778Ssam if(!numb(&p->xquant,argcp,argvp)) 23211778Ssam return; 23311778Ssam p->xqf = 1; 23411778Ssam } 23511778Ssam 23611778Ssam numb(np, argcp, argvp) 23711778Ssam int *argcp; 23811778Ssam float *np; 23911778Ssam register char ***argvp; 24011778Ssam { 24111778Ssam register char c; 24211778Ssam 24311778Ssam if(*argcp <= 1) 24411778Ssam return(0); 24511778Ssam while((c=(*argvp)[1][0]) == '+') 24611778Ssam (*argvp)[1]++; 24711778Ssam if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.')) 24811778Ssam return(0); 24911778Ssam *np = atof((*argvp)[1]); 25011778Ssam (*argcp)--; 25111778Ssam (*argvp)++; 25211778Ssam return(1); 25311778Ssam } 25411778Ssam 25511778Ssam readin() 25611778Ssam { 25711778Ssam register t; 25811778Ssam struct val *temp; 25911778Ssam 26011778Ssam if(absf==1) { 26111778Ssam if(xd.xlbf) 26211778Ssam absbot = xd.xlb; 26311778Ssam else if(xd.xf==log10) 26411778Ssam absbot = 1; 26511778Ssam } 26611778Ssam for(;;) { 26711778Ssam temp = (struct val *)realloc((char*)xx, 26811778Ssam (unsigned)(n+1)*sizeof(struct val)); 26911778Ssam if(temp==0) 27011778Ssam return; 27111778Ssam xx = temp; 27211778Ssam if(absf) 27311778Ssam xx[n].xv = n*dx + absbot; 27411778Ssam else 27511778Ssam if(!getfloat(&xx[n].xv)) 27611778Ssam return; 27711778Ssam if(!getfloat(&xx[n].yv)) 27811778Ssam return; 27911778Ssam xx[n].lblptr = -1; 28011778Ssam t = getstring(); 28111778Ssam if(t>0) 28211778Ssam xx[n].lblptr = copystring(t); 28311778Ssam n++; 28411778Ssam if(t<0) 28511778Ssam return; 28611778Ssam } 28711778Ssam } 28811778Ssam 28911778Ssam transpose() 29011778Ssam { 29111778Ssam register i; 29211778Ssam float f; 29311778Ssam struct xy t; 29411778Ssam if(!transf) 29511778Ssam return; 29611778Ssam t = xd; xd = yd; yd = t; 29711778Ssam for(i= 0;i<n;i++) { 29811778Ssam f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f; 29911778Ssam } 30011778Ssam } 30111778Ssam 30211778Ssam copystring(k) 30311778Ssam { 30411778Ssam register char *temp; 30511778Ssam register i; 30611778Ssam int q; 30711778Ssam 30811778Ssam temp = realloc(labs,(unsigned)(labsiz+1+k)); 30911778Ssam if(temp==0) 31011778Ssam return(0); 31111778Ssam labs = temp; 31211778Ssam q = labsiz; 31311778Ssam for(i=0;i<=k;i++) 31411778Ssam labs[labsiz++] = labbuf[i]; 31511778Ssam return(q); 31611778Ssam } 31711778Ssam 31811778Ssam float 31911778Ssam modceil(f,t) 32011778Ssam float f,t; 32111778Ssam { 32211778Ssam 32311778Ssam t = fabs(t); 32411778Ssam return(ceil(f/t)*t); 32511778Ssam } 32611778Ssam 32711778Ssam float 32811778Ssam modfloor(f,t) 32911778Ssam float f,t; 33011778Ssam { 33111778Ssam t = fabs(t); 33211778Ssam return(floor(f/t)*t); 33311778Ssam } 33411778Ssam 33511778Ssam getlim(p,v) 33611778Ssam register struct xy *p; 33711778Ssam struct val *v; 33811778Ssam { 33911778Ssam register i; 34011778Ssam 34111778Ssam i = 0; 34211778Ssam do { 34311778Ssam if(!p->xlbf && p->xlb>v[i].xv) 34411778Ssam p->xlb = v[i].xv; 34511778Ssam if(!p->xubf && p->xub<v[i].xv) 34611778Ssam p->xub = v[i].xv; 34711778Ssam i++; 34811778Ssam } while(i < n); 34911778Ssam } 35011778Ssam 35111778Ssam struct z { 35211778Ssam float lb,ub,mult,quant; 35311778Ssam } setloglim(), setlinlim(); 35411778Ssam 35511778Ssam setlim(p) 35611778Ssam register struct xy *p; 35711778Ssam { 35811778Ssam float t,delta,sign; 35911778Ssam struct z z; 36011778Ssam int mark[50]; 36111778Ssam float lb,ub; 36211778Ssam int lbf,ubf; 36311778Ssam 36411778Ssam lb = p->xlb; 36511778Ssam ub = p->xub; 36611778Ssam delta = ub-lb; 36711778Ssam if(p->xqf) { 36811778Ssam if(delta*p->xquant <=0 ) 36911778Ssam badarg(); 37011778Ssam return; 37111778Ssam } 37211778Ssam sign = 1; 37311778Ssam lbf = p->xlbf; 37411778Ssam ubf = p->xubf; 37511778Ssam if(delta < 0) { 37611778Ssam sign = -1; 37711778Ssam t = lb; 37811778Ssam lb = ub; 37911778Ssam ub = t; 38011778Ssam t = lbf; 38111778Ssam lbf = ubf; 38211778Ssam ubf = t; 38311778Ssam } 38411778Ssam else if(delta == 0) { 38511778Ssam if(ub > 0) { 38611778Ssam ub = 2*ub; 38711778Ssam lb = 0; 38811778Ssam } 38911778Ssam else 39011778Ssam if(lb < 0) { 39111778Ssam lb = 2*lb; 39211778Ssam ub = 0; 39311778Ssam } 39411778Ssam else { 39511778Ssam ub = 1; 39611778Ssam lb = -1; 39711778Ssam } 39811778Ssam } 39911778Ssam if(p->xf==log10 && lb>0 && ub>lb) { 40011778Ssam z = setloglim(lbf,ubf,lb,ub); 40111778Ssam p->xlb = z.lb; 40211778Ssam p->xub = z.ub; 40311778Ssam p->xmult *= z.mult; 40411778Ssam p->xquant = z.quant; 40511778Ssam if(setmark(mark,p)<2) { 40611778Ssam p->xqf = lbf = ubf = 1; 40711778Ssam lb = z.lb; ub = z.ub; 40811778Ssam } else 40911778Ssam return; 41011778Ssam } 41111778Ssam z = setlinlim(lbf,ubf,lb,ub); 41211778Ssam if(sign > 0) { 41311778Ssam p->xlb = z.lb; 41411778Ssam p->xub = z.ub; 41511778Ssam } else { 41611778Ssam p->xlb = z.ub; 41711778Ssam p->xub = z.lb; 41811778Ssam } 41911778Ssam p->xmult *= z.mult; 42011778Ssam p->xquant = sign*z.quant; 42111778Ssam } 42211778Ssam 42311778Ssam struct z 42411778Ssam setloglim(lbf,ubf,lb,ub) 42511778Ssam float lb,ub; 42611778Ssam { 42711778Ssam float r,s,t; 42811778Ssam struct z z; 42911778Ssam 43011778Ssam for(s=1; lb*s<1; s*=10) ; 43111778Ssam lb *= s; 43211778Ssam ub *= s; 43311778Ssam for(r=1; 10*r<=lb; r*=10) ; 43411778Ssam for(t=1; t<ub; t*=10) ; 43511778Ssam z.lb = !lbf ? r : lb; 43611778Ssam z.ub = !ubf ? t : ub; 43711778Ssam if(ub/lb<100) { 43811778Ssam if(!lbf) { 43911778Ssam if(lb >= 5*z.lb) 44011778Ssam z.lb *= 5; 44111778Ssam else if(lb >= 2*z.lb) 44211778Ssam z.lb *= 2; 44311778Ssam } 44411778Ssam if(!ubf) { 44511778Ssam if(ub*5 <= z.ub) 44611778Ssam z.ub /= 5; 44711778Ssam else if(ub*2 <= z.ub) 44811778Ssam z.ub /= 2; 44911778Ssam } 45011778Ssam } 45111778Ssam z.mult = s; 45211778Ssam z.quant = r; 45311778Ssam return(z); 45411778Ssam } 45511778Ssam 45611778Ssam struct z 45711778Ssam setlinlim(lbf,ubf,xlb,xub) 45811778Ssam int lbf,ubf; 45911778Ssam float xlb,xub; 46011778Ssam { 46111778Ssam struct z z; 46211778Ssam float r,s,delta; 46311778Ssam float ub,lb; 46411778Ssam 46511778Ssam loop: 46611778Ssam ub = xub; 46711778Ssam lb = xlb; 46811778Ssam delta = ub - lb; 46911778Ssam /*scale up by s, a power of 10, so range (delta) exceeds 1*/ 47011778Ssam /*find power of 10 quantum, r, such that delta/10<=r<delta*/ 47111778Ssam r = s = 1; 47211778Ssam while(delta*s < 10) 47311778Ssam s *= 10; 47411778Ssam delta *= s; 47511778Ssam while(10*r < delta) 47611778Ssam r *= 10; 47711778Ssam lb *= s; 47811778Ssam ub *= s; 47911778Ssam /*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/ 48011778Ssam if(r>=delta/2) 48111778Ssam r /= 2; 48211778Ssam else if(r<delta/5) 48311778Ssam r *= 2; 48411778Ssam z.ub = ubf? ub: modceil(ub,r); 48511778Ssam z.lb = lbf? lb: modfloor(lb,r); 48611778Ssam if(!lbf && z.lb<=r && z.lb>0) { 48711778Ssam xlb = 0; 48811778Ssam goto loop; 48911778Ssam } 49011778Ssam else if(!ubf && z.ub>=-r && z.ub<0) { 49111778Ssam xub = 0; 49211778Ssam goto loop; 49311778Ssam } 49411778Ssam z.quant = r; 49511778Ssam z.mult = s; 49611778Ssam return(z); 49711778Ssam } 49811778Ssam 49911778Ssam scale(p,v) 50011778Ssam register struct xy *p; 50111778Ssam struct val *v; 50211778Ssam { 50311778Ssam float edge; 50411778Ssam 50511778Ssam getlim(p,v); 50611778Ssam setlim(p); 50711778Ssam edge = top-bot; 50811778Ssam p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb)); 50911778Ssam p->xbot = bot + edge*p->xoff; 51011778Ssam p->xtop = p->xbot + (top-bot)*p->xsize; 51111778Ssam p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5; 51211778Ssam } 51311778Ssam 51411778Ssam axes() 51511778Ssam { 51611778Ssam register i; 51711778Ssam int mark[50]; 51811778Ssam int xn, yn; 51911778Ssam if(gridf==0) 52011778Ssam return; 52111778Ssam 52211778Ssam line(xd.xbot,yd.xbot,xd.xtop,yd.xbot); 52311778Ssam cont(xd.xtop,yd.xtop); 52411778Ssam cont(xd.xbot,yd.xtop); 52511778Ssam cont(xd.xbot,yd.xbot); 52611778Ssam 52711778Ssam xn = setmark(mark,&xd); 52811778Ssam for(i=0; i<xn; i++) { 52911778Ssam if(gridf==2) 53011778Ssam line(mark[i],yd.xbot,mark[i],yd.xtop); 53111778Ssam if(gridf==1) { 53211778Ssam line(mark[i],yd.xbot,mark[i],yd.xbot+tick); 53311778Ssam line(mark[i],yd.xtop-tick,mark[i],yd.xtop); 53411778Ssam } 53511778Ssam } 53611778Ssam yn = setmark(mark,&yd); 53711778Ssam for(i=0; i<yn; i++) { 53811778Ssam if(gridf==2) 53911778Ssam line(xd.xbot,mark[i],xd.xtop,mark[i]); 54011778Ssam if(gridf==1) { 54111778Ssam line(xd.xbot,mark[i],xd.xbot+tick,mark[i]); 54211778Ssam line(xd.xtop-tick,mark[i],xd.xtop,mark[i]); 54311778Ssam } 54411778Ssam } 54511778Ssam } 54611778Ssam 54711778Ssam setmark(xmark,p) 54811778Ssam int *xmark; 54911778Ssam register struct xy *p; 55011778Ssam { 55111778Ssam int xn = 0; 55211778Ssam float x,xl,xu; 55311778Ssam float q; 55411778Ssam if(p->xf==log10&&!p->xqf) { 55511778Ssam for(x=p->xquant; x<p->xub; x*=10) { 55611778Ssam submark(xmark,&xn,x,p); 55711778Ssam if(p->xub/p->xlb<=100) { 55811778Ssam submark(xmark,&xn,2*x,p); 55911778Ssam submark(xmark,&xn,5*x,p); 56011778Ssam } 56111778Ssam } 56211778Ssam } else { 56311778Ssam xn = 0; 56411778Ssam q = p->xquant; 56511778Ssam if(q>0) { 56611778Ssam xl = modceil(p->xlb+q/6,q); 56711778Ssam xu = modfloor(p->xub-q/6,q)+q/2; 56811778Ssam } else { 56911778Ssam xl = modceil(p->xub-q/6,q); 57011778Ssam xu = modfloor(p->xlb+q/6,q)-q/2; 57111778Ssam } 57211778Ssam for(x=xl; x<=xu; x+=fabs(p->xquant)) 57311778Ssam xmark[xn++] = (*p->xf)(x)*p->xa + p->xb; 57411778Ssam } 57511778Ssam return(xn); 57611778Ssam } 57711778Ssam submark(xmark,pxn,x,p) 57811778Ssam int *xmark; 57911778Ssam int *pxn; 58011778Ssam float x; 58111778Ssam struct xy *p; 58211778Ssam { 58311778Ssam if(1.001*p->xlb < x && .999*p->xub > x) 58411778Ssam xmark[(*pxn)++] = log10(x)*p->xa + p->xb; 58511778Ssam } 58611778Ssam 58711778Ssam plot() 58811778Ssam { 58911778Ssam int ix,iy; 59011778Ssam int i; 59111778Ssam int conn; 59211778Ssam 59311778Ssam conn = 0; 59411778Ssam if(mode!=0) 59511778Ssam linemod(modes[mode]); 59611778Ssam for(i=0; i<n; i++) { 59711778Ssam if(!conv(xx[i].xv,&xd,&ix) || 59811778Ssam !conv(xx[i].yv,&yd,&iy)) { 59911778Ssam conn = 0; 60011778Ssam continue; 60111778Ssam } 60211778Ssam if(mode!=0) { 60311778Ssam if(conn != 0) 60411778Ssam cont(ix,iy); 60511778Ssam else 60611778Ssam move(ix,iy); 60711778Ssam conn = 1; 60811778Ssam } 60911778Ssam conn &= symbol(ix,iy,xx[i].lblptr); 61011778Ssam } 61111778Ssam linemod(modes[1]); 61211778Ssam } 61311778Ssam 61411778Ssam conv(xv,p,ip) 61511778Ssam float xv; 61611778Ssam register struct xy *p; 61711778Ssam int *ip; 61811778Ssam { 61911778Ssam long ix; 62011778Ssam ix = p->xa*(*p->xf)(xv*p->xmult) + p->xb; 62111778Ssam if(ix<p->xbot || ix>p->xtop) 62211778Ssam return(0); 62311778Ssam *ip = ix; 62411778Ssam return(1); 62511778Ssam } 62611778Ssam 62711778Ssam getfloat(p) 62811778Ssam float *p; 62911778Ssam { 63011778Ssam register i; 63111778Ssam 63211778Ssam i = scanf("%f",p); 63311778Ssam return(i==1); 63411778Ssam } 63511778Ssam 63611778Ssam getstring() 63711778Ssam { 63811778Ssam register i; 63911778Ssam char junk[20]; 64011778Ssam i = scanf("%1s",labbuf); 64111778Ssam if(i==-1) 64211778Ssam return(-1); 64311778Ssam switch(*labbuf) { 64411778Ssam default: 64511778Ssam if(!isdigit(*labbuf)) { 64611778Ssam ungetc(*labbuf,stdin); 64711778Ssam i = scanf("%s",labbuf); 64811778Ssam break; 64911778Ssam } 65011778Ssam case '.': 65111778Ssam case '+': 65211778Ssam case '-': 65311778Ssam ungetc(*labbuf,stdin); 65411778Ssam return(0); 65511778Ssam case '"': 65611778Ssam i = scanf("%[^\"\n]",labbuf); 65711778Ssam scanf("%[\"]",junk); 65811778Ssam break; 65911778Ssam } 66011778Ssam if(i==-1) 66111778Ssam return(-1); 66211778Ssam return(strlen(labbuf)); 66311778Ssam } 66411778Ssam 66511778Ssam 66611778Ssam symbol(ix,iy,k) 66711778Ssam { 66811778Ssam 66911778Ssam if(symbf==0&&k<0) { 67011778Ssam if(mode==0) 67111778Ssam point(ix,iy); 67211778Ssam return(1); 67311778Ssam } 67411778Ssam else { 67511778Ssam move(ix,iy); 67611778Ssam label(k>=0?labs+k:plotsymb); 67711778Ssam move(ix,iy); 67811778Ssam return(!brkf|k<0); 67911778Ssam } 68011778Ssam } 68111778Ssam 68211778Ssam title() 68311778Ssam { 68411778Ssam move(xd.xbot,yd.xbot-60); 68511778Ssam if (titlebuf[0]) { 68611778Ssam label(titlebuf); 68711778Ssam label(" "); 68811778Ssam } 68911778Ssam if(erasf&&gridf) { 69011778Ssam axlab('x',&xd); 69111778Ssam label(" "); 69211778Ssam axlab('y',&yd); 69311778Ssam } 69411778Ssam } 69511778Ssam 69611778Ssam axlab(c,p) 69711778Ssam char c; 69811778Ssam struct xy *p; 69911778Ssam { 70011778Ssam char buf[50]; 70111778Ssam sprintf(buf,"%g -%s%c- %g", p->xlb/p->xmult, 70211778Ssam p->xf==log10?"log ":"", c, p->xub/p->xmult); 70311778Ssam label(buf); 70411778Ssam } 70511778Ssam 70611778Ssam badarg() 70711778Ssam { 70811778Ssam fprintf(stderr,"graph: error in arguments\n"); 70911778Ssam exit(1); 71011778Ssam } 711