X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/983d99b5365d68dae79af890ef12425ca23c5e57..596d02bc1b2078ed61c83cf1c1db0ddabd179755:/src/termcap.c diff --git a/src/termcap.c b/src/termcap.c index a1bbab2d9d..b87fee48e8 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -1,5 +1,6 @@ /* Work-alike for termcap, plus extra features. - Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc. + Copyright (C) 1985, 86, 93, 94, 95, 2000, 2001 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,17 +14,28 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Emacs config.h may rename various library functions such as malloc. */ #ifdef HAVE_CONFIG_H #include -#else /* not HAVE_CONFIG_H */ +#endif -#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) -#define bcopy(s, d, n) memcpy ((d), (s), (n)) +#ifdef emacs + +#include /* xmalloc is here */ +/* Get the O_* definitions for open et al. */ +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include #endif +#else /* not emacs */ + #ifdef STDC_HEADERS #include #include @@ -33,6 +45,11 @@ char *malloc (); char *realloc (); #endif +/* Do this after the include, in case string.h prototypes bcopy. */ +#if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy) +#define bcopy(s, d, n) memcpy ((d), (s), (n)) +#endif + #ifdef HAVE_UNISTD_H #include #endif @@ -40,7 +57,7 @@ char *realloc (); #include #endif -#endif /* not HAVE_CONFIG_H */ +#endif /* not emacs */ #ifndef NULL #define NULL (char *) 0 @@ -67,8 +84,8 @@ int bufsize = 128; #endif #endif -#ifndef TERMCAP_NAME -#define TERMCAP_NAME "/etc/termcap" +#ifndef TERMCAP_FILE +#define TERMCAP_FILE "/etc/termcap" #endif #ifndef emacs @@ -161,6 +178,17 @@ tgetstr (cap, area) return tgetst1 (ptr, area); } +#ifdef IS_EBCDIC_HOST +/* Table, indexed by a character in range 0200 to 0300 with 0200 subtracted, + gives meaning of character following \, or a space if no special meaning. + Sixteen characters per line within the string. */ + +static char esctab[] + = " \057\026 \047\014 \ + \025 \015 \ + \005 \013 \ + "; +#else /* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted, gives meaning of character following \, or a space if no special meaning. Eight characters per line within the string. */ @@ -170,6 +198,7 @@ static char esctab[] \012 \ \015 \011 \013 \ "; +#endif /* PTR points to a string value inside a termcap entry. Copy that value, processing \ and ^ abbreviations, @@ -211,7 +240,13 @@ tgetst1 (ptr, area) while ((c = *p++) && c != ':' && c != '\n') { if (c == '^') - c = *p++ & 037; + { + c = *p++; + if (c == '?') + c = 0177; + else + c &= 037; + } else if (c == '\\') { c = *p++; @@ -227,12 +262,21 @@ tgetst1 (ptr, area) p++; } } +#ifdef IS_EBCDIC_HOST + else if (c >= 0200 && c < 0360) + { + c1 = esctab[(c & ~0100) - 0200]; + if (c1 != ' ') + c = c1; + } +#else else if (c >= 0100 && c < 0200) { c1 = esctab[(c & ~040) - 0100]; if (c1 != ' ') c = c1; } +#endif } *r++ = c; } @@ -245,25 +289,30 @@ tgetst1 (ptr, area) /* Outputting a string with padding. */ +#ifndef emacs short ospeed; /* If OSPEED is 0, we use this as the actual baud rate. */ int tputs_baud_rate; +#endif char PC; +#ifndef emacs /* Actual baud rate if positive; - baud rate / 100 if negative. */ -static short speeds[] = +static int speeds[] = { #ifdef VMS 0, 50, 75, 110, 134, 150, -3, -6, -12, -18, -20, -24, -36, -48, -72, -96, -192 #else /* not VMS */ 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, - -18, -24, -48, -96, -192, -384 + -18, -24, -48, -96, -192, -288, -384, -576, -1152 #endif /* not VMS */ }; +#endif /* not emacs */ + void tputs (str, nlines, outfun) register char *str; @@ -274,8 +323,12 @@ tputs (str, nlines, outfun) register int speed; #ifdef emacs - extern baud_rate; + extern EMACS_INT baud_rate; speed = baud_rate; + /* For quite high speeds, convert to the smaller + units to avoid overflow. */ + if (speed > 10000) + speed = - speed / 100; #else if (ospeed == 0) speed = tputs_baud_rate; @@ -304,11 +357,14 @@ tputs (str, nlines, outfun) while (*str) (*outfun) (*str++); - /* padcount is now in units of tenths of msec. */ - padcount *= speeds[ospeed]; + /* PADCOUNT is now in units of tenths of msec. + SPEED is measured in characters per 10 seconds + or in characters per .1 seconds (if negative). + We use the smaller units for larger speeds to avoid overflow. */ + padcount *= speed; padcount += 500; padcount /= 1000; - if (speeds[ospeed] < 0) + if (speed < 0) padcount = -padcount; else { @@ -322,7 +378,7 @@ tputs (str, nlines, outfun) /* Finding the termcap entry in the termcap data base. */ -struct buffer +struct termcap_buffer { char *beg; int size; @@ -395,13 +451,13 @@ tgetent (bp, name) { register char *termcap_name; register int fd; - struct buffer buf; + struct termcap_buffer buf; register char *bp1; - char *bp2; + char *tc_search_point; char *term; int malloc_size = 0; register int c; - char *tcenv; /* TERMCAP value, if it contains :tc=. */ + char *tcenv = NULL; /* TERMCAP value, if it contains :tc=. */ char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ int filep; @@ -421,6 +477,11 @@ tgetent (bp, name) } #endif /* INTERNAL_TERMINAL */ + /* For compatibility with programs like `less' that want to + put data in the termcap buffer themselves as a fallback. */ + if (bp) + term_entry = bp; + termcap_name = getenv ("TERMCAP"); if (termcap_name && *termcap_name == '\0') termcap_name = NULL; @@ -458,7 +519,7 @@ tgetent (bp, name) } if (!termcap_name || !filep) - termcap_name = TERMCAP_NAME; + termcap_name = TERMCAP_FILE; /* Here we know we must search a file and termcap_name has its name. */ @@ -480,7 +541,7 @@ tgetent (bp, name) malloc_size = indirect ? strlen (tcenv) + 1 : buf.size; bp = (char *) xmalloc (malloc_size); } - bp1 = bp; + tc_search_point = bp1 = bp; if (indirect) /* Copy the data from the environment variable. */ @@ -508,14 +569,13 @@ tgetent (bp, name) /* If BP is malloc'd by us, make sure it is big enough. */ if (malloc_size) { - malloc_size = bp1 - bp + buf.size; - termcap_name = (char *) xrealloc (bp, malloc_size); - bp1 += termcap_name - bp; - bp = termcap_name; + int offset1 = bp1 - bp, offset2 = tc_search_point - bp; + malloc_size = offset1 + buf.size; + bp = termcap_name = (char *) xrealloc (bp, malloc_size); + bp1 = termcap_name + offset1; + tc_search_point = termcap_name + offset2; } - bp2 = bp1; - /* Copy the line of the entry from buf into bp. */ termcap_name = buf.ptr; while ((*bp1++ = c = *termcap_name++) && c != '\n') @@ -529,7 +589,8 @@ tgetent (bp, name) /* Does this entry refer to another terminal type's entry? If something is found, copy it into heap and null-terminate it. */ - term = tgetst1 (find_capability (bp2, "tc"), (char **) 0); + tc_search_point = find_capability (tc_search_point, "tc"); + term = tgetst1 (tc_search_point, (char **) 0); } close (fd); @@ -540,8 +601,6 @@ tgetent (bp, name) ret: term_entry = bp; - if (malloc_size) - return (int) bp; return 1; } @@ -555,7 +614,7 @@ static int scan_file (str, fd, bufp) char *str; int fd; - register struct buffer *bufp; + register struct termcap_buffer *bufp; { register char *end; @@ -651,7 +710,7 @@ compare_contin (str1, str2) static char * gobble_line (fd, bufp, append_end) int fd; - register struct buffer *bufp; + register struct termcap_buffer *bufp; char *append_end; { register char *end; @@ -752,4 +811,3 @@ tprint (cap) } #endif /* TEST */ -