summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-07 14:56:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:37 +0200
commitc37f9fba70085fedc8eede7559489d2321393005 (patch)
tree042455ebf1fa89a277a825f72e1ed805d0b4d296 /freebsd/contrib
parentUpdate to FreeBSD head 2017-06-01 (diff)
downloadrtems-libbsd-c37f9fba70085fedc8eede7559489d2321393005.tar.bz2
Update to FreeBSD head 2017-08-01
Git mirror commit f5002f5e5f78cae9f0269d812dc0aedb0339312c. Update #3472.
Diffstat (limited to 'freebsd/contrib')
-rw-r--r--freebsd/contrib/libxo/libxo/libxo.c672
-rw-r--r--freebsd/contrib/libxo/libxo/xo.h2
-rw-r--r--freebsd/contrib/libxo/libxo/xo_buf.h2
-rw-r--r--freebsd/contrib/libxo/libxo/xo_encoder.c8
-rw-r--r--freebsd/contrib/libxo/libxo/xo_encoder.h5
5 files changed, 462 insertions, 227 deletions
diff --git a/freebsd/contrib/libxo/libxo/libxo.c b/freebsd/contrib/libxo/libxo/libxo.c
index f36e7480..d922ba0b 100644
--- a/freebsd/contrib/libxo/libxo/libxo.c
+++ b/freebsd/contrib/libxo/libxo/libxo.c
@@ -97,6 +97,14 @@
#include <libintl.h>
#endif /* HAVE_GETTEXT */
+/* Rather lame that we can't count on these... */
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
/*
* Three styles of specifying thread-local variables are supported.
* configure.ac has the brains to run each possibility through the
@@ -205,6 +213,7 @@ typedef struct xo_stack_s {
* XO_COL_* ("colors") refers to fancy ansi codes, while X__EFF_*
* ("effects") are bits since we need to maintain state.
*/
+typedef uint8_t xo_color_t;
#define XO_COL_DEFAULT 0
#define XO_COL_BLACK 1
#define XO_COL_RED 2
@@ -240,7 +249,6 @@ typedef struct xo_stack_s {
#define XO_EFF_CLEAR_BITS XO_EFF_RESET /* Reset gets reset, surprisingly */
typedef uint8_t xo_effect_t;
-typedef uint8_t xo_color_t;
typedef struct xo_colors_s {
xo_effect_t xoc_effects; /* Current effect set */
xo_color_t xoc_col_fg; /* Foreground color */
@@ -281,8 +289,10 @@ struct xo_handle_s {
ssize_t xo_anchor_min_width; /* Desired width of anchored text */
ssize_t xo_units_offset; /* Start of units insertion point */
ssize_t xo_columns; /* Columns emitted during this xo_emit call */
+#ifndef LIBXO_TEXT_ONLY
uint8_t xo_color_map_fg[XO_NUM_COLORS]; /* Foreground color mappings */
uint8_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */
+#endif /* LIBXO_TEXT_ONLY */
xo_colors_t xo_colors; /* Current color and effect values */
xo_buffer_t xo_color_buf; /* HTML: buffer of colors and effects */
char *xo_version; /* Version string */
@@ -463,10 +473,17 @@ static ssize_t
xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
xo_state_t new_state);
+static int
+xo_set_options_simple (xo_handle_t *xop, const char *input);
+
+static int
+xo_color_find (const char *str);
+
static void
xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
const char *name, ssize_t nlen,
const char *value, ssize_t vlen,
+ const char *fmt, ssize_t flen,
const char *encoding, ssize_t elen);
static void
@@ -630,13 +647,6 @@ xo_init_handle (xo_handle_t *xop)
XOF_SET(xop, XOF_FLUSH_LINE);
/*
- * We only want to do color output on terminals, but we only want
- * to do this if the user has asked for color.
- */
- if (XOF_ISSET(xop, XOF_COLOR_ALLOWED) && isatty(1))
- XOF_SET(xop, XOF_COLOR);
-
- /*
* We need to initialize the locale, which isn't really pretty.
* Libraries should depend on their caller to set up the
* environment. But we really can't count on the caller to do
@@ -669,15 +679,6 @@ xo_init_handle (xo_handle_t *xop)
xop->xo_indent_by = XO_INDENT_BY;
xo_depth_check(xop, XO_DEPTH);
-#if !defined(NO_LIBXO_OPTIONS)
- if (!XOF_ISSET(xop, XOF_NO_ENV)) {
- char *env = getenv("LIBXO_OPTIONS");
- if (env)
- xo_set_options(xop, env);
-
- }
-#endif /* NO_GETENV */
-
XOIF_CLEAR(xop, XOIF_INIT_IN_PROGRESS);
}
@@ -691,6 +692,16 @@ xo_default_init (void)
xo_init_handle(xop);
+#if !defined(NO_LIBXO_OPTIONS)
+ if (!XOF_ISSET(xop, XOF_NO_ENV)) {
+ char *env = getenv("LIBXO_OPTIONS");
+
+ if (env)
+ xo_set_options_simple(xop, env);
+
+ }
+#endif /* NO_LIBXO_OPTIONS */
+
xo_default_inited = 1;
}
@@ -1043,32 +1054,36 @@ xo_printf (xo_handle_t *xop, const char *fmt, ...)
* These next few function are make The Essential UTF-8 Ginsu Knife.
* Identify an input and output character, and convert it.
*/
-static uint8_t xo_utf8_bits[7] = { 0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
+static uint8_t xo_utf8_data_bits[5] = { 0, 0x7f, 0x1f, 0x0f, 0x07 };
+static uint8_t xo_utf8_len_bits[5] = { 0, 0x00, 0xc0, 0xe0, 0xf0 };
+/*
+ * If the byte has a high-bit set, it's UTF-8, not ASCII.
+ */
static int
xo_is_utf8 (char ch)
{
return (ch & 0x80);
}
+/*
+ * Look at the high bits of the first byte to determine the length
+ * of the UTF-8 character.
+ */
static inline ssize_t
xo_utf8_to_wc_len (const char *buf)
{
- unsigned b = (unsigned char) *buf;
+ uint8_t bval = (uint8_t) *buf;
ssize_t len;
- if ((b & 0x80) == 0x0)
+ if ((bval & 0x80) == 0x0)
len = 1;
- else if ((b & 0xe0) == 0xc0)
+ else if ((bval & 0xe0) == 0xc0)
len = 2;
- else if ((b & 0xf0) == 0xe0)
+ else if ((bval & 0xf0) == 0xe0)
len = 3;
- else if ((b & 0xf8) == 0xf0)
+ else if ((bval & 0xf8) == 0xf0)
len = 4;
- else if ((b & 0xfc) == 0xf8)
- len = 5;
- else if ((b & 0xfe) == 0xfc)
- len = 6;
else
len = -1;
@@ -1078,12 +1093,11 @@ xo_utf8_to_wc_len (const char *buf)
static ssize_t
xo_buf_utf8_len (xo_handle_t *xop, const char *buf, ssize_t bufsiz)
{
-
unsigned b = (unsigned char) *buf;
ssize_t len, i;
len = xo_utf8_to_wc_len(buf);
- if (len == -1) {
+ if (len < 0) {
xo_failure(xop, "invalid UTF-8 data: %02hhx", b);
return -1;
}
@@ -1121,9 +1135,9 @@ xo_utf8_char (const char *buf, ssize_t len)
wchar_t wc;
const unsigned char *cp = (const unsigned char *) buf;
- wc = *cp & xo_utf8_bits[len];
+ wc = *cp & xo_utf8_data_bits[len];
for (i = 1; i < len; i++) {
- wc <<= 6;
+ wc <<= 6; /* Low six bits have data */
wc |= cp[i] & 0x3f;
if ((cp[i] & 0xc0) != 0x80)
return (wchar_t) -1;
@@ -1140,22 +1154,23 @@ xo_utf8_emit_len (wchar_t wc)
{
ssize_t len;
- if ((wc & ((1<<7) - 1)) == wc) /* Simple case */
+ if ((wc & ((1 << 7) - 1)) == wc) /* Simple case */
len = 1;
- else if ((wc & ((1<<11) - 1)) == wc)
+ else if ((wc & ((1 << 11) - 1)) == wc)
len = 2;
- else if ((wc & ((1<<16) - 1)) == wc)
+ else if ((wc & ((1 << 16) - 1)) == wc)
len = 3;
- else if ((wc & ((1<<21) - 1)) == wc)
+ else if ((wc & ((1 << 21) - 1)) == wc)
len = 4;
- else if ((wc & ((1<<26) - 1)) == wc)
- len = 5;
else
- len = 6;
+ len = -1; /* Invalid */
return len;
}
+/*
+ * Emit one wide character into the given buffer
+ */
static void
xo_utf8_emit_char (char *buf, ssize_t len, wchar_t wc)
{
@@ -1166,15 +1181,22 @@ xo_utf8_emit_char (char *buf, ssize_t len, wchar_t wc)
return;
}
+ /* Start with the low bits and insert them, six bits at a time */
for (i = len - 1; i >= 0; i--) {
buf[i] = 0x80 | (wc & 0x3f);
- wc >>= 6;
+ wc >>= 6; /* Drop the low six bits */
}
- buf[0] &= xo_utf8_bits[len];
- buf[0] |= ~xo_utf8_bits[len] << 1;
+ /* Finish off the first byte with the length bits */
+ buf[0] &= xo_utf8_data_bits[len]; /* Clear out the length bits */
+ buf[0] |= xo_utf8_len_bits[len]; /* Drop in new length bits */
}
+/*
+ * Append a single UTF-8 character to a buffer, converting it to locale
+ * encoding. Returns the number of columns consumed by that character,
+ * as best we can determine it.
+ */
static ssize_t
xo_buf_append_locale_from_utf8 (xo_handle_t *xop, xo_buffer_t *xbp,
const char *ibuf, ssize_t ilen)
@@ -1189,7 +1211,7 @@ xo_buf_append_locale_from_utf8 (xo_handle_t *xop, xo_buffer_t *xbp,
*/
wc = xo_utf8_char(ibuf, ilen);
if (wc == (wchar_t) -1) {
- xo_failure(xop, "invalid utf-8 byte sequence");
+ xo_failure(xop, "invalid UTF-8 byte sequence");
return 0;
}
@@ -1218,6 +1240,9 @@ xo_buf_append_locale_from_utf8 (xo_handle_t *xop, xo_buffer_t *xbp,
return xo_wcwidth(wc);
}
+/*
+ * Append a UTF-8 string to a buffer, converting it into locale encoding
+ */
static void
xo_buf_append_locale (xo_handle_t *xop, xo_buffer_t *xbp,
const char *cp, ssize_t len)
@@ -1504,6 +1529,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
newfmt[plen++] = ':';
newfmt[plen++] = ' ';
}
+
memcpy(newfmt + plen, fmt, len);
newfmt[len + plen] = '\0';
@@ -1523,6 +1549,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
ssize_t left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
ssize_t rc = vsnprintf(xbp->xb_curp, left, newfmt, vap);
+
if (rc >= left) {
if (!xo_buf_has_room(xbp, rc)) {
va_end(va_local);
@@ -1535,6 +1562,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
rc = vsnprintf(xbp->xb_curp, left, fmt, vap);
}
+
va_end(va_local);
rc = xo_escape_xml(xbp, rc, 1);
@@ -1545,6 +1573,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
if (code >= 0) {
const char *msg = strerror(code);
+
if (msg) {
xo_buf_append(xbp, ": ", 2);
xo_buf_append(xbp, msg, strlen(msg));
@@ -1558,6 +1587,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
vfprintf(stderr, newfmt, vap);
if (code >= 0) {
const char *msg = strerror(code);
+
if (msg)
fprintf(stderr, ": %s", msg);
}
@@ -1674,6 +1704,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
va_copy(va_local, vap);
ssize_t left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
+
rc = vsnprintf(xbp->xb_curp, left, fmt, vap);
if (rc >= left) {
if (!xo_buf_has_room(xbp, rc)) {
@@ -1687,6 +1718,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
rc = vsnprintf(xbp->xb_curp, left, fmt, vap);
}
+
va_end(va_local);
rc = xo_escape_xml(xbp, rc, 0);
@@ -1694,6 +1726,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
if (need_nl && code > 0) {
const char *msg = strerror(code);
+
if (msg) {
xo_buf_append(xbp, ": ", 2);
xo_buf_append(xbp, msg, strlen(msg));
@@ -1727,6 +1760,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
va_copy(va_local, vap);
rc = vsnprintf(bp, bufsiz, fmt, va_local);
}
+
va_end(va_local);
cp = bp + rc;
@@ -1738,7 +1772,8 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
rc += rc2;
}
- xo_buf_append_div(xop, "message", 0, NULL, 0, bp, rc, NULL, 0);
+ xo_buf_append_div(xop, "message", 0, NULL, 0, bp, rc,
+ NULL, 0, NULL, 0);
}
break;
@@ -1762,6 +1797,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
if (need_nl && code > 0) {
const char *msg = strerror(code);
+
if (msg) {
xo_printf(xop, ": %s", msg);
}
@@ -1776,6 +1812,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
case XO_STYLE_HTML:
if (XOIF_ISSET(xop, XOIF_DIV_OPEN)) {
static char div_close[] = "</div>";
+
XOIF_CLEAR(xop, XOIF_DIV_OPEN);
xo_data_append(xop, div_close, sizeof(div_close) - 1);
@@ -1848,8 +1885,10 @@ xo_failure (xo_handle_t *xop, const char *fmt, ...)
* Note: normal use of libxo does not require a distinct handle, since
* the default handle (used when NULL is passed) generates text on stdout.
*
- * @style Style of output desired (XO_STYLE_* value)
- * @flags Set of XOF_* flags in use with this handle
+ * @param style Style of output desired (XO_STYLE_* value)
+ * @param flags Set of XOF_* flags in use with this handle
+ * @return Newly allocated handle
+ * @see xo_destroy
*/
xo_handle_t *
xo_create (xo_style_t style, xo_xof_flags_t flags)
@@ -1871,9 +1910,12 @@ xo_create (xo_style_t style, xo_xof_flags_t flags)
/**
* Create a handle that will write to the given file. Use
* the XOF_CLOSE_FP flag to have the file closed on xo_destroy().
- * @fp FILE pointer to use
- * @style Style of output desired (XO_STYLE_* value)
- * @flags Set of XOF_* flags to use with this handle
+ *
+ * @param fp FILE pointer to use
+ * @param style Style of output desired (XO_STYLE_* value)
+ * @param flags Set of XOF_* flags to use with this handle
+ * @return Newly allocated handle
+ * @see xo_destroy
*/
xo_handle_t *
xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags)
@@ -1892,8 +1934,10 @@ xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags)
/**
* Set the default handler to output to a file.
- * @xop libxo handle
- * @fp FILE pointer to use
+ *
+ * @param xop libxo handle
+ * @param fp FILE pointer to use
+ * @return 0 on success, non-zero on failure
*/
int
xo_set_file_h (xo_handle_t *xop, FILE *fp)
@@ -1915,7 +1959,9 @@ xo_set_file_h (xo_handle_t *xop, FILE *fp)
/**
* Set the default handler to output to a file.
- * @fp FILE pointer to use
+ *
+ * @param fp FILE pointer to use
+ * @return 0 on success, non-zero on failure
*/
int
xo_set_file (FILE *fp)
@@ -1925,7 +1971,8 @@ xo_set_file (FILE *fp)
/**
* Release any resources held by the handle.
- * @xop XO handle to alter (or NULL for default handle)
+ *
+ * @param xop XO handle to alter (or NULL for default handle)
*/
void
xo_destroy (xo_handle_t *xop_arg)
@@ -1958,8 +2005,8 @@ xo_destroy (xo_handle_t *xop_arg)
* Record a new output style to use for the given handle (or default if
* handle is NULL). This output style will be used for any future output.
*
- * @xop XO handle to alter (or NULL for default handle)
- * @style new output style (XO_STYLE_*)
+ * @param xop XO handle to alter (or NULL for default handle)
+ * @param style new output style (XO_STYLE_*)
*/
void
xo_set_style (xo_handle_t *xop, xo_style_t style)
@@ -1968,6 +2015,12 @@ xo_set_style (xo_handle_t *xop, xo_style_t style)
xop->xo_style = style;
}
+/**
+ * Return the current style of a handle
+ *
+ * @param xop XO handle to access
+ * @return The handle's current style
+ */
xo_style_t
xo_get_style (xo_handle_t *xop)
{
@@ -1975,6 +2028,12 @@ xo_get_style (xo_handle_t *xop)
return xo_style(xop);
}
+/**
+ * Return the XO_STYLE_* value matching a given name
+ *
+ * @param name String name of a style
+ * @return XO_STYLE_* value
+ */
static int
xo_name_to_style (const char *name)
{
@@ -2010,8 +2069,8 @@ xo_style_is_encoding (xo_handle_t *xop)
/* Simple name-value mapping */
typedef struct xo_mapping_s {
- xo_xff_flags_t xm_value;
- const char *xm_name;
+ xo_xff_flags_t xm_value; /* Flag value */
+ const char *xm_name; /* String name */
} xo_mapping_t;
static xo_xff_flags_t
@@ -2058,6 +2117,7 @@ xo_value_lookup (xo_mapping_t *map, xo_xff_flags_t value)
static xo_mapping_t xo_xof_names[] = {
{ XOF_COLOR_ALLOWED, "color" },
+ { XOF_COLOR, "color-force" },
{ XOF_COLUMNS, "columns" },
{ XOF_DTRT, "dtrt" },
{ XOF_FLUSH, "flush" },
@@ -2082,6 +2142,21 @@ static xo_mapping_t xo_xof_names[] = {
{ 0, NULL }
};
+/* Options available via the environment variable ($LIBXO_OPTIONS) */
+static xo_mapping_t xo_xof_simple_names[] = {
+ { XOF_COLOR_ALLOWED, "color" },
+ { XOF_FLUSH, "flush" },
+ { XOF_FLUSH_LINE, "flush-line" },
+ { XOF_NO_HUMANIZE, "no-humanize" },
+ { XOF_NO_LOCALE, "no-locale" },
+ { XOF_RETAIN_NONE, "no-retain" },
+ { XOF_PRETTY, "pretty" },
+ { XOF_RETAIN_ALL, "retain" },
+ { XOF_UNDERSCORES, "underscores" },
+ { XOF_WARN, "warn" },
+ { 0, NULL }
+};
+
/*
* Convert string name to XOF_* flag value.
* Not all are useful. Or safe. Or sane.
@@ -2092,6 +2167,13 @@ xo_name_to_flag (const char *name)
return (unsigned) xo_name_lookup(xo_xof_names, name, -1);
}
+/**
+ * Set the style of an libxo handle based on a string name
+ *
+ * @param xop XO handle
+ * @param name String value of name
+ * @return 0 on success, non-zero on failure
+ */
int
xo_set_style_name (xo_handle_t *xop, const char *name)
{
@@ -2099,6 +2181,7 @@ xo_set_style_name (xo_handle_t *xop, const char *name)
return -1;
int style = xo_name_to_style(name);
+
if (style < 0)
return -1;
@@ -2107,9 +2190,95 @@ xo_set_style_name (xo_handle_t *xop, const char *name)
}
/*
+ * Fill in the color map, based on the input string; currently unimplemented
+ * Look for something like "colors=red/blue+green/yellow" as fg/bg pairs.
+ */
+static void
+xo_set_color_map (xo_handle_t *xop, char *value)
+{
+#ifdef LIBXO_TEXT_ONLY
+ return;
+#endif /* LIBXO_TEXT_ONLY */
+
+ char *cp, *ep, *vp, *np;
+ ssize_t len = value ? strlen(value) + 1 : 0;
+ int num = 1, fg, bg;
+
+ for (cp = value, ep = cp + len - 1; cp && *cp && cp < ep; cp = np) {
+ np = strchr(cp, '+');
+ if (np)
+ *np++ = '\0';
+
+ vp = strchr(cp, '/');
+ if (vp)
+ *vp++ = '\0';
+
+ fg = *cp ? xo_color_find(cp) : -1;
+ bg = (vp && *vp) ? xo_color_find(vp) : -1;
+
+ xop->xo_color_map_fg[num] = (fg < 0) ? num : fg;
+ xop->xo_color_map_bg[num] = (bg < 0) ? num : bg;
+ if (++num > XO_NUM_COLORS)
+ break;
+ }
+
+ /* If no color initialization happened, then we don't need the map */
+ if (num > 0)
+ XOF_SET(xop, XOF_COLOR_MAP);
+ else
+ XOF_CLEAR(xop, XOF_COLOR_MAP);
+
+ /* Fill in the rest of the colors with the defaults */
+ for ( ; num < XO_NUM_COLORS; num++)
+ xop->xo_color_map_fg[num] = xop->xo_color_map_bg[num] = num;
+}
+
+static int
+xo_set_options_simple (xo_handle_t *xop, const char *input)
+{
+ xo_xof_flags_t new_flag;
+ char *cp, *ep, *vp, *np, *bp;
+ ssize_t len = strlen(input) + 1;
+
+ bp = alloca(len);
+ memcpy(bp, input, len);
+
+ for (cp = bp, ep = cp + len - 1; cp && cp < ep; cp = np) {
+ np = strchr(cp, ',');
+ if (np)
+ *np++ = '\0';
+
+ vp = strchr(cp, '=');
+ if (vp)
+ *vp++ = '\0';
+
+ if (strcmp("colors", cp) == 0) {
+ xo_set_color_map(xop, vp);
+ continue;
+ }
+
+ new_flag = xo_name_lookup(xo_xof_simple_names, cp, -1);
+ if (new_flag != 0) {
+ XOF_SET(xop, new_flag);
+ } else if (strcmp(cp, "no-color") == 0) {
+ XOF_CLEAR(xop, XOF_COLOR_ALLOWED);
+ } else {
+ xo_failure(xop, "unknown simple option: %s", cp);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
* Set the options for a handle using a string of options
* passed in. The input is a comma-separated set of names
* and optional values: "xml,pretty,indent=4"
+ *
+ * @param xop XO handle
+ * @param input Comma-separated set of option values
+ * @return 0 on success, non-zero on failure
*/
int
xo_set_options (xo_handle_t *xop, const char *input)
@@ -2229,7 +2398,7 @@ xo_set_options (xo_handle_t *xop, const char *input)
*vp++ = '\0';
if (strcmp("colors", cp) == 0) {
- /* XXX Look for colors=red-blue+green-yellow */
+ xo_set_color_map(xop, vp);
continue;
}
@@ -2247,28 +2416,26 @@ xo_set_options (xo_handle_t *xop, const char *input)
new_flag = xo_name_to_flag(cp);
if (new_flag != 0)
XOF_SET(xop, new_flag);
- else {
- if (strcmp(cp, "no-color") == 0) {
- XOF_CLEAR(xop, XOF_COLOR_ALLOWED);
- } else if (strcmp(cp, "indent") == 0) {
- if (vp)
- xop->xo_indent_by = atoi(vp);
- else
- xo_failure(xop, "missing value for indent option");
- } else if (strcmp(cp, "encoder") == 0) {
- if (vp == NULL)
- xo_failure(xop, "missing value for encoder option");
- else {
- if (xo_encoder_init(xop, vp)) {
- xo_failure(xop, "encoder not found: %s", vp);
- rc = -1;
- }
+ else if (strcmp(cp, "no-color") == 0)
+ XOF_CLEAR(xop, XOF_COLOR_ALLOWED);
+ else if (strcmp(cp, "indent") == 0) {
+ if (vp)
+ xop->xo_indent_by = atoi(vp);
+ else
+ xo_failure(xop, "missing value for indent option");
+ } else if (strcmp(cp, "encoder") == 0) {
+ if (vp == NULL)
+ xo_failure(xop, "missing value for encoder option");
+ else {
+ if (xo_encoder_init(xop, vp)) {
+ xo_failure(xop, "encoder not found: %s", vp);
+ rc = -1;
}
-
- } else {
- xo_warnx("unknown libxo option value: '%s'", cp);
- rc = -1;
}
+
+ } else {
+ xo_warnx("unknown libxo option value: '%s'", cp);
+ rc = -1;
}
}
}
@@ -2283,8 +2450,8 @@ xo_set_options (xo_handle_t *xop, const char *input)
* Set one or more flags for a given handle (or default if handle is NULL).
* These flags will affect future output.
*
- * @xop XO handle to alter (or NULL for default handle)
- * @flags Flags to be set (XOF_*)
+ * @param xop XO handle to alter (or NULL for default handle)
+ * @param flags Flags to be set (XOF_*)
*/
void
xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags)
@@ -2294,6 +2461,11 @@ xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags)
XOF_SET(xop, flags);
}
+/**
+ * Accessor to return the current set of flags for a handle
+ * @param xop XO handle
+ * @return Current set of flags
+ */
xo_xof_flags_t
xo_get_flags (xo_handle_t *xop)
{
@@ -2302,8 +2474,8 @@ xo_get_flags (xo_handle_t *xop)
return xop->xo_flags;
}
-/*
- * strndup with a twist: len < 0 means strlen
+/**
+ * strndup with a twist: len < 0 means len = strlen(str)
*/
static char *
xo_strndup (const char *str, ssize_t len)
@@ -2325,8 +2497,8 @@ xo_strndup (const char *str, ssize_t len)
* generated data to be placed within an XML hierarchy but still have
* accurate XPath expressions.
*
- * @xop XO handle to alter (or NULL for default handle)
- * @path The XPath expression
+ * @param xop XO handle to alter (or NULL for default handle)
+ * @param path The XPath expression
*/
void
xo_set_leading_xpath (xo_handle_t *xop, const char *path)
@@ -2347,9 +2519,9 @@ xo_set_leading_xpath (xo_handle_t *xop, const char *path)
/**
* Record the info data for a set of tags
*
- * @xop XO handle to alter (or NULL for default handle)
- * @info Info data (xo_info_t) to be recorded (or NULL) (MUST BE SORTED)
- * @count Number of entries in info (or -1 to count them ourselves)
+ * @param xop XO handle to alter (or NULL for default handle)
+ * @param info Info data (xo_info_t) to be recorded (or NULL) (MUST BE SORTED)
+ * @pararm count Number of entries in info (or -1 to count them ourselves)
*/
void
xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count)
@@ -2386,8 +2558,8 @@ xo_set_formatter (xo_handle_t *xop, xo_formatter_t func,
* Clear one or more flags for a given handle (or default if handle is NULL).
* These flags will affect future output.
*
- * @xop XO handle to alter (or NULL for default handle)
- * @flags Flags to be cleared (XOF_*)
+ * @param xop XO handle to alter (or NULL for default handle)
+ * @param flags Flags to be cleared (XOF_*)
*/
void
xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags)
@@ -2543,6 +2715,8 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp,
if ((flags & XFF_UNESCAPE) && (*cp == '\\' || *cp == '%')) {
cp += 1;
len -= 1;
+ if (len == 0 || *cp == '\0')
+ break;
}
}
@@ -3079,6 +3253,11 @@ xo_data_append_content (xo_handle_t *xop, const char *str, ssize_t len,
xop->xo_anchor_columns += cols;
}
+/**
+ * Bump one of the 'width' values in a format strings (e.g. "%40.50.60s").
+ * @param xfp Formatting instructions
+ * @param digit Single digit (0-9) of input
+ */
static void
xo_bump_width (xo_format_t *xfp, int digit)
{
@@ -3325,7 +3504,8 @@ xo_do_format_field (xo_handle_t *xop, xo_buffer_t *xbp,
rc = xo_trim_ws(xbp, rc);
} else {
- ssize_t columns = rc = xo_vsnprintf(xop, xbp, newfmt, xop->xo_vap);
+ ssize_t columns = rc = xo_vsnprintf(xop, xbp, newfmt,
+ xop->xo_vap);
/*
* For XML and HTML, we need "&<>" processing; for JSON,
@@ -3478,6 +3658,10 @@ xo_do_format_field (xo_handle_t *xop, xo_buffer_t *xbp,
return 0;
}
+/*
+ * Remove any numeric precision/width format from the format string by
+ * inserting the "%" after the [0-9]+, returning the substring.
+ */
static char *
xo_fix_encoding (xo_handle_t *xop UNUSED, char *encoding)
{
@@ -3491,8 +3675,7 @@ xo_fix_encoding (xo_handle_t *xop UNUSED, char *encoding)
break;
}
- cp -= 1;
- *cp = '%';
+ *--cp = '%'; /* Back off and insert the '%' */
return cp;
}
@@ -3611,10 +3794,35 @@ xo_format_humanize (xo_handle_t *xop, xo_buffer_t *xbp,
}
}
+/*
+ * Convenience function that either append a fixed value (if one is
+ * given) or formats a field using a format string. If it's
+ * encode_only, then we can't skip formatting the field, since it may
+ * be pulling arguments off the stack.
+ */
+static inline void
+xo_simple_field (xo_handle_t *xop, unsigned encode_only,
+ const char *value, ssize_t vlen,
+ const char *fmt, ssize_t flen, xo_xff_flags_t flags)
+{
+ if (encode_only)
+ flags |= XFF_NO_OUTPUT;
+
+ if (vlen == 0)
+ xo_do_format_field(xop, NULL, fmt, flen, flags);
+ else if (!encode_only)
+ xo_data_append_content(xop, value, vlen, flags);
+}
+
+/*
+ * Html mode: append a <div> to the output buffer contain a field
+ * along with all the supporting information indicated by the flags.
+ */
static void
xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
const char *name, ssize_t nlen,
const char *value, ssize_t vlen,
+ const char *fmt, ssize_t flen,
const char *encoding, ssize_t elen)
{
static char div_start[] = "<div class=\"";
@@ -3625,10 +3833,10 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
static char div_close[] = "</div>";
/* The encoding format defaults to the normal format */
- if (encoding == NULL) {
- char *enc = alloca(vlen + 1);
- memcpy(enc, value, vlen);
- enc[vlen] = '\0';
+ if (encoding == NULL && fmt != NULL) {
+ char *enc = alloca(flen + 1);
+ memcpy(enc, fmt, flen);
+ enc[flen] = '\0';
encoding = xo_fix_encoding(xop, enc);
elen = strlen(encoding);
}
@@ -3695,10 +3903,10 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
/*
* Even if this is encode-only, we need to go through the
* work of formatting it to make sure the args are cleared
- * from xo_vap.
+ * from xo_vap. This is not true when vlen is zero, since
+ * that means our "value" isn't on the stack.
*/
- xo_do_format_field(xop, NULL, encoding, elen,
- flags | XFF_NO_OUTPUT);
+ xo_simple_field(xop, TRUE, NULL, 0, encoding, elen, flags);
return;
}
@@ -3806,7 +4014,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
save.xhs_columns = xop->xo_columns;
save.xhs_anchor_columns = xop->xo_anchor_columns;
- xo_do_format_field(xop, NULL, value, vlen, flags);
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
if (flags & XFF_HUMANIZE) {
/*
@@ -3857,14 +4065,14 @@ xo_format_text (xo_handle_t *xop, const char *str, ssize_t len)
break;
case XO_STYLE_HTML:
- xo_buf_append_div(xop, "text", 0, NULL, 0, str, len, NULL, 0);
+ xo_buf_append_div(xop, "text", 0, NULL, 0, str, len, NULL, 0, NULL, 0);
break;
}
}
static void
xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip,
- const char *str, ssize_t len)
+ const char *value, ssize_t vlen)
{
const char *fmt = xfip->xfi_format;
ssize_t flen = xfip->xfi_flen;
@@ -3888,8 +4096,7 @@ xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip,
* Even though we don't care about text, we need to do
* enough parsing work to skip over the right bits of xo_vap.
*/
- if (len == 0)
- xo_do_format_field(xop, NULL, fmt, flen, flags | XFF_NO_OUTPUT);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
return;
}
@@ -3908,17 +4115,17 @@ xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip,
}
start = xbp->xb_curp - xbp->xb_bufp; /* Reset start */
- if (len) {
+ if (vlen) {
char *newfmt = alloca(flen + 1);
memcpy(newfmt, fmt, flen);
newfmt[flen] = '\0';
/* If len is non-zero, the format string apply to the name */
- char *newstr = alloca(len + 1);
- memcpy(newstr, str, len);
- newstr[len] = '\0';
+ char *newstr = alloca(vlen + 1);
+ memcpy(newstr, value, vlen);
+ newstr[vlen] = '\0';
- if (newstr[len - 1] == 's') {
+ if (newstr[vlen - 1] == 's') {
char *bp;
rc = snprintf(NULL, 0, newfmt, newstr);
@@ -4000,8 +4207,9 @@ xo_arg (xo_handle_t *xop)
static void
xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
- const char *format, ssize_t flen,
- const char *encoding, ssize_t elen, xo_xff_flags_t flags)
+ const char *value, ssize_t vlen,
+ const char *fmt, ssize_t flen,
+ const char *encoding, ssize_t elen, xo_xff_flags_t flags)
{
int pretty = XOF_ISSET(xop, XOF_PRETTY);
int quote;
@@ -4087,7 +4295,7 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
save.xhs_columns = xop->xo_columns;
save.xhs_anchor_columns = xop->xo_anchor_columns;
- xo_do_format_field(xop, NULL, format, flen, flags);
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
if (flags & XFF_HUMANIZE)
xo_format_humanize(xop, xbp, &save, flags);
@@ -4097,8 +4305,8 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
if (flags & XFF_ENCODE_ONLY)
flags |= XFF_NO_OUTPUT;
- xo_buf_append_div(xop, "data", flags, name, nlen,
- format, flen, encoding, elen);
+ xo_buf_append_div(xop, "data", flags, name, nlen, value, vlen,
+ fmt, flen, encoding, elen);
break;
case XO_STYLE_XML:
@@ -4107,25 +4315,24 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
* let the formatting code handle the va_arg popping.
*/
if (flags & XFF_DISPLAY_ONLY) {
- flags |= XFF_NO_OUTPUT;
- xo_do_format_field(xop, NULL, format, flen, flags);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
break;
}
if (encoding) {
- format = encoding;
+ fmt = encoding;
flen = elen;
} else {
char *enc = alloca(flen + 1);
- memcpy(enc, format, flen);
+ memcpy(enc, fmt, flen);
enc[flen] = '\0';
- format = xo_fix_encoding(xop, enc);
- flen = strlen(format);
+ fmt = xo_fix_encoding(xop, enc);
+ flen = strlen(fmt);
}
if (nlen == 0) {
static char missing[] = "missing-field-name";
- xo_failure(xop, "missing field name: %s", format);
+ xo_failure(xop, "missing field name: %s", fmt);
name = missing;
nlen = sizeof(missing) - 1;
}
@@ -4161,7 +4368,9 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
}
xo_data_append(xop, ">", 1);
- xo_do_format_field(xop, NULL, format, flen, flags);
+
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
+
xo_data_append(xop, "</", 2);
xo_data_escape(xop, name, nlen);
xo_data_append(xop, ">", 1);
@@ -4171,20 +4380,19 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
case XO_STYLE_JSON:
if (flags & XFF_DISPLAY_ONLY) {
- flags |= XFF_NO_OUTPUT;
- xo_do_format_field(xop, NULL, format, flen, flags);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
break;
}
if (encoding) {
- format = encoding;
+ fmt = encoding;
flen = elen;
} else {
char *enc = alloca(flen + 1);
- memcpy(enc, format, flen);
+ memcpy(enc, fmt, flen);
enc[flen] = '\0';
- format = xo_fix_encoding(xop, enc);
- flen = strlen(format);
+ fmt = xo_fix_encoding(xop, enc);
+ flen = strlen(fmt);
}
int first = (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST)
@@ -4196,18 +4404,20 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
quote = 1;
else if (flags & XFF_NOQUOTE)
quote = 0;
+ else if (vlen != 0)
+ quote = 1;
else if (flen == 0) {
quote = 0;
- format = "true"; /* JSON encodes empty tags as a boolean true */
+ fmt = "true"; /* JSON encodes empty tags as a boolean true */
flen = 4;
- } else if (strchr("diouDOUeEfFgG", format[flen - 1]) == NULL)
+ } else if (strchr("diouDOUeEfFgG", fmt[flen - 1]) == NULL)
quote = 1;
else
quote = 0;
if (nlen == 0) {
static char missing[] = "missing-field-name";
- xo_failure(xop, "missing field name: %s", format);
+ xo_failure(xop, "missing field name: %s", fmt);
name = missing;
nlen = sizeof(missing) - 1;
}
@@ -4241,7 +4451,7 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
if (quote)
xo_data_append(xop, "\"", 1);
- xo_do_format_field(xop, NULL, format, flen, flags);
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
if (quote)
xo_data_append(xop, "\"", 1);
@@ -4249,39 +4459,39 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
case XO_STYLE_SDPARAMS:
if (flags & XFF_DISPLAY_ONLY) {
- flags |= XFF_NO_OUTPUT;
- xo_do_format_field(xop, NULL, format, flen, flags);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
break;
}
if (encoding) {
- format = encoding;
+ fmt = encoding;
flen = elen;
} else {
char *enc = alloca(flen + 1);
- memcpy(enc, format, flen);
+ memcpy(enc, fmt, flen);
enc[flen] = '\0';
- format = xo_fix_encoding(xop, enc);
- flen = strlen(format);
+ fmt = xo_fix_encoding(xop, enc);
+ flen = strlen(fmt);
}
if (nlen == 0) {
static char missing[] = "missing-field-name";
- xo_failure(xop, "missing field name: %s", format);
+ xo_failure(xop, "missing field name: %s", fmt);
name = missing;
nlen = sizeof(missing) - 1;
}
xo_data_escape(xop, name, nlen);
xo_data_append(xop, "=\"", 2);
- xo_do_format_field(xop, NULL, format, flen, flags);
+
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
+
xo_data_append(xop, "\" ", 2);
break;
case XO_STYLE_ENCODER:
if (flags & XFF_DISPLAY_ONLY) {
- flags |= XFF_NO_OUTPUT;
- xo_do_format_field(xop, NULL, format, flen, flags);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
break;
}
@@ -4291,27 +4501,27 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
quote = 0;
else if (flen == 0) {
quote = 0;
- format = "true"; /* JSON encodes empty tags as a boolean true */
+ fmt = "true"; /* JSON encodes empty tags as a boolean true */
flen = 4;
- } else if (strchr("diouxXDOUeEfFgGaAcCp", format[flen - 1]) == NULL)
+ } else if (strchr("diouxXDOUeEfFgGaAcCp", fmt[flen - 1]) == NULL)
quote = 1;
else
quote = 0;
if (encoding) {
- format = encoding;
+ fmt = encoding;
flen = elen;
} else {
char *enc = alloca(flen + 1);
- memcpy(enc, format, flen);
+ memcpy(enc, fmt, flen);
enc[flen] = '\0';
- format = xo_fix_encoding(xop, enc);
- flen = strlen(format);
+ fmt = xo_fix_encoding(xop, enc);
+ flen = strlen(fmt);
}
if (nlen == 0) {
static char missing[] = "missing-field-name";
- xo_failure(xop, "missing field name: %s", format);
+ xo_failure(xop, "missing field name: %s", fmt);
name = missing;
nlen = sizeof(missing) - 1;
}
@@ -4321,12 +4531,14 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
xo_data_append(xop, "", 1);
ssize_t value_offset = xo_buf_offset(&xop->xo_data);
- xo_do_format_field(xop, NULL, format, flen, flags);
+
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
+
xo_data_append(xop, "", 1);
xo_encoder_handle(xop, quote ? XO_OP_STRING : XO_OP_CONTENT,
xo_buf_data(&xop->xo_data, name_offset),
- xo_buf_data(&xop->xo_data, value_offset));
+ xo_buf_data(&xop->xo_data, value_offset), flags);
xo_buf_reset(&xop->xo_data);
break;
}
@@ -4370,37 +4582,27 @@ xo_set_gettext_domain (xo_handle_t *xop, xo_field_info_t *xfip,
static void
xo_format_content (xo_handle_t *xop, const char *class_name,
const char *tag_name,
- const char *str, ssize_t len, const char *fmt, ssize_t flen,
+ const char *value, ssize_t vlen,
+ const char *fmt, ssize_t flen,
xo_xff_flags_t flags)
{
switch (xo_style(xop)) {
case XO_STYLE_TEXT:
- if (len)
- xo_data_append_content(xop, str, len, flags);
- else
- xo_do_format_field(xop, NULL, fmt, flen, flags);
+ xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
break;
case XO_STYLE_HTML:
- if (len == 0) {
- str = fmt;
- len = flen;
- }
-
- xo_buf_append_div(xop, class_name, flags, NULL, 0, str, len, NULL, 0);
+ xo_buf_append_div(xop, class_name, flags, NULL, 0,
+ value, vlen, fmt, flen, NULL, 0);
break;
case XO_STYLE_XML:
case XO_STYLE_JSON:
case XO_STYLE_SDPARAMS:
if (tag_name) {
- if (len == 0) {
- str = fmt;
- len = flen;
- }
-
xo_open_container_h(xop, tag_name);
- xo_format_value(xop, "message", 7, str, len, NULL, 0, flags);
+ xo_format_value(xop, "message", 7, value, vlen,
+ fmt, flen, NULL, 0, flags);
xo_close_container_h(xop, tag_name);
} else {
@@ -4408,16 +4610,12 @@ xo_format_content (xo_handle_t *xop, const char *class_name,
* Even though we don't care about labels, we need to do
* enough parsing work to skip over the right bits of xo_vap.
*/
- if (len == 0)
- xo_do_format_field(xop, NULL, fmt, flen,
- flags | XFF_NO_OUTPUT);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
}
break;
case XO_STYLE_ENCODER:
- if (len == 0)
- xo_do_format_field(xop, NULL, fmt, flen,
- flags | XFF_NO_OUTPUT);
+ xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
break;
}
}
@@ -4583,6 +4781,28 @@ xo_colors_enabled (xo_handle_t *xop UNUSED)
#endif /* LIBXO_TEXT_ONLY */
}
+/*
+ * If the color map is in use (--libxo colors=xxxx), then update
+ * the incoming foreground and background colors from the map.
+ */
+static void
+xo_colors_update (xo_handle_t *xop, xo_colors_t *newp)
+{
+#ifdef LIBXO_TEXT_ONLY
+ return;
+#endif /* LIBXO_TEXT_ONLY */
+
+ xo_color_t fg = newp->xoc_col_fg;
+ if (XOF_ISSET(xop, XOF_COLOR_MAP) && fg < XO_NUM_COLORS)
+ fg = xop->xo_color_map_fg[fg]; /* Fetch from color map */
+ newp->xoc_col_fg = fg;
+
+ xo_color_t bg = newp->xoc_col_bg;
+ if (XOF_ISSET(xop, XOF_COLOR_MAP) && bg < XO_NUM_COLORS)
+ bg = xop->xo_color_map_bg[bg]; /* Fetch from color map */
+ newp->xoc_col_bg = bg;
+}
+
static void
xo_colors_handle_text (xo_handle_t *xop, xo_colors_t *newp)
{
@@ -4629,16 +4849,16 @@ xo_colors_handle_text (xo_handle_t *xop, xo_colors_t *newp)
}
}
- if (newp->xoc_col_fg != oldp->xoc_col_fg) {
+ xo_color_t fg = newp->xoc_col_fg;
+ if (fg != oldp->xoc_col_fg) {
cp += snprintf(cp, ep - cp, ";3%u",
- (newp->xoc_col_fg != XO_COL_DEFAULT)
- ? newp->xoc_col_fg - 1 : 9);
+ (fg != XO_COL_DEFAULT) ? fg - 1 : 9);
}
- if (newp->xoc_col_bg != oldp->xoc_col_bg) {
+ xo_color_t bg = newp->xoc_col_bg;
+ if (bg != oldp->xoc_col_bg) {
cp += snprintf(cp, ep - cp, ";4%u",
- (newp->xoc_col_bg != XO_COL_DEFAULT)
- ? newp->xoc_col_bg - 1 : 9);
+ (bg != XO_COL_DEFAULT) ? bg - 1 : 9);
}
if (cp - buf != 1 && cp < ep - 3) {
@@ -4710,7 +4930,7 @@ xo_colors_handle_html (xo_handle_t *xop, xo_colors_t *newp)
static void
xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip,
- const char *str, ssize_t len)
+ const char *value, ssize_t vlen)
{
const char *fmt = xfip->xfi_format;
ssize_t flen = xfip->xfi_flen;
@@ -4718,13 +4938,13 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip,
xo_buffer_t xb;
/* If the string is static and we've in an encoding style, bail */
- if (len != 0 && xo_style_is_encoding(xop))
+ if (vlen != 0 && xo_style_is_encoding(xop))
return;
xo_buf_init(&xb);
- if (len)
- xo_buf_append(&xb, str, len);
+ if (vlen)
+ xo_buf_append(&xb, value, vlen);
else if (flen)
xo_do_format_field(xop, &xb, fmt, flen, 0);
else
@@ -4738,6 +4958,7 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip,
xo_colors_t xoc = xop->xo_colors;
xo_colors_parse(xop, &xoc, xb.xb_bufp);
+ xo_colors_update(xop, &xoc);
if (xo_style(xop) == XO_STYLE_TEXT) {
/*
@@ -4783,7 +5004,7 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip,
static void
xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip,
- const char *str, ssize_t len)
+ const char *value, ssize_t vlen)
{
const char *fmt = xfip->xfi_format;
ssize_t flen = xfip->xfi_flen;
@@ -4793,7 +5014,7 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip,
static char units_start_html[] = " data-units=\"";
if (!XOIF_ISSET(xop, XOIF_UNITS_PENDING)) {
- xo_format_content(xop, "units", NULL, str, len, fmt, flen, flags);
+ xo_format_content(xop, "units", NULL, value, vlen, fmt, flen, flags);
return;
}
@@ -4808,8 +5029,8 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip,
else
return;
- if (len)
- xo_data_escape(xop, str, len);
+ if (vlen)
+ xo_data_escape(xop, value, vlen);
else
xo_do_format_field(xop, NULL, fmt, flen, flags);
@@ -4837,7 +5058,7 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip,
static ssize_t
xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip,
- const char *str, ssize_t len)
+ const char *value, ssize_t vlen)
{
const char *fmt = xfip->xfi_format;
ssize_t flen = xfip->xfi_flen;
@@ -4846,10 +5067,10 @@ xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip,
char *bp;
char *cp;
- if (len) {
- bp = alloca(len + 1); /* Make local NUL-terminated copy of str */
- memcpy(bp, str, len);
- bp[len] = '\0';
+ if (vlen) {
+ bp = alloca(vlen + 1); /* Make local NUL-terminated copy of value */
+ memcpy(bp, value, vlen);
+ bp[vlen] = '\0';
width = strtol(bp, &cp, 0);
if (width == LONG_MIN || width == LONG_MAX
@@ -4886,7 +5107,7 @@ xo_anchor_clear (xo_handle_t *xop)
*/
static void
xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip,
- const char *str, ssize_t len)
+ const char *value, ssize_t vlen)
{
if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
return;
@@ -4903,12 +5124,12 @@ xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip,
* Now we find the width, if possible. If it's not there,
* we'll get it on the end anchor.
*/
- xop->xo_anchor_min_width = xo_find_width(xop, xfip, str, len);
+ xop->xo_anchor_min_width = xo_find_width(xop, xfip, value, vlen);
}
static void
xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip,
- const char *str, ssize_t len)
+ const char *value, ssize_t vlen)
{
if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
return;
@@ -4920,7 +5141,7 @@ xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip,
XOIF_CLEAR(xop, XOIF_UNITS_PENDING);
- ssize_t width = xo_find_width(xop, xfip, str, len);
+ ssize_t width = xo_find_width(xop, xfip, value, vlen);
if (width == 0)
width = xop->xo_anchor_min_width;
@@ -5839,12 +6060,12 @@ xo_gettext_build_format (xo_handle_t *xop,
if (gtfmt == NULL || gtfmt == fmt || strcmp(gtfmt, fmt) == 0)
goto bail2;
- xo_buf_cleanup(&xb);
-
char *new_fmt = xo_strndup(gtfmt, -1);
if (new_fmt == NULL)
goto bail2;
+ xo_buf_cleanup(&xb);
+
*new_fmtp = new_fmt;
return new_fmt;
@@ -5977,7 +6198,7 @@ xo_do_emit_fields (xo_handle_t *xop, xo_field_info_t *fields,
ssize_t fend[flimit];
bzero(fend, flimit * sizeof(fend[0]));
- for (xfip = fields, field = 0; xfip->xfi_ftype && field < max_fields;
+ for (xfip = fields, field = 0; field < max_fields && xfip->xfi_ftype;
xfip++, field++) {
ftype = xfip->xfi_ftype;
flags = xfip->xfi_flags;
@@ -6024,12 +6245,12 @@ xo_do_emit_fields (xo_handle_t *xop, xo_field_info_t *fields,
if (flags & XFF_WS) {
xo_format_content(xop, "padding", NULL, " ", 1,
NULL, 0, flags);
- flags &= ~XFF_WS; /* Block later handling of this */
+ flags &= ~XFF_WS; /* Prevent later handling of this flag */
}
}
if (ftype == 'V')
- xo_format_value(xop, content, clen,
+ xo_format_value(xop, content, clen, NULL, 0,
xfip->xfi_format, xfip->xfi_flen,
xfip->xfi_encoding, xfip->xfi_elen, flags);
else if (ftype == '[')
@@ -6460,7 +6681,7 @@ xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)
*xbp->xb_curp = '\0';
rc = xo_encoder_handle(xop, XO_OP_ATTRIBUTE,
xo_buf_data(xbp, name_offset),
- xo_buf_data(xbp, value_offset));
+ xo_buf_data(xbp, value_offset), 0);
}
}
@@ -6538,7 +6759,7 @@ xo_depth_change (xo_handle_t *xop, const char *name,
xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth];
if (XOF_ISSET(xop, XOF_WARN)) {
const char *top = xsp->xs_name;
- if (top && strcmp(name, top) != 0) {
+ if (top != NULL && name != NULL && strcmp(name, top) != 0) {
xo_failure(xop, "incorrect close: '%s' .vs. '%s'",
name, top);
return;
@@ -6650,7 +6871,7 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
break;
case XO_STYLE_ENCODER:
- rc = xo_encoder_handle(xop, XO_OP_OPEN_CONTAINER, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_OPEN_CONTAINER, name, NULL, flags);
break;
}
@@ -6740,7 +6961,7 @@ xo_do_close_container (xo_handle_t *xop, const char *name)
case XO_STYLE_ENCODER:
xo_depth_change(xop, name, -1, 0, XSS_CLOSE_CONTAINER, 0);
- rc = xo_encoder_handle(xop, XO_OP_CLOSE_CONTAINER, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_CLOSE_CONTAINER, name, NULL, 0);
break;
}
@@ -6806,7 +7027,7 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
break;
case XO_STYLE_ENCODER:
- rc = xo_encoder_handle(xop, XO_OP_OPEN_LIST, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_OPEN_LIST, name, NULL, flags);
break;
}
@@ -6881,7 +7102,7 @@ xo_do_close_list (xo_handle_t *xop, const char *name)
case XO_STYLE_ENCODER:
xo_depth_change(xop, name, -1, 0, XSS_CLOSE_LIST, XSF_LIST);
- rc = xo_encoder_handle(xop, XO_OP_CLOSE_LIST, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_CLOSE_LIST, name, NULL, 0);
break;
default:
@@ -6955,7 +7176,7 @@ xo_do_open_leaf_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
break;
case XO_STYLE_ENCODER:
- rc = xo_encoder_handle(xop, XO_OP_OPEN_LEAF_LIST, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_OPEN_LEAF_LIST, name, NULL, flags);
break;
}
@@ -6999,7 +7220,7 @@ xo_do_close_leaf_list (xo_handle_t *xop, const char *name)
break;
case XO_STYLE_ENCODER:
- rc = xo_encoder_handle(xop, XO_OP_CLOSE_LEAF_LIST, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_CLOSE_LEAF_LIST, name, NULL, 0);
/* FALLTHRU */
default:
@@ -7056,7 +7277,7 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
break;
case XO_STYLE_ENCODER:
- rc = xo_encoder_handle(xop, XO_OP_OPEN_INSTANCE, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_OPEN_INSTANCE, name, NULL, flags);
break;
}
@@ -7144,7 +7365,7 @@ xo_do_close_instance (xo_handle_t *xop, const char *name)
case XO_STYLE_ENCODER:
xo_depth_change(xop, name, -1, 0, XSS_CLOSE_INSTANCE, 0);
- rc = xo_encoder_handle(xop, XO_OP_CLOSE_INSTANCE, name, NULL);
+ rc = xo_encoder_handle(xop, XO_OP_CLOSE_INSTANCE, name, NULL, 0);
break;
}
@@ -7620,7 +7841,7 @@ xo_flush_h (xo_handle_t *xop)
switch (xo_style(xop)) {
case XO_STYLE_ENCODER:
- xo_encoder_handle(xop, XO_OP_FLUSH, NULL, NULL);
+ xo_encoder_handle(xop, XO_OP_FLUSH, NULL, NULL, 0);
}
rc = xo_write(xop);
@@ -7658,7 +7879,7 @@ xo_finish_h (xo_handle_t *xop)
break;
case XO_STYLE_ENCODER:
- xo_encoder_handle(xop, XO_OP_FINISH, NULL, NULL);
+ xo_encoder_handle(xop, XO_OP_FINISH, NULL, NULL, 0);
break;
}
@@ -7710,7 +7931,8 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
case XO_STYLE_HTML:
va_copy(xop->xo_vap, vap);
- xo_buf_append_div(xop, "error", 0, NULL, 0, fmt, strlen(fmt), NULL, 0);
+ xo_buf_append_div(xop, "error", 0, NULL, 0, NULL, 0,
+ fmt, strlen(fmt), NULL, 0);
if (XOIF_ISSET(xop, XOIF_DIV_OPEN))
xo_line_close(xop);
@@ -7726,7 +7948,8 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
va_copy(xop->xo_vap, vap);
xo_open_container_h(xop, "error");
- xo_format_value(xop, "message", 7, fmt, strlen(fmt), NULL, 0, 0);
+ xo_format_value(xop, "message", 7, NULL, 0,
+ fmt, strlen(fmt), NULL, 0, 0);
xo_close_container_h(xop, "error");
va_end(xop->xo_vap);
@@ -7781,6 +8004,8 @@ xo_parse_args (int argc, char **argv)
if (cp)
xo_program = cp + 1;
+ xo_handle_t *xop = xo_default(NULL);
+
for (save = i = 1; i < argc; i++) {
if (argv[i] == NULL
|| strncmp(argv[i], libxo_opt, sizeof(libxo_opt) - 1) != 0) {
@@ -7798,14 +8023,14 @@ xo_parse_args (int argc, char **argv)
return -1;
}
- if (xo_set_options(NULL, cp) < 0)
+ if (xo_set_options(xop, cp) < 0)
return -1;
} else if (*cp == ':') {
- if (xo_set_options(NULL, cp) < 0)
+ if (xo_set_options(xop, cp) < 0)
return -1;
} else if (*cp == '=') {
- if (xo_set_options(NULL, ++cp) < 0)
+ if (xo_set_options(xop, ++cp) < 0)
return -1;
} else if (*cp == '-') {
@@ -7823,6 +8048,13 @@ xo_parse_args (int argc, char **argv)
}
}
+ /*
+ * We only want to do color output on terminals, but we only want
+ * to do this if the user has asked for color.
+ */
+ if (XOF_ISSET(xop, XOF_COLOR_ALLOWED) && isatty(1))
+ XOF_SET(xop, XOF_COLOR);
+
argv[save] = NULL;
return save;
}
@@ -7884,7 +8116,7 @@ xo_set_version_h (xo_handle_t *xop, const char *version)
break;
case XO_STYLE_ENCODER:
- xo_encoder_handle(xop, XO_OP_VERSION, NULL, version);
+ xo_encoder_handle(xop, XO_OP_VERSION, NULL, version, 0);
break;
}
}
@@ -7934,7 +8166,7 @@ xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
xo_buffer_t *src = &temp.xo_data;
xo_format_value(xop, "message", 7, src->xb_bufp,
- src->xb_curp - src->xb_bufp, NULL, 0, 0);
+ src->xb_curp - src->xb_bufp, NULL, 0, NULL, 0, 0);
xo_free(temp.xo_stack);
xo_buf_cleanup(src);
diff --git a/freebsd/contrib/libxo/libxo/xo.h b/freebsd/contrib/libxo/libxo/xo.h
index 13023d38..c39fa47e 100644
--- a/freebsd/contrib/libxo/libxo/xo.h
+++ b/freebsd/contrib/libxo/libxo/xo.h
@@ -101,6 +101,8 @@ typedef unsigned long long xo_xof_flags_t;
#define XOF_RETAIN_ALL XOF_BIT(30) /** Force use of XOEF_RETAIN */
#define XOF_RETAIN_NONE XOF_BIT(31) /** Prevent use of XOEF_RETAIN */
+#define XOF_COLOR_MAP XOF_BIT(32) /** Color map has been initialized */
+
typedef unsigned xo_emit_flags_t; /* Flags to xo_emit() and friends */
#define XOEF_RETAIN (1<<0) /* Retain parsed formatting information */
diff --git a/freebsd/contrib/libxo/libxo/xo_buf.h b/freebsd/contrib/libxo/libxo/xo_buf.h
index 3bb5628a..d6a05005 100644
--- a/freebsd/contrib/libxo/libxo/xo_buf.h
+++ b/freebsd/contrib/libxo/libxo/xo_buf.h
@@ -133,7 +133,7 @@ xo_buf_has_room (xo_buffer_t *xbp, ssize_t len)
static inline void
xo_buf_append (xo_buffer_t *xbp, const char *str, ssize_t len)
{
- if (!xo_buf_has_room(xbp, len))
+ if (str == NULL || len == 0 || !xo_buf_has_room(xbp, len))
return;
memcpy(xbp->xb_curp, str, len);
diff --git a/freebsd/contrib/libxo/libxo/xo_encoder.c b/freebsd/contrib/libxo/libxo/xo_encoder.c
index 436e57f5..b114ea78 100644
--- a/freebsd/contrib/libxo/libxo/xo_encoder.c
+++ b/freebsd/contrib/libxo/libxo/xo_encoder.c
@@ -311,7 +311,7 @@ xo_encoder_init (xo_handle_t *xop, const char *name)
xo_set_encoder(xop, xep->xe_handler);
- return xo_encoder_handle(xop, XO_OP_CREATE, NULL, NULL);
+ return xo_encoder_handle(xop, XO_OP_CREATE, NULL, NULL, 0);
}
/*
@@ -337,7 +337,7 @@ xo_encoder_create (const char *name, xo_xof_flags_t flags)
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
- const char *name, const char *value)
+ const char *name, const char *value, xo_xof_flags_t flags)
{
void *private = xo_get_private(xop);
xo_encoder_func_t func = xo_get_encoder(xop);
@@ -345,7 +345,7 @@ xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
if (func == NULL)
return -1;
- return func(xop, op, name, value, private);
+ return func(xop, op, name, value, private, flags);
}
const char *
@@ -416,7 +416,7 @@ xo_encoder_create (const char *name, xo_xof_flags_t flags)
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
- const char *name, const char *value)
+ const char *name, const char *value, xo_xof_flags_t flags)
{
return -1;
}
diff --git a/freebsd/contrib/libxo/libxo/xo_encoder.h b/freebsd/contrib/libxo/libxo/xo_encoder.h
index f73552b1..0e20e72a 100644
--- a/freebsd/contrib/libxo/libxo/xo_encoder.h
+++ b/freebsd/contrib/libxo/libxo/xo_encoder.h
@@ -50,7 +50,8 @@ typedef unsigned xo_encoder_op_t;
xo_encoder_op_t op __attribute__ ((__unused__)), \
const char *name __attribute__ ((__unused__)), \
const char *value __attribute__ ((__unused__)), \
- void *private __attribute__ ((__unused__))
+ void *private __attribute__ ((__unused__)), \
+ xo_xof_flags_t flags __attribute__ ((__unused__))
typedef int (*xo_encoder_func_t)(XO_ENCODER_HANDLER_ARGS);
@@ -105,7 +106,7 @@ xo_encoder_create (const char *name, xo_xof_flags_t flags);
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
- const char *name, const char *value);
+ const char *name, const char *value, xo_xof_flags_t flags);
void
xo_encoders_clean (void);