aboutsummaryrefslogtreecommitdiff
path: root/contrib/ncurses/ncurses/tinfo/read_termcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ncurses/ncurses/tinfo/read_termcap.c')
-rw-r--r--contrib/ncurses/ncurses/tinfo/read_termcap.c1424
1 files changed, 705 insertions, 719 deletions
diff --git a/contrib/ncurses/ncurses/tinfo/read_termcap.c b/contrib/ncurses/ncurses/tinfo/read_termcap.c
index d60a92d63f0a..26e72d403263 100644
--- a/contrib/ncurses/ncurses/tinfo/read_termcap.c
+++ b/contrib/ncurses/ncurses/tinfo/read_termcap.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,7 +31,6 @@
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
****************************************************************************/
-
/*
* Termcap compatibility support
*
@@ -56,11 +55,7 @@
#include <tic.h>
#include <term_entry.h>
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-MODULE_ID("$Id: read_termcap.c,v 1.43 1999/04/10 20:52:52 tom Exp $")
+MODULE_ID("$Id: read_termcap.c,v 1.47 2000/04/15 16:53:19 Todd.C.Miller Exp $")
#ifndef PURE_TERMINFO
@@ -86,7 +81,7 @@ MODULE_ID("$Id: read_termcap.c,v 1.43 1999/04/10 20:52:52 tom Exp $")
#define _nc_cgetset cgetset
#else
static int _nc_cgetmatch(char *, const char *);
-static int _nc_getent(char **, unsigned int *, int *, int, char **, int, const char *, int, char *);
+static int _nc_getent(char **, unsigned *, int *, int, char **, int, const char *, int, char *);
static int _nc_nfcmp(const char *, char *);
/*-
@@ -130,16 +125,16 @@ static int _nc_nfcmp(const char *, char *);
#define BFRAG 1024
#define BSIZE 1024
#define ESC ('[' & 037) /* ASCII ESC */
-#define MAX_RECURSION 32 /* maximum getent recursion */
-#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
+#define MAX_RECURSION 32 /* maximum getent recursion */
+#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
#define RECOK (char)0
#define TCERR (char)1
#define SHADOW (char)2
-static size_t topreclen; /* toprec length */
-static char *toprec; /* Additional record specified by cgetset() */
-static int gottoprec; /* Flag indicating retrieval of toprecord */
+static size_t topreclen; /* toprec length */
+static char *toprec; /* Additional record specified by cgetset() */
+static int gottoprec; /* Flag indicating retrieval of toprecord */
/*
* Cgetset() allows the addition of a user specified buffer to be added to the
@@ -149,20 +144,20 @@ static int gottoprec; /* Flag indicating retrieval of toprecord */
static int
_nc_cgetset(const char *ent)
{
- if (ent == 0) {
- FreeIfNeeded(toprec);
- toprec = 0;
- topreclen = 0;
- return (0);
- }
- topreclen = strlen(ent);
- if ((toprec = typeMalloc(char, topreclen + 1)) == 0) {
- errno = ENOMEM;
- return (-1);
- }
- gottoprec = 0;
- (void)strcpy(toprec, ent);
+ if (ent == 0) {
+ FreeIfNeeded(toprec);
+ toprec = 0;
+ topreclen = 0;
return (0);
+ }
+ topreclen = strlen(ent);
+ if ((toprec = typeMalloc(char, topreclen + 1)) == 0) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ gottoprec = 0;
+ (void) strcpy(toprec, ent);
+ return (0);
}
/*
@@ -180,43 +175,43 @@ _nc_cgetset(const char *ent)
static char *
_nc_cgetcap(char *buf, const char *cap, int type)
{
- register const char *cp;
- register char *bp;
+ register const char *cp;
+ register char *bp;
- bp = buf;
+ bp = buf;
+ for (;;) {
+ /*
+ * Skip past the current capability field - it's either the
+ * name field if this is the first time through the loop, or
+ * the remainder of a field whose name failed to match cap.
+ */
for (;;) {
- /*
- * Skip past the current capability field - it's either the
- * name field if this is the first time through the loop, or
- * the remainder of a field whose name failed to match cap.
- */
- for (;;) {
- if (*bp == '\0')
- return (0);
- else if (*bp++ == ':')
- break;
- }
+ if (*bp == '\0')
+ return (0);
+ else if (*bp++ == ':')
+ break;
+ }
- /*
- * Try to match (cap, type) in buf.
- */
- for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++)
- continue;
- if (*cp != '\0')
- continue;
- if (*bp == '@')
- return (0);
- if (type == ':') {
- if (*bp != '\0' && *bp != ':')
- continue;
- return(bp);
- }
- if (*bp != type)
- continue;
- bp++;
- return (*bp == '@' ? 0 : bp);
+ /*
+ * Try to match (cap, type) in buf.
+ */
+ for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++)
+ continue;
+ if (*cp != '\0')
+ continue;
+ if (*bp == '@')
+ return (0);
+ if (type == ':') {
+ if (*bp != '\0' && *bp != ':')
+ continue;
+ return (bp);
}
- /* NOTREACHED */
+ if (*bp != type)
+ continue;
+ bp++;
+ return (*bp == '@' ? 0 : bp);
+ }
+ /* NOTREACHED */
}
/*
@@ -236,9 +231,9 @@ _nc_cgetcap(char *buf, const char *cap, int type)
static int
_nc_cgetent(char **buf, int *oline, char **db_array, const char *name)
{
- unsigned int dummy;
+ unsigned dummy;
- return (_nc_getent(buf, &dummy, oline, 0, db_array, -1, name, 0, 0));
+ return (_nc_getent(buf, &dummy, oline, 0, db_array, -1, name, 0, 0));
}
/*
@@ -262,327 +257,327 @@ _nc_cgetent(char **buf, int *oline, char **db_array, const char *name)
#define DOALLOC(size) typeRealloc(char, size, record)
static int
_nc_getent(
- char **cap, /* termcap-content */
- unsigned int *len, /* length, needed for recursion */
- int *beginning, /* line-number at match */
- int in_array, /* index in 'db_array[] */
- char **db_array, /* list of files to search */
- int fd,
- const char *name,
- int depth,
- char *nfield)
+ char **cap, /* termcap-content */
+ unsigned *len, /* length, needed for recursion */
+ int *beginning, /* line-number at match */
+ int in_array, /* index in 'db_array[] */
+ char **db_array, /* list of files to search */
+ int fd,
+ const char *name,
+ int depth,
+ char *nfield)
{
- register char *r_end, *rp;
- int myfd = FALSE;
- char *record = 0;
- int tc_not_resolved;
- int current;
- int lineno;
-
- /*
- * Return with ``loop detected'' error if we've recurred more than
- * MAX_RECURSION times.
- */
- if (depth > MAX_RECURSION)
- return (TC_REF_LOOP);
+ register char *r_end, *rp;
+ int myfd = FALSE;
+ char *record = 0;
+ int tc_not_resolved;
+ int current;
+ int lineno;
+
+ /*
+ * Return with ``loop detected'' error if we've recurred more than
+ * MAX_RECURSION times.
+ */
+ if (depth > MAX_RECURSION)
+ return (TC_REF_LOOP);
+
+ /*
+ * Check if we have a top record from cgetset().
+ */
+ if (depth == 0 && toprec != 0 && _nc_cgetmatch(toprec, name) == 0) {
+ if ((record = DOALLOC(topreclen + BFRAG)) == 0) {
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ (void) strcpy(record, toprec);
+ rp = record + topreclen + 1;
+ r_end = rp + BFRAG;
+ current = in_array;
+ } else {
+ int foundit;
/*
- * Check if we have a top record from cgetset().
+ * Allocate first chunk of memory.
*/
- if (depth == 0 && toprec != 0 && _nc_cgetmatch(toprec, name) == 0) {
- if ((record = DOALLOC(topreclen + BFRAG)) == 0) {
- errno = ENOMEM;
- return (TC_SYS_ERR);
- }
- (void)strcpy(record, toprec);
- rp = record + topreclen + 1;
- r_end = rp + BFRAG;
- current = in_array;
- } else {
- int foundit;
-
- /*
- * Allocate first chunk of memory.
- */
- if ((record = DOALLOC(BFRAG)) == 0) {
- errno = ENOMEM;
- return (TC_SYS_ERR);
- }
- rp = r_end = record + BFRAG;
- foundit = FALSE;
-
- /*
- * Loop through database array until finding the record.
- */
- for (current = in_array; db_array[current] != 0; current++) {
- int eof = FALSE;
-
- /*
- * Open database if not already open.
- */
- if (fd >= 0) {
- (void)lseek(fd, (off_t)0, SEEK_SET);
- } else if ((_nc_access(db_array[current], R_OK) < 0)
- || (fd = open(db_array[current], O_RDONLY, 0)) < 0) {
- /* No error on unfound file. */
- if (errno == ENOENT)
- continue;
- free(record);
- return (TC_SYS_ERR);
- } else {
- myfd = TRUE;
- }
- lineno = 0;
-
- /*
- * Find the requested capability record ...
- */
- {
- char buf[2048];
- register char *b_end = buf;
- register char *bp = buf;
- register int c;
-
- /*
- * Loop invariants:
- * There is always room for one more character in record.
- * R_end always points just past end of record.
- * Rp always points just past last character in record.
- * B_end always points just past last character in buf.
- * Bp always points at next character in buf.
- */
-
- for (;;) {
- int first = lineno + 1;
-
- /*
- * Read in a line implementing (\, newline)
- * line continuation.
- */
- rp = record;
- for (;;) {
- if (bp >= b_end) {
- int n;
-
- n = read(fd, buf, sizeof(buf));
- if (n <= 0) {
- if (myfd)
- (void)close(fd);
- if (n < 0) {
- free(record);
- return (TC_SYS_ERR);
- }
- fd = -1;
- eof = TRUE;
- break;
- }
- b_end = buf+n;
- bp = buf;
- }
-
- c = *bp++;
- if (c == '\n') {
- lineno++;
- if (rp == record || *(rp-1) != '\\')
- break;
- }
- *rp++ = c;
-
- /*
- * Enforce loop invariant: if no room
- * left in record buffer, try to get
- * some more.
- */
- if (rp >= r_end) {
- unsigned int pos;
- size_t newsize;
-
- pos = rp - record;
- newsize = r_end - record + BFRAG;
- record = DOALLOC(newsize);
- if (record == 0) {
- if (myfd)
- (void)close(fd);
- errno = ENOMEM;
- return (TC_SYS_ERR);
- }
- r_end = record + newsize;
- rp = record + pos;
- }
- }
- /* loop invariant lets us do this */
- *rp++ = '\0';
-
- /*
- * If encountered eof check next file.
- */
- if (eof)
- break;
-
- /*
- * Toss blank lines and comments.
- */
- if (*record == '\0' || *record == '#')
- continue;
-
- /*
- * See if this is the record we want ...
- */
- if (_nc_cgetmatch(record, name) == 0
- && (nfield == 0
- || !_nc_nfcmp(nfield, record))) {
- foundit = TRUE;
- *beginning = first;
- break; /* found it! */
- }
- }
- }
- if (foundit)
- break;
- }
-
- if (!foundit)
- return (TC_NOT_FOUND);
+ if ((record = DOALLOC(BFRAG)) == 0) {
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
}
+ rp = r_end = record + BFRAG;
+ foundit = FALSE;
/*
- * Got the capability record, but now we have to expand all tc=name
- * references in it ...
+ * Loop through database array until finding the record.
*/
- {
- register char *newicap, *s;
- register int newilen;
- unsigned int ilen;
- int diff, iret, tclen, oline;
- char *icap, *scan, *tc, *tcstart, *tcend;
+ for (current = in_array; db_array[current] != 0; current++) {
+ int eof = FALSE;
+
+ /*
+ * Open database if not already open.
+ */
+ if (fd >= 0) {
+ (void) lseek(fd, (off_t) 0, SEEK_SET);
+ } else if ((_nc_access(db_array[current], R_OK) < 0)
+ || (fd = open(db_array[current], O_RDONLY, 0)) < 0) {
+ /* No error on unfound file. */
+ if (errno == ENOENT)
+ continue;
+ free(record);
+ return (TC_SYS_ERR);
+ } else {
+ myfd = TRUE;
+ }
+ lineno = 0;
+
+ /*
+ * Find the requested capability record ...
+ */
+ {
+ char buf[2048];
+ register char *b_end = buf;
+ register char *bp = buf;
+ register int c;
/*
* Loop invariants:
- * There is room for one more character in record.
- * R_end points just past end of record.
- * Rp points just past last character in record.
- * Scan points at remainder of record that needs to be
- * scanned for tc=name constructs.
+ * There is always room for one more character in record.
+ * R_end always points just past end of record.
+ * Rp always points just past last character in record.
+ * B_end always points just past last character in buf.
+ * Bp always points at next character in buf.
*/
- scan = record;
- tc_not_resolved = FALSE;
- for (;;) {
- if ((tc = _nc_cgetcap(scan, "tc", '=')) == 0)
- break;
- /*
- * Find end of tc=name and stomp on the trailing `:'
- * (if present) so we can use it to call ourselves.
- */
- s = tc;
- while (*s != '\0') {
- if (*s++ == ':') {
- *(s - 1) = '\0';
- break;
- }
- }
- tcstart = tc - 3;
- tclen = s - tcstart;
- tcend = s;
-
- iret = _nc_getent(&icap, &ilen, &oline, current, db_array, fd, tc, depth+1, 0);
- newicap = icap; /* Put into a register. */
- newilen = ilen;
- if (iret != TC_SUCCESS) {
- /* an error */
- if (iret < TC_NOT_FOUND) {
- if (myfd)
- (void)close(fd);
- free(record);
- return (iret);
- }
- if (iret == TC_UNRESOLVED)
- tc_not_resolved = TRUE;
- /* couldn't resolve tc */
- if (iret == TC_NOT_FOUND) {
- *(s - 1) = ':';
- scan = s - 1;
- tc_not_resolved = TRUE;
- continue;
+ for (;;) {
+ int first = lineno + 1;
+
+ /*
+ * Read in a line implementing (\, newline)
+ * line continuation.
+ */
+ rp = record;
+ for (;;) {
+ if (bp >= b_end) {
+ int n;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n <= 0) {
+ if (myfd)
+ (void) close(fd);
+ if (n < 0) {
+ free(record);
+ return (TC_SYS_ERR);
}
+ fd = -1;
+ eof = TRUE;
+ break;
+ }
+ b_end = buf + n;
+ bp = buf;
}
- /* not interested in name field of tc'ed record */
- s = newicap;
- while (*s != '\0' && *s++ != ':')
- ;
- newilen -= s - newicap;
- newicap = s;
-
- /* make sure interpolated record is `:'-terminated */
- s += newilen;
- if (*(s-1) != ':') {
- *s = ':'; /* overwrite NUL with : */
- newilen++;
+ c = *bp++;
+ if (c == '\n') {
+ lineno++;
+ if (rp == record || *(rp - 1) != '\\')
+ break;
}
+ *rp++ = c;
/*
- * Make sure there's enough room to insert the
- * new record.
+ * Enforce loop invariant: if no room
+ * left in record buffer, try to get
+ * some more.
*/
- diff = newilen - tclen;
- if (diff >= r_end - rp) {
- unsigned int pos, tcpos, tcposend;
- size_t newsize;
-
- pos = rp - record;
- newsize = r_end - record + diff + BFRAG;
- tcpos = tcstart - record;
- tcposend = tcend - record;
- record = DOALLOC(newsize);
- if (record == 0) {
- if (myfd)
- (void)close(fd);
- free(icap);
- errno = ENOMEM;
- return (TC_SYS_ERR);
- }
- r_end = record + newsize;
- rp = record + pos;
- tcstart = record + tcpos;
- tcend = record + tcposend;
+ if (rp >= r_end) {
+ unsigned pos;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + BFRAG;
+ record = DOALLOC(newsize);
+ if (record == 0) {
+ if (myfd)
+ (void) close(fd);
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
}
+ }
+ /* loop invariant lets us do this */
+ *rp++ = '\0';
+
+ /*
+ * If encountered eof check next file.
+ */
+ if (eof)
+ break;
- /*
- * Insert tc'ed record into our record.
- */
- s = tcstart + newilen;
- memmove(s, tcend, (size_t)(rp - tcend));
- memmove(tcstart, newicap, (size_t)newilen);
- rp += diff;
- free(icap);
+ /*
+ * Toss blank lines and comments.
+ */
+ if (*record == '\0' || *record == '#')
+ continue;
- /*
- * Start scan on `:' so next cgetcap works properly
- * (cgetcap always skips first field).
- */
- scan = s-1;
+ /*
+ * See if this is the record we want ...
+ */
+ if (_nc_cgetmatch(record, name) == 0
+ && (nfield == 0
+ || !_nc_nfcmp(nfield, record))) {
+ foundit = TRUE;
+ *beginning = first;
+ break; /* found it! */
+ }
}
+ }
+ if (foundit)
+ break;
}
+ if (!foundit)
+ return (TC_NOT_FOUND);
+ }
+
+ /*
+ * Got the capability record, but now we have to expand all tc=name
+ * references in it ...
+ */
+ {
+ register char *newicap, *s;
+ register int newilen;
+ unsigned ilen;
+ int diff, iret, tclen, oline;
+ char *icap, *scan, *tc, *tcstart, *tcend;
+
/*
- * Close file (if we opened it), give back any extra memory, and
- * return capability, length and success.
+ * Loop invariants:
+ * There is room for one more character in record.
+ * R_end points just past end of record.
+ * Rp points just past last character in record.
+ * Scan points at remainder of record that needs to be
+ * scanned for tc=name constructs.
*/
- if (myfd)
- (void)close(fd);
- *len = rp - record - 1; /* don't count NUL */
- if (r_end > rp) {
- if ((record = DOALLOC((size_t)(rp - record))) == 0) {
- errno = ENOMEM;
- return (TC_SYS_ERR);
+ scan = record;
+ tc_not_resolved = FALSE;
+ for (;;) {
+ if ((tc = _nc_cgetcap(scan, "tc", '=')) == 0)
+ break;
+
+ /*
+ * Find end of tc=name and stomp on the trailing `:'
+ * (if present) so we can use it to call ourselves.
+ */
+ s = tc;
+ while (*s != '\0') {
+ if (*s++ == ':') {
+ *(s - 1) = '\0';
+ break;
+ }
+ }
+ tcstart = tc - 3;
+ tclen = s - tcstart;
+ tcend = s;
+
+ iret = _nc_getent(&icap, &ilen, &oline, current, db_array, fd,
+ tc, depth + 1, 0);
+ newicap = icap; /* Put into a register. */
+ newilen = ilen;
+ if (iret != TC_SUCCESS) {
+ /* an error */
+ if (iret < TC_NOT_FOUND) {
+ if (myfd)
+ (void) close(fd);
+ free(record);
+ return (iret);
}
+ if (iret == TC_UNRESOLVED)
+ tc_not_resolved = TRUE;
+ /* couldn't resolve tc */
+ if (iret == TC_NOT_FOUND) {
+ *(s - 1) = ':';
+ scan = s - 1;
+ tc_not_resolved = TRUE;
+ continue;
+ }
+ }
+
+ /* not interested in name field of tc'ed record */
+ s = newicap;
+ while (*s != '\0' && *s++ != ':') ;
+ newilen -= s - newicap;
+ newicap = s;
+
+ /* make sure interpolated record is `:'-terminated */
+ s += newilen;
+ if (*(s - 1) != ':') {
+ *s = ':'; /* overwrite NUL with : */
+ newilen++;
+ }
+
+ /*
+ * Make sure there's enough room to insert the
+ * new record.
+ */
+ diff = newilen - tclen;
+ if (diff >= r_end - rp) {
+ unsigned pos, tcpos, tcposend;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + diff + BFRAG;
+ tcpos = tcstart - record;
+ tcposend = tcend - record;
+ record = DOALLOC(newsize);
+ if (record == 0) {
+ if (myfd)
+ (void) close(fd);
+ free(icap);
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ tcstart = record + tcpos;
+ tcend = record + tcposend;
+ }
+
+ /*
+ * Insert tc'ed record into our record.
+ */
+ s = tcstart + newilen;
+ memmove(s, tcend, (size_t) (rp - tcend));
+ memmove(tcstart, newicap, (size_t) newilen);
+ rp += diff;
+ free(icap);
+
+ /*
+ * Start scan on `:' so next cgetcap works properly
+ * (cgetcap always skips first field).
+ */
+ scan = s - 1;
+ }
+ }
+
+ /*
+ * Close file (if we opened it), give back any extra memory, and
+ * return capability, length and success.
+ */
+ if (myfd)
+ (void) close(fd);
+ *len = rp - record - 1; /* don't count NUL */
+ if (r_end > rp) {
+ if ((record = DOALLOC((size_t) (rp - record))) == 0) {
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
}
+ }
- *cap = record;
- if (tc_not_resolved)
- return (TC_UNRESOLVED);
- return (current);
+ *cap = record;
+ if (tc_not_resolved)
+ return (TC_UNRESOLVED);
+ return (current);
}
/*
@@ -592,40 +587,40 @@ _nc_getent(
static int
_nc_cgetmatch(char *buf, const char *name)
{
- register const char *np;
- register char *bp;
-
+ register const char *np;
+ register char *bp;
+
+ /*
+ * Start search at beginning of record.
+ */
+ bp = buf;
+ for (;;) {
/*
- * Start search at beginning of record.
+ * Try to match a record name.
*/
- bp = buf;
+ np = name;
for (;;) {
- /*
- * Try to match a record name.
- */
- np = name;
- for (;;) {
- if (*np == '\0') {
- if (*bp == '|' || *bp == ':' || *bp == '\0')
- return (0);
- else
- break;
- } else if (*bp++ != *np++) {
- break;
- }
- }
+ if (*np == '\0') {
+ if (*bp == '|' || *bp == ':' || *bp == '\0')
+ return (0);
+ else
+ break;
+ } else if (*bp++ != *np++) {
+ break;
+ }
+ }
- /*
- * Match failed, skip to next name in record.
- */
- bp--; /* a '|' or ':' may have stopped the match */
- for (;;) {
- if (*bp == '\0' || *bp == ':')
- return (-1); /* match failed totally */
- else if (*bp++ == '|')
- break; /* found next name */
- }
+ /*
+ * Match failed, skip to next name in record.
+ */
+ bp--; /* a '|' or ':' may have stopped the match */
+ for (;;) {
+ if (*bp == '\0' || *bp == ':')
+ return (-1); /* match failed totally */
+ else if (*bp++ == '|')
+ break; /* found next name */
}
+ }
}
/*
@@ -634,18 +629,17 @@ _nc_cgetmatch(char *buf, const char *name)
static int
_nc_nfcmp(const char *nf, char *rec)
{
- char *cp, tmp;
- int ret;
+ char *cp, tmp;
+ int ret;
- for (cp = rec; *cp != ':'; cp++)
- ;
+ for (cp = rec; *cp != ':'; cp++) ;
- tmp = *(cp + 1);
- *(cp + 1) = '\0';
- ret = strcmp(nf, rec);
- *(cp + 1) = tmp;
+ tmp = *(cp + 1);
+ *(cp + 1) = '\0';
+ ret = strcmp(nf, rec);
+ *(cp + 1) = tmp;
- return (ret);
+ return (ret);
}
#endif /* HAVE_BSD_CGETENT */
@@ -706,63 +700,63 @@ static char *tbuf;
static char *
get_tc_token(char **srcp, int *endp)
{
- int ch;
- bool found = FALSE;
- char *s, *base;
- char *tok = 0;
-
- *endp = TRUE;
- for (s = base = *srcp; *s != '\0'; ) {
- ch = *s++;
- if (ch == '\\') {
- if (*s == '\0') {
- break;
- } else if (*s++ == '\n') {
- while (isspace(*s))
- s++;
- } else {
- found = TRUE;
- }
- } else if (ch == ':') {
- if (found) {
- tok = base;
- s[-1] = '\0';
- *srcp = s;
- *endp = FALSE;
- break;
- }
- base = s;
- } else if (isgraph(ch)) {
- found = TRUE;
- }
- }
-
- /* malformed entry may end without a ':' */
- if (tok == 0 && found) {
+ int ch;
+ bool found = FALSE;
+ char *s, *base;
+ char *tok = 0;
+
+ *endp = TRUE;
+ for (s = base = *srcp; *s != '\0';) {
+ ch = *s++;
+ if (ch == '\\') {
+ if (*s == '\0') {
+ break;
+ } else if (*s++ == '\n') {
+ while (isspace(*s))
+ s++;
+ } else {
+ found = TRUE;
+ }
+ } else if (ch == ':') {
+ if (found) {
tok = base;
+ s[-1] = '\0';
+ *srcp = s;
+ *endp = FALSE;
+ break;
+ }
+ base = s;
+ } else if (isgraph(ch)) {
+ found = TRUE;
}
+ }
+
+ /* malformed entry may end without a ':' */
+ if (tok == 0 && found) {
+ tok = base;
+ }
- return tok;
+ return tok;
}
static char *
copy_tc_token(char *dst, const char *src, size_t len)
{
- int ch;
+ int ch;
- while ((ch = *src++) != '\0') {
- if (ch == '\\' && *src == '\n') {
- while (isspace(*src))
- src++;
- continue;
- }
- if (--len == 0) {
- dst = 0;
- break;
- }
- *dst++ = ch;
+ while ((ch = *src++) != '\0') {
+ if (ch == '\\' && *src == '\n') {
+ while (isspace(*src))
+ src++;
+ continue;
+ }
+ if (--len == 0) {
+ dst = 0;
+ break;
}
- return dst;
+ *dst++ = ch;
+ }
+ return dst;
}
/*
@@ -771,127 +765,126 @@ copy_tc_token(char *dst, const char *src, size_t len)
static int
_nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
{
- static char *the_source;
-
- register char *p;
- register char *cp;
- 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;
- cp = getenv("TERMCAP");
-
- /*
- * TERMCAP can have one of two things in it. It can be the name of a
- * file to use instead of /etc/termcap. In this case it better start
- * with a "/". Or it can be an entry to use so we don't have to read
- * the file. In this case it has to already have the newlines crunched
- * out. If TERMCAP does not hold a file name then a path of names is
- * searched instead. The path is found in the TERMPATH variable, or
- * becomes "$HOME/.termcap /etc/termcap" if no TERMPATH exists.
- */
- if (!is_pathname(cp)) { /* no TERMCAP or it holds an entry */
- if ((termpath = getenv("TERMPATH")) != 0) {
- strncpy(pathbuf, termpath, PBUFSIZ - 1);
- } else {
- if ((home = getenv("HOME")) != 0 &&
- strlen(home) < PBUFSIZ) { /* setup path */
- p += strlen(home); /* path, looking in */
- strcpy(pathbuf, home); /* $HOME first */
- *p++ = '/';
- } /* if no $HOME look in current directory */
+ static char *the_source;
+
+ register char *p;
+ register char *cp;
+ 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;
+ cp = getenv("TERMCAP");
+
+ /*
+ * TERMCAP can have one of two things in it. It can be the name of a file
+ * to use instead of /etc/termcap. In this case it better start with a
+ * "/". Or it can be an entry to use so we don't have to read the file.
+ * In this case it has to already have the newlines crunched out. If
+ * TERMCAP does not hold a file name then a path of names is searched
+ * instead. The path is found in the TERMPATH variable, or becomes
+ * "$HOME/.termcap /etc/termcap" if no TERMPATH exists.
+ */
+ if (!is_pathname(cp)) { /* no TERMCAP or it holds an entry */
+ if ((termpath = getenv("TERMPATH")) != 0) {
+ strncpy(pathbuf, termpath, PBUFSIZ - 1);
+ } else {
+ if ((home = getenv("HOME")) != 0 &&
+ strlen(home) < PBUFSIZ) { /* setup path */
+ p += strlen(home); /* path, looking in */
+ strcpy(pathbuf, home); /* $HOME first */
+ *p++ = '/';
+ } /* if no $HOME look in current directory */
#define MY_PATH_DEF ".termcap /etc/termcap /usr/share/misc/termcap"
- strncpy(p, MY_PATH_DEF, (size_t)(PBUFSIZ - (p - pathbuf) - 1));
- }
+ strncpy(p, MY_PATH_DEF, (size_t) (PBUFSIZ - (p - pathbuf) - 1));
}
- else /* user-defined name in TERMCAP */
- strncpy(pathbuf, cp, PBUFSIZ - 1); /* still can be tokenized */
- pathbuf[PBUFSIZ - 1] = '\0';
-
- *fname++ = pathbuf; /* tokenize path into vector of names */
- while (*++p) {
- if (*p == ' ' || *p == ':') {
- *p = '\0';
- while (*++p)
- if (*p != ' ' && *p != ':')
- break;
- if (*p == '\0')
- break;
- *fname++ = p;
- if (fname >= pathvec + PVECSIZ) {
- fname--;
- break;
- }
- }
+ } else /* user-defined name in TERMCAP */
+ strncpy(pathbuf, cp, PBUFSIZ - 1); /* still can be tokenized */
+ pathbuf[PBUFSIZ - 1] = '\0';
+
+ *fname++ = pathbuf; /* tokenize path into vector of names */
+ while (*++p) {
+ if (*p == ' ' || *p == ':') {
+ *p = '\0';
+ while (*++p)
+ if (*p != ' ' && *p != ':')
+ break;
+ if (*p == '\0')
+ break;
+ *fname++ = p;
+ if (fname >= pathvec + PVECSIZ) {
+ fname--;
+ break;
+ }
}
- *fname = 0; /* mark end of vector */
- if (is_pathname(cp)) {
- if (_nc_cgetset(cp) < 0) {
- return(TC_SYS_ERR);
- }
+ }
+ *fname = 0; /* mark end of vector */
+ if (is_pathname(cp)) {
+ if (_nc_cgetset(cp) < 0) {
+ return (TC_SYS_ERR);
}
-
- i = _nc_cgetent(&dummy, lineno, pathvec, name);
-
- /* ncurses' termcap-parsing routines cannot handle multiple adjacent
- * empty fields, and mistakenly use the last valid cap entry instead of
- * the first (breaks tc= includes)
- */
- if (i >= 0) {
- char *pd, *ps, *tok;
- int endflag = FALSE;
- char *list[1023];
- size_t n, count = 0;
-
- pd = bp;
- ps = dummy;
- while (!endflag && (tok = get_tc_token(&ps, &endflag)) != 0) {
- bool ignore = FALSE;
-
- for (n = 1; n < count; n++) {
- char *s = list[n];
- if (s[0] == tok[0]
- && s[1] == tok[1]) {
- ignore = TRUE;
- break;
- }
- }
- if (ignore != TRUE) {
- list[count++] = tok;
- pd = copy_tc_token(pd, tok, TBUFSIZ - (2+pd-bp));
- if (pd == 0) {
- i = -1;
- break;
- }
- *pd++ = ':';
- *pd = '\0';
- }
+ }
+
+ i = _nc_cgetent(&dummy, lineno, pathvec, name);
+
+ /* ncurses' termcap-parsing routines cannot handle multiple adjacent
+ * empty fields, and mistakenly use the last valid cap entry instead of
+ * the first (breaks tc= includes)
+ */
+ if (i >= 0) {
+ char *pd, *ps, *tok;
+ int endflag = FALSE;
+ char *list[1023];
+ size_t n, count = 0;
+
+ pd = bp;
+ ps = dummy;
+ while (!endflag && (tok = get_tc_token(&ps, &endflag)) != 0) {
+ bool ignore = FALSE;
+
+ for (n = 1; n < count; n++) {
+ char *s = list[n];
+ if (s[0] == tok[0]
+ && s[1] == tok[1]) {
+ ignore = TRUE;
+ break;
}
+ }
+ if (ignore != TRUE) {
+ list[count++] = tok;
+ pd = copy_tc_token(pd, tok, TBUFSIZ - (2 + pd - bp));
+ if (pd == 0) {
+ i = -1;
+ break;
+ }
+ *pd++ = ':';
+ *pd = '\0';
+ }
}
-
- FreeIfNeeded(dummy);
- FreeIfNeeded(the_source);
- the_source = 0;
-
- /* This is not related to the BSD cgetent(), but to fake up a suitable
- * filename for ncurses' error reporting. (If we are not using BSD
- * cgetent, then it is the actual filename).
- */
- if (i >= 0) {
- if ((the_source = strdup(pathvec[i])) != 0)
- *sourcename = the_source;
- }
-
- return(i);
+ }
+
+ FreeIfNeeded(dummy);
+ FreeIfNeeded(the_source);
+ the_source = 0;
+
+ /* This is not related to the BSD cgetent(), but to fake up a suitable
+ * filename for ncurses' error reporting. (If we are not using BSD
+ * cgetent, then it is the actual filename).
+ */
+ if (i >= 0) {
+ if ((the_source = strdup(pathvec[i])) != 0)
+ *sourcename = the_source;
+ }
+
+ return (i);
}
#endif /* USE_BSD_TGETENT */
#endif /* USE_GETCAP */
@@ -903,214 +896,207 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
* a right to open the file.
*/
#if !USE_GETCAP
-static int add_tc(char *termpaths[], char *path, int count)
+static int
+add_tc(char *termpaths[], char *path, int count)
{
- if (count < MAXPATHS
- && _nc_access(path, R_OK) == 0)
- termpaths[count++] = path;
- termpaths[count] = 0;
- return count;
+ if (count < MAXPATHS
+ && _nc_access(path, R_OK) == 0)
+ termpaths[count++] = path;
+ termpaths[count] = 0;
+ return count;
}
#define ADD_TC(path, count) filecount = add_tc(termpaths, path, count)
#endif /* !USE_GETCAP */
-int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
+int
+_nc_read_termcap_entry(const char *const tn, TERMTYPE * const tp)
{
- int found = FALSE;
- ENTRY *ep;
+ int found = FALSE;
+ ENTRY *ep;
#if USE_GETCAP_CACHE
- char cwd_buf[PATH_MAX];
+ char cwd_buf[PATH_MAX];
#endif
#if USE_GETCAP
- char tc[TBUFSIZ];
- static char *source;
- static int lineno;
-
+ char *p, tc[TBUFSIZ];
+ static char *source;
+ static int lineno;
+
+ if ((p = getenv("TERMCAP")) != 0
+ && !is_pathname(p) && _nc_name_match(p, tn, "|:")) {
+ /* TERMCAP holds a termcap entry */
+ strncpy(tc, p, sizeof(tc) - 1);
+ tc[sizeof(tc) - 1] = '\0';
+ _nc_set_source("TERMCAP");
+ } else {
/* we're using getcap(3) */
if (_nc_tgetent(tc, &source, &lineno, tn) < 0)
- return (ERR);
+ return (ERR);
_nc_curr_line = lineno;
_nc_set_source(source);
- _nc_read_entry_source((FILE *)0, tc, FALSE, FALSE, NULLHOOK);
+ }
+ _nc_read_entry_source((FILE *) 0, tc, FALSE, FALSE, NULLHOOK);
#else
- /*
- * Here is what the 4.4BSD termcap(3) page prescribes:
- *
- * It will look in the environment for a TERMCAP variable. If found,
- * and the value does not begin with a slash, and the terminal type
- * name is the same as the environment string TERM, the TERMCAP string
- * is used instead of reading a termcap file. If it does begin with a
- * slash, the string is used as a path name of the termcap file to
- * search. If TERMCAP does not begin with a slash and name is
- * different from TERM, tgetent() searches the files $HOME/.termcap and
- * /usr/share/misc/termcap, in that order, unless the environment
- * variable TERMPATH exists, in which case it specifies a list of file
- * pathnames (separated by spaces or colons) to be searched instead.
- *
- * It goes on to state:
- *
- * Whenever multiple files are searched and a tc field occurs in the
- * requested entry, the entry it names must be found in the same file
- * or one of the succeeding files.
- *
- * However, this restriction is relaxed in ncurses; tc references to
- * previous files are permitted.
- *
- * This routine returns 1 if an entry is found, 0 if not found, and -1
- * if the database is not accessible.
- */
- FILE *fp;
- char *tc, *termpaths[MAXPATHS];
- int filecount = 0;
- bool use_buffer = FALSE;
- char tc_buf[1024];
- char pathbuf[PATH_MAX];
-
- termpaths[filecount] = 0;
- if ((tc = getenv("TERMCAP")) != 0)
- {
- if (is_pathname(tc)) /* interpret as a filename */
- {
- ADD_TC(tc, 0);
- }
- else if (_nc_name_match(tc, tn, "|:")) /* treat as a capability file */
- {
- use_buffer = TRUE;
- (void) sprintf(tc_buf, "%.*s\n", (int)sizeof(tc_buf)-2, tc);
- }
- else if ((tc = getenv("TERMPATH")) != 0)
- {
- char *cp;
-
- for (cp = tc; *cp; cp++)
- {
- if (*cp == ':')
- *cp = '\0';
- else if (cp == tc || cp[-1] == '\0')
- {
- ADD_TC(cp, filecount);
- }
- }
+ /*
+ * Here is what the 4.4BSD termcap(3) page prescribes:
+ *
+ * It will look in the environment for a TERMCAP variable. If found, and
+ * the value does not begin with a slash, and the terminal type name is the
+ * same as the environment string TERM, the TERMCAP string is used instead
+ * of reading a termcap file. If it does begin with a slash, the string is
+ * used as a path name of the termcap file to search. If TERMCAP does not
+ * begin with a slash and name is different from TERM, tgetent() searches
+ * the files $HOME/.termcap and /usr/share/misc/termcap, in that order,
+ * unless the environment variable TERMPATH exists, in which case it
+ * specifies a list of file pathnames (separated by spaces or colons) to be
+ * searched instead.
+ *
+ * It goes on to state:
+ *
+ * Whenever multiple files are searched and a tc field occurs in the
+ * requested entry, the entry it names must be found in the same file or
+ * one of the succeeding files.
+ *
+ * However, this restriction is relaxed in ncurses; tc references to
+ * previous files are permitted.
+ *
+ * This routine returns 1 if an entry is found, 0 if not found, and -1 if
+ * the database is not accessible.
+ */
+ FILE *fp;
+ char *tc, *termpaths[MAXPATHS];
+ int filecount = 0;
+ bool use_buffer = FALSE;
+ char tc_buf[1024];
+ char pathbuf[PATH_MAX];
+
+ termpaths[filecount] = 0;
+ if ((tc = getenv("TERMCAP")) != 0) {
+ if (is_pathname(tc)) { /* interpret as a filename */
+ ADD_TC(tc, 0);
+ } else if (_nc_name_match(tc, tn, "|:")) { /* treat as a capability file */
+ use_buffer = TRUE;
+ (void) sprintf(tc_buf, "%.*s\n", (int) sizeof(tc_buf) - 2, tc);
+ } else if ((tc = getenv("TERMPATH")) != 0) {
+ char *cp;
+
+ for (cp = tc; *cp; cp++) {
+ if (*cp == ':')
+ *cp = '\0';
+ else if (cp == tc || cp[-1] == '\0') {
+ ADD_TC(cp, filecount);
}
+ }
}
- else /* normal case */
- {
- char envhome[PATH_MAX], *h;
+ } else { /* normal case */
+ char envhome[PATH_MAX], *h;
- filecount = 0;
+ filecount = 0;
- /*
- * Probably /etc/termcap is a symlink to /usr/share/misc/termcap.
- * Avoid reading the same file twice.
- */
- if (_nc_access("/etc/termcap", F_OK) == 0)
- ADD_TC("/etc/termcap", filecount);
- else
- ADD_TC("/usr/share/misc/termcap", filecount);
+ /*
+ * Probably /etc/termcap is a symlink to /usr/share/misc/termcap.
+ * Avoid reading the same file twice.
+ */
+ if (_nc_access("/etc/termcap", F_OK) == 0)
+ ADD_TC("/etc/termcap", filecount);
+ else
+ ADD_TC("/usr/share/misc/termcap", filecount);
#define PRIVATE_CAP "%s/.termcap"
- if ((h = getenv("HOME")) != NULL
- && (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX)
- {
- /* user's .termcap, if any, should override it */
- (void) strcpy(envhome, h);
- (void) sprintf(pathbuf, PRIVATE_CAP, envhome);
- ADD_TC(pathbuf, filecount);
- }
+ if ((h = getenv("HOME")) != NULL
+ && (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX) {
+ /* user's .termcap, if any, should override it */
+ (void) strcpy(envhome, h);
+ (void) sprintf(pathbuf, PRIVATE_CAP, envhome);
+ ADD_TC(pathbuf, filecount);
}
+ }
- /* parse the sources */
- if (use_buffer)
- {
- _nc_set_source("TERMCAP");
+ /* parse the sources */
+ if (use_buffer) {
+ _nc_set_source("TERMCAP");
- /*
- * We don't suppress warning messages here. The presumption is
- * that since it's just a single entry, they won't be a pain.
- */
- _nc_read_entry_source((FILE *)0, tc_buf, FALSE, FALSE, NULLHOOK);
- } else {
- int i;
+ /*
+ * We don't suppress warning messages here. The presumption is
+ * that since it's just a single entry, they won't be a pain.
+ */
+ _nc_read_entry_source((FILE *) 0, tc_buf, FALSE, FALSE, NULLHOOK);
+ } else {
+ int i;
- for (i = 0; i < filecount; i++) {
+ for (i = 0; i < filecount; i++) {
- T(("Looking for %s in %s", tn, termpaths[i]));
- if ((fp = fopen(termpaths[i], "r")) != (FILE *)0)
- {
- _nc_set_source(termpaths[i]);
+ T(("Looking for %s in %s", tn, termpaths[i]));
+ if ((fp = fopen(termpaths[i], "r")) != (FILE *) 0) {
+ _nc_set_source(termpaths[i]);
- /*
- * Suppress warning messages. Otherwise you
- * get 400 lines of crap from archaic termcap
- * files as ncurses complains about all the
- * obsolete capabilities.
- */
- _nc_read_entry_source(fp, (char*)0, FALSE, TRUE, NULLHOOK);
+ /*
+ * Suppress warning messages. Otherwise you get 400 lines of
+ * crap from archaic termcap files as ncurses complains about
+ * all the obsolete capabilities.
+ */
+ _nc_read_entry_source(fp, (char *) 0, FALSE, TRUE, NULLHOOK);
- (void) fclose(fp);
- }
- }
+ (void) fclose(fp);
+ }
}
+ }
#endif /* USE_GETCAP */
- if (_nc_head == 0)
- return(ERR);
+ if (_nc_head == 0)
+ return (ERR);
- /* resolve all use references */
- _nc_resolve_uses();
+ /* resolve all use references */
+ _nc_resolve_uses(TRUE);
- /* find a terminal matching tn, if we can */
+ /* find a terminal matching tn, if we can */
#if USE_GETCAP_CACHE
- if (getcwd(cwd_buf, sizeof(cwd_buf)) != 0)
- {
- _nc_set_writedir((char *)0); /* note: this does a chdir */
+ if (getcwd(cwd_buf, sizeof(cwd_buf)) != 0) {
+ _nc_set_writedir((char *) 0); /* note: this does a chdir */
#endif
- for_entry_list(ep) {
- if (_nc_name_match(ep->tterm.term_names, tn, "|:"))
- {
- /*
- * Make a local copy of the terminal
- * capabilities. Free all entry storage except
- * the string table for the loaded type (which
- * we disconnected from the list by NULLing out
- * ep->tterm.str_table above).
- */
- *tp = ep->tterm;
- ep->tterm.str_table = (char *)0;
-
- /*
- * OK, now try to write the type to user's
- * terminfo directory. Next time he loads
- * this, it will come through terminfo.
- *
- * Advantage: Second and subsequent fetches of
- * this entry will be very fast.
- *
- * Disadvantage: After the first time a
- * termcap type is loaded by its user, editing
- * it in the /etc/termcap file, or in TERMCAP,
- * or in a local ~/.termcap, will be
- * ineffective unless the terminfo entry is
- * explicitly removed.
- */
+ for_entry_list(ep) {
+ if (_nc_name_match(ep->tterm.term_names, tn, "|:")) {
+ /*
+ * Make a local copy of the terminal capabilities. Free all
+ * entry storage except the string table for the loaded type
+ * (which we disconnected from the list by NULLing out
+ * ep->tterm.str_table above).
+ */
+ *tp = ep->tterm;
+ ep->tterm.str_table = (char *) 0;
+
+ /*
+ * OK, now try to write the type to user's terminfo directory.
+ * Next time he loads this, it will come through terminfo.
+ *
+ * Advantage: Second and subsequent fetches of this entry will
+ * be very fast.
+ *
+ * Disadvantage: After the first time a termcap type is loaded
+ * by its user, editing it in the /etc/termcap file, or in
+ * TERMCAP, or in a local ~/.termcap, will be ineffective
+ * unless the terminfo entry is explicitly removed.
+ */
#if USE_GETCAP_CACHE
- (void) _nc_write_entry(tp);
+ (void) _nc_write_entry(tp);
#endif
- found = TRUE;
- break;
- }
- }
-#if USE_GETCAP_CACHE
- chdir(cwd_buf);
+ found = TRUE;
+ break;
+ }
}
+#if USE_GETCAP_CACHE
+ chdir(cwd_buf);
+ }
#endif
- _nc_free_entries(_nc_head);
- return(found);
+ _nc_free_entries(_nc_head);
+ return (found);
}
#else
-extern void _nc_read_termcap(void);
- void _nc_read_termcap(void) { }
-#endif /* PURE_TERMINFO */
+extern void _nc_read_termcap(void);
+void
+_nc_read_termcap(void)
+{
+}
+#endif /* PURE_TERMINFO */