- use the double-buffer buffer to allow redrawing on resize events.
specifing -d on the command line now only disables synchronous drawing events. - use threaded mouse and keyboard to allow for asynchronous receoption of quit messages. this allows plot to exit before drawing is completed. for programs like mapdemo, this is important. there were two things that needed to get fixed as a result - replace fprint(2, ...); exits("bad"); with sysfatal. also get rid of stdio. - dpoint needed a mach-dependentent (sic) version. otherwise points on a resized screen will not be properly placed.
This commit is contained in:
parent
05d3cc414d
commit
8ff7d518c6
7 changed files with 236 additions and 160 deletions
|
@ -1,6 +1,5 @@
|
||||||
#include "mplot.h"
|
#include "mplot.h"
|
||||||
void dpoint(double x, double y){
|
void dpoint(double x, double y){
|
||||||
draw(screen, Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1), getcolor(e1->foregr),
|
m_dpt(x, y);
|
||||||
nil, ZP);
|
|
||||||
move(x, y);
|
move(x, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,7 @@ static void polygon(int cnt[], double *pts[], Windrule w, int v){
|
||||||
edges=(Edge *)malloc(nvert*sizeof(Edge));
|
edges=(Edge *)malloc(nvert*sizeof(Edge));
|
||||||
if(edges==0){
|
if(edges==0){
|
||||||
NoSpace:
|
NoSpace:
|
||||||
fprintf(stderr, "polygon: no space\n");
|
sysfatal("polygon: no space");
|
||||||
exits("malloc failed");
|
|
||||||
}
|
}
|
||||||
ylist=(Edge **)malloc(Dy(screen->r)*sizeof(Edge *));
|
ylist=(Edge **)malloc(Dy(screen->r)*sizeof(Edge *));
|
||||||
if(ylist==0) goto NoSpace;
|
if(ylist==0) goto NoSpace;
|
||||||
|
|
|
@ -1,75 +1,102 @@
|
||||||
#include "mplot.h"
|
#include "mplot.h"
|
||||||
Image *offscreen;
|
Image *offscreen;
|
||||||
|
static int buffer;
|
||||||
|
|
||||||
|
static Point
|
||||||
|
xlp(Point p)
|
||||||
|
{
|
||||||
|
p.x += screen->r.min.x + 4 - offscreen->r.min.x;
|
||||||
|
p.y += screen->r.min.y + 4 - offscreen->r.min.y;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rectangle
|
||||||
|
xlr(Rectangle r)
|
||||||
|
{
|
||||||
|
int dx, dy;
|
||||||
|
|
||||||
|
dx = screen->r.min.x + 4 - offscreen->r.min.x;
|
||||||
|
dy = screen->r.min.y + 4 - offscreen->r.min.y;
|
||||||
|
r.min.x += dx;
|
||||||
|
r.min.y += dy;
|
||||||
|
r.max.x += dx;
|
||||||
|
r.max.y += dy;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the window from x0, y0 to x1, y1 (inclusive) to color c
|
* Clear the window from x0, y0 to x1, y1 (inclusive) to color c
|
||||||
*/
|
*/
|
||||||
void m_clrwin(int x0, int y0, int x1, int y1, int c){
|
void
|
||||||
|
m_clrwin(int x0, int y0, int x1, int y1, int c)
|
||||||
|
{
|
||||||
draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);
|
draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);
|
||||||
|
if(offscreen != screen && !buffer)
|
||||||
|
draw(screen, xlr(Rect(x0, y0, x1+1, y1+1)), getcolor(c), nil, ZP);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Draw text between pointers p and q with first character centered at x, y.
|
* Draw text between pointers p and q with first character centered at x, y.
|
||||||
* Use color c. Centered if cen is non-zero, right-justified if right is non-zero.
|
* Use color c. Centered if cen is non-zero, right-justified if right is non-zero.
|
||||||
* Returns the y coordinate for any following line of text.
|
* Returns the y coordinate for any following line of text.
|
||||||
*/
|
*/
|
||||||
int m_text(int x, int y, char *p, char *q, int c, int cen, int right){
|
int
|
||||||
|
m_text(int x, int y, char *p, char *q, int c, int cen, int right)
|
||||||
|
{
|
||||||
Point tsize;
|
Point tsize;
|
||||||
USED(c);
|
|
||||||
tsize = stringsize(font, p);
|
tsize = stringsize(font, p);
|
||||||
if(cen) x -= tsize.x/2;
|
if(cen)
|
||||||
else if(right) x -= tsize.x;
|
x -= tsize.x/2;
|
||||||
|
else if(right)
|
||||||
|
x -= tsize.x;
|
||||||
stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p);
|
stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p);
|
||||||
|
if(offscreen != screen && !buffer)
|
||||||
|
stringn(screen, xlp(Pt(x, y-tsize.y/2)), getcolor(c), ZP, font, p, q-p);
|
||||||
return y+tsize.y;
|
return y+tsize.y;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* draw point x, y
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
m_dpt(double x, double y)
|
||||||
|
{
|
||||||
|
Image *c;
|
||||||
|
|
||||||
|
c = getcolor(e1->foregr);
|
||||||
|
draw(offscreen, Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1), c, nil, ZP);
|
||||||
|
if(offscreen != screen && !buffer)
|
||||||
|
draw(screen, xlr(Rect(SCX(x), SCY(y), SCX(x)+1, SCY(y)+1)), c, nil, ZP);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw the vector from x0, y0 to x1, y1 in color c.
|
* Draw the vector from x0, y0 to x1, y1 in color c.
|
||||||
* Clipped by caller
|
* Clipped by caller
|
||||||
*/
|
*/
|
||||||
void m_vector(int x0, int y0, int x1, int y1, int c){
|
void
|
||||||
|
m_vector(int x0, int y0, int x1, int y1, int c)
|
||||||
|
{
|
||||||
line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);
|
line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);
|
||||||
}
|
if(offscreen != screen && !buffer)
|
||||||
char *scanint(char *s, int *n){
|
line(screen, xlp(Pt(x0, y0)), xlp(Pt(x1, y1)), Endsquare, Endsquare, 0, getcolor(c), ZP);
|
||||||
while(*s<'0' || '9'<*s){
|
|
||||||
if(*s=='\0'){
|
|
||||||
fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n");
|
|
||||||
exits("bad arg");
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
*n=0;
|
|
||||||
while('0'<=*s && *s<='9'){
|
|
||||||
*n=*n*10+*s-'0';
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
char *rdenv(char *name){
|
|
||||||
char *v;
|
|
||||||
int fd, size;
|
|
||||||
fd=open(name, OREAD);
|
|
||||||
if(fd<0) return 0;
|
|
||||||
size=seek(fd, 0, 2);
|
|
||||||
v=malloc(size+1);
|
|
||||||
if(v==0){
|
|
||||||
fprint(2, "Can't malloc: %r\n");
|
|
||||||
exits("no mem");
|
|
||||||
}
|
|
||||||
seek(fd, 0, 0);
|
|
||||||
read(fd, v, size);
|
|
||||||
v[size]=0;
|
|
||||||
close(fd);
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Startup initialization
|
* Startup initialization
|
||||||
*/
|
*/
|
||||||
void m_initialize(char *s){
|
void m_initialize(char*)
|
||||||
static int first=1;
|
{
|
||||||
|
static int once;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
USED(s);
|
|
||||||
if(first){
|
if(once)
|
||||||
if(initdraw(0,0,"plot") < 0)
|
return;
|
||||||
|
once = 1;
|
||||||
|
|
||||||
|
if(initdraw(nil, nil, "plot") < 0)
|
||||||
sysfatal("initdraw: %r");
|
sysfatal("initdraw: %r");
|
||||||
einit(Emouse);
|
///// einit(Emouse);
|
||||||
|
offscreen = allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1);
|
||||||
|
if(offscreen == nil)
|
||||||
|
sysfatal("Can't double buffer\n");
|
||||||
clipminx = mapminx = screen->r.min.x+4;
|
clipminx = mapminx = screen->r.min.x+4;
|
||||||
clipminy = mapminy = screen->r.min.y+4;
|
clipminy = mapminy = screen->r.min.y+4;
|
||||||
clipmaxx = mapmaxx = screen->r.max.x-5;
|
clipmaxx = mapmaxx = screen->r.max.x-5;
|
||||||
|
@ -84,31 +111,25 @@ void m_initialize(char *s){
|
||||||
mapminy += (dy-dx)/2;
|
mapminy += (dy-dx)/2;
|
||||||
mapmaxy = mapminy+dx;
|
mapmaxy = mapminy+dx;
|
||||||
}
|
}
|
||||||
first=0;
|
|
||||||
offscreen = screen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Clean up when finished
|
* Clean up when finished
|
||||||
*/
|
*/
|
||||||
void m_finish(void){
|
void m_finish(void)
|
||||||
|
{
|
||||||
m_swapbuf();
|
m_swapbuf();
|
||||||
}
|
}
|
||||||
void m_swapbuf(void){
|
void m_swapbuf(void)
|
||||||
if(offscreen!=screen)
|
{
|
||||||
draw(screen, offscreen->r, offscreen, nil, offscreen->r.min);
|
draw(screen, insetrect(screen->r, 4), offscreen, nil, offscreen->r.min);
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
}
|
}
|
||||||
void m_dblbuf(void){
|
void m_dblbuf(void)
|
||||||
if(offscreen==screen){
|
{
|
||||||
offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1);
|
buffer = 1;
|
||||||
if(offscreen==0){
|
|
||||||
fprintf(stderr, "Can't double buffer\n");
|
|
||||||
offscreen=screen;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
/*
|
||||||
/* Assume colormap entry because
|
|
||||||
* Use cache to avoid repeated allocation.
|
* Use cache to avoid repeated allocation.
|
||||||
*/
|
*/
|
||||||
struct{
|
struct{
|
||||||
|
@ -127,16 +148,14 @@ getcolor(int v)
|
||||||
return icache[j].i;
|
return icache[j].i;
|
||||||
|
|
||||||
i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v);
|
i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v);
|
||||||
if(i == nil){
|
if(i == nil)
|
||||||
fprint(2, "plot: can't allocate image for color: %r\n");
|
sysfatal("plot: can't allocate image for color: %r");
|
||||||
exits("allocimage");
|
|
||||||
}
|
|
||||||
for(j=0; j<nelem(icache); j++)
|
for(j=0; j<nelem(icache); j++)
|
||||||
if(icache[j].i == nil){
|
if(icache[j].i == nil){
|
||||||
icache[j].v = v;
|
icache[j].v = v;
|
||||||
icache[j].i = i;
|
icache[j].i = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(j == nelem(icache))sysfatal("icache: too small");
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <stdio.h>
|
//#include <stdio.h>
|
||||||
#include <draw.h>
|
#include <draw.h>
|
||||||
#include <event.h>
|
#include <event.h>
|
||||||
#define SCX(A) ((((A) - e1->xmin)*e1->scalex + e1->left)+.5)
|
#define SCX(A) ((((A) - e1->xmin)*e1->scalex + e1->left)+.5)
|
||||||
|
@ -39,6 +39,7 @@ void m_clrwin(int, int, int, int, int);
|
||||||
void m_finish(void);
|
void m_finish(void);
|
||||||
void m_initialize(char *);
|
void m_initialize(char *);
|
||||||
int m_text(int, int, char *, char *, int, int, int);
|
int m_text(int, int, char *, char *, int, int, int);
|
||||||
|
void m_dpt(double, double);
|
||||||
void m_vector(int, int, int, int, int);
|
void m_vector(int, int, int, int, int);
|
||||||
void m_swapbuf(void);
|
void m_swapbuf(void);
|
||||||
void m_dblbuf(void);
|
void m_dblbuf(void);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "mplot.h"
|
#include "mplot.h"
|
||||||
void ppause(void){
|
void ppause(void){
|
||||||
char aa[4];
|
char aa[4];
|
||||||
fflush(stdout);
|
|
||||||
read(0, aa, 4);
|
read(0, aa, 4);
|
||||||
erase();
|
erase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "mplot.h"
|
#include "mplot.h"
|
||||||
void
|
void
|
||||||
pprompt(void){
|
pprompt(void){
|
||||||
fprintf(stderr, ":");
|
fprint(2, ":");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#include <bio.h>
|
#include <bio.h>
|
||||||
#include "plot.h"
|
#include "plot.h"
|
||||||
#include <draw.h>
|
#include <draw.h>
|
||||||
#include <event.h>
|
#include <thread.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
|
||||||
void define(char*);
|
void define(char*);
|
||||||
void call(char*);
|
void call(char*);
|
||||||
|
@ -106,6 +108,7 @@ struct fcall *fptr = flibr;
|
||||||
|
|
||||||
#define NFSTACK 50
|
#define NFSTACK 50
|
||||||
struct fstack{
|
struct fstack{
|
||||||
|
char name[128];
|
||||||
int peekc;
|
int peekc;
|
||||||
int lineno;
|
int lineno;
|
||||||
char *corebuf;
|
char *corebuf;
|
||||||
|
@ -124,37 +127,123 @@ double x[NX]; /* numeric arguments */
|
||||||
int cnt[NPTS]; /* control-polygon vertex counts */
|
int cnt[NPTS]; /* control-polygon vertex counts */
|
||||||
double *pts[NPTS]; /* control-polygon vertex pointers */
|
double *pts[NPTS]; /* control-polygon vertex pointers */
|
||||||
|
|
||||||
void eresized(int new){
|
extern void m_swapbuf(void); /* reaching into implementation. ick. */
|
||||||
if(new && getwindow(display, Refnone) < 0){
|
extern Image *offscreen;
|
||||||
fprint(2, "Can't reattach to window: %r\n");
|
|
||||||
exits("resize");
|
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\n");
|
||||||
|
// resizeto((Point){Dx(offscreen->r)+4, Dy(offscreen->r)+4});
|
||||||
|
m_swapbuf();
|
||||||
|
}
|
||||||
|
|
||||||
char *items[]={
|
char *items[]={
|
||||||
"exit",
|
"exit",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
Menu menu={items};
|
Menu menu={items};
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int arc, char *arv[]){
|
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 0x7f:
|
||||||
|
case 0x04:
|
||||||
|
threadexitsall("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Aresize:
|
||||||
|
eresized(1);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
threadmain(int arc, char *arv[]){
|
||||||
char *ap;
|
char *ap;
|
||||||
Biobuf *bp;
|
Biobuf *bp;
|
||||||
int fd;
|
int fd;
|
||||||
int i;
|
int i;
|
||||||
int dflag;
|
int dflag;
|
||||||
char *oflag;
|
char *oflag;
|
||||||
Mouse m;
|
|
||||||
bp = 0;
|
bp = 0;
|
||||||
fd = dup(0, -1); /* because openpl will close 0! */
|
fd = dup(0, -1); /* because openpl will close 0! */
|
||||||
dflag=0;
|
dflag=0;
|
||||||
oflag="";
|
oflag="";
|
||||||
|
argv0 = arv[0];
|
||||||
for(i=1;i!=arc;i++) if(arv[i][0]=='-') switch(arv[i][1]){
|
for(i=1;i!=arc;i++) if(arv[i][0]=='-') switch(arv[i][1]){
|
||||||
case 'd': dflag=1; break;
|
case 'd': dflag=1; break;
|
||||||
case 'o': oflag=arv[i]+2; break;
|
case 'o': oflag=arv[i]+2; break;
|
||||||
case 's': fd=server(); break;
|
case 's': fd=server(); break;
|
||||||
}
|
}
|
||||||
openpl(oflag);
|
openpl(oflag);
|
||||||
if(dflag) doublebuffer();
|
proccreate(mouseproc, nil, 32*1024);
|
||||||
|
if(dflag)
|
||||||
|
doublebuffer();
|
||||||
for (; arc > 1; arc--, arv++) {
|
for (; arc > 1; arc--, arv++) {
|
||||||
if (arv[1][0] == '-') {
|
if (arv[1][0] == '-') {
|
||||||
ap = arv[1];
|
ap = arv[1];
|
||||||
|
@ -192,10 +281,8 @@ main(int arc, char *arv[]){
|
||||||
}
|
}
|
||||||
closepl();
|
closepl();
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
for(;;){
|
for(;;)
|
||||||
m=emouse();
|
sleep(1000);
|
||||||
if(m.buttons&4 && emenuhit(3, &m, &menu)==0) exits(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int isalpha(int c)
|
int isalpha(int c)
|
||||||
{
|
{
|
||||||
|
@ -320,10 +407,8 @@ numargs(int n){
|
||||||
c=nextc();
|
c=nextc();
|
||||||
}while(strchr(" \t\n", c) || c!='.' && c!='+' && c!='-' && ispunct(c));
|
}while(strchr(" \t\n", c) || c!='.' && c!='+' && c!='-' && ispunct(c));
|
||||||
fsp->peekc=c;
|
fsp->peekc=c;
|
||||||
if(!numstring()){
|
if(!numstring())
|
||||||
fprint(2, "line %d: number expected\n", fsp->lineno);
|
sysfatal("%s:%d: number expected\n", fsp->name, fsp->lineno);
|
||||||
exits("input error");
|
|
||||||
}
|
|
||||||
x[i]=atof(argstr)*fsp->scale;
|
x[i]=atof(argstr)*fsp->scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,17 +439,11 @@ polyarg(void){
|
||||||
c=nextc();
|
c=nextc();
|
||||||
if(c==r){
|
if(c==r){
|
||||||
if(*cntp){
|
if(*cntp){
|
||||||
if(*cntp&1){
|
if(*cntp&1)
|
||||||
fprint(2, "line %d: phase error\n",
|
sysfatal("%s:%d: phase error", fsp->name, fsp->lineno);
|
||||||
fsp->lineno);
|
|
||||||
exits("bad input");
|
|
||||||
}
|
|
||||||
*cntp/=2;
|
*cntp/=2;
|
||||||
if(ptsp==&pts[NPTS]){
|
if(ptsp==&pts[NPTS])
|
||||||
fprint(2, "line %d: out of polygons\n",
|
sysfatal("%s:%d: out of polygons", fsp->name, fsp->lineno);
|
||||||
fsp->lineno);
|
|
||||||
exits("exceeded limit");
|
|
||||||
}
|
|
||||||
*++ptsp=xp;
|
*++ptsp=xp;
|
||||||
*++cntp=0;
|
*++cntp=0;
|
||||||
}
|
}
|
||||||
|
@ -379,14 +458,10 @@ polyarg(void){
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
fsp->peekc=c;
|
fsp->peekc=c;
|
||||||
if(!numstring()){
|
if(!numstring())
|
||||||
fprint(2, "line %d: expected number\n", fsp->lineno);
|
sysfatal("%s:%d: expected number", fsp->name, fsp->lineno);
|
||||||
exits("bad input");
|
if(xp==&x[NX])
|
||||||
}
|
sysfatal("%s:%d: out of space", fsp->name, fsp->lineno);
|
||||||
if(xp==&x[NX]){
|
|
||||||
fprint(2, "line %d: out of space\n", fsp->lineno);
|
|
||||||
exits("exceeded limit");
|
|
||||||
}
|
|
||||||
*xp++=atof(argstr);
|
*xp++=atof(argstr);
|
||||||
++*cntp;
|
++*cntp;
|
||||||
break;
|
break;
|
||||||
|
@ -443,19 +518,14 @@ process(Biobuf *fd){
|
||||||
for(pplots=plots;pplots->cc;pplots++)
|
for(pplots=plots;pplots->cc;pplots++)
|
||||||
if(strncmp(argstr, pplots->cc, pplots->numc)==0)
|
if(strncmp(argstr, pplots->cc, pplots->numc)==0)
|
||||||
break;
|
break;
|
||||||
if(pplots->cc==0){
|
if(pplots->cc==0)
|
||||||
fprint(2, "line %d, %s unknown\n", fsp->lineno,
|
sysfatal("%s:%d: %s unknown", fsp->name, fsp->lineno, argstr);
|
||||||
argstr);
|
|
||||||
exits("bad command");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
fsp->peekc=c;
|
fsp->peekc=c;
|
||||||
}
|
}
|
||||||
if(!pplots){
|
if(!pplots)
|
||||||
fprint(2, "line %d, no command!\n", fsp->lineno);
|
sysfatal("%s:%d: no command\n", fsp->name, fsp->lineno);
|
||||||
exits("no command");
|
|
||||||
}
|
|
||||||
switch(pplots-plots){
|
switch(pplots-plots){
|
||||||
case ARC: numargs(7); rarc(x[0],x[1],x[2],x[3],x[4],x[5],x[6]); break;
|
case ARC: numargs(7); rarc(x[0],x[1],x[2],x[3],x[4],x[5],x[6]); break;
|
||||||
case BOX: numargs(4); box(x[0], x[1], x[2], x[3]); break;
|
case BOX: numargs(4); box(x[0], x[1], x[2], x[3]); break;
|
||||||
|
@ -494,8 +564,7 @@ process(Biobuf *fd){
|
||||||
case TEXT: strarg(); text(argstr); pplots=0; break;
|
case TEXT: strarg(); text(argstr); pplots=0; break;
|
||||||
case VEC: numargs(2); vec(x[0], x[1]); break;
|
case VEC: numargs(2); vec(x[0], x[1]); break;
|
||||||
default:
|
default:
|
||||||
fprint(2, "plot: missing case %ld\n", pplots-plots);
|
sysfatal("%s:%d: plot: missing case %ld\n", fsp->name, fsp->lineno, pplots-plots);
|
||||||
exits("internal error");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -512,10 +581,8 @@ void define(char *a){
|
||||||
int curly = 0;
|
int curly = 0;
|
||||||
ap = a;
|
ap = a;
|
||||||
while(isalpha(*ap))ap++;
|
while(isalpha(*ap))ap++;
|
||||||
if(ap == a){
|
if(ap == a)
|
||||||
fprint(2,"no name with define\n");
|
sysfatal("plot: no name with define\n");
|
||||||
exits("define");
|
|
||||||
}
|
|
||||||
i = ap - a;
|
i = ap - a;
|
||||||
if(names+i+1 > enames){
|
if(names+i+1 > enames){
|
||||||
names = malloc((unsigned)512);
|
names = malloc((unsigned)512);
|
||||||
|
@ -532,10 +599,8 @@ void define(char *a){
|
||||||
fptr->stash = nstash;
|
fptr->stash = nstash;
|
||||||
while(*ap != '{')
|
while(*ap != '{')
|
||||||
if(*ap == '\n'){
|
if(*ap == '\n'){
|
||||||
if((ap=Brdline(fsp->fd, '\n'))==0){
|
if((ap=Brdline(fsp->fd, '\n'))==0)
|
||||||
fprint(2,"unexpected end of file\n");
|
sysfatal("plot: unexpected eof");
|
||||||
exits("eof");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else ap++;
|
else ap++;
|
||||||
while((j=Bgetc(fsp->fd))!= Beof){
|
while((j=Bgetc(fsp->fd))!= Beof){
|
||||||
|
@ -549,14 +614,14 @@ void define(char *a){
|
||||||
free(bstash);
|
free(bstash);
|
||||||
size += 1024;
|
size += 1024;
|
||||||
bstash = realloc(bstash,size);
|
bstash = realloc(bstash,size);
|
||||||
|
if(bstash == nil)
|
||||||
|
sysfatal("plot: realloc: %r");
|
||||||
estash = bstash+size;
|
estash = bstash+size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*nstash++ = '\0';
|
*nstash++ = '\0';
|
||||||
if(fptr++ >= &flibr[MAXL]){
|
if(fptr++ >= &flibr[MAXL])
|
||||||
fprint(2,"Too many objects\n");
|
sysfatal("too many objects");
|
||||||
exits("too many objects");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void call(char *a){
|
void call(char *a){
|
||||||
char *ap;
|
char *ap;
|
||||||
|
@ -571,20 +636,17 @@ void call(char *a){
|
||||||
if (!(strcmp(a, f->name)))
|
if (!(strcmp(a, f->name)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(f == fptr){
|
if(f == fptr)
|
||||||
fprint(2, "object %s not defined\n",a);
|
sysfatal("plot: object %s not defined",a);
|
||||||
exits("undefined");
|
|
||||||
}
|
|
||||||
*ap = sav;
|
*ap = sav;
|
||||||
while (isspace(*ap) || *ap == ',')
|
while (isspace(*ap) || *ap == ',')
|
||||||
ap++;
|
ap++;
|
||||||
if (*ap != '\0')
|
if (*ap != '\0')
|
||||||
SC = atof(ap);
|
SC = atof(ap);
|
||||||
else SC = 1.;
|
else SC = 1.;
|
||||||
if(++fsp==&fstack[NFSTACK]){
|
if(++fsp==&fstack[NFSTACK])
|
||||||
fprint(2, "input stack overflow\n");
|
sysfatal("plot: input stack overflow");
|
||||||
exits("blew stack");
|
snprint(fsp->name, sizeof fsp->name, "call %s", f->name);
|
||||||
}
|
|
||||||
fsp->peekc=Beof;
|
fsp->peekc=Beof;
|
||||||
fsp->lineno=1;
|
fsp->lineno=1;
|
||||||
fsp->corebuf=f->stash;
|
fsp->corebuf=f->stash;
|
||||||
|
@ -594,14 +656,11 @@ void call(char *a){
|
||||||
void include(char *a){
|
void include(char *a){
|
||||||
Biobuf *fd;
|
Biobuf *fd;
|
||||||
fd=Bopen(a, OREAD);
|
fd=Bopen(a, OREAD);
|
||||||
if(fd==0){
|
if(fd==0)
|
||||||
perror(a);
|
sysfatal("plot: cant include %s: %r", a);
|
||||||
exits("can't include");
|
if(++fsp==&fstack[NFSTACK])
|
||||||
}
|
sysfatal("plot: input stack overflow");
|
||||||
if(++fsp==&fstack[NFSTACK]){
|
snprint(fsp->name, sizeof fsp->name, "%s", a);
|
||||||
fprint(2, "input stack overflow\n");
|
|
||||||
exits("blew stack");
|
|
||||||
}
|
|
||||||
fsp->peekc=Beof;
|
fsp->peekc=Beof;
|
||||||
fsp->lineno=1;
|
fsp->lineno=1;
|
||||||
fsp->corebuf=0;
|
fsp->corebuf=0;
|
||||||
|
|
Loading…
Reference in a new issue