(doc-view-new-window-function): Be a bit more defensive.
[bpt/emacs.git] / src / termcap.c
index 472005f..9b4a7f6 100644 (file)
@@ -1,5 +1,6 @@
 /* Work-alike for termcap, plus extra features.
-   Copyright (C) 1985, 86, 93, 94, 95 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1993, 1994, 1995, 2000, 2001, 2002, 2003,
+                 2004, 2005, 2006, 2007, 2008 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,8 +14,8 @@ 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, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, 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
@@ -23,6 +24,7 @@ Boston, MA 02111-1307, USA.  */
 
 #ifdef emacs
 
+#include <setjmp.h>
 #include <lisp.h>              /* xmalloc is here */
 /* Get the O_* definitions for open et al.  */
 #include <sys/file.h>
@@ -52,7 +54,7 @@ char *realloc ();
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#ifdef _POSIX_VERSION
+#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
 
@@ -182,7 +184,7 @@ tgetstr (cap, area)
    gives meaning of character following \, or a space if no special meaning.
    Sixteen characters per line within the string.  */
 
-static char esctab[]
+static const char esctab[]
   = " \057\026  \047\014         \
      \025   \015      \
    \005 \013          \
@@ -192,7 +194,7 @@ static char esctab[]
    gives meaning of character following \, or a space if no special meaning.
    Eight characters per line within the string.  */
 
-static char esctab[]
+static const char esctab[]
   = " \007\010  \033\014 \
       \012 \
   \015 \011 \013 \
@@ -279,6 +281,52 @@ tgetst1 (ptr, area)
        }
       *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)
@@ -288,25 +336,26 @@ tgetst1 (ptr, 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
+
 char PC;
 
+#ifndef emacs
 /* Actual baud rate if positive;
    - baud rate / 100 if negative.  */
 
-static int speeds[] =
+static const 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, -288, -384, -576, -1152
-#endif /* not VMS */
   };
 
+#endif /* not emacs */
+
 void
 tputs (str, nlines, outfun)
      register char *str;
@@ -317,7 +366,7 @@ tputs (str, nlines, outfun)
   register int speed;
 
 #ifdef emacs
-  extern int baud_rate;
+  extern EMACS_INT baud_rate;
   speed = baud_rate;
   /* For quite high speeds, convert to the smaller
      units to avoid overflow.  */
@@ -326,10 +375,8 @@ tputs (str, nlines, outfun)
 #else
   if (ospeed == 0)
     speed = tputs_baud_rate;
-  else if (ospeed > 0 && ospeed < (sizeof speeds / sizeof speeds[0]))
-    speed = speeds[ospeed];
   else
-    speed = 0;
+    speed = speeds[ospeed];
 #endif
 
   if (!str)
@@ -390,33 +437,6 @@ static char *gobble_line ();
 static int compare_contin ();
 static int name_match ();
 
-#ifdef VMS
-
-#include <rmsdef.h>
-#include <fab.h>
-#include <nam.h>
-
-static int
-valid_filename_p (fn)
-     char *fn;
-{
-  struct FAB fab = cc$rms_fab;
-  struct NAM nam = cc$rms_nam;
-  char esa[NAM$C_MAXRSS];
-
-  fab.fab$l_fna = fn;
-  fab.fab$b_fns = strlen(fn);
-  fab.fab$l_nam = &nam;
-  fab.fab$l_fop = FAB$M_NAM;
-
-  nam.nam$l_esa = esa;
-  nam.nam$b_ess = sizeof esa;
-
-  return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL;
-}
-
-#else /* !VMS */
-
 #ifdef MSDOS /* MW, May 1993 */
 static int
 valid_filename_p (fn)
@@ -428,8 +448,6 @@ valid_filename_p (fn)
 #define valid_filename_p(fn) (*(fn) == '/')
 #endif
 
-#endif /* !VMS */
-
 /* Find the termcap entry data for terminal type NAME
    and store it in the block that BP points to.
    Record its address for future use.
@@ -453,7 +471,7 @@ tgetent (bp, name)
   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;
 
@@ -565,11 +583,11 @@ 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;
-         tc_search_point += 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;
        }
 
       /* Copy the line of the entry from buf into bp.  */
@@ -807,3 +825,6 @@ tprint (cap)
 }
 
 #endif /* TEST */
+
+/* arch-tag: c2e8d427-2271-4fac-95fe-411857238b80
+   (do not change this comment) */