aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--doc/api.rst59
-rw-r--r--doc/encoders.rst13
-rw-r--r--doc/options.rst20
-rw-r--r--encoder/csv/enc_csv.c24
-rw-r--r--libxo/libxo.c103
-rw-r--r--libxo/xo.h9
-rw-r--r--libxo/xo_encoder.c21
-rw-r--r--libxo/xo_encoder.h1
-rw-r--r--tests/core/Makefile.am11
-rw-r--r--tests/core/saved/test_02.H.out3
-rw-r--r--tests/core/saved/test_02.HIPx.out15
-rw-r--r--tests/core/saved/test_02.HP.out15
-rw-r--r--tests/core/saved/test_02.J.out2
-rw-r--r--tests/core/saved/test_02.JP.out12
-rw-r--r--tests/core/saved/test_02.T.err3
-rw-r--r--tests/core/saved/test_02.X.out3
-rw-r--r--tests/core/saved/test_02.XP.out15
-rw-r--r--tests/core/test_02.c6
-rw-r--r--tests/core/test_12.c2
20 files changed, 294 insertions, 45 deletions
diff --git a/configure.ac b/configure.ac
index 62d5a0383f79..e28db9396082 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,7 +12,7 @@
#
AC_PREREQ(2.2)
-AC_INIT([libxo], [1.3.1], [phil@juniper.net])
+AC_INIT([libxo], [1.4.0], [phil@juniper.net])
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
# Support silent build rules. Requires at least automake-1.11.
diff --git a/doc/api.rst b/doc/api.rst
index 4ca51306472a..94358489f075 100644
--- a/doc/api.rst
+++ b/doc/api.rst
@@ -1204,6 +1204,11 @@ message associated with either *errno* or the *code* parameter::
xo_err(1, "cannot open file '%s'", filename);
.. index:: xo_error
+.. index:: xo_error_h
+.. index:: xo_error_hv
+.. index:: xo_errorn
+.. index:: xo_errorn_h
+.. index:: xo_errorn_hv
xo_error
~~~~~~~~
@@ -1214,6 +1219,50 @@ xo_error
:type fmt: const char *
:returns: void
+.. c:function:: void xo_error_h (xo_handle_t *xop, const char *fmt, ...)
+
+ :param xop: libxo handle pointer
+ :type xop: xo_handle_t *
+ :param fmt: Format string
+ :type fmt: const char *
+ :returns: void
+
+.. c:function:: void xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
+
+ :param xop: libxo handle pointer
+ :type xop: xo_handle_t *
+ :param fmt: Format string
+ :type fmt: const char *
+ :param vap: variadic arguments
+ :type xop: va_list
+ :returns: void
+
+.. c:function:: void xo_errorn (const char *fmt, ...)
+
+ :param fmt: Format string
+ :type fmt: const char *
+ :returns: void
+
+.. c:function:: void xo_errorn_h (xo_handle_t *xop, const char *fmt, ...)
+
+ :param xop: libxo handle pointer
+ :type xop: xo_handle_t *
+ :param fmt: Format string
+ :type fmt: const char *
+ :returns: void
+
+.. c:function:: void xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap)
+
+ :param xop: libxo handle pointer
+ :type xop: xo_handle_t *
+ :param need_newline: boolean indicating need for trailing newline
+ :type need_newline: int
+ :param fmt: Format string
+ :type fmt: const char *
+ :param vap: variadic arguments
+ :type xop: va_list
+ :returns: void
+
The `xo_error` function can be used for generic errors that should
be reported over the handle, rather than to stderr. The `xo_error`
function behaves like `xo_err` for TEXT and HTML output styles, but
@@ -1226,6 +1275,16 @@ xo_error
JSON::
"error": { "message": "Does not compute" }
+ The `xo_error_h` and `xo_error_hv` add a handle object and a
+ variadic-ized parameter to the signature, respectively.
+
+ The `xo_errorn` function supplies a newline at the end the error
+ message if the format string does not include one. The
+ `xo_errorn_h` and `xo_errorn_hv` functions add a handle object and
+ a variadic-ized parameter to the signature, respectively. The
+ `xo_errorn_hv` function also adds a boolean to indicate the need for
+ a trailing newline.
+
.. index:: xo_no_setlocale
.. index:: Locale
diff --git a/doc/encoders.rst b/doc/encoders.rst
index d06e0e9177c9..dfd0316bfb97 100644
--- a/doc/encoders.rst
+++ b/doc/encoders.rst
@@ -26,12 +26,13 @@ example uses the "cbor" encoder, saving the output into a file::
df --libxo encoder=cbor > df-output.cbor
Encoders can support specific options that can be accessed by
-following the encoder name with a colon (':') and one of more options,
-separated by a plus sign "+"::
+following the encoder name with a colon (':') or a plus sign ('+') and
+one of more options, separated by the same character::
- df --libxo encoder=csv:path=filesystem+leaf=name+no-header
+ df --libxo encoder=csv+path=filesystem+leaf=name+no-header
+ df --libxo encoder=csv:path=filesystem:leaf=name:no-header
-This example instructs libxo to load the "csv" encoder and pass the
+These examples instructs libxo to load the "csv" encoder and pass the
following options::
path=filesystem
@@ -42,6 +43,10 @@ Each of these option is interpreted by the encoder, and all such
options names and semantics are specific to the particular encoder.
Refer to the intended encoder for documentation on its options.
+The string "@" can be used in place of the string "encoder=".
+
+ df --libxo @csv:no-header
+
.. _csv_encoder:
CSV - Comma Separated Values
diff --git a/doc/options.rst b/doc/options.rst
index bd0fa565e281..79cd360a1f44 100644
--- a/doc/options.rst
+++ b/doc/options.rst
@@ -162,3 +162,23 @@ foreground and background output to "yellow", give only the fifth
mapping, skipping the first four mappings with bare plus signs ("+")::
--libxo colors=++++yellow/yellow
+
+Encoders
+--------
+
+In addition to the four "built-in" formats, libxo supports an
+extensible mechanism for adding encoders. These are activated
+using the "encoder" keyword::
+
+ --libxo encoder=cbor
+
+The encoder can include encoder-specific options, separated by either
+colons (":") or plus signs ("+"):
+
+ --libxo encoder=csv+path=filesystem+leaf=name+no-header
+ --libxo encoder=csv:path=filesystem:leaf=name:no-header
+
+For brevity, the string "@" can be used in place of the string
+"encoder=".
+
+ df --libxo @csv:no-header
diff --git a/encoder/csv/enc_csv.c b/encoder/csv/enc_csv.c
index 88e93f37cc97..10f9110f4939 100644
--- a/encoder/csv/enc_csv.c
+++ b/encoder/csv/enc_csv.c
@@ -41,10 +41,12 @@
* (double) quote characters.
* - Leading and trialing whitespace require fields be quoted.
*
- * Cheesy, but simple. The RFC also requires MS-DOS end-of-line, which
- * we only do with the "dos" option. Strange that we still live in a
- * DOS-friendly world, but then again, we make spaceships based on the
- * horse butts (http://www.astrodigital.org/space/stshorse.html).
+ * Cheesy, but simple. The RFC also requires MS-DOS end-of-line,
+ * which we only do with the "dos" option. Strange that we still live
+ * in a DOS-friendly world, but then again, we make spaceships based
+ * on the horse butts (http://www.astrodigital.org/space/stshorse.html
+ * though the "built by English expatriates” bit is rubbish; better to
+ * say the first engines used in America were built by Englishmen.)
*/
#include <string.h>
@@ -655,10 +657,12 @@ csv_record_path (xo_handle_t *xop, csv_private_t *csv, const char *path_raw)
/*
* Extract the option values. The format is:
- * -libxo encoder=csv:kw=val+kw=val+kw=val,pretty,etc
+ * -libxo encoder=csv:kw=val:kw=val:kw=val,pretty
+ * -libxo encoder=csv+kw=val+kw=val+kw=val,pretty
*/
static int
-csv_options (xo_handle_t *xop, csv_private_t *csv, const char *raw_opts)
+csv_options (xo_handle_t *xop, csv_private_t *csv,
+ const char *raw_opts, char opts_char)
{
ssize_t len = strlen(raw_opts);
char *options = alloca(len + 1);
@@ -667,7 +671,7 @@ csv_options (xo_handle_t *xop, csv_private_t *csv, const char *raw_opts)
char *cp, *ep, *np, *vp;
for (cp = options, ep = options + len + 1; cp && cp < ep; cp = np) {
- np = strchr(cp, '+');
+ np = strchr(cp, opts_char);
if (np)
*np++ = '\0';
@@ -761,7 +765,11 @@ csv_handler (XO_ENCODER_HANDLER_ARGS)
break;
case XO_OP_OPTIONS:
- rc = csv_options(xop, csv, value);
+ rc = csv_options(xop, csv, value, ':');
+ break;
+
+ case XO_OP_OPTIONS_PLUS:
+ rc = csv_options(xop, csv, value, '+');
break;
case XO_OP_OPEN_LIST:
diff --git a/libxo/libxo.c b/libxo/libxo.c
index 14268d1b250e..ea64feb82747 100644
--- a/libxo/libxo.c
+++ b/libxo/libxo.c
@@ -2371,6 +2371,25 @@ xo_set_options (xo_handle_t *xop, const char *input)
if (np)
*np++ = '\0';
+ /*
+ * "@foo" is a shorthand for "encoder=foo". This is driven
+ * chiefly by a desire to make pluggable encoders not appear
+ * so distinct from built-in encoders.
+ */
+ if (*cp == '@') {
+ vp = cp + 1;
+
+ if (*vp == '\0')
+ xo_failure(xop, "missing value for encoder option");
+ else {
+ rc = xo_encoder_init(xop, vp);
+ if (rc)
+ xo_warnx("error initializing encoder: %s", vp);
+ }
+
+ continue;
+ }
+
vp = strchr(cp, '=');
if (vp)
*vp++ = '\0';
@@ -8007,7 +8026,7 @@ xo_finish_atexit (void)
* Generate an error message, such as would be displayed on stderr
*/
void
-xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
+xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap)
{
xop = xo_default(xop);
@@ -8015,13 +8034,15 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
* If the format string doesn't end with a newline, we pop
* one on ourselves.
*/
- ssize_t len = strlen(fmt);
- if (len > 0 && fmt[len - 1] != '\n') {
- char *newfmt = alloca(len + 2);
- memcpy(newfmt, fmt, len);
- newfmt[len] = '\n';
- newfmt[len + 1] = '\0';
- fmt = newfmt;
+ if (need_newline) {
+ ssize_t len = strlen(fmt);
+ if (len > 0 && fmt[len - 1] != '\n') {
+ char *newfmt = alloca(len + 2);
+ memcpy(newfmt, fmt, len);
+ newfmt[len] = '\n';
+ newfmt[len + 1] = '\0';
+ fmt = newfmt;
+ }
}
switch (xo_style(xop)) {
@@ -8069,7 +8090,7 @@ xo_error_h (xo_handle_t *xop, const char *fmt, ...)
va_list vap;
va_start(vap, fmt);
- xo_error_hv(xop, fmt, vap);
+ xo_errorn_hv(xop, 0, fmt, vap);
va_end(vap);
}
@@ -8082,7 +8103,30 @@ xo_error (const char *fmt, ...)
va_list vap;
va_start(vap, fmt);
- xo_error_hv(NULL, fmt, vap);
+ xo_errorn_hv(NULL, 0, fmt, vap);
+ va_end(vap);
+}
+
+void
+xo_errorn_h (xo_handle_t *xop, const char *fmt, ...)
+{
+ va_list vap;
+
+ va_start(vap, fmt);
+ xo_errorn_hv(xop, 1, fmt, vap);
+ va_end(vap);
+}
+
+/*
+ * Generate an error message, such as would be displayed on stderr
+ */
+void
+xo_errorn (const char *fmt, ...)
+{
+ va_list vap;
+
+ va_start(vap, fmt);
+ xo_errorn_hv(NULL, 1, fmt, vap);
va_end(vap);
}
@@ -8099,21 +8143,30 @@ xo_parse_args (int argc, char **argv)
char *cp;
int i, save;
- /* Save our program name for xo_err and friends */
- xo_program = argv[0];
- cp = strrchr(xo_program, '/');
- if (cp)
- xo_program = ++cp;
- else
- cp = argv[0]; /* Reset to front of string */
-
- /* GNU tools add an annoying ".test" as the program extension; remove it */
- size_t len = strlen(xo_program);
- static const char gnu_ext[] = ".test";
- if (len >= sizeof(gnu_ext)) {
- cp += len + 1 - sizeof(gnu_ext);
- if (xo_streq(cp, gnu_ext))
- *cp = '\0';
+ /*
+ * If xo_set_program has always been called, we honor that value
+ */
+ if (xo_program == NULL) {
+ /* Save our program name for xo_err and friends */
+ xo_program = argv[0];
+ cp = strrchr(xo_program, '/');
+ if (cp)
+ xo_program = ++cp;
+ else
+ cp = argv[0]; /* Reset to front of string */
+
+ /*
+ * GNU libtool add an annoying ".test" as the program
+ * extension; we remove it. libtool also adds a "lt-" prefix
+ * that we cannot remove.
+ */
+ size_t len = strlen(xo_program);
+ static const char gnu_ext[] = ".test";
+ if (len >= sizeof(gnu_ext)) {
+ cp += len + 1 - sizeof(gnu_ext);
+ if (xo_streq(cp, gnu_ext))
+ *cp = '\0';
+ }
}
xo_handle_t *xop = xo_default(NULL);
diff --git a/libxo/xo.h b/libxo/xo.h
index 8404c6cb93ae..6a61a16c7cae 100644
--- a/libxo/xo.h
+++ b/libxo/xo.h
@@ -389,6 +389,15 @@ xo_error_h (xo_handle_t *xop, const char *fmt, ...);
void
xo_error (const char *fmt, ...);
+void
+xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap);
+
+void
+xo_errorn_h (xo_handle_t *xop, const char *fmt, ...);
+
+void
+xo_errorn (const char *fmt, ...);
+
xo_ssize_t
xo_flush_h (xo_handle_t *xop);
diff --git a/libxo/xo_encoder.c b/libxo/xo_encoder.c
index 7e6cc1643374..475b6d70fa9d 100644
--- a/libxo/xo_encoder.c
+++ b/libxo/xo_encoder.c
@@ -290,8 +290,21 @@ xo_encoder_init (xo_handle_t *xop, const char *name)
{
xo_encoder_setup();
- const char *opts = strchr(name, ':');
+ char opts_char = '\0';
+ const char *col_opts = strchr(name, ':');
+ const char *plus_opts = strchr(name, '+');
+
+ /*
+ * Find the option-separating character (plus or colon) which
+ * appears first in the options string.
+ */
+ const char *opts = (col_opts == NULL) ? plus_opts
+ : (plus_opts == NULL) ? col_opts
+ : (plus_opts < col_opts) ? plus_opts : col_opts;
+
if (opts) {
+ opts_char = *opts;
+
/* Make a writable copy of the name */
size_t len = strlen(name);
char *copy = alloca(len + 1);
@@ -329,7 +342,11 @@ xo_encoder_init (xo_handle_t *xop, const char *name)
int rc = xo_encoder_handle(xop, XO_OP_CREATE, name, NULL, 0);
if (rc == 0 && opts != NULL) {
- rc = xo_encoder_handle(xop, XO_OP_OPTIONS, name, opts, 0);
+ xo_encoder_op_t op;
+
+ /* Encoder API is limited, so we're stuck with two different options */
+ op = (opts_char == '+') ? XO_OP_OPTIONS_PLUS : XO_OP_OPTIONS;
+ rc = xo_encoder_handle(xop, op, name, opts, 0);
}
return rc;
diff --git a/libxo/xo_encoder.h b/libxo/xo_encoder.h
index 2a940336293c..099248ae13a6 100644
--- a/libxo/xo_encoder.h
+++ b/libxo/xo_encoder.h
@@ -90,6 +90,7 @@ typedef unsigned xo_encoder_op_t;
#define XO_OP_ATTRIBUTE 15 /* Attribute name/value */
#define XO_OP_VERSION 16 /* Version string */
#define XO_OP_OPTIONS 17 /* Additional command line options */
+#define XO_OP_OPTIONS_PLUS 18 /* Additional command line options */
#define XO_ENCODER_HANDLER_ARGS \
xo_handle_t *xop __attribute__ ((__unused__)), \
diff --git a/tests/core/Makefile.am b/tests/core/Makefile.am
index 9f7ffc441448..a1dad2cc96a2 100644
--- a/tests/core/Makefile.am
+++ b/tests/core/Makefile.am
@@ -88,7 +88,7 @@ TEST_JIG = \
TEST_JIG2 = \
echo "... $$test ... $$fmt ..."; \
-xoopts==warn,encoder=csv$$csv ; \
+xoopts==warn,$$csv ; \
${TEST_JIG}; true;
TEST_FORMATS = T XP JP HP X J H HIPx
@@ -111,9 +111,12 @@ test tests: ${bin_PROGRAMS}
done) \
done)
-@ (${TEST_TRACE} test=test_01.c; base=test_01; \
- ( fmt=Ecsv1; csv= ; ${TEST_JIG2} ); \
- ( fmt=Ecsv2; csv=:path=top/data/item+no-header ; ${TEST_JIG2} ); \
- ( fmt=Ecsv3; csv=:path=item+leafs=sku.sold+no-quotes ; ${TEST_JIG2} ); \
+ ( fmt=Ecsv1; csv=encoder=csv ; \
+ ${TEST_JIG2} ); \
+ ( fmt=Ecsv2; csv=encoder=csv:path=top/data/item:no-header ; \
+ ${TEST_JIG2} ); \
+ ( fmt=Ecsv3; csv=@csv:path=item:leafs=sku.sold:no-quotes ; \
+ ${TEST_JIG2} ); \
)
diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out
index 66a158502766..a3d88030075a 100644
--- a/tests/core/saved/test_02.H.out
+++ b/tests/core/saved/test_02.H.out
@@ -4,4 +4,7 @@
</div></div><div class="line"><div class="text">length </div><div class="data" data-tag="length">abcdef</div></div><div class="line"><div class="text">close </div><div class="data" data-tag="fd">-1</div><div class="text"> returned </div><div class="data" data-tag="error">Bad file descriptor</div><div class="text"> </div><div class="data" data-tag="test">good</div></div><div class="line"><div class="text">close </div><div class="data" data-tag="fd">-1</div><div class="text"> returned </div><div class="data" data-tag="error">Bad fi</div><div class="text"> </div><div class="data" data-tag="test">good</div></div><div class="line"><div class="message">improper use of profanity; ten yard penalty; first down
</div></div><div class="line"><div class="text"> </div><div class="data" data-tag="lines"> 20</div><div class="text"> </div><div class="data" data-tag="words"> 30</div><div class="text"> </div><div class="data" data-tag="characters"> 40</div><div class="text"> </div><div class="data" data-tag="filename">file</div></div><div class="line"><div class="data" data-tag="bytes">0</div><div class="padding"> </div><div class="note">bytes</div></div><div class="line"><div class="data" data-tag="bytes">1</div><div class="padding"> </div><div class="note">byte</div></div><div class="line"><div class="data" data-tag="bytes">2</div><div class="padding"> </div><div class="note">bytes</div></div><div class="line"><div class="data" data-tag="bytes">3</div><div class="padding"> </div><div class="note">bytes</div></div><div class="line"><div class="data" data-tag="bytes">4</div><div class="padding"> </div><div class="note">bytes</div></div><div class="line"><div class="data" data-tag="mbuf-current">10</div><div class="text">/</div><div class="data" data-tag="mbuf-cache">20</div><div class="text">/</div><div class="data" data-tag="mbuf-total">30</div><div class="text"> </div><div class="note">mbufs &lt;&amp;&gt; in use (current/cache/total)</div></div><div class="line"><div class="data" data-tag="distance" data-units="miles">50</div><div class="padding"> </div><div class="text"> from </div><div class="data" data-tag="location">Boston</div></div><div class="line"><div class="data" data-tag="memory" data-units="k">64</div><div class="text"> left out of </div><div class="data" data-tag="total" data-units="kb">640</div></div><div class="line"><div class="data" data-tag="memory" data-units="k">64</div><div class="text"> left out of </div><div class="data" data-tag="total" data-units="kilobytes">640</div></div><div class="line"><div class="title">beforeworkingafter:</div></div><div class="line"><div class="data" data-tag="some">string</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="ten">10</div><div class="data" data-tag="eleven">11</div></div><div class="line"><div class="data" data-tag="unknown">1010</div><div class="text"> </div><div class="note">packets here/there/everywhere</div></div><div class="line"><div class="data" data-tag="unknown">1010</div><div class="text"> </div><div class="note">packets here/there/everywhere</div></div><div class="line"><div class="text">(</div><div class="padding"> </div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="text">)</div></div><div class="line"><div class="text">(</div><div class="padding"> </div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="text">)</div></div><div class="line"><div class="text">(</div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="padding"> </div><div class="text">)</div></div><div class="line"><div class="text">(</div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="padding"> </div><div class="text">)</div></div><div class="line"><div class="text">Humanize: </div><div class="data" data-tag="val1" data-number="21">21</div><div class="text">, </div><div class="data" data-tag="val2" data-number="58368">57 K</div><div class="text">, </div><div class="data" data-tag="val3" data-number="100663296">96M</div><div class="text">, </div><div class="data" data-tag="val4" data-number="44470272">44M</div><div class="text">, </div><div class="data" data-tag="val5" data-number="1342172800">1.2G</div></div><div class="line"><div class="data" data-tag="flag">one</div><div class="text"> </div><div class="data" data-tag="flag">two</div><div class="text"> </div><div class="data" data-tag="flag">three</div></div><div class="line"><div class="data" data-tag="works">(null)</div></div><div class="line"><div class="text">1:</div><div class="data" data-tag="t1"> 1000</div><div class="text"> 2:</div><div class="data" data-tag="t2">test5000 </div><div class="text"> 3:</div><div class="data" data-tag="t3"> ten-longx</div><div class="text"> 4:</div><div class="data" data-tag="t4">xtest </div></div><div class="line"><div class="error">this is an error</div></div><div class="line"><div class="error">two more errors</div></div><div class="line"><div class="warning">this is an warning</div></div><div class="line"><div class="warning">two more warnings</div></div><div class="line"><div class="label">V1/V2 packets</div><div class="text">: </div><div class="data" data-tag="count">10</div></div><div class="line"><div class="data" data-tag="test">0004</div><div class="text"> </div><div class="label">tries</div></div><div class="line"><div class="message">improper use of profanity; ten yard penalty; first down
</div></div><div class="line"><div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
+</div></div><div class="line"><div class="error">err message (1)</div></div><div class="line"><div class="error">err message (2)
+</div></div><div class="line"><div class="error">err message (1)
+</div></div><div class="line"><div class="error">err message (2)
</div></div> \ No newline at end of file
diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out
index e2b51086d9b6..984caa3297fe 100644
--- a/tests/core/saved/test_02.HIPx.out
+++ b/tests/core/saved/test_02.HIPx.out
@@ -225,3 +225,18 @@
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</div>
</div>
+<div class="line">
+ <div class="error">err message (1)</div>
+</div>
+<div class="line">
+ <div class="error">err message (2)
+</div>
+</div>
+<div class="line">
+ <div class="error">err message (1)
+</div>
+</div>
+<div class="line">
+ <div class="error">err message (2)
+</div>
+</div>
diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out
index 2a4b954c94ed..f2634522dbcb 100644
--- a/tests/core/saved/test_02.HP.out
+++ b/tests/core/saved/test_02.HP.out
@@ -225,3 +225,18 @@
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</div>
</div>
+<div class="line">
+ <div class="error">err message (1)</div>
+</div>
+<div class="line">
+ <div class="error">err message (2)
+</div>
+</div>
+<div class="line">
+ <div class="error">err message (1)
+</div>
+</div>
+<div class="line">
+ <div class="error">err message (2)
+</div>
+</div>
diff --git a/tests/core/saved/test_02.J.out b/tests/core/saved/test_02.J.out
index d6d175339c74..c34e685b4ac5 100644
--- a/tests/core/saved/test_02.J.out
+++ b/tests/core/saved/test_02.J.out
@@ -1 +1 @@
-{"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}}
+{"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}, "error": {"message":"err message (1)"}, "error": {"message":"err message (2)\n"}, "error": {"message":"err message (1)\n"}, "error": {"message":"err message (2)\n"}}}}
diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out
index cf211401be6f..1a3b464231bd 100644
--- a/tests/core/saved/test_02.JP.out
+++ b/tests/core/saved/test_02.JP.out
@@ -80,6 +80,18 @@
"test": 4,
"error": {
"message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"
+ },
+ "error": {
+ "message": "err message (1)"
+ },
+ "error": {
+ "message": "err message (2)\n"
+ },
+ "error": {
+ "message": "err message (1)\n"
+ },
+ "error": {
+ "message": "err message (2)\n"
}
}
}
diff --git a/tests/core/saved/test_02.T.err b/tests/core/saved/test_02.T.err
index d0b94597587c..debdac6a5157 100644
--- a/tests/core/saved/test_02.T.err
+++ b/tests/core/saved/test_02.T.err
@@ -1,2 +1,5 @@
test_02: key field emitted after normal value field: 'name'
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
+err message (1)err message (2)
+err message (1)
+err message (2)
diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out
index 2eb122d00c8c..598480be9946 100644
--- a/tests/core/saved/test_02.X.out
+++ b/tests/core/saved/test_02.X.out
@@ -4,4 +4,7 @@
</message><length>abcdef</length><fd>-1</fd><error>Bad file descriptor</error><test>good</test><fd>-1</fd><error>Bad fi</error><test>good</test><message>improper use of profanity; ten yard penalty; first down
</message><lines>20</lines><words>30</words><characters>40</characters><bytes>0</bytes><bytes>1</bytes><bytes>2</bytes><bytes>3</bytes><bytes>4</bytes><mbuf-current>10</mbuf-current><mbuf-cache>20</mbuf-cache><mbuf-total>30</mbuf-total><distance units="miles">50</distance><location>Boston</location><memory units="k">64</memory><total units="kb">640</total><memory units="k">64</memory><total units="kilobytes">640</total><ten>10</ten><eleven>11</eleven><unknown>1010</unknown><unknown>1010</unknown><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><val1>21</val1><val2>58368</val2><val3>100663296</val3><val4>44470272</val4><val5>1342172800</val5><flag>one</flag><flag>two</flag><flag>three</flag><works>null</works><empty-tag></empty-tag><t1>1000</t1><t2>test5000</t2><t3>ten-longx</t3><t4>xtest</t4><__error><message>this is an error</message></__error><__error><message>two more errors</message></__error><__warning><message>this is an warning</message></__warning><__warning><message>two more warnings</message></__warning><count>10</count><test>4</test><message>improper use of profanity; ten yard penalty; first down
</message><error><message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
+</message></error><error><message>err message (1)</message></error><error><message>err message (2)
+</message></error><error><message>err message (1)
+</message></error><error><message>err message (2)
</message></error></data></top> \ No newline at end of file
diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out
index 9c18c5edca4f..9a0755e01421 100644
--- a/tests/core/saved/test_02.XP.out
+++ b/tests/core/saved/test_02.XP.out
@@ -87,5 +87,20 @@
<message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</message>
</error>
+ <error>
+ <message>err message (1)</message>
+ </error>
+ <error>
+ <message>err message (2)
+</message>
+ </error>
+ <error>
+ <message>err message (1)
+</message>
+ </error>
+ <error>
+ <message>err message (2)
+</message>
+ </error>
</data>
</top>
diff --git a/tests/core/test_02.c b/tests/core/test_02.c
index 7402f04f4b80..4ea8c459047c 100644
--- a/tests/core/test_02.c
+++ b/tests/core/test_02.c
@@ -21,6 +21,8 @@
int
main (int argc, char **argv)
{
+ xo_set_program("test_02");
+
argc = xo_parse_args(argc, argv);
if (argc < 0)
return 1;
@@ -144,6 +146,10 @@ main (int argc, char **argv)
"ten yard penalty", "first down");
xo_error("Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n");
+ xo_error("err message (%d)", 1);
+ xo_error("err message (%d)\n", 2);
+ xo_errorn("err message (%d)", 1);
+ xo_errorn("err message (%d)\n", 2);
xo_close_container("data");
diff --git a/tests/core/test_12.c b/tests/core/test_12.c
index 90392196629f..32af2d211857 100644
--- a/tests/core/test_12.c
+++ b/tests/core/test_12.c
@@ -25,6 +25,8 @@ main (int argc, char **argv)
xo_emit_flags_t flags = XOEF_RETAIN;
int opt_color = 1;
+ xo_set_program("test_12");
+
argc = xo_parse_args(argc, argv);
if (argc < 0)
return 1;