/* 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
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., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* Emacs config.h may rename various library functions such as malloc. */
#ifdef HAVE_CONFIG_H
#include <config.h>
-#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 <lisp.h> /* xmalloc is here */
+/* Get the O_* definitions for open et al. */
+#include <sys/file.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#else /* not emacs */
#ifdef STDC_HEADERS
#include <stdlib.h>
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 <unistd.h>
#endif
-#ifdef _POSIX_VERSION
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#endif /* not HAVE_CONFIG_H */
+#endif /* not emacs */
#ifndef NULL
#define NULL (char *) 0
#endif
#endif
-#ifndef TERMCAP_NAME
-#define TERMCAP_NAME "/etc/termcap"
+#ifndef TERMCAP_FILE
+#define TERMCAP_FILE "/etc/termcap"
#endif
#ifndef emacs
return NULL;
}
+/* These are already defined in the System framework in Mac OS X and
+ cause prebinding to fail. */
+#ifndef MAC_OSX
int
tgetnum (cap)
char *cap;
return NULL;
return tgetst1 (ptr, area);
}
+#endif /* MAC_OSX */
+
+#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. */
\012 \
\015 \011 \013 \
";
+#endif
/* PTR points to a string value inside a termcap entry.
Copy that value, processing \ and ^ abbreviations,
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++;
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;
}
+
+ /* Sometimes entries have "%pN" which means use parameter N in the
+ next %-substitution. If all such N are continuous in the range
+ [1,9] we can remove each "%pN" because they are redundant, thus
+ reducing bandwidth requirements. True, Emacs is well beyond the
+ days of 150baud teletypes, but some of its users aren't much so.
+
+ This pass could probably be integrated into the one above but
+ abbreviation expansion makes that effort a little more hairy than
+ its worth; this is cleaner. */
+ {
+ register int last_p_param = 0;
+ int remove_p_params = 1;
+ struct { char *beg; int len; } cut[11];
+
+ for (cut[0].beg = p = ret; p < r - 3; p++)
+ {
+ if (!remove_p_params)
+ break;
+ if (*p == '%' && *(p + 1) == 'p')
+ {
+ if (*(p + 2) - '0' == 1 + last_p_param)
+ {
+ cut[last_p_param].len = p - cut[last_p_param].beg;
+ last_p_param++;
+ p += 3;
+ cut[last_p_param].beg = p;
+ }
+ else /* not continuous: bail */
+ remove_p_params = 0;
+ if (last_p_param > 10) /* too many: bail */
+ remove_p_params = 0;
+ }
+ }
+ if (remove_p_params && last_p_param)
+ {
+ register int i;
+ char *wp;
+
+ cut[last_p_param].len = r - cut[last_p_param].beg;
+ for (i = 0, wp = ret; i <= last_p_param; wp += cut[i++].len)
+ bcopy (cut[i].beg, wp, cut[i].len);
+ r = wp;
+ }
+ }
+
*r = '\0';
/* Update *AREA. */
if (area)
\f
/* 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
+
+/* Already defined in the System framework in Mac OS X and causes
+ prebinding to fail. */
+#ifndef MAC_OSX
char PC;
+#endif /* MAC_OSX */
+#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 */
+
+/* Already defined in the System framework in Mac OS X and causes
+ prebinding to fail. */
+#ifndef MAC_OSX
void
tputs (str, nlines, outfun)
register char *str;
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;
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
{
while (padcount-- > 0)
(*outfun) (PC);
}
+#endif /* MAC_OSX */
\f
/* Finding the termcap entry in the termcap data base. */
-struct buffer
+struct termcap_buffer
{
char *beg;
int size;
#include <rmsdef.h>
#include <fab.h>
#include <nam.h>
+#include <starlet.h>
static int
valid_filename_p (fn)
0 if the data base is accessible but the type NAME is not defined
in it, and some other value otherwise. */
+/* Already defined in the System framework in Mac OS X and causes
+ prebinding to fail. */
+#ifndef MAC_OSX
int
tgetent (bp, name)
char *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;
}
#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;
}
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. */
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. */
/* 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')
/* 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);
ret:
term_entry = bp;
- if (malloc_size)
- return (int) bp;
return 1;
}
+#endif /* MAC_OSX */
/* Given file open on FD and buffer BUFP,
scan the file from the beginning until a line is found
scan_file (str, fd, bufp)
char *str;
int fd;
- register struct buffer *bufp;
+ register struct termcap_buffer *bufp;
{
register char *end;
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;
#endif /* TEST */
+/* arch-tag: c2e8d427-2271-4fac-95fe-411857238b80
+ (do not change this comment) */