+
+/*
+ * These functions handles the case of outputting terminal strings depending
+ * on the terminfo setting.
+ */
+
+/*
+ * We should only be called if we haven't yet called setupterm()
+ */
+
+void
+initialize_terminfo(void)
+{
+ int errret, rc;
+
+ rc = setupterm(NULL, fileno(stdout), &errret);
+
+ if (rc != 0 || errret != 1)
+ termstatus = -1;
+ else
+ termstatus = 1;
+}
+
+/*
+ * Place the results of the specified string entry into the str register.
+ *
+ * Arguments are:
+ *
+ * t - Pointer to instruction table entry (used to create fmt instruction)
+ * cap - Name of terminfo capability to insert (e.g., "bold", or "sgr0").
+ *
+ * This ended up being more complicated than I hoped. You need to fetch the
+ * entry via tigetstr(), but there MAY be a padding format embedded in what
+ * gets returned by tigetstr(), so you have to run it through tputs().
+ * And of course tputs() is designed to output to a terminal, so you have
+ * capture every byte output by the tputs() callback to get the final
+ * string to write to the format engine.
+ *
+ * If padding bytes are NULs that will be a problem for us, but some quick
+ * experimentation suggests that padding bytes are mostly a non-issue anymore.
+ * If they still crop up we'll have to figure out how to deal with them.
+ */
+
+void
+get_term_stringcap(struct ftable *t, char *cap)
+{
+ char *parm;
+
+ /*
+ * Common to all functions; initialize the termcap if we need it.
+ * If it didn't initialize successfully, return silently
+ */
+
+ if (termstatus == 0)
+ initialize_terminfo();
+
+ if (termstatus == -1)
+ return;
+
+ parm = tigetstr(cap);
+
+ if (parm == (char *) -1 || parm == NULL) {
+ return;
+ }
+
+ termcbufp = termcbuf;
+
+ tputs(parm, 1, termbytes);
+
+ termcbufp = '\0';
+
+ LS(t->f_type, termcbuf);
+}
+
+/*
+ * Store a sequence of characters in our local buffer
+ */
+
+static int
+termbytes(int c)
+{
+ size_t offset;
+
+ /*
+ * Bump up the buffer size if we've reached the end (leave room for
+ * a trailing NUL)
+ */
+
+ if ((offset = termcbufp - termcbuf) - 1 >= termcbufsz) {
+ termcbufsz += 64;
+ termcbuf = mh_xrealloc(termcbuf, termcbufsz);
+ termcbufp = termcbuf + offset;
+ }
+
+ *termcbufp++ = c;
+
+ return 0;
+}