From 8fd390d88ae7ed1296ac76debb7e0797034a6a3d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 13 Nov 2019 14:49:09 -0500 Subject: [PATCH 01/23] Fix "horse butt" comment in source code --- encoder/csv/enc_csv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/encoder/csv/enc_csv.c b/encoder/csv/enc_csv.c index 88e93f37..c22ef29d 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 From 2a272d78de9bdfd8e5e4c52a709892be80c25402 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:07 -0500 Subject: [PATCH 02/23] add docs for xo_errorn* --- doc/api.rst | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/doc/api.rst b/doc/api.rst index 4ca51306..94358489 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 From 0686071ae53f4034946c502421935de14f80cba1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:35 -0500 Subject: [PATCH 03/23] add xo_errorn* function; repair newline-adding-on-xo_error bug --- libxo/libxo.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 14268d1b..f72b0abd 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -8007,7 +8007,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 +8015,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 +8071,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 +8084,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); } From 1546aba1fcd89d295ac0f630b34ee757cc7a0d2b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:37 -0500 Subject: [PATCH 04/23] add xo_errorn* function; repair newline-adding-on-xo_error bug --- libxo/xo.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libxo/xo.h b/libxo/xo.h index 8404c6cb..6a61a16c 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); From eec8fdb40e0a5acc8ce4fc5524a2cc696d27f380 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:43 -0500 Subject: [PATCH 05/23] update test cases --- tests/core/saved/test_02.H.out | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out index 66a15850..a3d88030 100644 --- a/tests/core/saved/test_02.H.out +++ b/tests/core/saved/test_02.H.out @@ -4,4 +4,7 @@
length
abcdef
close
-1
returned
Bad file descriptor
good
close
-1
returned
Bad fi
good
improper use of profanity; ten yard penalty; first down
20
30
40
file
0
bytes
1
byte
2
bytes
3
bytes
4
bytes
10
/
20
/
30
mbufs <&> in use (current/cache/total)
50
from
Boston
64
left out of
640
64
left out of
640
beforeworkingafter:
string
:
10
11
1010
packets here/there/everywhere
1010
packets here/there/everywhere
(
15
/
20
/
125
)
(
15
/
20
/
125
)
(
15
/
20
/
125
)
(
15
/
20
/
125
)
Humanize:
21
,
57 K
,
96M
,
44M
,
1.2G
one
two
three
(null)
1:
1000
2:
test5000
3:
ten-longx
4:
xtest
this is an error
two more errors
this is an warning
two more warnings
V1/V2 packets
:
10
0004
tries
improper use of profanity; ten yard penalty; first down
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +
err message (1)
err message (2) +
err message (1) +
err message (2)
\ No newline at end of file From be941c1a1376f60e6daffd03e14b03555370c396 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:44 -0500 Subject: [PATCH 06/23] update test cases --- tests/core/saved/test_02.HIPx.out | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out index e2b51086..984caa32 100644 --- a/tests/core/saved/test_02.HIPx.out +++ b/tests/core/saved/test_02.HIPx.out @@ -225,3 +225,18 @@
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
+
+
err message (1)
+
+
+
err message (2) +
+
+
+
err message (1) +
+
+
+
err message (2) +
+
From 53d810622c5af8b00184bc5e9b6b73509e6b84d1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:45 -0500 Subject: [PATCH 07/23] update test cases --- tests/core/saved/test_02.HP.out | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out index 2a4b954c..f2634522 100644 --- a/tests/core/saved/test_02.HP.out +++ b/tests/core/saved/test_02.HP.out @@ -225,3 +225,18 @@
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
+
+
err message (1)
+
+
+
err message (2) +
+
+
+
err message (1) +
+
+
+
err message (2) +
+
From 64f3f5026610a9a2c0d1a8b4762515ceb63ac34b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:46 -0500 Subject: [PATCH 08/23] update test cases --- tests/core/saved/test_02.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.J.out b/tests/core/saved/test_02.J.out index d6d17533..c34e685b 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"}}}} From 4a6e203e67b0d3e689f3705c0c2d7d3f6ad5a354 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:47 -0500 Subject: [PATCH 09/23] update test cases --- tests/core/saved/test_02.JP.out | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out index cf211401..1a3b4642 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" } } } From 4dc98ba6a9a585361a6ed719543433ae86219fce Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:49 -0500 Subject: [PATCH 10/23] update test cases --- tests/core/saved/test_02.T.err | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/core/saved/test_02.T.err b/tests/core/saved/test_02.T.err index d0b94597..debdac6a 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) From ea23cf1f6bdd0e7e92fb00a46c529832e8fbd4b1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:50 -0500 Subject: [PATCH 11/23] update test cases --- tests/core/saved/test_02.X.out | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index 2eb122d0..598480be 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -4,4 +4,7 @@ abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down 2030400123410203050Boston646406464010111010101015201251520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtest<__error>this is an error<__error>two more errors<__warning>this is an warning<__warning>two more warnings104improper use of profanity; ten yard penalty; first down Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +err message (1)err message (2) +err message (1) +err message (2) \ No newline at end of file From b3bd3a27a7f84e0a7b8ff250dd64f81a02b09797 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:51 -0500 Subject: [PATCH 12/23] update test cases --- tests/core/saved/test_02.XP.out | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index 9c18c5ed..9a0755e0 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -85,6 +85,21 @@ Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> + + + + err message (1) + + + err message (2) + + + + err message (1) + + + + err message (2) From a6b2d651262ed37d4749d39ac59faad531aec428 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 21 Dec 2019 13:11:54 -0500 Subject: [PATCH 13/23] update test cases --- tests/core/test_02.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/core/test_02.c b/tests/core/test_02.c index 7402f04f..ec5ca8b8 100644 --- a/tests/core/test_02.c +++ b/tests/core/test_02.c @@ -144,6 +144,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"); From b0858c7b1522975f5d783860ee1f9cda199cfdec Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:04:35 -0500 Subject: [PATCH 14/23] Add docs for encoder options (colon, plus, and at sign) --- doc/encoders.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/encoders.rst b/doc/encoders.rst index d06e0e91..dfd0316b 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 From a216489c168597a50c2a03e151f9a9614a5a5b0a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:04:40 -0500 Subject: [PATCH 15/23] Add docs for encoder options (colon, plus, and at sign) --- doc/options.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/options.rst b/doc/options.rst index bd0fa565..79cd360a 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 From 7277cae85e8fd950ad72ca6113c67a19ddb88b86 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:05:05 -0500 Subject: [PATCH 16/23] parse new encoder options (plus and colon) --- encoder/csv/enc_csv.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/encoder/csv/enc_csv.c b/encoder/csv/enc_csv.c index c22ef29d..10f9110f 100644 --- a/encoder/csv/enc_csv.c +++ b/encoder/csv/enc_csv.c @@ -657,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); @@ -669,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'; @@ -763,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: From c1858331ed1329752b8ea6edae3c5a794e388cac Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:05:23 -0500 Subject: [PATCH 17/23] handle @foo encoder shorthand --- libxo/libxo.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libxo/libxo.c b/libxo/libxo.c index f72b0abd..29ebc79b 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'; From 7f199af194a57e55eca8ae9d33097a82f99229c3 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:05:40 -0500 Subject: [PATCH 18/23] handle colon and plus sign options --- libxo/xo_encoder.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/libxo/xo_encoder.c b/libxo/xo_encoder.c index 7e6cc164..475b6d70 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; From d987610218d542f2989622822e877b15099900c7 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:05:53 -0500 Subject: [PATCH 19/23] new options_plus op code --- libxo/xo_encoder.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/xo_encoder.h b/libxo/xo_encoder.h index 2a940336..099248ae 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__)), \ From c85783d4ded76ccb3e18fdf04be7f4d8e376b2f8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 01:06:14 -0500 Subject: [PATCH 20/23] add test for @csv; update for colon/plus only tests --- tests/core/Makefile.am | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/core/Makefile.am b/tests/core/Makefile.am index 9f7ffc44..a1dad2cc 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} ); \ ) From 910c3df0ac6c3722cc5e3f0412ed9b6f39ff974c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 16:59:43 -0500 Subject: [PATCH 21/23] force test program name, since linux libtool prefixs "lt-" --- tests/core/test_02.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/core/test_02.c b/tests/core/test_02.c index ec5ca8b8..4ea8c459 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; From 2eb8888b64f9e99b100a2c652c1fc37d5435afce Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 16:59:45 -0500 Subject: [PATCH 22/23] force test program name, since linux libtool prefixs "lt-" --- tests/core/test_12.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/core/test_12.c b/tests/core/test_12.c index 90392196..32af2d21 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; From 10a1e141e04f9afdfdfd7819a25627c032cada87 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 23 Jan 2020 17:22:07 -0500 Subject: [PATCH 23/23] If xo_set_program is called before xo_parse_args, honor the requested value --- libxo/libxo.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 29ebc79b..ea64feb8 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -8143,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);