99 struct pcall *pplots; /* last command read */
105 } flibr[MAXL]; /* define strings */
107 struct fcall *fptr = flibr;
117 }fstack[NFSTACK]; /* stack of open input files & defines */
118 struct fstack *fsp=fstack;
121 char argstr[NARGSTR+1]; /* string arguments */
124 double x[NX]; /* numeric arguments */
127 int cnt[NPTS]; /* control-polygon vertex counts */
128 double *pts[NPTS]; /* control-polygon vertex pointers */
130 extern void m_swapbuf(void); /* reaching into implementation. ick. */
131 extern Image *offscreen;
138 fd = open("/dev/wctl", OWRITE);
140 fprint(fd, "resize -dx %d -dy %d", p.x+4*2, p.y+4*2);
150 s = (Point){Dx(screen->r), Dy(screen->r)};
159 if(new && getwindow(display, Refnone) < 0)
160 sysfatal("plot: can't reattach to window: %r\n");
161 // resizeto((Point){Dx(offscreen->r)+4, Dy(offscreen->r)+4});
180 enum{Amouse, Akbd, Aresize, Aend};
182 m = initmouse(nil, screen);
183 k = initkeyboard(nil);
185 memset(alts, 0, sizeof alts);
186 alts[Amouse].c = m->c;
187 alts[Amouse].v = &mc;
188 alts[Amouse].op = CHANRCV;
192 alts[Akbd].op = CHANRCV;
194 alts[Aresize].c = m->resizec;
195 alts[Aresize].v = &v;
196 alts[Aresize].op = CHANRCV;
198 alts[Aend].op = CHANEND;
206 if(menuhit(3, m, &menu, nil) == 0)
225 threadmain(int arc, char *arv[]){
234 fd = dup(0, -1); /* because openpl will close 0! */
238 for(i=1;i!=arc;i++) if(arv[i][0]=='-') switch(arv[i][1]){
239 case 'd': dflag=1; break;
240 case 'o': oflag=arv[i]+2; break;
241 case 's': fd=server(); break;
244 proccreate(mouseproc, nil, 32*1024);
247 for (; arc > 1; arc--, arv++) {
248 if (arv[1][0] == '-') {
253 fprint(2, "%s not allowed as argument\n", ap);
261 case 'e': erase(); break;
262 case 'C': closepl(); break;
263 case 'w': ppause(); break;
264 case 'c': color(ap+1); break;
265 case 'f': cfill(ap+1); break;
266 case 'p': pen(ap+1); break;
267 case 'g': grade(atof(ap+1)); break;
270 else if ((bp = Bopen(arv[1], OREAD)) == 0) {
272 fprint(2, "Cannot find file %s\n", arv[1]);
274 else if(process(bp)) Bterm(fsp->fd);
278 bp = malloc(sizeof *bp);
279 Binit(bp, fd, OREAD);
283 flushimage(display, 1);
289 return ('a'<=c && c<='z') || ('A'<=c && c<='Z');
293 return 'A'<=c && c<='Z';
297 return '0'<=c && c<='9';
301 return strchr("!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~", c)!=0;
305 return strchr(" \t\n\v\f\r", c)!=0;
311 if(fsp->peekc!=Beof){
318 else if(*fsp->corebuf){
319 fsp->corebuf+=chartorune(&r, fsp->corebuf);
323 if(c!=Beof || fsp==fstack) break;
324 if(fsp->fd) Bterm(fsp->fd);
327 if(c=='\n') fsp->lineno++;
331 * Read a string into argstr -- ignores leading spaces
332 * and an optional leading quote-mark
342 while(c==' ' || c=='\t');
343 if(c=='\'' || c=='"'){
348 while(c!='\n' && c!=Beof){
350 s+=runetochar(s, &r);
353 if(quote && s!=argstr && r==quote) --s;
357 * Read a floating point number into argstr
364 if(c=='+' || c=='-'){
368 while(isdigit(c) || c=='.'){
369 if(s!=&argstr[NARGSTR]) *s++=c;
374 if(ndp>1 || ndig==0){
378 if(c=='e' || c=='E'){
379 if(s!=&argstr[NARGSTR]) *s++=c;
381 if(c=='+' || c=='-'){
382 if(s!=&argstr[NARGSTR]) *s++=c;
390 if(s!=&argstr[NARGSTR]) *s++=c;
399 * Read n numeric arguments, storing them in
408 }while(strchr(" \t\n", c) || c!='.' && c!='+' && c!='-' && ispunct(c));
411 sysfatal("%s:%d: number expected\n", fsp->name, fsp->lineno);
412 x[i]=atof(argstr)*fsp->scale;
416 * Read a list of lists of control vertices, storing points in x[.],
417 * pointers in pts[.] and counts in cnt[.]
422 double **ptsp=pts, *xp=x;
426 }while(c==' ' || c=='\t');
443 sysfatal("%s:%d: phase error", fsp->name, fsp->lineno);
446 sysfatal("%s:%d: out of polygons", fsp->name, fsp->lineno);
450 if(--nleft==0) return;
457 case '.': case '+': case '-':
458 case '0': case '1': case '2': case '3': case '4':
459 case '5': case '6': case '7': case '8': case '9':
462 sysfatal("%s:%d: expected number", fsp->name, fsp->lineno);
464 sysfatal("%s:%d: out of space", fsp->name, fsp->lineno);
470 else if(!ispunct(c)){
490 while(c==' ' || c=='\t');
494 while(c!='\n' && c!=Beof);
501 if(fsp->fd) Bungetc(fsp->fd);
508 if(c=='\n') continue;
512 if(isupper(c)) c=tolower(c);
513 if(s!=&argstr[NARGSTR]) *s++=c;
518 for(pplots=plots;pplots->cc;pplots++)
519 if(strncmp(argstr, pplots->cc, pplots->numc)==0)
522 sysfatal("%s:%d: %s unknown", fsp->name, fsp->lineno, argstr);
528 sysfatal("%s:%d: no command\n", fsp->name, fsp->lineno);
529 switch(pplots-plots){
530 case ARC: numargs(7); rarc(x[0],x[1],x[2],x[3],x[4],x[5],x[6]); break;
531 case BOX: numargs(4); box(x[0], x[1], x[2], x[3]); break;
532 case CALL: strarg(); call(argstr); pplots=0; break;
533 case CFILL: strarg(); cfill(argstr); pplots=0; break;
534 case CIRC: numargs(3); circ(x[0], x[1], x[2]); break;
535 case CLOSEPL: strarg(); closepl(); pplots=0; break;
536 case COLOR: strarg(); color(argstr); pplots=0; break;
537 case CSPLINE: polyarg(); splin(4, cnt, pts); break;
538 case DEFINE: strarg(); define(argstr); pplots=0; break;
539 case DISK: numargs(3); plotdisc(x[0], x[1], x[2]); break;
540 case DSPLINE: polyarg(); splin(3, cnt, pts); break;
541 case ERASE: strarg(); erase(); pplots=0; break;
542 case FILL: polyarg(); fill(cnt, pts); break;
543 case FRAME: numargs(4); frame(x[0], x[1], x[2], x[3]); break;
544 case FSPLINE: polyarg(); splin(1, cnt, pts); break;
545 case GRADE: numargs(1); grade(x[0]); break;
546 case IDLE: strarg(); idle(); pplots=0; break;
547 case INCLUDE: strarg(); include(argstr); pplots=0; break;
548 case LINE: numargs(4); plotline(x[0], x[1], x[2], x[3]); break;
549 case LSPLINE: polyarg(); splin(2, cnt, pts); break;
550 case MOVE: numargs(2); move(x[0], x[1]); break;
551 case OPENPL: strarg(); openpl(argstr); pplots=0; break;
552 case PARABOLA: numargs(6); parabola(x[0],x[1],x[2],x[3],x[4],x[5]); break;
553 case PAUSE: strarg(); ppause(); pplots=0; break;
554 case PEN: strarg(); pen(argstr); pplots=0; break;
555 case POINT: numargs(2); dpoint(x[0], x[1]); break;
556 case POLY: polyarg(); plotpoly(cnt, pts); break;
557 case RANGE: numargs(4); range(x[0], x[1], x[2], x[3]); break;
558 case RESTORE: strarg(); restore(); pplots=0; break;
559 case RMOVE: numargs(2); rmove(x[0], x[1]); break;
560 case RVEC: numargs(2); rvec(x[0], x[1]); break;
561 case SAVE: strarg(); save(); pplots=0; break;
562 case SBOX: numargs(4); sbox(x[0], x[1], x[2], x[3]); break;
563 case SPLINE: polyarg(); splin(0, cnt, pts); break;
564 case TEXT: strarg(); text(argstr); pplots=0; break;
565 case VEC: numargs(2); vec(x[0], x[1]); break;
567 sysfatal("%s:%d: plot: missing case %ld\n", fsp->name, fsp->lineno, pplots-plots);
576 unsigned size = 1024;
578 void define(char *a){
583 while(isalpha(*ap))ap++;
585 sysfatal("plot: no name with define\n");
587 if(names+i+1 > enames){
588 names = malloc((unsigned)512);
589 enames = names + 512;
596 bstash = nstash = malloc(size);
597 estash = bstash + size;
599 fptr->stash = nstash;
602 if((ap=Brdline(fsp->fd, '\n'))==0)
603 sysfatal("plot: unexpected eof");
606 while((j=Bgetc(fsp->fd))!= Beof){
613 if(nstash == estash){
616 bstash = realloc(bstash,size);
618 sysfatal("plot: realloc: %r");
619 estash = bstash+size;
623 if(fptr++ >= &flibr[MAXL])
624 sysfatal("too many objects");
632 while(isalpha(*ap))ap++;
635 for(f=flibr;f<fptr;f++){
636 if (!(strcmp(a, f->name)))
640 sysfatal("plot: object %s not defined",a);
642 while (isspace(*ap) || *ap == ',')
647 if(++fsp==&fstack[NFSTACK])
648 sysfatal("plot: input stack overflow");
649 snprint(fsp->name, sizeof fsp->name, "call %s", f->name);
652 fsp->corebuf=f->stash;
654 fsp->scale=fsp[-1].scale*SC;
656 void include(char *a){
660 sysfatal("plot: cant include %s: %r", a);
661 if(++fsp==&fstack[NFSTACK])
662 sysfatal("plot: input stack overflow");
663 snprint(fsp->name, sizeof fsp->name, "%s", a);
676 fd = create("/srv/plot", 1, 0666);
677 sprint(buf, "%d", p[1]);
678 write(fd, buf, strlen(buf));