683 lines · 13.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include "plot.h"#include <draw.h>#include <thread.h>#include <mouse.h>#include <keyboard.h> void	define(char*);void	call(char*);void	include(char*);int	process(Biobuf*);int	server(void); enum{	ARC,	BOX,	CALL,	CFILL,	CIRC,	CLOSEPL,	COLOR,	CSPLINE,	DEFINE,	DISK,	DSPLINE,	ERASE,	FILL,	FRAME,	FSPLINE,	GRADE,	IDLE,	INCLUDE,	LINE,	LSPLINE,	MOVE,	OPENPL,	PARABOLA,	PEN,	PAUSE,	POINT,	POLY,	RANGE,	RESTORE,	RMOVE,	RVEC,	SAVE,	SBOX,	SPLINE,	TEXT,	VEC,	LAST}; struct pcall {	char	*cc;	int	numc;} plots[] = {	[ARC] 		"a", 	1,	[BOX] 		"bo", 	2,	[CALL]		"ca",	2,	[CFILL] 	"cf", 	2,	[CIRC] 		"ci", 	2,	[CLOSEPL] 	"cl", 	2,	[COLOR] 	"co", 	2,	[CSPLINE]	"cs",	2,	[DEFINE]	"de",	2,	[DISK]		"di",	2,	[DSPLINE]	"ds",	2,	[ERASE] 	"e", 	1,	[FILL] 		"fi", 	2,	[FRAME] 	"fr", 	2,	[FSPLINE]	"fs",	2,	[GRADE] 	"g", 	1,	[IDLE] 		"id", 	2,	[INCLUDE]	"in",	2,	[LINE] 		"li", 	2,	[LSPLINE]	"ls",	2,	[MOVE] 		"m", 	1,	[OPENPL] 	"o", 	1,	[PARABOLA] 	"par", 	3,	[PEN] 		"pe", 	2,	[PAUSE] 	"pau", 	3,	[POINT] 	"poi", 	3,	[POLY] 		"pol", 	3,	[RANGE] 	"ra", 	2,	[RESTORE] 	"re", 	2,	[RMOVE] 	"rm", 	2,	[RVEC] 		"rv", 	2,	[SAVE] 		"sa", 	2,	[SBOX] 		"sb", 	2,	[SPLINE] 	"sp", 	2,	[TEXT] 		"t", 	1,	[VEC] 		"v", 	1,	[LAST]	 	0, 	0,}; struct pcall *pplots;		/* last command read */ #define MAXL 16struct fcall {	char *name;	char *stash;} flibr[MAXL];			/* define strings */ struct fcall *fptr = flibr; #define	NFSTACK	50struct fstack{	char name[128];	int peekc;	int lineno;	char *corebuf;	Biobuf *fd;	double scale;}fstack[NFSTACK];		/* stack of open input files & defines */struct fstack *fsp=fstack; #define	NARGSTR	8192char argstr[NARGSTR+1];		/* string arguments */ #define	NX	8192double x[NX];			/* numeric arguments */ #define	NPTS	256int cnt[NPTS];			/* control-polygon vertex counts */double *pts[NPTS];		/* control-polygon vertex pointers */ extern void m_swapbuf(void);	/* reaching into implementation.  ick. */extern Image *offscreen; voidresize(Point p){	int fd; 	fd = open("/dev/wctl", OWRITE);	if(fd >= 0){		fprint(fd, "resize -dx %d -dy %d", p.x+4*2, p.y+4*2);		close(fd);	}} voidresizeto(Point p){	Point s; 	s = (Point){Dx(screen->r), Dy(screen->r)};	if(eqpt(p, s))		return;	resize(p);} voideresized(int new){	if(new && getwindow(display, Refnone) < 0)		sysfatal("plot: can't reattach to window: %r");//	resizeto((Point){Dx(offscreen->r)+4, Dy(offscreen->r)+4});	m_swapbuf();} char *items[]={	"exit",	0};Menu menu={items}; voidmouseproc(void*){	void *v;	Rune r;	Alt alts[4];	Keyboardctl *k;	Mousectl *m;	Mouse mc;	enum{Amouse, Akbd, Aresize, Aend}; 	m = initmouse(nil, screen);	k = initkeyboard(nil); 	memset(alts, 0, sizeof alts);	alts[Amouse].c = m->c;	alts[Amouse].v = &mc;	alts[Amouse].op = CHANRCV; 	alts[Akbd].c = k->c;	alts[Akbd].v = &r;	alts[Akbd].op = CHANRCV; 	alts[Aresize].c = m->resizec;	alts[Aresize].v = &v;	alts[Aresize].op = CHANRCV; 	alts[Aend].op = CHANEND; 	for(;;)		switch(alt(alts)){		default:			sysfatal("mouse!");		case Amouse:			if(mc.buttons & 4) {				if(menuhit(3, m, &menu, nil) == 0)					threadexitsall("");			}			break;		case Akbd:			switch(r){			case 'q':			case Kdel:			case Keof:				threadexitsall("");			}			break;		case Aresize:			eresized(1);			;		}} voidthreadmain(int arc, char *arv[]){	char *ap;	Biobuf *bp;	int fd;	int i;	int dflag;	char *oflag; 	bp = 0;	fd = dup(0, -1);		/* because openpl will close 0! */	dflag=0;	oflag="";	argv0 = arv[0];	for(i=1;i!=arc;i++) if(arv[i][0]=='-') switch(arv[i][1]){	case 'd': dflag=1; break;	case 'o': oflag=arv[i]+2; break;	case 's': fd=server(); break;	}	openpl(oflag);	proccreate(mouseproc, nil, 32*1024);	if(dflag)		doublebuffer();	for (; arc > 1; arc--, arv++) {		if (arv[1][0] == '-') {			ap = arv[1];			ap++;			switch (*ap) {			default:				fprint(2, "%s not allowed as argument\n", ap);				exits("usage");			case 'T': break;			case 'D': break;			case 'd': break;			case 'o': break;			case 'W': break;			case 's': break;			case 'e': erase(); break;			case 'C': closepl(); break;			case 'w': ppause(); break;			case 'c': color(ap+1); break;			case 'f': cfill(ap+1); break;			case 'p': pen(ap+1); break;			case 'g': grade(atof(ap+1)); break;			}		}		else if ((bp = Bopen(arv[1], OREAD)) == 0) {			perror(arv[1]);			fprint(2, "Cannot find file %s\n", arv[1]);		}		else if(process(bp)) Bterm(fsp->fd);		else break;	}	if (bp == 0){		bp = malloc(sizeof *bp);		Binit(bp, fd, OREAD);		process(bp);	}	closepl();	flushimage(display, 1);	for(;;)		sleep(1000);}int isalpha(int c){	return ('a'<=c && c<='z') || ('A'<=c && c<='Z');}int isupper(int c){	return 'A'<=c && c<='Z';}int isdigit(int c){	return '0'<=c && c<='9';}int ispunct(int c){	return strchr("!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~", c)!=0;}int isspace(int c){	return strchr(" \t\n\v\f\r", c)!=0;}int nextc(void){	int c;	Rune r;	for(;;){		if(fsp->peekc!=Beof){			c=fsp->peekc;			fsp->peekc=Beof;			return c;		}		if(fsp->fd)			c=Bgetrune(fsp->fd);		else if(*fsp->corebuf){			fsp->corebuf+=chartorune(&r, fsp->corebuf);			c=r;		}else			c=Beof;		if(c!=Beof || fsp==fstack) break;		if(fsp->fd) Bterm(fsp->fd);		--fsp;	}	if(c=='\n') fsp->lineno++;	return c;}/* * Read a string into argstr -- ignores leading spaces * and an optional leading quote-mark */voidstrarg(void){	int c;	Rune r;	int quote=0;	char *s=argstr;	do		c=nextc();	while(c==' ' || c=='\t');	if(c=='\'' || c=='"'){		quote=c;		c=nextc();	}	r = 0;	while(c!='\n' && c!=Beof){		r=c;		s+=runetochar(s, &r);		c=nextc();	}	if(quote && s!=argstr && r==quote) --s;	*s='\0';}/* * Read a floating point number into argstr */numstring(void){	int ndp=0;	int ndig=0;	char *s=argstr;	int c=nextc();	if(c=='+' || c=='-'){		*s++=c;		c=nextc();	}	while(isdigit(c) || c=='.'){		if(s!=&argstr[NARGSTR]) *s++=c;		if(c=='.') ndp++;		else ndig++;		c=nextc();	}	if(ndp>1 || ndig==0){		fsp->peekc=c;		return 0;	}	if(c=='e' || c=='E'){		if(s!=&argstr[NARGSTR]) *s++=c;		c=nextc();		if(c=='+' || c=='-'){			if(s!=&argstr[NARGSTR]) *s++=c;			c=nextc();		}		if(!isdigit(c)){			fsp->peekc=c;			return 0;		}		while(isdigit(c)){			if(s!=&argstr[NARGSTR]) *s++=c;			c=nextc();		}	}	fsp->peekc=c;	*s='\0';	return 1;}/* * Read n numeric arguments, storing them in * x[0], ..., x[n-1] */voidnumargs(int n){	int i, c;	for(i=0;i!=n;i++){		do{			c=nextc();		}while(strchr(" \t\n", c) || c!='.' && c!='+' && c!='-' && ispunct(c));		fsp->peekc=c;		if(!numstring())			sysfatal("%s:%d: number expected", fsp->name, fsp->lineno);		x[i]=atof(argstr)*fsp->scale;	}}/* * Read a list of lists of control vertices, storing points in x[.], * pointers in pts[.] and counts in cnt[.] */voidpolyarg(void){	int nleft, l, r, c;	double **ptsp=pts, *xp=x;	int *cntp=cnt;	do{		c=nextc();	}while(c==' ' || c=='\t');	if(c=='{'){		l='{';		r='}';	}	else{		l=r='\n';		fsp->peekc=c;	}	nleft=1;	*cntp=0;	*ptsp=xp;	for(;;){		c=nextc();		if(c==r){			if(*cntp){				if(*cntp&1)					sysfatal("%s:%d: phase error", fsp->name, fsp->lineno);				*cntp/=2;				if(ptsp==&pts[NPTS])					sysfatal("%s:%d: out of polygons", fsp->name, fsp->lineno);				*++ptsp=xp;				*++cntp=0;			}			if(--nleft==0) return;		}		else switch(c){		case Beof:  return;		case ' ':  break;		case '\t': break;		case '\n': break;		case '.': case '+': case '-':		case '0': case '1': case '2': case '3': case '4':		case '5': case '6': case '7': case '8': case '9':			fsp->peekc=c;			if(!numstring())				sysfatal("%s:%d: expected number", fsp->name, fsp->lineno);			if(xp==&x[NX])				sysfatal("%s:%d: out of space", fsp->name, fsp->lineno);			*xp++=atof(argstr);			++*cntp;			break;		default:			if(c==l) nleft++;			else if(!ispunct(c)){				fsp->peekc=c;				return;			}		}	}} process(Biobuf *fd){	char *s;	int c;	fsp=fstack;	fsp->fd=fd;	fsp->corebuf=0;	fsp->peekc=Beof;	fsp->lineno=1;	fsp->scale=1.;	for(;;){		do			c=nextc();		while(c==' ' || c=='\t');		if(c==':'){			do				c=nextc();			while(c!='\n' && c!=Beof);			if(c==Beof) break;			continue;		}		while(c=='.'){			c=nextc();			if(isdigit(c)){

Lines 1–500 of 683.