/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include #include #include #include "grap.h" #include "y.tab.h" int nnum = 0; /* number of saved numbers */ double num[MAXNUM]; int just; /* current justification mode (RJUST, etc.) */ int sizeop; /* current optional operator for size change */ double sizexpr; /* current size change expression */ void savenum(int n, double f) /* save f in num[n] */ { num[n] = f; nnum = n+1; if (nnum >= MAXNUM) ERROR "too many numbers" WARNING; } void setjust(int j) { just |= j; } void setsize(int op, double expr) { sizeop = op; sizexpr = expr; } char *tostring(char *s) { register char *p; p = malloc(strlen(s)+1); if (p == NULL) ERROR "out of space in tostring on %s", s FATAL; strcpy(p, s); return(p); } void range(Point pt) /* update the range for point pt */ { Obj *p = pt.obj; if (!(p->coord & XFLAG)) { if (pt.x > p->pt1.x) p->pt1.x = pt.x; if (pt.x < p->pt.x) p->pt.x = pt.x; } if (!(p->coord & YFLAG)) { if (pt.y > p->pt1.y) p->pt1.y = pt.y; if (pt.y < p->pt.y) p->pt.y = pt.y; } } void halfrange(Obj *p, int side, double val) /* record max and min for one direction */ { if (!(p->coord&XFLAG) && (side == LEFT || side == RIGHT)) { if (val < p->pt.y) p->pt.y = val; if (val > p->pt1.y) p->pt1.y = val; } else if (!(p->coord&YFLAG) && (side == TOP || side == BOT)) { if (val < p->pt.x) p->pt.x = val; if (val > p->pt1.x) p->pt1.x = val; } } Obj *lookup(char *s, int inst) /* find s in objlist, install if inst */ { Obj *p; int found = 0; for (p = objlist; p; p = p->next){ if (strcmp(s, p->name) == 0) { found = 1; break; } } if (p == NULL && inst != 0) { p = (Obj *) calloc(1, sizeof(Obj)); if (p == NULL) ERROR "out of space in lookup" FATAL; p->name = tostring(s); p->type = NAME; p->pt = ptmax; p->pt1 = ptmin; p->fval = 0.0; p->next = objlist; objlist = p; } dprintf("lookup(%s,%d) = %d\n", s, inst, found); return p; } double getvar(Obj *p) /* return value of variable */ { return p->fval; } double setvar(Obj *p, double f) /* set value of variable to f */ { if (strcmp(p->name, "pointsize") == 0) { /* kludge */ pointsize = f; ps_set = 1; } p->type = VARNAME; return p->fval = f; } Point makepoint(Obj *s, double x, double y) /* make a Point */ { Point p; dprintf("makepoint: %s, %g,%g\n", s->name, x, y); p.obj = s; p.x = x; p.y = y; return p; } Attr *makefattr(int type, double fval) /* set double in attribute */ { return makeattr(type, fval, (char *) 0, 0, 0); } Attr *makesattr(char *s) /* make an Attr cell containing s */ { Attr *ap = makeattr(STRING, sizexpr, s, just, sizeop); just = sizeop = 0; sizexpr = 0.0; return ap; } Attr *makeattr(int type, double fval, char *sval, int just, int op) { Attr *a; a = (Attr *) malloc(sizeof(Attr)); if (a == NULL) ERROR "out of space in makeattr" FATAL; a->type = type; a->fval = fval; a->sval = sval; a->just = just; a->op = op; a->next = NULL; return a; } Attr *addattr(Attr *a1, Attr *ap) /* add attr ap to end of list a1 */ { Attr *p; if (a1 == 0) return ap; if (ap == 0) return a1; for (p = a1; p->next; p = p->next) ; p->next = ap; return a1; } void freeattr(Attr *ap) /* free an attribute list */ { Attr *p; while (ap) { p = ap->next; /* save next */ if (ap->sval) free(ap->sval); free((char *) ap); ap = p; } } char *slprint(Attr *stringlist) /* print strings from stringlist */ { int ntext, n, last_op, last_just; double last_fval; static char buf[1000]; Attr *ap; buf[0] = '\0'; last_op = last_just = 0; last_fval = 0.0; for (ntext = 0, ap = stringlist; ap != NULL; ap = ap->next) ntext++; sprintf(buf, "box invis wid 0 ht %d*textht", ntext); n = strlen(buf); for (ap = stringlist; ap != NULL; ap = ap->next) { if (ap->op == 0) { /* propagate last value */ ap->op = last_op; ap->fval = last_fval; } else { last_op = ap->op; last_fval = ap->fval; } sprintf(buf+n, " \"%s\"", ps_set || ap->op ? sizeit(ap) : ap->sval); if (ap->just) last_just = ap->just; if (last_just) strcat(buf+n, juststr(last_just)); n = strlen(buf); } return buf; /* watch it: static */ } char *juststr(int j) /* convert RJUST, etc., into string */ { static char buf[50]; buf[0] = '\0'; if (j & RJUST) strcat(buf, " rjust"); if (j & LJUST) strcat(buf, " ljust"); if (j & ABOVE) strcat(buf, " above"); if (j & BELOW) strcat(buf, " below"); return buf; /* watch it: static */ } char *sprntf(char *s, Attr *ap) /* sprintf(s, attrlist ap) */ { char buf[500]; int n; Attr *p; for (n = 0, p = ap; p; p = p->next) n++; switch (n) { case 0: return s; case 1: sprintf(buf, s, ap->fval); break; case 2: sprintf(buf, s, ap->fval, ap->next->fval); break; case 3: sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval); break; case 5: ERROR "too many expressions in sprintf" WARNING; case 4: sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval, ap->next->next->next->fval); break; } free(s); return tostring(buf); }