Pádraig Brady wrote:
> > You could determine that programatically with something like:
> > 
> > if os.system(r'{ tput bold || tput md; } >/dev/null 2>&1') == 0:
> >    # enable bold output

Thanks for the hint. Use of 'tput bold' indeed activates bold-face
output on
  - Linux console (TERM=linux),
  - NetBSD console (TERM=wsvt25),
  - OpenBSD console (TERM=vt220),
  - Emacs *terminal* (TERM=eterm-color).

On the Solaris 11.4 I cannot get bold output; all text is bold there.

On the Solaris 11 OmniOS console (TERM=sun-color), one needs to use
'tput smso'. However, care needs to be taken to not use it on other
systems, including Solaris 11.4, because on most systems, 'tput smso'
activates reverse-video output, not bold output, and that is more
ugly than nothing.

I cannot see why 'tput md' would be useful. 'md' is a termcap capability
name, and termcap is deprecated for 25 years since it's inherently insecure.

Tested with
  $ ./gnulib-tool --create-testdir --dir=aaa assert-h


2024-03-29  Bruno Haible  <br...@clisp.org>

        gnulib-tool: Use bold output on Linux, NetBSD, OpenBSD, OmniOS consoles.
        Reported by Pádraig Brady in
        <https://lists.gnu.org/archive/html/bug-gnulib/2024-03/msg00399.html>.
        * gnulib-tool.sh (func_show_module_list): Use 'tput' to determine the
        "bold" capability of terminal types other than xterm*.
        * pygnulib/constants.py (get_terminfo_string, bold_escapes): New
        functions.
        * pygnulib/GLTestDir.py (GLTestDir.execute): Invoke
        constants.bold_escapes.
        * pygnulib/GLImport.py (GLImport.prepare): Likewise.

diff --git a/gnulib-tool.sh b/gnulib-tool.sh
index e0c8cfafbd..6b12542adc 100755
--- a/gnulib-tool.sh
+++ b/gnulib-tool.sh
@@ -3260,13 +3260,30 @@ func_modules_transitive_closure ()
 # - tmp             pathname of a temporary directory
 func_show_module_list ()
 {
-  if case "$TERM" in
-       xterm*) test -t 1;;
-       *) false;;
-     esac; then
-    # Assume xterm compatible escape sequences.
-    bold_on=`printf '\033[1m'`
-    bold_off=`printf '\033[0m'`
+  if test -n "$TERM" && test -t 1; then
+    case "$TERM" in
+      xterm*)
+        # Assume xterm compatible escape sequences.
+        bold_on=`printf '\033[1m'`
+        bold_off=`printf '\033[0m'`
+        ;;
+      *)
+        # Use the terminfo capability strings for "bold" and "sgr0".
+        if test "$TERM" = sun-color && test "`tput smso`" != "`tput rev`"; then
+          # Solaris 11 OmniOS: `tput smso` renders as bold,
+          #                    `tput rmso` is the same as `tput sgr0`.
+          bold_on=`tput smso 2>/dev/null`
+          bold_off=`tput rmso 2>/dev/null`
+        else
+          bold_on=`tput bold 2>/dev/null`
+          bold_off=`tput sgr0 2>/dev/null`
+        fi
+        if test -z "$bold_on" || test -z "$bold_off"; then
+          bold_on=
+          bold_off=
+        fi
+        ;;
+    esac
   else
     bold_on=
     bold_off=
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index 84e1c08689..eb382cadac 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -847,12 +847,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
 
         # Show final module list.
         if verbose >= 0:
-            bold_on = ''
-            bold_off = ''
-            term = os.getenv('TERM', '')
-            if term.startswith('xterm') and os.isatty(1):
-                bold_on = '\033[1m'
-                bold_off = '\033[0m'
+            (bold_on, bold_off) = constants.bold_escapes()
             print('Module list with included dependencies (indented):')
             for module in final_modules:
                 if str(module) in self.config.getModules():
diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py
index e395090b83..2a39eb3c5d 100644
--- a/pygnulib/GLTestDir.py
+++ b/pygnulib/GLTestDir.py
@@ -258,12 +258,7 @@ class GLTestDir(object):
 
         # Show final module list.
         if verbose >= 0:
-            bold_on = ''
-            bold_off = ''
-            term = os.getenv('TERM', '')
-            if term.startswith('xterm') and os.isatty(1):
-                bold_on = '\033[1m'
-                bold_off = '\033[0m'
+            (bold_on, bold_off) = constants.bold_escapes()
             print('Module list with included dependencies (indented):')
             specified_modules_set = { str(module)
                                       for module in specified_modules }
diff --git a/pygnulib/constants.py b/pygnulib/constants.py
index 16a60d1d3d..a6ef32cb47 100644
--- a/pygnulib/constants.py
+++ b/pygnulib/constants.py
@@ -568,4 +568,42 @@ def combine_lines_matching(pattern: re.Pattern, text: str) 
-> str:
     return text
 
 
+def get_terminfo_string(capability: str) -> str:
+    '''Returns the value of a string-type terminfo capability for the current 
value of $TERM.
+    Returns the empty string if not defined.'''
+    value = ''
+    try:
+        value = sp.run(['tput', capability], stdout=sp.PIPE, 
stderr=sp.DEVNULL).stdout.decode('utf-8')
+    except Exception:
+        pass
+    return value
+
+
+def bold_escapes() -> tuple[str, str]:
+    '''Returns the escape sequences for turning bold-face on and off.'''
+    term = os.getenv('TERM', '')
+    if term != '' and os.isatty(1):
+        if term.startswith('xterm'):
+            # Assume xterm compatible escape sequences.
+            bold_on = '\033[1m'
+            bold_off = '\033[0m'
+        else:
+            # Use the terminfo capability strings for "bold" and "sgr0".
+            if term == 'sun-color' and get_terminfo_string('smso') != 
get_terminfo_string('rev'):
+                # Solaris 11 OmniOS: `tput smso` renders as bold,
+                #                    `tput rmso` is the same as `tput sgr0`.
+                bold_on = get_terminfo_string('smso')
+                bold_off = get_terminfo_string('rmso')
+            else:
+                bold_on = get_terminfo_string('bold')
+                bold_off = get_terminfo_string('sgr0')
+            if bold_on == '' or bold_off == '':
+                bold_on = ''
+                bold_off = ''
+    else:
+        bold_on = ''
+        bold_off = ''
+    return (bold_on, bold_off)
+
+
 __all__ += ['APP', 'DIRS', 'MODES', 'UTILS']




Reply via email to