From: Bruno Haible Date: Mon, 18 Dec 2006 12:19:01 +0000 (+0000) Subject: Use the terminfo functions where possible. X-Git-Tag: v0.17~575 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5139e56f7cf0cbfe606b29b1cb41215bdcf32a2;p=thirdparty%2Fgettext.git Use the terminfo functions where possible. --- diff --git a/gnulib-local/ChangeLog b/gnulib-local/ChangeLog index 0228f8ab8..78355ed42 100644 --- a/gnulib-local/ChangeLog +++ b/gnulib-local/ChangeLog @@ -1,3 +1,13 @@ +2006-12-16 Bruno Haible + + * 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 * lib/term-ostream.oo.c (term_ostream_create): Fix tgetstr argument diff --git a/gnulib-local/lib/term-ostream.oo.c b/gnulib-local/lib/term-ostream.oo.c index 855d18433..7b98b88a8 100644 --- a/gnulib-local/lib/term-ostream.oo.c +++ b/gnulib-local/lib/term-ostream.oo.c @@ -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. */ diff --git a/gnulib-local/lib/termcap.h b/gnulib-local/lib/termcap.h index 1dec4ffb5..5c76898d1 100644 --- a/gnulib-local/lib/termcap.h +++ b/gnulib-local/lib/termcap.h @@ -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 . */ diff --git a/gnulib-local/m4/termcap.m4 b/gnulib-local/m4/termcap.m4 index 3ea6ec1b0..195fb5794 100644 --- a/gnulib-local/m4/termcap.m4 +++ b/gnulib-local/m4/termcap.m4 @@ -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], [