(describe_syntax_1): Pass new args to describe_vector.
[bpt/emacs.git] / src / termcap.c
index bcd1ece..f41f24f 100644 (file)
@@ -1,5 +1,5 @@
 /* Work-alike for termcap, plus extra features.
-   Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86, 93, 94, 95 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,12 +13,15 @@ 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 <config.h>
+#endif
+
+#ifdef emacs
 
 /* Get the O_* definitions for open et al.  */
 #include <sys/file.h>
@@ -26,11 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <fcntl.h>
 #endif
 
-#else /* not HAVE_CONFIG_H */
-
-#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
-#define bcopy(s, d, n) memcpy ((d), (s), (n))
-#endif
+#else /* not emacs */
 
 #ifdef STDC_HEADERS
 #include <stdlib.h>
@@ -41,6 +40,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 <unistd.h>
 #endif
@@ -48,7 +52,7 @@ char *realloc ();
 #include <fcntl.h>
 #endif
 
-#endif /* not HAVE_CONFIG_H */
+#endif /* not emacs */
 
 #ifndef NULL
 #define NULL (char *) 0
@@ -75,8 +79,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
@@ -267,14 +271,14 @@ char PC;
 /* 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 */
   };
 
@@ -290,11 +294,17 @@ tputs (str, nlines, outfun)
 #ifdef emacs
   extern 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;
-  else
+  else if (ospeed > 0 && ospeed < (sizeof speeds / sizeof speeds[0]))
     speed = speeds[ospeed];
+  else
+    speed = 0;
 #endif
 
   if (!str)
@@ -318,11 +328,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
     {
@@ -411,7 +424,7 @@ tgetent (bp, name)
   register int fd;
   struct buffer buf;
   register char *bp1;
-  char *bp2;
+  char *tc_search_point;
   char *term;
   int malloc_size = 0;
   register int c;
@@ -435,6 +448,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;
@@ -472,7 +490,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.  */
 
@@ -494,7 +512,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.  */
@@ -525,11 +543,10 @@ tgetent (bp, name)
          malloc_size = bp1 - bp + buf.size;
          termcap_name = (char *) xrealloc (bp, malloc_size);
          bp1 += termcap_name - bp;
+         tc_search_point += termcap_name - bp;
          bp = termcap_name;
        }
 
-      bp2 = bp1;
-
       /* Copy the line of the entry from buf into bp.  */
       termcap_name = buf.ptr;
       while ((*bp1++ = c = *termcap_name++) && c != '\n')
@@ -543,7 +560,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);
@@ -554,8 +572,6 @@ tgetent (bp, name)
 
  ret:
   term_entry = bp;
-  if (malloc_size)
-    return (int) bp;
   return 1;
 }
 
@@ -766,4 +782,3 @@ tprint (cap)
 }
 
 #endif /* TEST */
-