From ec79563b8fb11d33fcd4917ec58cc515a50370c1 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sun, 7 Feb 2021 05:37:22 +0000 Subject: [PATCH] libast: optget(): fix emphasis state initialisation This fixes a bug in libast optget()'s use of emphasis in the display of --man(uals) via standard error on a terminal. Symptom: $ printf --man 2>&1 | more (ok; emphasis disabled, no escape codes shown) $ printf --man (ok; emphasis correctly displayed) $ printf --man 2>&1 | more (whoops; emphasis not disabled; escape codes garble 'more' output) The problem was that the state.emphasis variable was not initialised and, when set to one, was never reset again (except through the use of the --api, --html or --nroff option). The source code also reveals an undocumented feature: if the environment variable $ERROR_OPTIONS contains 'noemphasi', emphasis is forced off, else if it contains 'emphasi', it's forced on. Other characters (such as the final 's' of emphasis) are ignored. This was also broken (forcing off didn't work) and is now fixed. src/lib/libast/misc/optget.c: - Do not assume that enabling emphasis is forever; re-initialise the state on every relevant getopts invocation. - Increase the number of terminals on which emphasis is displayed using ANSI escape codes. (This is a hack and we should ask the OS for the correct codes, but never mind -- ANSI is now universal.) --- src/lib/libast/misc/optget.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/lib/libast/misc/optget.c b/src/lib/libast/misc/optget.c index 6b249737f..ae49831d3 100644 --- a/src/lib/libast/misc/optget.c +++ b/src/lib/libast/misc/optget.c @@ -2535,21 +2535,19 @@ opthelp(const char* oopts, const char* what) sfputc(mp, '\f'); break; default: - if (!state.emphasis) + state.emphasis = 0; + if (x = getenv("ERROR_OPTIONS")) { - if (x = getenv("ERROR_OPTIONS")) + if (strmatch(x, "*noemphasi*")) + break; + if (strmatch(x, "*emphasi*")) { - if (strmatch(x, "*noemphasi*")) - break; - if (strmatch(x, "*emphasi*")) - { - state.emphasis = 1; - break; - } - } - if ((x = getenv("TERM")) && strmatch(x, "(ansi|vt100|xterm)*") && isatty(sffileno(sfstderr))) state.emphasis = 1; + break; + } } + if ((x = getenv("TERM")) && strmatch(x, "(ansi|vt???|xterm|linux|cons|wsvt|sun)*") && isatty(sffileno(sfstderr))) + state.emphasis = 1; break; } x = "";