%;
%;
%; First, test to see if this is the current message. If it is, then
-%; output the bold sequence for this terminal. We use %(zputlit) so the
+%; output the standout sequence for this terminal (or the color red).
+%; We use %(zputlit) so the
%; characters we output don't count against the terminal width.
%;
-%<(cur)%(zputlit(bold))%>\
+%<(cur)%<(hascolor)%(zputlit(fgcolor red))%|%(zputlit(standout))%>%>\
%;
-%; If it's unseen, mark it with an underline
+%; If it's unseen, mark it with bold (or the color green)
%;
-%<(unseen)%(zputlit(underline))%>\
+%<(unseen)%<(hascolor)%(zputlit(fgcolor green))%|%(zputlit(bold))%>%>\
%;
%; Next, output the message number. We print it out using 4 digits, right-
%; justified, padding with spaces.
putlit expr print \fIstr\fR without space compression
zputlit expr print \fIstr\fR without space compression;
\fIstr\fR must occupy no width on display
+bold string set terminal bold mode
+underline string set terminal underlined mode
+standout string set terminal standout mode
+resetterm string reset all terminal attributes
+hascolor boolean terminal supports color
+fgcolor literal string set terminal foreground color
+bgcolor literal string set terminal background color
formataddr expr append \fIarg\fR to \fIstr\fR as a
(comma separated) address list
concataddr expr append \fIarg\fR to \fIstr\fR as a
output width. It can therefore be used for outputting terminal escape
sequences.
.PP
+There are a limited number of function escapes to output terminal escape
+sequences. These sequences are retrieved from the
+.IR terminfo (5)
+database according to the current terminal setting. The (\fIbold\fR\^),
+(\fIunderline\fR\^), and (\fIstandout\fR\^) escapes set bold mode,
+underline mode, and standout mode respectively.
+.PP
+(\fIhascolor\fR\^)
+can be used to determine if the current terminal supports color.
+(\fIfgcolor\fR\^) and (\fIbgcolor\fR\^) set the foreground and
+background colors respectively. Both of these escapes take one literal
+argument, the color name, which can be one of: black, red, green, yellow,
+blue, magenta, cyan, white. (\fIresetterm\fR\^) resets all terminal
+attributes back to their default setting.
+.PP
+All of these terminal escape should be used in conjunction with
+(\fIzputlit\fR\^) (preferred) or (\fIputlit\fR\^), as the normal
+(\fputstr\fR\^) function will strip out control characters.
+.PP
The available output width is kept in an internal register; any output
-past this width will be truncated.
+past this width will be truncated. The one exception to this is
+(\fIzputlit\fR\^) functions will still be executed in case a terminal reset
+code is being placed at the end of the line.
.SS Special Handling
A few functions have different behavior depending on what command they are
being invoked from.
#define TF_STNDOUT 14 /* special - enter underline mode */
#define TF_RESET 15 /* special - reset terminal modes */
#define TF_HASCLR 16 /* special - terminal have color? */
+#define TF_FGCOLR 17 /* special - foreground term color */
+#define TF_BGCOLR 18 /* special - background term color */
/* ftable->flags */
/* NB that TFL_PUTS is also used to decide whether the test
* what maps a particular function name into a format instruction.
* type - The type of argument this function expects. Those types are
* listed above (with the TF_ prefix). This affects what gets
- * placed in the format instruction (the f_un union).
+ * placed in the format instruction (the f_un union). Also,
+ * instructions that require special handling are distinguished
+ * here (TF_MYMBOX is one example).
* f_type - The instruction corresponding to this function (from the list
* in fmt_compile.h).
* extra - Used by some functions to provide extra data to the compiler.
{ "standout", TF_STNDOUT,FT_LS_LIT, 0, TFL_PUTS },
{ "resetterm", TF_RESET, FT_LS_LIT, 0, TFL_PUTS },
{ "hascolor", TF_HASCLR, FT_LV_LIT, 0, 0 },
+ { "fgcolor", TF_FGCOLR, FT_LS_LIT, 0, TFL_PUTS },
+ { "bgcolor", TF_BGCOLR, FT_LS_LIT, 0, TFL_PUTS },
{ NULL, 0, 0, 0, 0 }
};
+/*
+ * A mapping of color names to terminfo color numbers.
+ *
+ * There are two sets of terminal-setting codes: 'setaf/setab' (ANSI) and
+ * 'setf/setb'. Different terminals support different capabilities, so
+ * we provide a mapping for both. I'm not crazy about putting numbers
+ * directly in here, but it seems these are well defined by terminfo
+ * so it should be okay.
+ */
+
+struct colormap {
+ char *colorname; /* Name of color */
+ int ansinum; /* The ANSI escape color number */
+ int nonansinum; /* The non-ANSI escape color number */
+};
+
+static struct colormap colortable[] = {
+ { "black", 0, 0 },
+ { "red", 1, 4 },
+ { "green", 2, 2 },
+ { "yellow", 3, 6 },
+ { "blue", 4, 1 },
+ { "magenta", 5, 5 },
+ { "cyan", 6, 3 },
+ { "white", 7, 7 },
+ { NULL, 0, 0 }
+};
+
/*
* Hash function for component name. The function should be
* case independent and probably shouldn't involve a routine
LV(t->f_type, get_term_numcap("colors") > 1);
break;
+ case TF_FGCOLR:
+ case TF_BGCOLR: {
+ struct colormap *cmap = colortable;
+ char *code;
+
+ sp = cp - 1;
+ while (c && c != ')')
+ c = *cp++;
+ cp[-1] = '\0';
+
+ while (cmap->colorname != NULL) {
+ if (strcasecmp(sp, cmap->colorname) == 0)
+ break;
+ cmap++;
+ }
+
+ if (cmap->colorname == NULL) {
+ CERROR("Unknown color name");
+ break;
+ }
+
+ code = get_term_stringparm(t->type == TF_FGCOLR ? "setaf" : "setab",
+ cmap->ansinum, 0);
+
+ /*
+ * If this doesn't have anything, try falling back to setf/setb
+ */
+
+ if (! code)
+ code = get_term_stringparm(t->type == TF_FGCOLR ? "setf" : "setb",
+ cmap->nonansinum, 0);
+
+ LS(t->f_type, code);
+ break;
+ }
+
case TF_NOW:
LV(t->f_type, time((time_t *) 0));
break;
there isn't enough room in the buffer for the entire
string, skip it completely. Need room for null
terminator, and maybe trailing newline (added below). */
- if (cp - scanl + strlen (str) + 1 < max) {
+ if (str && (cp - scanl + strlen (str) + 1 < max)) {
for (sp = str; *sp; *cp++ = *sp++) continue;
}
if (callbacks && callbacks->trace_func)