home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / CV / TRANS.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  6KB  |  299 lines

  1. /* Copyright (c) 1990 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)trans.c 2.1 11/12/91 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Translator utilities
  9.  *
  10.  *    Greg Ward
  11.  */
  12.  
  13. #include <stdio.h>
  14.  
  15. #include "trans.h"
  16.  
  17.  
  18. fgetid(idp, dls, fp)        /* read an id up to char in dls from fp */
  19. ID    *idp;
  20. char    *dls;
  21. register FILE    *fp;
  22. {
  23.     char    dset[256/8];
  24.     char    buf[MAXSTR];
  25.     register int    c;
  26.     register char    *cp;
  27.                     /* create delimiter set */
  28.     for (cp = dset+sizeof(dset); cp-- > dset; )
  29.         *cp = 0;
  30.     for (cp = dls; *cp; cp++)
  31.         dset[*cp>>3] |= 1<<(*cp&7);
  32.                     /* get characters up to delimiter */
  33.     cp = buf;
  34.     while ((c = getc(fp)) != EOF && !(dset[c>>3] & 1<<(c&7)))
  35.         *cp++ = c;
  36.                     /* check for empty */
  37.     if (cp == buf) {
  38.         if (c == EOF)
  39.             return(EOF);
  40.         idp->number = 0;
  41.         idp->name = NULL;
  42.         return(0);
  43.     }
  44.                     /* truncate space at end */
  45.     while (cp[-1] == ' ' || cp[-1] == '\t')
  46.         cp--;
  47.     *cp = '\0';
  48.                     /* skip white space at beginning */
  49.     for (cp = buf; *cp && (*cp == ' ' || *cp == '\t'); cp++)
  50.         ;
  51.                     /* assign value */
  52.     idp->number = atoi(cp);
  53.     idp->name = NULL;
  54.                     /* check for ghost string */
  55.     if (!*cp)
  56.         return(0);
  57.                     /* check for name */
  58.     if (idp->number == 0 && *cp != '0')
  59.         idp->name = savestr(cp);
  60.     return(0);
  61. }
  62.  
  63.  
  64. int
  65. findid(idl, idp, insert)        /* find (or insert) id in list */
  66. register IDLIST    *idl;
  67. ID    *idp;
  68. int    insert;
  69. {
  70.     int  upper, lower;
  71.     register int  cm, i;
  72.                     /* binary search */
  73.     lower = 0;
  74.     upper = cm = idl->nids;
  75.     while ((i = (lower + upper) >> 1) != cm) {
  76.         cm = idcmp(idp, &idl->id[i]);
  77.         if (cm > 0)
  78.             lower = i;
  79.         else if (cm < 0)
  80.             upper = i;
  81.         else
  82.             return(i);
  83.         cm = i;
  84.     }
  85.     if (!insert)
  86.             return(-1);
  87.         if (idl->nids == 0) {            /* create new list */
  88.             idl->id = (ID *)malloc(sizeof(ID));
  89.             if (idl->id == NULL)
  90.                 goto memerr;
  91.         } else {                /* grow old list */
  92.             idl->id = (ID *)realloc((char *)idl->id,(idl->nids+1)*sizeof(ID));
  93.             if (idl->id == NULL)
  94.                 goto memerr;
  95.             for (i = idl->nids; i > upper; i--) {
  96.                 idl->id[i].number = idl->id[i-1].number;
  97.                 idl->id[i].name = idl->id[i-1].name;
  98.             }
  99.         }
  100.         idl->nids++;                /* insert new element */
  101.     idl->id[i].number = idp->number;
  102.         if (idp->name == NULL)
  103.             idl->id[i].name = NULL;
  104.         else
  105.             idl->id[i].name = savestr(idp->name);
  106.     return(i);
  107. memerr:
  108.     eputs("Out of memory in findid\n");
  109.     quit(1);
  110. }
  111.  
  112.  
  113. int
  114. idcmp(id1, id2)                /* compare two identifiers */
  115. register ID    *id1, *id2;
  116. {
  117.                     /* names are greater than numbers */
  118.     if (id1->name == NULL)
  119.         if (id2->name == NULL)
  120.             return(id1->number - id2->number);
  121.         else
  122.             return(-1);
  123.     else
  124.         if (id2->name == NULL)
  125.             return(1);
  126.         else
  127.             return(strcmp(id1->name, id2->name));
  128. }
  129.  
  130.  
  131. write_quals(qlp, idl, fp)    /* write out qualifier lists */
  132. QLIST    *qlp;
  133. IDLIST    idl[];
  134. FILE    *fp;
  135. {
  136.     int    i;
  137.     
  138.     for (i = 0; i < qlp->nquals; i++)
  139.         if (idl[i].nids > 0) {
  140.             fprintf(fp, "qualifier %s begin\n", qlp->qual[i]);
  141.             fputidlist(&idl[i], fp);
  142.             fprintf(fp, "end\n");
  143.         }
  144. }
  145.  
  146.  
  147. fputidlist(qp, fp)        /* put id list out to fp */
  148. IDLIST    *qp;
  149. FILE    *fp;
  150. {
  151.     int    fi;
  152.     register int    i;
  153.                     /* print numbers/ranges */
  154.     fi = 0;
  155.     for (i = 0; i < qp->nids && qp->id[i].name == NULL; i++)
  156.         if (i > 0 && qp->id[i].number > qp->id[i-1].number+1) {
  157.             if (i > fi+1)
  158.                 fprintf(fp, "[%d:%d]\n", qp->id[fi].number,
  159.                         qp->id[i-1].number);
  160.             else
  161.                 fprintf(fp, "%d\n", qp->id[fi].number);
  162.             fi = i;
  163.         }
  164.     if (i-1 > fi)
  165.         fprintf(fp, "[%d:%d]\n", qp->id[fi].number,
  166.                 qp->id[i-1].number);
  167.     else if (i > 0)
  168.         fprintf(fp, "%d\n", qp->id[fi].number);
  169.     for ( ; i < qp->nids; i++)
  170.         fprintf(fp, "\"%s\"\n", qp->id[i].name);
  171. }
  172.  
  173.  
  174. RULEHD *
  175. getmapping(file, qlp)        /* read in mapping file */
  176. char    *file;
  177. QLIST    *qlp;
  178. {
  179.     char    *err;
  180.     register int    c;
  181.     RULEHD    *mp = NULL;
  182.     int    nrules = 0;
  183.     register RULEHD    *rp;
  184.     register int    qt;
  185.     char    buf[MAXSTR];
  186.     FILE    *fp;
  187.     
  188.     if ((fp = fopen(file, "r")) == NULL) {
  189.         eputs(file);
  190.         eputs(": cannot open\n");
  191.         quit(1);
  192.     }
  193.                             /* get each rule */
  194.     while (fscanf(fp, " %[^     ;\n]", buf) == 1) {
  195.         if (buf[0] == '#') {            /* comment */
  196.             while ((c = getc(fp)) != EOF && c != '\n')
  197.                 ;
  198.             continue;
  199.         }
  200.         rp = (RULEHD *)calloc(1, rulsiz(qlp->nquals));
  201.         if (rp == NULL)
  202.             goto memerr;
  203.         rp->mnam = savestr(buf);
  204.         for ( ; ; ) {                /* get conditions */
  205.             while ((c = getc(fp)) != '(')
  206.                 if (c == ';' || c == EOF)
  207.                     goto endloop;
  208.             if (fscanf(fp, " %s ", buf) != 1) {
  209.                 err = "missing variable";
  210.                 goto fmterr;
  211.             }
  212.             if ((qt = qtype(buf, qlp)) == -1) {
  213.                 err = "unknown variable";
  214.                 goto fmterr;
  215.             }
  216.             if (rp->qflg & FL(qt)) {
  217.                 err = "variable repeated";
  218.                 goto fmterr;
  219.             }
  220.             rp->qflg |= FL(qt);
  221.             c = getc(fp);
  222.             switch (c) {
  223.             case '"':            /* id name */
  224.                 if (fscanf(fp, "%[^\"]\" )", buf) != 1) {
  225.                     err = "bad string value";
  226.                     goto fmterr;
  227.                 }
  228.                 idm(rp)[qt].nam = savestr(buf);
  229.                 break;
  230.             case '[':            /* id range */
  231.                 if (fscanf(fp, "%d : %d ] )", &idm(rp)[qt].min,
  232.                         &idm(rp)[qt].max) != 2) {
  233.                     err = "bad range value";
  234.                     goto fmterr;
  235.                 }
  236.                 if (idm(rp)[qt].min > idm(rp)[qt].max) {
  237.                     err = "reverse range value";
  238.                     goto fmterr;
  239.                 }
  240.                 break;
  241.             default:            /* id number? */
  242.                 if ((c < '0' || c > '9') && c != '-') {
  243.                     err = "unrecognizable value";
  244.                     goto fmterr;
  245.                 }
  246.                 ungetc(c, fp);
  247.                 if (fscanf(fp, "%d )", &idm(rp)[qt].min) != 1) {
  248.                     err = "bad number id";
  249.                     goto fmterr;
  250.                 }
  251.                 idm(rp)[qt].max = idm(rp)[qt].min;
  252.                 break;
  253.             }
  254.         }
  255.     endloop:
  256.         rp->next = mp;
  257.         mp = rp;
  258.         nrules++;
  259.     }
  260.     fclose(fp);
  261.     return(mp);
  262. fmterr:
  263.     sprintf(buf, "%s: %s for rule %d\n", file, err, nrules+1);
  264.     eputs(buf);
  265.     quit(1);
  266. memerr:
  267.     eputs("Out of memory in getmapping\n");
  268.     quit(1);
  269. }
  270.  
  271.  
  272. int
  273. qtype(qnm, qlp)            /* return number for qualifier name */
  274. char    *qnm;
  275. register QLIST    *qlp;
  276. {
  277.     register int    i;
  278.     
  279.     for (i = 0; i < qlp->nquals; i++)
  280.         if (!strcmp(qnm, qlp->qual[i]))
  281.             return(i);
  282.     return(-1);
  283. }
  284.  
  285.  
  286. matchid(it, im)            /* see if we match an id */
  287. register ID    *it;
  288. register IDMATCH    *im;
  289. {
  290.     if (it->name == NULL) {
  291.         if (im->nam != NULL)
  292.             return(0);
  293.         return(it->number >= im->min && it->number <= im->max);
  294.     }
  295.     if (im->nam == NULL)
  296.         return(0);
  297.     return(!strcmp(it->name, im->nam));
  298. }
  299.