#include "macros.h"
#include "quis.h"
#include "report.h"
+#include "tty.h"
#include "ttycolour.h"
#include "tvec.h"
* @const char *what, ...@ = format string describing where the
* setting came from
*
- * Returns: @0@ if the string, or variable, is set to something
+ * Returns: @0@ if the string, or variable, is set to something
* falseish, @1@ if it's set to something truish, or @dflt@
* otherwise.
*/
/*----- Human-readable output ---------------------------------------------*/
+#define GENATTR(want, attrs, fgspc, fgcol, bgspc, bgcol) \
+ { (want), (want), \
+ { ((fgspc) << TTAF_FGSPCSHIFT) | \
+ ((bgspc) << TTAF_BGSPCSHIFT) | (attrs), \
+ 0, (fgcol), (bgcol) } }
+
+#define FGBG(want, attrs, fgcol, bgcol) \
+ GENATTR(want | TTACF_FG | TTACF_BG, attrs, \
+ TTCSPC_1BPCBR, TTCOL_##fgcol, TTCSPC_1BPCBR, TTCOL_##bgcol)
+#define FG(want, attrs, fgcol) \
+ GENATTR(want | TTACF_FG, attrs, \
+ TTCSPC_1BPCBR, TTCOL_##fgcol, TTCSPC_NONE, 0)
+#define BG(want, attrs, bgcol) \
+ GENATTR(want | TTACF_BG, attrs, \
+ TTCSPC_NONE, 0, TTCSPC_1BPCBR, TTCOL_##bgcol)
+#define ATTR(want, attrs) \
+ GENATTR(want, attrs, TTCSPC_NONE, 0, TTCSPC_NONE, 0)
+
+#define BOLD (TTWT_BOLD << TTAF_WTSHIFT)
+
+static const struct tty_attrlist
+ loc_attrs[] = { FG(0, 0, CYN), TTY_ATTRLIST_CLEAR },
+ locsep_attrs[] = { FG(0, 0, BRBLU), TTY_ATTRLIST_CLEAR },
+ note_attrs[] = { FG(0, 0, YLW), TTY_ATTRLIST_CLEAR },
+ err_attrs[] = { FG(0, BOLD, MGN), TTY_ATTRLIST_CLEAR },
+ unklv_attrs[] = { FGBG(0, BOLD, BRWHT, BRRED), ATTR(0, TTAF_INVV) },
+ vfound_attrs[] = { FG(0, 0, RED), TTY_ATTRLIST_CLEAR },
+ vexpect_attrs[] = { FG(0, 0, GRN), TTY_ATTRLIST_CLEAR },
+ vunset_attrs[] = { FG(0, 0, YLW), TTY_ATTRLIST_CLEAR },
+ lose_attrs[] = { FG(0, BOLD, RED), ATTR(0, BOLD | TTAF_INVV) },
+ skip_attrs[] = { FG(0, 0, YLW), TTY_ATTRLIST_CLEAR },
+ xfail_attrs[] = { FG(0, BOLD, BLU), ATTR(0, BOLD) },
+ win_attrs[] = { FG(0, 0, GRN), TTY_ATTRLIST_CLEAR },
+ sblose_attrs[] = { FG(0, BOLD, RED), ATTR(0, BOLD) };
+
+#undef GENATTR
+#undef FGBG
+#undef FG
+#undef BG
+#undef ATTR
+#undef BOLD
+
/* Predefined attributes. */
#define HIGHLIGHTS(_st, _) \
- _(_st, LOCFN, "lf", TC_FG(CYAN)) /* location filename */ \
- _(_st, LOCLN, "ln", TC_FG(CYAN)) /* location line number */ \
- _(_st, LOCSEP, "ls", TC_FG(BRBLUE)) /* location separator `:' */ \
+ _(_st, LOCFN, "lf", loc_attrs) /* location filename */ \
+ _(_st, LOCLN, "ln", loc_attrs) /* location line number */ \
+ _(_st, LOCSEP, "ls", locsep_attrs) /* location separator `:' */ \
_(_st, INFO, "mi", 0) /* information */ \
- _(_st, NOTE, "mn", TC_FG(YELLOW)) /* notices */ \
- _(_st, ERR, "me", TC_FG(MAGENTA) | TCAF_BOLD) /* error messages */ \
- _(_st, UNKLEV, "mu", TC_FG(WHITE) | TC_BG(RED) | TCAF_BOLD) \
+ _(_st, NOTE, "mn", note_attrs) /* notices */ \
+ _(_st, ERR, "me", err_attrs) /* error messages */ \
+ _(_st, UNKLV, "mu", unklv_attrs) /* unknown-level messages */ \
_(_st, DSINPUT, "di", 0) /* disposition for input value */ \
_(_st, DSOUTPUT, "do", 0) /* ... unsolicited output */ \
_(_st, DSMATCH, "dm", 0) /* ... matching output */ \
_(_st, VINPUT, "vi", 0) /* input value */ \
_(_st, VOUTPUT, "vo", 0) /* unsolicited output value */ \
_(_st, VMATCH, "vm", 0) /* matching output value */ \
- _(_st, VFOUND, "vf", TC_FG(BRRED)) /* incorrect output value */ \
- _(_st, VEXPECT, "vx", TC_FG(GREEN)) /* reference output value */ \
- _(_st, VUNSET, "vu", TC_FG(YELLOW)) /* register not set */ \
- _(_st, LOSE, "ol", TC_FG(RED) | TCAF_BOLD) /* report failure */ \
- _(_st, SKIP, "os", TC_FG(YELLOW)) /* report a skipped test/group */ \
- _(_st, XFAIL, "ox", TC_FG(BLUE) | TCAF_BOLD) /* report expected fail */ \
- _(_st, WIN, "ow", TC_FG(GREEN)) /* report success */ \
- _(_st, SBLOSE, "sl", TC_FG(RED) | TCAF_BOLD) /* scoreboard failure */ \
- _(_st, SBSKIP, "ss", TC_FG(YELLOW)) /* scoreboard skipped test */ \
- _(_st, SBXFAIL, "sx", TC_FG(BLUE) | TCAF_BOLD) /* scoreboard xfail */ \
+ _(_st, VFOUND, "vf", vfound_attrs) /* incorrect output value */ \
+ _(_st, VEXPECT, "vx", vexpect_attrs) /* reference output value */ \
+ _(_st, VUNSET, "vu", vunset_attrs) /* register not set */ \
+ _(_st, LOSE, "ol", lose_attrs) /* report failure */ \
+ _(_st, SKIP, "os", skip_attrs) /* report a skipped test/group */ \
+ _(_st, XFAIL, "ox", xfail_attrs) /* report expected fail */ \
+ _(_st, WIN, "ow", win_attrs) /* report success */ \
+ _(_st, SBLOSE, "sl", sblose_attrs) /* scoreboard failure */ \
+ _(_st, SBSKIP, "ss", skip_attrs) /* scoreboard skipped test */ \
+ _(_st, SBXFAIL, "sx", xfail_attrs) /* scoreboard xfail */ \
_(_st, SBWIN, "sw", 0) /* scoreboard success */
TTYCOLOUR_DEFENUM(HIGHLIGHTS, HL_);
struct tvec_output _o; /* output base class */
struct tvec_state *tv; /* stashed testing state */
arena *a; /* arena for memory allocation */
+ struct tty *tty; /* output terminal, or null */
struct layout lyt; /* output layout */
char *outbuf; size_t outsz; /* buffer for formatted output */
dstr scoreboard; /* history of test group results */
- unsigned short attr[HL__LIMIT]; /* highlight attribute map */
- struct ttycolour_state tc; /* terminal colour state */
+ struct tty_attr attr[HL__LIMIT]; /* highlight attribute map */
int maxlen; /* longest register name */
unsigned f; /* flags */
/* bits 0--7 from @TVHF_...@ */
const struct gprintf_ops *gops, void *go, int hl)
{
if (h->f&TVHF_COLOUR)
- ttycolour_setattr(gops, go, &h->tc, hl < 0 ? 0 : h->attr[hl]);
+ tty_setattrg(h->tty, gops, go, hl >= 0 ? &h->attr[hl] : 0);
}
static void setattr(struct human_output *h, int hl)
*
* Arguments: @struct tvec_output *o@ = output sink, secretly a
* @struct human_output@
- * @unsigned level@ = message level (@TVLEV_...@)
+ * @unsigned level@ = message level (@TVLV_...@)
* @const char *msg@, @va_list *ap@ = format string and
* arguments
*
switch (level) {
#define CASE(tag, name, val) \
- case TVLEV_##tag: levstr = name; levhl = HL_##tag; break;
+ case TVLV_##tag: levstr = name; levhl = HL_##tag; break;
TVEC_LEVELS(CASE)
- default: levstr = "??"; levhl = HL_UNKLEV; break;
+ default: levstr = "??"; levhl = HL_UNKLV; break;
}
if (h->f&HOF_PROGRESS) { clear_progress(h); f |= f_progress; }
{
struct human_output *h = (struct human_output *)o;
+ tty_close(h->tty);
destroy_layout(&h->lyt,
h->lyt.fp == stdout || h->lyt.fp == stderr ? 0 : DLF_CLOSE);
dstr_destroy(&h->scoreboard);
struct tvec_output *tvec_humanoutput(FILE *fp, unsigned f, unsigned m)
{
struct human_output *h;
- const char *p;
struct stat st_out, st_err;
int rc_out, rc_err;
assert(!(f&~m));
if (!(m&TVHF_TTY))
- switch (getenv_boolean("TVEC_TTY", -1)) {
+ switch (getenv_boolean("MLIB_TVEC_TTY", -1)) {
case 1: f |= TVHF_TTY; break;
case 0: break;
default:
break;
}
if (!(m&TVHF_COLOUR))
- switch (getenv_boolean("TVEC_COLOUR", -1)) {
+ switch (getenv_boolean("MLIB_TVEC_COLOUR", -1)) {
case 1: f |= TVHF_COLOUR; break;
case 0: break;
default:
- if (f&TVHF_TTY) {
- p = getenv("TERM");
- if (p && STRCMP(p, !=, "dumb")) f |= TVHF_COLOUR;
- }
+ if (ttycolour_enablep((f&TVHF_TTY ? TCEF_TTY : 0) | TCEF_DFLT))
+ f |= TVHF_COLOUR;
break;
}
h->f = f;
/* Initialize the colour tables. */
- if (h->f&TVHF_COLOUR) {
- ttycolour_config(h->attr, "TVEC_COLOURS", TCIF_GETENV | TCIF_REPORT,
- hltab);
- ttycolour_init(&h->tc);
+ if (!(h->f&TVHF_COLOUR))
+ h->tty = 0;
+ else {
+ h->tty = tty_open(fp, TTF_BORROW, 0);
+ if (!h->tty)
+ h->f &= ~TVHF_COLOUR;
+ else
+ ttycolour_config(h->attr, "MLIB_TVEC_COLOURS",
+ TCIF_GETENV | TCIF_REPORT, h->tty, hltab);
}
init_layout(&h->lyt, fp, 0);
*
* Arguments: @struct tvec_output *o@ = output sink, secretly a
* @struct machine_output@
- * @unsigned level@ = message level (@TVLEV_...@)
+ * @unsigned level@ = message level (@TVLV_...@)
* @const char *msg@, @va_list *ap@ = format string and
* arguments
*
*
* Arguments: @struct tvec_output *o@ = output sink, secretly a
* @struct tap_output@
- * @unsigned level@ = message level (@TVLEV_...@)
+ * @unsigned level@ = message level (@TVLV_...@)
* @const char *msg@, @va_list *ap@ = format string and
* arguments
*
*
* Arguments: @struct tvec_output *o@ = output sink, secretly a
* @struct automake_output@
- * @unsigned level@ = message level (@TVLEV_...@)
+ * @unsigned level@ = message level (@TVLV_...@)
* @const char *msg@, @va_list *ap@ = format string and
* arguments
*
struct tvec_output *tvec_dfltoutput(FILE *fp)
{
- int ttyp = getenv_boolean("TVEC_TTY", -1);
+ int ttyp = getenv_boolean("MLIB_TVEC_TTY", -1);
if (ttyp == -1) ttyp = isatty(fileno(fp));
- if (ttyp) return (tvec_humanoutput(fp, 0, 0));
+ if (ttyp) return (tvec_humanoutput(fp, TVHF_TTY, TVHF_TTY));
else return (tvec_machineoutput(fp));
}