URI:
       tmisc.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tmisc.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 }