diff options
Diffstat (limited to 'src/cmd/grap/misc.c')
-rw-r--r-- | src/cmd/grap/misc.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/src/cmd/grap/misc.c b/src/cmd/grap/misc.c new file mode 100644 index 00000000..7a68a692 --- /dev/null +++ b/src/cmd/grap/misc.c @@ -0,0 +1,263 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#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); +} |