]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Use the terminfo functions where possible.
authorBruno Haible <bruno@clisp.org>
Mon, 18 Dec 2006 12:19:01 +0000 (12:19 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:14:30 +0000 (12:14 +0200)
gnulib-local/ChangeLog
gnulib-local/lib/term-ostream.oo.c
gnulib-local/lib/termcap.h
gnulib-local/m4/termcap.m4

index 0228f8ab8204e060b634d69d05393d27a7f9c035..78355ed42f0b4cc07c86b77f5be168765e4cb71a 100644 (file)
@@ -1,3 +1,13 @@
+2006-12-16  Bruno Haible  <bruno@clisp.org>
+
+       * m4/termcap.m4 (gl_TERMCAP_BODY): Also test for the terminfo
+       functions.
+       * lib/termcap.h (setupterm, tigetnum, tigetflag, tigetstr): New
+       declarations.
+       * lib/term-ostream.oo.c (xstrdup0) [HAVE_TERMINFO]: Handle (char*)-1
+       return value from tigetstr.
+       (term_ostream_create) [HAVE_TERMINFO]: Prefer the terminfo API.
+
 2006-12-16  Bruno Haible  <bruno@clisp.org>
 
        * lib/term-ostream.oo.c (term_ostream_create): Fix tgetstr argument
index 855d18433be6f7559fbfea726677d4021548aad3..7b98b88a85246f50833c0e6fe4075b500026ed8b 100644 (file)
@@ -1661,7 +1661,13 @@ term_ostream::set_underline (term_ostream_t stream, term_underline_t underline)
 static inline char *
 xstrdup0 (const char *str)
 {
-  return (str != NULL ? xstrdup (str) : NULL);
+  if (str == NULL)
+    return NULL;
+#if HAVE_TERMINFO
+  if (str == (const char *)(-1))
+    return NULL;
+#endif
+  return xstrdup (str);
 }
 
 term_ostream_t
@@ -1693,6 +1699,33 @@ term_ostream_create (int fd, const char *filename)
   term = getenv ("TERM");
   if (term != NULL && term[0] != '\0')
     {
+      /* When the terminfo function are available, we prefer them over the
+        termcap functions because
+          1. they don't risk a buffer overflow,
+          2. on OSF/1, for TERM=xterm, the tiget* functions provide access
+             to the number of colors and the color escape sequences, whereas
+             the tget* functions don't provide them.  */
+#if HAVE_TERMINFO
+      int err = 1;
+
+      if (setupterm (term, fd, &err) || err == 1)
+       {
+         /* Retrieve particular values depending on the terminal type.  */
+         stream->max_colors = tigetnum ("colors");
+         stream->no_color_video = tigetnum ("ncv");
+         stream->set_a_foreground = xstrdup0 (tigetstr ("setaf"));
+         stream->set_foreground = xstrdup0 (tigetstr ("setf"));
+         stream->set_a_background = xstrdup0 (tigetstr ("setab"));
+         stream->set_background = xstrdup0 (tigetstr ("setb"));
+         stream->orig_pair = xstrdup0 (tigetstr ("op"));
+         stream->enter_bold_mode = xstrdup0 (tigetstr ("bold"));
+         stream->enter_italics_mode = xstrdup0 (tigetstr ("sitm"));
+         stream->exit_italics_mode = xstrdup0 (tigetstr ("ritm"));
+         stream->enter_underline_mode = xstrdup0 (tigetstr ("smul"));
+         stream->exit_underline_mode = xstrdup0 (tigetstr ("rmul"));
+         stream->exit_attribute_mode = xstrdup0 (tigetstr ("sgr0"));
+       }
+#else
       struct { char buf[1024]; char canary[4]; } termcapbuf;
       int retval;
 
@@ -1729,7 +1762,7 @@ term_ostream_create (int fd, const char *filename)
          stream->exit_underline_mode = xstrdup0 (tgetstr ("ue", TEBP));
          stream->exit_attribute_mode = xstrdup0 (tgetstr ("me", TEBP));
 
-#ifdef __BEOS__
+# ifdef __BEOS__
          /* The BeOS termcap entry for "beterm" is broken: For "AF" and "AB"
             it contains balues in terminfo syntax but the system's tparam()
             function understands only the termcap syntax.  */
@@ -1745,7 +1778,7 @@ term_ostream_create (int fd, const char *filename)
              free (stream->set_a_background);
              stream->set_a_background = xstrdup ("\033[4%dm");
            }
-#endif
+# endif
 
          /* Done with tgetstr.  Detect possible buffer overflow.  */
          #undef TEBP
@@ -1753,6 +1786,7 @@ term_ostream_create (int fd, const char *filename)
            /* Buffer overflow!  */
            abort ();
        }
