>From a539037f3bf78ac6cd607cc21490bad587fa94b7 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 30 Jan 2022 16:44:27 +0100 Subject: [PATCH 1/2] terminfo, terminfo-h: New modules. * lib/terminfo.h: New file, from GNU gettext. * m4/terminfo.m4: New file, from GNU gettext. * modules/terminfo: New file, from GNU gettext. * modules/terminfo-h: New file, from GNU gettext. --- ChangeLog | 8 + lib/terminfo.h | 116 +++++++++++++ m4/terminfo.m4 | 401 +++++++++++++++++++++++++++++++++++++++++++++ modules/terminfo | 29 ++++ modules/terminfo-h | 21 +++ 5 files changed, 575 insertions(+) create mode 100644 lib/terminfo.h create mode 100644 m4/terminfo.m4 create mode 100644 modules/terminfo create mode 100644 modules/terminfo-h diff --git a/ChangeLog b/ChangeLog index e4cd2b65e6..16e2955418 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2022-01-30 Bruno Haible + + terminfo, terminfo-h: New modules. + * lib/terminfo.h: New file, from GNU gettext. + * m4/terminfo.m4: New file, from GNU gettext. + * modules/terminfo: New file, from GNU gettext. + * modules/terminfo-h: New file, from GNU gettext. + 2022-01-30 Bruno Haible termcap: Add tests. diff --git a/lib/terminfo.h b/lib/terminfo.h new file mode 100644 index 0000000000..d542ef2d55 --- /dev/null +++ b/lib/terminfo.h @@ -0,0 +1,116 @@ +/* Information about terminal capabilities. + Copyright (C) 2006-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2006. */ + +#ifndef _TERMINFO_H +#define _TERMINFO_H + +/* Including or is dangerous, because it also declares + a lot of junk, such as variables PC, UP, and other. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#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); + +#elif HAVE_TERMCAP + +/* Gets the capability information for terminal type TYPE. + BP must point to a buffer, at least 2048 bytes large. + Returns 1 if successful, 0 if TYPE is unknown, -1 on other error. */ +extern int tgetent (char *bp, const char *type); + +/* Retrieves the value of a numerical capability. + Returns -1 if it is not available. */ +extern int tgetnum (const char *id); + +/* Retrieves the value of a boolean capability. + Returns 1 if it available, 0 otherwise. */ +extern int tgetflag (const char *id); + +/* Retrieves the value of a string capability. + Returns NULL if it is not available. + Also, if AREA != NULL, stores it at *AREA and advances *AREA. */ +extern const char * tgetstr (const char *id, char **area); + +#endif + +#if HAVE_TPARAM + +/* API provided by GNU termcap in . */ + +/* Instantiates a string capability with format strings. + BUF must be a buffer having room for BUFSIZE bytes. + The return value is either equal to BUF or freshly malloc()ed. */ +extern char * tparam (const char *str, void *buf, int bufsize, ...); + +#else + +/* API provided by + - GNU ncurses in , , , + - OSF/1 curses in , , + - Solaris, AIX, HP-UX, IRIX curses in , + - gnulib's replacement. */ + +/* Instantiates a string capability with format strings. + The return value is statically allocated and must not be freed. */ +extern char * tparm (const char *str, ...); + +#endif + +#if HAVE_TERMINFO || HAVE_TERMCAP + +/* Retrieves a string that causes cursor positioning to (column, row). + This function is necessary because the string returned by tgetstr ("cm") + is in a special format. */ +extern const char * tgoto (const char *cm, int column, int row); + +#endif + +/* Retrieves the value of a string capability. + OUTCHARFUN is called in turn for each 'char' of the result. + This function is necessary because string capabilities can contain + padding commands. */ +extern void tputs (const char *cp, int affcnt, int (*outcharfun) (int)); + +/* The ncurses functions for color handling (see ncurses/base/lib_color.c) + are overkill: Most terminal emulators support only a fixed, small number + of colors. */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TERMINFO_H */ diff --git a/m4/terminfo.m4 b/m4/terminfo.m4 new file mode 100644 index 0000000000..e923518540 --- /dev/null +++ b/m4/terminfo.m4 @@ -0,0 +1,401 @@ +# terminfo.m4 serial 4 +dnl Copyright (C) 2000-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gl_TERMINFO], +[ + AC_REQUIRE([gl_TERMINFO_BODY]) + if test $gl_cv_terminfo_tparam = no && test $gl_cv_terminfo_tparm = no; then + AC_LIBOBJ([tparm]) + fi + case "$gl_cv_terminfo" in + no*) + case "$gl_cv_termcap" in + no*) + AC_LIBOBJ([tputs]) + ;; + esac + ;; + esac +]) + +AC_DEFUN([gl_TERMINFO_BODY], +[ + dnl Some systems have setupterm(), tigetnum(), tigetstr(), tigetflag(), + dnl tputs(), tgoto() in the same library as tgetent(), tgetnum(), tgetstr(), + dnl tgetflag(), e.g. Linux (in libncurses) or Solaris (in libtermcap = + dnl libncurses). + dnl Some systems have them in a different library, e.g. OSF/1 (in libcurses, + dnl not in libtermcap) or HP-UX (in libxcurses, not in libtermcap). + dnl Some systems, like NetBSD or BeOS, don't have these functions at all; + dnl they have only a libtermcap. + dnl Some systems, like BeOS, use GNU termcap, which has tparam() instead of + dnl tparm(). + dnl Some systems, like mingw, have nothing at all. + + dnl Some people want to avoid these libraries, in special situations such + dnl as when cross-compiling. + AC_REQUIRE([gl_CURSES]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + if test "$gl_curses_allowed" != no; then + + dnl Search for libncurses and define LIBNCURSES, LTLIBNCURSES and INCNCURSES + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([ncurses]) + + dnl Search for libtermcap and define LIBTERMCAP, LTLIBTERMCAP and INCTERMCAP + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([termcap]) + + dnl Search for libxcurses and define LIBXCURSES, LTLIBXCURSES and INCXCURSES + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([xcurses]) + + dnl Search for libcurses and define LIBCURSES, LTLIBCURSES and INCCURSES + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([curses]) + + else + + LIBNCURSES= + LTLIBNCURSES= + INCNCURSES= + + LIBTERMCAP= + LTLIBTERMCAP= + INCTERMCAP= + + LIBXCURSES= + LTLIBXCURSES= + INCXCURSES= + + LIBCURSES= + LTLIBCURSES= + INCCURSES= + + fi + + dnl When searching for the terminfo functions, prefer libtermcap over + dnl libxcurses and libcurses, because it is smaller. + AC_CACHE_CHECK([where terminfo library functions come from], [gl_cv_terminfo], [ + gl_cv_terminfo="not found, consider installing GNU ncurses" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[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_terminfo=libc]) + if test "$gl_cv_terminfo" != libc; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBNCURSES" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[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_terminfo=libncurses]) + LIBS="$gl_save_LIBS" + if test "$gl_cv_terminfo" != libncurses; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBTERMCAP" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[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_terminfo=libtermcap]) + LIBS="$gl_save_LIBS" + if test "$gl_cv_terminfo" != libtermcap; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBXCURSES" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[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_terminfo=libxcurses]) + LIBS="$gl_save_LIBS" + if test "$gl_cv_terminfo" != libxcurses; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBCURSES" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[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_terminfo=libcurses]) + LIBS="$gl_save_LIBS" + fi + fi + fi + fi + ]) + case "$gl_cv_terminfo" in + libc) + LIBTERMINFO= + LTLIBTERMINFO= + INCTERMINFO= + ;; + libncurses) + LIBTERMINFO="$LIBNCURSES" + LTLIBTERMINFO="$LTLIBNCURSES" + INCTERMINFO="$INCNCURSES" + ;; + libtermcap) + LIBTERMINFO="$LIBTERMCAP" + LTLIBTERMINFO="$LTLIBTERMCAP" + INCTERMINFO="$INCTERMCAP" + ;; + libxcurses) + LIBTERMINFO="$LIBXCURSES" + LTLIBTERMINFO="$LTLIBXCURSES" + INCTERMINFO="$INCXCURSES" + ;; + libcurses) + LIBTERMINFO="$LIBCURSES" + LTLIBTERMINFO="$LTLIBCURSES" + INCTERMINFO="$INCCURSES" + ;; + esac + case "$gl_cv_terminfo" in + libc | libncurses | libtermcap | libxcurses | libcurses) + AC_DEFINE([HAVE_TERMINFO], 1, + [Define if setupterm(), tigetnum(), tigetstr(), tigetflag() + are among the termcap library functions.]) + ;; + *) + dnl Use the termcap functions as a fallback. + AC_CACHE_CHECK([where termcap library functions come from], [gl_cv_termcap], [ + gl_cv_termcap="not found, consider installing GNU ncurses" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern + #ifdef __cplusplus + "C" + #endif + int tgetent (char *, const char *); + ]], + [[return tgetent ((char *) 0, "xterm");]])], + [gl_cv_termcap=libc]) + if test "$gl_cv_termcap" != libc; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBNCURSES" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern + #ifdef __cplusplus + "C" + #endif + int tgetent (char *, const char *); + ]], + [[return tgetent ((char *) 0, "xterm");]])], + [gl_cv_termcap=libncurses]) + LIBS="$gl_save_LIBS" + if test "$gl_cv_termcap" != libncurses; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBTERMCAP" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern + #ifdef __cplusplus + "C" + #endif + int tgetent (char *, const char *); + ]], + [[return tgetent ((char *) 0, "xterm");]])], + [gl_cv_termcap=libtermcap]) + LIBS="$gl_save_LIBS" + fi + fi + ]) + case "$gl_cv_termcap" in + libc) + LIBTERMINFO= + LTLIBTERMINFO= + INCTERMINFO= + ;; + libncurses) + LIBTERMINFO="$LIBNCURSES" + LTLIBTERMINFO="$LTLIBNCURSES" + INCTERMINFO="$INCNCURSES" + ;; + libtermcap) + LIBTERMINFO="$LIBTERMCAP" + LTLIBTERMINFO="$LTLIBTERMCAP" + INCTERMINFO="$INCTERMCAP" + ;; + esac + case "$gl_cv_termcap" in + libc | libncurses | libtermcap) + AC_DEFINE([HAVE_TERMCAP], 1, + [Define if tgetent(), tgetnum(), tgetstr(), tgetflag() + are among the termcap library functions.]) + ;; + esac + ;; + esac + AC_SUBST([LIBTERMINFO]) + AC_SUBST([LTLIBTERMINFO]) + AC_SUBST([INCTERMINFO]) + + 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_terminfo_tparam], [ + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBTERMINFO" + gl_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCTERMINFO" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern + #ifdef __cplusplus + "C" + #endif + char * tparam (const char *, void *, int, ...); + char buf; + ]], + [[return tparam ("\033\133%dm", &buf, 1, 8);]])], + [gl_cv_terminfo_tparam=yes], + [gl_cv_terminfo_tparam=no]) + CPPFLAGS="$gl_save_CPPFLAGS" + LIBS="$gl_save_LIBS" + ]) + if test $gl_cv_terminfo_tparam = yes; then + AC_DEFINE([HAVE_TPARAM], 1, + [Define if tparam() is among the termcap library functions.]) + else + dnl Test whether a tparm() function is provided. It is missing e.g. + dnl in NetBSD 3.0 libtermcap. + AC_CACHE_CHECK([for tparm], [gl_cv_terminfo_tparm], [ + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBTERMINFO" + gl_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCTERMINFO" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern + #ifdef __cplusplus + "C" + #endif + char * tparm (const char *, ...); + ]], + [[return tparm ("\033\133%dm", 8);]])], + [gl_cv_terminfo_tparm=yes], [gl_cv_terminfo_tparm=no]) + CPPFLAGS="$gl_save_CPPFLAGS" + LIBS="$gl_save_LIBS" + ]) + fi +]) diff --git a/modules/terminfo b/modules/terminfo new file mode 100644 index 0000000000..c7b0a8b71f --- /dev/null +++ b/modules/terminfo @@ -0,0 +1,29 @@ +Description: +Information about terminal capabilities. + +Files: +m4/terminfo.m4 +m4/curses.m4 +lib/tparm.c +lib/tputs.c + +Depends-on: +havelib +attribute +c-ctype + +configure.ac: +gl_TERMINFO + +Makefile.am: +if GL_COND_LIBTOOL +lib_LDFLAGS += $(LTLIBTERMINFO) +endif + +Include: + +License: +LGPL + +Maintainer: +Bruno Haible diff --git a/modules/terminfo-h b/modules/terminfo-h new file mode 100644 index 0000000000..528b03d507 --- /dev/null +++ b/modules/terminfo-h @@ -0,0 +1,21 @@ +Description: +Information about terminal capabilities. + +Files: +lib/terminfo.h + +Depends-on: +terminfo + +configure.ac: + +Makefile.am: + +Include: +"terminfo.h" + +License: +LGPL + +Maintainer: +Bruno Haible -- 2.25.1