mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
263 lines
5 KiB
C
263 lines
5 KiB
C
#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);
|
|
}
|