+#endif
     }
 
   /* Infer the capabilities.  */
index 1dec4ffb5ec778be9daf196bf243b2fd14d53765..5c76898d1d3cdfd451b053dca6136a467b201bdc 100644 (file)
@@ -43,6 +43,27 @@ extern int tgetflag (const char *id);
    Also, if AREA != NULL, stores it at *AREA and advances *AREA.  */
 extern const char * tgetstr (const char *id, char **area);
 
+#if HAVE_TERMINFO
+
+/* Gets the capability information for terminal type TYPE and prepares FD.
+   Returns 0 if successful, -1 upon error.  If ERRP is non-NULL, also returns
+   an error indicator in *ERRP; otherwise an error is signalled.  */
+extern int setupterm (const char *type, int fd, int *errp);
+
+/* Retrieves the value of a numerical capability.
+   Returns -1 if it is not available, -2 if ID is invalid.  */
+extern int tigetnum (const char *id);
+
+/* Retrieves the value of a boolean capability.
+   Returns 1 if it available, 0 if not available, -1 if ID is invalid.  */
+extern int tigetflag (const char *id);
+
+/* Retrieves the value of a string capability.
+   Returns NULL if it is not available, (char *)(-1) if ID is invalid.  */
+extern const char * tigetstr (const char *id);
+
+#endif
+
 #if HAVE_TPARAM
 
 /* API provided by GNU termcap in <termcap.h>.  */
index 3ea6ec1b057aa93c857e85b91fbcd49b7dc73899..195fb5794d59d261174329e9257947881a27f32e 100644 (file)
@@ -1,4 +1,4 @@
-# termcap.m4 serial 3 (gettext-0.16.2)
+# termcap.m4 serial 4 (gettext-0.16.2)
 dnl Copyright (C) 2000-2002, 2006 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -23,6 +23,8 @@ AC_DEFUN([gl_TERMCAP_BODY],
   dnl because libtermcap is unsecure by design and obsolete since 1994.
   dnl libcurses is useless: all platforms which have libcurses also have
   dnl libtermcap, and libcurses is unusable on some old Unices.
+  dnl Some systems have the terminfo functions setupterm(), tigetnum(),
+  dnl tigetstr(), tigetflag() in the same library.
   dnl Some systems, like BeOS, use GNU termcap, which has tparam() instead of
   dnl tparm().
 
@@ -87,6 +89,44 @@ AC_DEFUN([gl_TERMCAP_BODY],
   AC_SUBST([LTLIBTERMCAP])
   AC_SUBST([INCTERMCAP])
 
+  dnl Test whether the terminfo functions are available from the same library.
+  AC_CACHE_CHECK([for terminfo functions], [gl_cv_func_terminfo], [
+    gl_save_LIBS="$LIBS"
+    LIBS="$LIBS $LIBTERMCAP"
+    gl_save_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $INCTERMCAP"
+    AC_TRY_LINK([extern
+      #ifdef __cplusplus
+      "C"
+      #endif
+      int setupterm (const char *, int, int *);
+      extern
+      #ifdef __cplusplus
+      "C"
+      #endif
+      int tigetnum (const char *);
+      extern
+      #ifdef __cplusplus
+      "C"
+      #endif
+      int tigetflag (const char *);
+      extern
+      #ifdef __cplusplus
+      "C"
+      #endif
+      const char * tigetstr (const char *);
+      ], [return setupterm ("xterm", 0, (int *)0)
+                 + tigetnum ("colors") + tigetflag ("hc") + * tigetstr("oc");],
+      [gl_cv_func_terminfo=yes], [gl_cv_func_terminfo=no])
+    CPPFLAGS="$gl_save_CPPFLAGS"
+    LIBS="$gl_save_LIBS"
+  ])
+  if test $gl_cv_func_terminfo = yes; then
+    AC_DEFINE([HAVE_TERMINFO], 1,
+      [Define if setupterm(), tigetnum(), tigetstr(), tigetflag()
+       are among the termcap library functions.])
+  fi
+
   dnl Test against the old GNU termcap, which provides a tparam() function
   dnl instead of the classical tparm() function.
   AC_CACHE_CHECK([for tparam], [gl_cv_func_tparam], [