groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3] [grotty]: Use terminfo.


From: Lennart Jablonka
Subject: Re: [PATCH v3] [grotty]: Use terminfo.
Date: Mon, 26 Feb 2024 14:40:53 +0000

Quoth G. Branden Robinson:
I'm attaching my progress so far.

Nice! I guess I’ll drop a few comments on it. (Uncommented hunks omitted.)

--- a/src/devices/grotty/tty.cpp
+++ b/src/devices/grotty/tty.cpp
@@ -916,8 +920,86 @@ printer *make_printer()
  return new tty_printer();
}

-static void update_options()
+static void initialize_terminal()
{
+  int err;
+
+  char *terminal_type = strdup(getenv("TERM"));
+  int ret = setupterm(NULL /* use TERM */, STDOUT_FILENO, &err);
+  size_t len = strlen(terminal_type);
+
+  if (len == 0)
+      fatal("TERM environment variable must be set; aborting");
+
+  if (OK == ret) {
+    ;
+  }
+  else if (ERR == ret) {
+    const char msg1[] = "entry for '";
+    const char msg2[] = "' not found in terminal database";
+    const int bufsz = len + sizeof msg1 + sizeof msg2 + 1 /* `\0` */;

bufsz should be size_t. len is size_t, the sizeof expressions are size_t, and calloc takes size_t.

+    char *errbuf = static_cast<char *>(calloc(bufsz, sizeof (char)));
+    (void) snprintf(errbuf, bufsz, "%s%s%s", msg1, terminal_type, msg2);

You could simplify that string handling using any of
  • snprintf(malloc((size = snprintf(NULL, 0, …))), size, …),
  • asprintf,
  • the string class,
  • the std::string class,
but …

+    const char no_database[] = "terminfo database entry not found";
+
+    switch (err) {
+    case -1:
+      fatal(no_database);
+      break;
+    case 0:
+      fatal(errbuf);

Did I miss something on why you’re allocating the error buffer even if never used (err == 1), not freeing it in that case, and introducing a bug à la printf(user_input) (when TERM=%), instead of doing:

        fatal("entry for '%1' not found in terminal database", terminal_type);

For the record, I think fatal() should be a simple wrapper for vfprintf.

+    case 1:
+      // POSIX calls this case "Success".  As an extension, to ncurses
+      // it means a hardcopy terminal.  While fatal for many terminfo
+      // applications, we're fine with it.
+      break;
+    default:
+      fatal("terminfo interface is nonstandard; aborting");
+    }
+  }
+  else
+    fatal("terminfo interface is nonstandard; aborting");
+
+  if (tigetflag("hc")) {

Why are you using tigetflag instead of accessing the long names defined by term.h? They do seem a little underspecified by X/Open Curses, but do exist, both there, somewhat, and in the implementations.

+    // hardcopy terminal
+    do_sgr_italics = false;
+    do_reverse_video = false;
+
+    if (want_sgr_italics) {
+      if (want_capability_warnings)
+       warning("terminal type %1 is incapable of SGR italics",
+               terminal_type);

Above, you 'quoted' terminal_type; here, you don’t.

+      want_sgr_italics = false;
+    }
+  }
+  else
+    if (want_sgr_italics)
+      if ((tigetstr("sitm") == 0 /* nullptr */)
+          || (tigetstr("ritm") == 0 /* nullptr */)) {
+       if (want_capability_warnings)
+         warning("terminal type %1 is incapable of SGR italics",
+                 terminal_type);
+       want_sgr_italics = false;
+      }
+
+  // X/Open Curses Issue 7 defines "os" as "Terminal overstrikes on
+  // hard-copy terminal".  However, ncurses's terminfo database defines
+  // it for graphical terminals as well; see entries for wy99gt-tek,
+  // wy370-tek, tek, tek4013, gt40, and so on.  We therefore regard it
+  // as generally relevant.
+  if (tigetflag("os")) {
+    // can overstrike
+    do_bold = want_emboldening_by_overstriking;
+    do_underline = want_italics_by_underlining;
+  }
+  else
+    if (want_emboldening_by_overstriking
+       || want_italics_by_underlining
+       || want_glyph_composition_by_overstriking)
+      if (want_capability_warnings)
+       warning("terminal type %1 is incapable of overstriking",
+               terminal_type);
+
  if (use_overstriking_drawing_scheme) {
    do_sgr_italics = false;
    do_reverse_video = false;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]