Rewrote to use getcap(3) routines.
authorElan Amir <elan@ucbvax.Berkeley.EDU>
Wed, 2 Sep 1992 02:42:29 +0000 (18:42 -0800)
committerElan Amir <elan@ucbvax.Berkeley.EDU>
Wed, 2 Sep 1992 02:42:29 +0000 (18:42 -0800)
SCCS-vsn: lib/libterm/termcap.c 5.7

usr/src/lib/libterm/termcap.c

index 6245c98..63c7a05 100644 (file)
@@ -2,20 +2,46 @@
  * Copyright (c) 1980 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1980 The Regents of the University of California.
  * All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)termcap.c  5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)termcap.c  5.7 (Berkeley) 8/6/92";
 #endif /* not lint */
 
 #endif /* not lint */
 
-#define        BUFSIZ          1024
-#define MAXHOP         32      /* max number of tc= indirections */
 #define        PBUFSIZ         512     /* max length of filename path */
 #define        PVECSIZ         32      /* max number of names in path */
 
 #define        PBUFSIZ         512     /* max length of filename path */
 #define        PVECSIZ         32      /* max number of names in path */
 
+#include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <string.h>
 #include "pathnames.h"
 
 /*
 #include "pathnames.h"
 
 /*
@@ -32,27 +58,27 @@ static char sccsid[] = "@(#)termcap.c       5.6 (Berkeley) %G%";
  * doesn't, and because living w/o it is not hard.
  */
 
  * doesn't, and because living w/o it is not hard.
  */
 
-static char *tbuf;
-static int hopcount;   /* detect infinite loops in termcap, init 0 */
-static char pathbuf[PBUFSIZ];          /* holds raw path of filenames */
-static char *pathvec[PVECSIZ];         /* to point to names in pathbuf */
-static char **pvec;                    /* holds usable tail of path vector */
-
-static char *tdecode __P((char *, char **));
-static char *tskip __P ((char *));
+static char *tbuf;     /* termcap buffer */
 
 /*
  * Get an entry for terminal name in buffer bp from the termcap file.
  */
 
 /*
  * Get an entry for terminal name in buffer bp from the termcap file.
  */
+int
 tgetent(bp, name)
        char *bp, *name;
 {
        register char *p;
        register char *cp;
 tgetent(bp, name)
        char *bp, *name;
 {
        register char *p;
        register char *cp;
-       register int c;
-       char *term, *home, *termpath;
-       char **fname = pathvec;
-
+       char  *dummy;
+       char **fname;
+       char  *home;
+       int    i;
+       char   pathbuf[PBUFSIZ];        /* holds raw path of filenames */
+       char  *pathvec[PVECSIZ];        /* to point to names in pathbuf */
+       char **pvec;                    /* holds usable tail of path vector */
+       char  *termpath;
+
+       fname = pathvec;
        pvec = pathvec;
        tbuf = bp;
        p = pathbuf;
        pvec = pathvec;
        tbuf = bp;
        p = pathbuf;
@@ -98,176 +124,21 @@ tgetent(bp, name)
                        }
                }
        *fname = (char *) 0;                    /* mark end of vector */
                        }
                }
        *fname = (char *) 0;                    /* mark end of vector */
