#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. Load more
#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 16 struct fcall { char *name; char *stash; } flibr[MAXL]; /* define strings */ struct fcall *fptr = flibr; #define NFSTACK 50 struct 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 8192 char argstr[NARGSTR+1]; /* string arguments */ #define NX 8192 double x[NX]; /* numeric arguments */ #define NPTS 256 int 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; void resize(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); } } void resizeto(Point p) { Point s; s = (Point){Dx(screen->r), Dy(screen->r)}; if(eqpt(p, s)) return; resize(p); } void eresized(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}; void mouseproc(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); ; } } void threadmain(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 */ void strarg(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] */ void numargs(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[.] */ void polyarg(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)){