misc.c (5080B)
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include "grap.h" 5 #include "y.tab.h" 6 7 int nnum = 0; /* number of saved numbers */ 8 double num[MAXNUM]; 9 10 int just; /* current justification mode (RJUST, etc.) */ 11 int sizeop; /* current optional operator for size change */ 12 double sizexpr; /* current size change expression */ 13 14 void savenum(int n, double f) /* save f in num[n] */ 15 { 16 num[n] = f; 17 nnum = n+1; 18 if (nnum >= MAXNUM) 19 ERROR "too many numbers" WARNING; 20 } 21 22 void setjust(int j) 23 { 24 just |= j; 25 } 26 27 void setsize(int op, double expr) 28 { 29 sizeop = op; 30 sizexpr = expr; 31 } 32 33 char *tostring(char *s) 34 { 35 register char *p; 36 37 p = malloc(strlen(s)+1); 38 if (p == NULL) 39 ERROR "out of space in tostring on %s", s FATAL; 40 strcpy(p, s); 41 return(p); 42 } 43 44 void range(Point pt) /* update the range for point pt */ 45 { 46 Obj *p = pt.obj; 47 48 if (!(p->coord & XFLAG)) { 49 if (pt.x > p->pt1.x) 50 p->pt1.x = pt.x; 51 if (pt.x < p->pt.x) 52 p->pt.x = pt.x; 53 } 54 if (!(p->coord & YFLAG)) { 55 if (pt.y > p->pt1.y) 56 p->pt1.y = pt.y; 57 if (pt.y < p->pt.y) 58 p->pt.y = pt.y; 59 } 60 } 61 62 void halfrange(Obj *p, int side, double val) /* record max and min for one direction */ 63 { 64 if (!(p->coord&XFLAG) && (side == LEFT || side == RIGHT)) { 65 if (val < p->pt.y) 66 p->pt.y = val; 67 if (val > p->pt1.y) 68 p->pt1.y = val; 69 } else if (!(p->coord&YFLAG) && (side == TOP || side == BOT)) { 70 if (val < p->pt.x) 71 p->pt.x = val; 72 if (val > p->pt1.x) 73 p->pt1.x = val; 74 } 75 } 76 77 78 Obj *lookup(char *s, int inst) /* find s in objlist, install if inst */ 79 { 80 Obj *p; 81 int found = 0; 82 83 for (p = objlist; p; p = p->next){ 84 if (strcmp(s, p->name) == 0) { 85 found = 1; 86 break; 87 } 88 } 89 if (p == NULL && inst != 0) { 90 p = (Obj *) calloc(1, sizeof(Obj)); 91 if (p == NULL) 92 ERROR "out of space in lookup" FATAL; 93 p->name = tostring(s); 94 p->type = NAME; 95 p->pt = ptmax; 96 p->pt1 = ptmin; 97 p->fval = 0.0; 98 p->next = objlist; 99 objlist = p; 100 } 101 dprintf("lookup(%s,%d) = %d\n", s, inst, found); 102 return p; 103 } 104 105 double getvar(Obj *p) /* return value of variable */ 106 { 107 return p->fval; 108 } 109 110 double setvar(Obj *p, double f) /* set value of variable to f */ 111 { 112 if (strcmp(p->name, "pointsize") == 0) { /* kludge */ 113 pointsize = f; 114 ps_set = 1; 115 } 116 p->type = VARNAME; 117 return p->fval = f; 118 } 119 120 Point makepoint(Obj *s, double x, double y) /* make a Point */ 121 { 122 Point p; 123 124 dprintf("makepoint: %s, %g,%g\n", s->name, x, y); 125 p.obj = s; 126 p.x = x; 127 p.y = y; 128 return p; 129 } 130 131 Attr *makefattr(int type, double fval) /* set double in attribute */ 132 { 133 return makeattr(type, fval, (char *) 0, 0, 0); 134 } 135 136 Attr *makesattr(char *s) /* make an Attr cell containing s */ 137 { 138 Attr *ap = makeattr(STRING, sizexpr, s, just, sizeop); 139 just = sizeop = 0; 140 sizexpr = 0.0; 141 return ap; 142 } 143 144 Attr *makeattr(int type, double fval, char *sval, int just, int op) 145 { 146 Attr *a; 147 148 a = (Attr *) malloc(sizeof(Attr)); 149 if (a == NULL) 150 ERROR "out of space in makeattr" FATAL; 151 a->type = type; 152 a->fval = fval; 153 a->sval = sval; 154 a->just = just; 155 a->op = op; 156 a->next = NULL; 157 return a; 158 } 159 160 Attr *addattr(Attr *a1, Attr *ap) /* add attr ap to end of list a1 */ 161 { 162 Attr *p; 163 164 if (a1 == 0) 165 return ap; 166 if (ap == 0) 167 return a1; 168 for (p = a1; p->next; p = p->next) 169 ; 170 p->next = ap; 171 return a1; 172 } 173 174 void freeattr(Attr *ap) /* free an attribute list */ 175 { 176 Attr *p; 177 178 while (ap) { 179 p = ap->next; /* save next */ 180 if (ap->sval) 181 free(ap->sval); 182 free((char *) ap); 183 ap = p; 184 } 185 } 186 187 char *slprint(Attr *stringlist) /* print strings from stringlist */ 188 { 189 int ntext, n, last_op, last_just; 190 double last_fval; 191 static char buf[1000]; 192 Attr *ap; 193 194 buf[0] = '\0'; 195 last_op = last_just = 0; 196 last_fval = 0.0; 197 for (ntext = 0, ap = stringlist; ap != NULL; ap = ap->next) 198 ntext++; 199 sprintf(buf, "box invis wid 0 ht %d*textht", ntext); 200 n = strlen(buf); 201 for (ap = stringlist; ap != NULL; ap = ap->next) { 202 if (ap->op == 0) { /* propagate last value */ 203 ap->op = last_op; 204 ap->fval = last_fval; 205 } else { 206 last_op = ap->op; 207 last_fval = ap->fval; 208 } 209 sprintf(buf+n, " \"%s\"", ps_set || ap->op ? sizeit(ap) : ap->sval); 210 if (ap->just) 211 last_just = ap->just; 212 if (last_just) 213 strcat(buf+n, juststr(last_just)); 214 n = strlen(buf); 215 } 216 return buf; /* watch it: static */ 217 } 218 219 char *juststr(int j) /* convert RJUST, etc., into string */ 220 { 221 static char buf[50]; 222 223 buf[0] = '\0'; 224 if (j & RJUST) 225 strcat(buf, " rjust"); 226 if (j & LJUST) 227 strcat(buf, " ljust"); 228 if (j & ABOVE) 229 strcat(buf, " above"); 230 if (j & BELOW) 231 strcat(buf, " below"); 232 return buf; /* watch it: static */ 233 } 234 235 char *sprntf(char *s, Attr *ap) /* sprintf(s, attrlist ap) */ 236 { 237 char buf[500]; 238 int n; 239 Attr *p; 240 241 for (n = 0, p = ap; p; p = p->next) 242 n++; 243 switch (n) { 244 case 0: 245 return s; 246 case 1: 247 sprintf(buf, s, ap->fval); 248 break; 249 case 2: 250 sprintf(buf, s, ap->fval, ap->next->fval); 251 break; 252 case 3: 253 sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval); 254 break; 255 case 5: 256 ERROR "too many expressions in sprintf" WARNING; 257 case 4: 258 sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval, ap->next->next->next->fval); 259 break; 260 } 261 free(s); 262 return tostring(buf); 263 }