-       if (cp && *cp && *cp != '/') {
-               tbuf = cp;
-               c = tnamatch(name);
-               tbuf = bp;
-               if (c) {
-                       strcpy(bp,cp);
-                       return (tnchktc());
-               }
-       }
-       return (tfindent(bp, name));    /* find terminal entry in path */
-}
-
-/*
- * tfindent - reads through the list of files in pathvec as if they were one
- * continuous file searching for terminal entries along the way.  It will
- * participate in indirect recursion if the call to tnchktc() finds a tc=
- * field, which is only searched for in the current file and files ocurring
- * after it in pathvec.  The usable part of this vector is kept in the global
- * variable pvec.  Terminal entries may not be broken across files.  Parse is
- * very rudimentary; we just notice escaped newlines.
- */
-tfindent(bp, name)
-       char *bp, *name;
-{
-       register char *cp;
-       register int c;
-       register int i, cnt;
-       char ibuf[BUFSIZ];
-       int opencnt = 0;
-       int tf;
-
-       tbuf = bp;
-nextfile:
-       i = cnt = 0;
-       while (*pvec && (tf = open(*pvec, 0)) < 0)
-               pvec++;
-       if (!*pvec)
-               return (opencnt ? 0 : -1);
-       opencnt++;
-       for (;;) {
-               cp = bp;
-               for (;;) {
-                       if (i == cnt) {
-                               cnt = read(tf, ibuf, BUFSIZ);
-                               if (cnt <= 0) {
-                                       close(tf);
-                                       pvec++;
-                                       goto nextfile;
-                               }
-                               i = 0;
-                       }
-                       c = ibuf[i++];
-                       if (c == '\n') {
-                               if (cp > bp && cp[-1] == '\\'){
-                                       cp--;
-                                       continue;
-                               }
-                               break;
-                       }
-                       if (cp >= bp+BUFSIZ) {
-                               write(2,"Termcap entry too long\n", 23);
-                               break;
-                       } else
-                               *cp++ = c;
-               }
-               *cp = 0;
-
-               /*
-                * The real work for the match.
-                */
-               if (tnamatch(name)) {
-                       close(tf);
-                       return(tnchktc());
-               }
-       }
-}
-
-/*
- * tnchktc: check the last entry, see if it's tc=xxx. If so,
- * recursively find xxx and append that entry (minus the names)
- * to take the place of the tc=xxx entry. This allows termcap
- * entries to say "like an HP2621 but doesn't turn on the labels".
- * Note that this works because of the left to right scan.
- */
-tnchktc()
-{
-       register char *p, *q;
-       char tcname[16];        /* name of similar terminal */
-       char tcbuf[BUFSIZ];
-       char *holdtbuf = tbuf;
-       int l;
-
-       p = tbuf + strlen(tbuf) - 2;    /* before the last colon */
-       while (*--p != ':')
-               if (p<tbuf) {
-                       write(2, "Bad termcap entry\n", 18);
-                       return (0);
-               }
-       p++;
-       /* p now points to beginning of last field */
-       if (p[0] != 't' || p[1] != 'c')
-               return(1);
-       strcpy(tcname,p+3);
-       q = tcname;
-       while (*q && *q != ':')
-               q++;
-       *q = 0;
-       if (++hopcount > MAXHOP) {
-               write(2, "Infinite tc= loop\n", 18);
-               return (0);
-       }
-       if (tfindent(tcbuf, tcname) != 1) {
-               hopcount = 0;           /* unwind recursion */
-               return(0);
-       }
-       for (q=tcbuf; *q != ':'; q++)
-               ;
-       l = p - holdtbuf + strlen(q);
-       if (l > BUFSIZ) {
-               write(2, "Termcap entry too long\n", 23);
-               q[BUFSIZ - (p-tbuf)] = 0;
-       }
-       strcpy(p, q+1);
-       tbuf = holdtbuf;
-       hopcount = 0;                   /* unwind recursion */
-       return(1);
-}
-
-/*
- * Tnamatch deals with name matching.  The first field of the termcap
- * entry is a sequence of names separated by |'s, so we compare
- * against each such name.  The normal : terminator after the last
- * name (before the first field) stops us.
- */
-tnamatch(np)
-       char *np;
-{
-       register char *Np, *Bp;
-
-       Bp = tbuf;
-       if (*Bp == '#')
-               return(0);
-       for (;;) {
-               for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
-                       continue;
-               if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
-                       return (1);
-               while (*Bp && *Bp != ':' && *Bp != '|')
-                       Bp++;
-               if (*Bp == 0 || *Bp == ':')
-                       return (0);
-               Bp++;
-       }
-}
-
-/*
- * Skip to the next field.  Notice that this is very dumb, not
- * knowing about \: escapes or any such.  If necessary, :'s can be put
- * into the termcap file in octal.
- */
-static char *
-tskip(bp)
-       register char *bp;
-{
-
-       while (*bp && *bp != ':')
-               bp++;
-       if (*bp == ':')
-               bp++;
-       return (bp);
+       if (cp && *cp && *cp != '/')
+               if (cgetset(cp) < 0)
+                       return(-2);
+
+       i = cgetent(&dummy, pathvec, name);      
+       
+       if (i == 0)
+               strcpy(bp, dummy);
+       
+       if (dummy)
+               free(dummy);
+       /* no tc reference loop return code in libterm XXX */
+       if (i == -3)
+               return(-1);
+       return(i + 1);
 }
 
 /*
 }
 
 /*
@@ -278,31 +149,16 @@ tskip(bp)
  * a # character.  If the option is not found we return -1.
  * Note that we handle octal numbers beginning with 0.
  */
  * a # character.  If the option is not found we return -1.
  * Note that we handle octal numbers beginning with 0.
  */
