# 2.11BSD#431 - /usr/src/ucb/vgrind/vgrindefs.c

##### Functions

    tgetent           X
    tgetflag          X
    tgetnum           X
    tgetstr           X
    tnamatch          X
    tnchktc           X

##### Macros

    BUFSIZ            X
    MAXHOP            X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #ifndef lint
       8: static char sccsid[] = "@(#)vgrindefs.c	5.1 (Berkeley) 6/5/85";
       9: #endif not lint
      10:
      11: #define BUFSIZ  1024
      12: #define MAXHOP  32  /* max number of tc= indirections */
      13:
      14: #include <ctype.h>
      15: /*
      16:  * grindcap - routines for dealing with the language definitions data base
      17:  *	(code stolen almost totally from termcap)
      18:  *
      19:  * BUG:		Should use a "last" pointer in tbuf, so that searching
      20:  *		for capabilities alphabetically would not be a n**2/2
      21:  *		process when large numbers of capabilities are given.
      22:  * Note:	If we add a last pointer now we will screw up the
      23:  *		tc capability. We really should compile termcap.
      24:  *
      25:  * Essentially all the work here is scanning and decoding escapes
      26:  * in string capabilities.  We don't use stdio because the editor
      27:  * doesn't, and because living w/o it is not hard.
      28:  */
      29:
      30: static  char *tbuf;
      31: static  char *filename;
      32: static  int hopcount;   /* detect infinite loops in termcap, init 0 */
      33: char    *tskip();
      34: char    *tgetstr();
      35: char    *tdecode();
      36: char    *getenv();
      37:
      38: /*
      39:  * Get an entry for terminal name in buffer bp,
      40:  * from the termcap file.  Parse is very rudimentary;
      41:  * we just notice escaped newlines.
      42:  */
      43: tgetent(bp, name, file)
      44:     char *bp, *name, *file;
      45: {
      46:     register char *cp;
      47:     register int c;
      48:     register int i = 0, cnt = 0;
      49:     char ibuf[BUFSIZ];
      50:     char *cp2;
      51:     int tf;
      52:
      53:     tbuf = bp;
      54:     tf = 0;
      55:     filename = file;
      56:     tf = open(filename, 0);
      57:     if (tf < 0)
      58:         return (-1);
      59:     for (;;) {
      60:         cp = bp;
      61:         for (;;) {
      62:             if (i == cnt) {
      63:                 cnt = read(tf, ibuf, BUFSIZ);
      64:                 if (cnt <= 0) {
      65:                     close(tf);
      66:                     return (0);
      67:                 }
      68:                 i = 0;
      69:             }
      70:             c = ibuf[i++];
      71:             if (c == '\n') {
      72:                 if (cp > bp && cp[-1] == '\\'){
      73:                     cp--;
      74:                     continue;
      75:                 }
      76:                 break;
      77:             }
      78:             if (cp >= bp+BUFSIZ) {
      79:                 write(2,"Vgrind entry too long\n", 23);
      80:                 break;
      81:             } else
      82:                 *cp++ = c;
      83:         }
      84:         *cp = 0;
      85:
      86:         /*
      87: 		 * The real work for the match.
      88: 		 */
      89:         if (tnamatch(name)) {
      90:             close(tf);
      91:             return(tnchktc());
      92:         }
      93:     }
      94: }
      95:
      96: /*
      97:  * tnchktc: check the last entry, see if it's tc=xxx. If so,
      98:  * recursively find xxx and append that entry (minus the names)
      99:  * to take the place of the tc=xxx entry. This allows termcap
     100:  * entries to say "like an HP2621 but doesn't turn on the labels".
     101:  * Note that this works because of the left to right scan.
     102:  */
     103: tnchktc()
     104: {
     105:     register char *p, *q;
     106:     char tcname[16];    /* name of similar terminal */
     107:     char tcbuf[BUFSIZ];
     108:     char *holdtbuf = tbuf;
     109:     int l;
     110:
     111:     p = tbuf + strlen(tbuf) - 2;    /* before the last colon */
     112:     while (*--p != ':')
     113:         if (p<tbuf) {
     114:             write(2, "Bad vgrind entry\n", 18);
     115:             return (0);
     116:         }
     117:     p++;
     118:     /* p now points to beginning of last field */
     119:     if (p[0] != 't' || p[1] != 'c')
     120:         return(1);
     121:     strcpy(tcname,p+3);
     122:     q = tcname;
     123:     while (q && *q != ':')
     124:         q++;
     125:     *q = 0;
     126:     if (++hopcount > MAXHOP) {
     127:         write(2, "Infinite tc= loop\n", 18);
     128:         return (0);
     129:     }
     130:     if (tgetent(tcbuf, tcname, filename) != 1)
     131:         return(0);
     132:     for (q=tcbuf; *q != ':'; q++)
     133:         ;
     134:     l = p - holdtbuf + strlen(q);
     135:     if (l > BUFSIZ) {
     136:         write(2, "Vgrind entry too long\n", 23);
     137:         q[BUFSIZ - (p-tbuf)] = 0;
     138:     }
     139:     strcpy(p, q+1);
     140:     tbuf = holdtbuf;
     141:     return(1);
     142: }
     143:
     144: /*
     145:  * Tnamatch deals with name matching.  The first field of the termcap
     146:  * entry is a sequence of names separated by |'s, so we compare
     147:  * against each such name.  The normal : terminator after the last
     148:  * name (before the first field) stops us.
     149:  */
     150: tnamatch(np)
     151:     char *np;
     152: {
     153:     register char *Np, *Bp;
     154:
     155:     Bp = tbuf;
     156:     if (*Bp == '#')
     157:         return(0);
     158:     for (;;) {
     159:         for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
     160:             continue;
     161:         if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
     162:             return (1);
     163:         while (*Bp && *Bp != ':' && *Bp != '|')
     164:             Bp++;
     165:         if (*Bp == 0 || *Bp == ':')
     166:             return (0);
     167:         Bp++;
     168:     }
     169: }
     170:
     171: /*
     172:  * Skip to the next field.  Notice that this is very dumb, not
     173:  * knowing about \: escapes or any such.  If necessary, :'s can be put
     174:  * into the termcap file in octal.
     175:  */
     176: static char *
     177: tskip(bp)
     178:     register char *bp;
     179: {
     180:
     181:     while (*bp && *bp != ':')
     182:         bp++;
     183:     if (*bp == ':')
     184:         bp++;
     185:     return (bp);
     186: }
     187:
     188: /*
     189:  * Return the (numeric) option id.
     190:  * Numeric options look like
     191:  *	li#80
     192:  * i.e. the option string is separated from the numeric value by
     193:  * a # character.  If the option is not found we return -1.
     194:  * Note that we handle octal numbers beginning with 0.
     195:  */
     196: tgetnum(id)
     197:     char *id;
     198: {
     199:     register int i, base;
     200:     register char *bp = tbuf;
     201:
     202:     for (;;) {
     203:         bp = tskip(bp);
     204:         if (*bp == 0)
     205:             return (-1);
     206:         if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
     207:             continue;
     208:         if (*bp == '@')
     209:             return(-1);
     210:         if (*bp != '#')
     211:             continue;
     212:         bp++;
     213:         base = 10;
     214:         if (*bp == '0')
     215:             base = 8;
     216:         i = 0;
     217:         while (isdigit(*bp))
     218:             i *= base, i += *bp++ - '0';
     219:         return (i);
     220:     }
     221: }
     222:
     223: /*
     224:  * Handle a flag option.
     225:  * Flag options are given "naked", i.e. followed by a : or the end
     226:  * of the buffer.  Return 1 if we find the option, or 0 if it is
     227:  * not given.
     228:  */
     229: tgetflag(id)
     230:     char *id;
     231: {
     232:     register char *bp = tbuf;
     233:
     234:     for (;;) {
     235:         bp = tskip(bp);
     236:         if (!*bp)
     237:             return (0);
     238:         if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
     239:             if (!*bp || *bp == ':')
     240:                 return (1);
     241:             else if (*bp == '@')
     242:                 return(0);
     243:         }
     244:     }
     245: }
     246:
     247: /*
     248:  * Get a string valued option.
     249:  * These are given as
     250:  *	cl=^Z
     251:  * Much decoding is done on the strings, and the strings are
     252:  * placed in area, which is a ref parameter which is updated.
     253:  * No checking on area overflow.
     254:  */
     255: char *
     256: tgetstr(id, area)
     257:     char *id, **area;
     258: {
     259:     register char *bp = tbuf;
     260:
     261:     for (;;) {
     262:         bp = tskip(bp);
     263:         if (!*bp)
     264:             return (0);
     265:         if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
     266:             continue;
     267:         if (*bp == '@')
     268:             return(0);
     269:         if (*bp != '=')
     270:             continue;
     271:         bp++;
     272:         return (tdecode(bp, area));
     273:     }
     274: }
     275:
     276: /*
     277:  * Tdecode does the grung work to decode the
     278:  * string capability escapes.
     279:  */
     280: static char *
     281: tdecode(str, area)
     282:     register char *str;
     283:     char **area;
     284: {
     285:     register char *cp;
     286:     register int c;
     287:     int i;
     288:
     289:     cp = *area;
     290:     while (c = *str++) {
     291:         if (c == ':' && *(cp-1) != '\\')
     292:         break;
     293:         *cp++ = c;
     294:     }
     295:     *cp++ = 0;
     296:     str = *area;
     297:     *area = cp;
     298:     return (str);
     299: }

#### Defined functions

tdecode defined in line 280; used 2 times

- in line 35, 272

tgetent defined in line 43; used 2 times

- in line 130
- in /usr/src/ucb/vgrind/vfontedpr.c line 200

tgetflag defined in line 229; used 2 times

- in /usr/src/ucb/vgrind/vfontedpr.c line 249-250(2)

tgetnum defined in line 196; never used
tgetstr defined in line 255; used 14 times

- in line 34
- in /usr/src/ucb/vgrind/vfontedpr.c line 39, 209, 227-247(11)

tnamatch defined in line 150; used 1 times

- in line 89

tnchktc defined in line 103; used 1 times

- in line 91

tskip defined in line 176; used 4 times

- in line 33, 203, 235, 262

#### Defined variables

filename defined in line 31; used 3 times

- in line 55-56(2), 130

hopcount defined in line 32; used 1 times

- in line 126

sccsid defined in line 8; never used
tbuf defined in line 30; used 11 times

- in line 53, 108-113(4), 137-140(2), 155, 200, 232, 259

#### Defined macros

BUFSIZ defined in line 11; used 6 times

- in line 49, 63, 78, 107, 135-137(2)

MAXHOP defined in line 12; used 1 times

- in line 126

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1413 |