+int
 tgetnum(id)
        char *id;
 {
 tgetnum(id)
        char *id;
 {
-       register int i, base;
-       register char *bp = tbuf;
+       long num;
 
 
-       for (;;) {
-               bp = tskip(bp);
-               if (*bp == 0)
-                       return (-1);
-               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
-                       continue;
-               if (*bp == '@')
-                       return(-1);
-               if (*bp != '#')
-                       continue;
-               bp++;
-               base = 10;
-               if (*bp == '0')
-                       base = 8;
-               i = 0;
-               while (isdigit(*bp))
-                       i *= base, i += *bp++ - '0';
-               return (i);
-       }
+       if (cgetnum(tbuf, id, &num) == 0)
+               return(num);
+       else
+               return(-1);
 }
 
 /*
 }
 
 /*
@@ -311,22 +167,11 @@ tgetnum(id)
  * of the buffer.  Return 1 if we find the option, or 0 if it is
  * not given.
  */
  * of the buffer.  Return 1 if we find the option, or 0 if it is
  * not given.
  */
+int
 tgetflag(id)
        char *id;
 {
 tgetflag(id)
        char *id;
 {
-       register char *bp = tbuf;
-
-       for (;;) {
-               bp = tskip(bp);
-               if (!*bp)
-                       return (0);
-               if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
-                       if (!*bp || *bp == ':')
-                               return (1);
-                       else if (*bp == '@')
-                               return(0);
-               }
-       }
+       return(cgetcap(tbuf, id, ':') != NULL);
 }
 
 /*
 }
 
 /*
@@ -341,68 +186,13 @@ char *
 tgetstr(id, area)
        char *id, **area;
 {
 tgetstr(id, area)
        char *id, **area;
 {
-       register char *bp = tbuf;
-
-       for (;;) {
-               bp = tskip(bp);
-               if (!*bp)
-                       return (0);
-               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
-                       continue;
-               if (*bp == '@')
-                       return(0);
-               if (*bp != '=')
-                       continue;
-               bp++;
-               return (tdecode(bp, area));
-       }
-}
-
-/*
- * Tdecode does the grung work to decode the
- * string capability escapes.
- */
-static char *
-tdecode(str, area)
-       register char *str;
-       char **area;
-{
-       register char *cp;
-       register int c;
-       register char *dp;
+       char *s;
        int i;
        int i;
-
-       cp = *area;
-       while ((c = *str++) && c != ':') {
-               switch (c) {
-
-               case '^':
-                       c = *str++ & 037;
-                       break;
-
-               case '\\':
-                       dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
-                       c = *str++;
-nextc:
-                       if (*dp++ == c) {
-                               c = *dp++;
-                               break;
-                       }
-                       dp++;
-                       if (*dp)
-                               goto nextc;
-                       if (isdigit(c)) {
-                               c -= '0', i = 2;
-                               do
-                                       c <<= 3, c |= *str++ - '0';
-                               while (--i && isdigit(*str));
-                       }
-                       break;
-               }
-               *cp++ = c;
-       }
-       *cp++ = 0;
-       str = *area;
-       *area = cp;
-       return (str);
+       
+       if ((i = cgetstr(tbuf, id, &s)) < 0)
+               return NULL;
+       
+       strcpy(*area, s);
+       *area += i + 1;
+       return(s);
 }
 }