From ca7490233d3b7b9d95033310f6aef4d3352f7d7c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:56:30 -0400 Subject: [PATCH 001/514] fix doc bugs --- doc/libxo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index d93845e9..f3173bbe 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -31,7 +31,7 @@ the field is and what it means. Each field descriptor is placed in braces with a printf-like format string: xo_emit(" {:lines/%7ju} {:words/%7ju} " - "{:characters/%7ju}{d:filename/%s}\n", + "{:characters/%7ju} {d:filename/%s}\n", linect, wordct, charct, file); Each field can have a role, with the 'value' role being the default, @@ -132,7 +132,7 @@ A single libxo function call in source code is all that's required: xo_emit("Connecting to {:host}.{:domain}...\n", host, domain); TEXT: - Connection to my-box.example.com... + Connecting to my-box.example.com... XML: my-box example.com From 6fa7576ed3e69e05eedeb63e03f8078571ac24fd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:56:49 -0400 Subject: [PATCH 002/514] xo_destroy now calls xo_flush --- libxo/libxo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libxo/libxo.c b/libxo/libxo.c index 7e95d5e0..2ac6541a 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -1541,6 +1541,8 @@ xo_destroy (xo_handle_t *xop_arg) { xo_handle_t *xop = xo_default(xop_arg); + xo_flush_h(xop); + if (xop->xo_close && (xop->xo_flags & XOF_CLOSE_FP)) xop->xo_close(xop->xo_opaque); From 5b6eed00b380acd2d673c0416ada26f443a31356 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:56:59 -0400 Subject: [PATCH 003/514] update test case --- 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 68da5813..8de81a4c 100644 --- a/tests/core/test_02.c +++ b/tests/core/test_02.c @@ -47,6 +47,10 @@ main (int argc, char **argv) xo_open_container("data"); + xo_emit(" {:lines/%7ju} {:words/%7ju} " + "{:characters/%7ju} {d:filename/%s}\n", + 20, 30, 40, "file"); + xo_emit("{:mbuf-current/%u}/{:mbuf-cache/%u}/{:mbuf-total/%u} " "{N:mbufs <&> in use (current\\/cache\\/total)}\n", 10, 20, 30); From 99df5675d7a4a9d9e212baa74f43e1e507d069db Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:01 -0400 Subject: [PATCH 004/514] update test case --- tests/core/test_05.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index 1175ebfd..66964945 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -85,7 +85,7 @@ main (int argc, char **argv) xo_open_instance("employee"); xo_emit("{[:-25}{:first-name/%s} ({:nic-name/\"%s\"}){]:}" "{:last-name/%-14..14s/%s}" - "{:department/%8u/%u}{:percent-time/%8u/%u}\n", + "{:department/%8u}{:percent-time/%8u}\n", ep->e_first, ep->e_nic, ep->e_last, ep->e_dept, ep->e_percent); if (ep->e_percent > 50) { xo_attr("full-time", "%s", "honest & for true"); From cdeb39014c163c5b86242976d722a60c15f4c8ef Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:48 -0400 Subject: [PATCH 005/514] update test cases --- tests/core/saved/test_02.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out index ba603723..043c7044 100644 --- a/tests/core/saved/test_02.H.out +++ b/tests/core/saved/test_02.H.out @@ -1,3 +1,3 @@ -
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
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 +
20
30
40
file
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
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! <>!,"!<>
\ No newline at end of file From e40ac854cb15ebc416581e6464d62cd33dad33f9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:49 -0400 Subject: [PATCH 006/514] update test cases --- tests/core/saved/test_02.HIPx.out | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out index 0ed8b82d..60733885 100644 --- a/tests/core/saved/test_02.HIPx.out +++ b/tests/core/saved/test_02.HIPx.out @@ -1,3 +1,13 @@ +
+
+
20
+
+
30
+
+
40
+
+
file
+
10
/
From 290746a436dca7f28c13c06246720fec96289425 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:50 -0400 Subject: [PATCH 007/514] update test cases --- tests/core/saved/test_02.HP.out | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out index 80264679..bc5701e0 100644 --- a/tests/core/saved/test_02.HP.out +++ b/tests/core/saved/test_02.HP.out @@ -1,3 +1,13 @@ +
+
+
20
+
+
30
+
+
40
+
+
file
+
10
/
From fd78b77ffb5bb4b0454cfcbe9bb748eb583f1787 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:51 -0400 Subject: [PATCH 008/514] 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 13898bf0..b6ac0e30 100644 --- a/tests/core/saved/test_02.J.out +++ b/tests/core/saved/test_02.J.out @@ -1,2 +1,2 @@ -{"top": {"data": {"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":30,"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"],"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}} +{"top": {"data": {"lines":20,"words":30,"characters":40,"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":30,"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"],"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}} } From a9d0df47aa13e19bc37e286d5587e5dc426c0ee6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:53 -0400 Subject: [PATCH 009/514] update test cases --- tests/core/saved/test_02.JP.out | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out index 8b3c92d2..9f0edc7e 100644 --- a/tests/core/saved/test_02.JP.out +++ b/tests/core/saved/test_02.JP.out @@ -1,6 +1,9 @@ { "top": { "data": { + "lines": 20, + "words": 30, + "characters": 40, "mbuf-current": 10, "mbuf-cache": 20, "mbuf-total": 30, From ef3940e66d6d06daff730aa36fb95a0a663a81bb Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:55 -0400 Subject: [PATCH 010/514] update test cases --- tests/core/saved/test_02.T.out | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core/saved/test_02.T.out b/tests/core/saved/test_02.T.out index d2eb170d..de8b230d 100644 --- a/tests/core/saved/test_02.T.out +++ b/tests/core/saved/test_02.T.out @@ -1,3 +1,4 @@ + 20 30 40 file 10/20/30 mbufs <&> in use (current/cache/total) 50 miles from Boston 64k left out of 640kb From 1b23d923634e4f35b3401bf0ba994915d7f40c5d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:57 -0400 Subject: [PATCH 011/514] update test cases --- tests/core/saved/test_02.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index 086fb5c0..988be8fe 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -1,3 +1,3 @@ -10203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothree1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down +20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothree1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> \ No newline at end of file From e9725c8dcf97843ea0187f52a4ca2d4bbf3e1c5c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 8 Jun 2015 02:57:59 -0400 Subject: [PATCH 012/514] update test cases --- tests/core/saved/test_02.XP.out | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index 3ac24e6b..ce674212 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -1,5 +1,8 @@ + 20 + 30 + 40 10 20 30 From ec5a53e266a809eb0431cddad138c7bf11df986e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:15 -0400 Subject: [PATCH 013/514] update .Nm values in NAME --- libxo/xo_attr.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_attr.3 b/libxo/xo_attr.3 index 1c183605..8c53f31f 100644 --- a/libxo/xo_attr.3 +++ b/libxo/xo_attr.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_attr , xo_attr_h , xo_attr_hv .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From def160e3aa393a7f709844dd98108b4881567511 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:17 -0400 Subject: [PATCH 014/514] update .Nm values in NAME --- libxo/xo_create.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_create.3 b/libxo/xo_create.3 index b0e89652..ae240adc 100644 --- a/libxo/xo_create.3 +++ b/libxo/xo_create.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_create , xo_create_to_file , xo_destroy .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 4ca523b4b7a237b64eaf858f5ba3bfa0b03e0dc8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:18 -0400 Subject: [PATCH 015/514] update .Nm values in NAME --- libxo/xo_emit.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_emit.3 b/libxo/xo_emit.3 index 70608245..c92af96b 100644 --- a/libxo/xo_emit.3 +++ b/libxo/xo_emit.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_emit , xo_emit_h , xo_emit_hv .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 56412b87adc34278c197edaa852db68575414136 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:19 -0400 Subject: [PATCH 016/514] update .Nm values in NAME --- libxo/xo_err.3 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libxo/xo_err.3 b/libxo/xo_err.3 index 5584309f..f027b44b 100644 --- a/libxo/xo_err.3 +++ b/libxo/xo_err.3 @@ -11,7 +11,9 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_err +.Nm xo_err , xo_errc , xo_errx +.Nm xo_warn , xo_warnx , xo_warn_c , xo_warn_hc +.Nm xo_message , xo_message_c , xo_message_hc , xo_message_hcv .Nd emit errors and warnings in multiple formats .Sh LIBRARY .Lb libxo From a408907fe97c17ea03d2c5faa2f1e2d7e557a0ca Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:20 -0400 Subject: [PATCH 017/514] update .Nm values in NAME --- libxo/xo_finish.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_finish.3 b/libxo/xo_finish.3 index 421e9455..b70854a4 100644 --- a/libxo/xo_finish.3 +++ b/libxo/xo_finish.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_finish , xo_finish_h .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 37318e6ceb2cd47316ec6a0746b126a7a53848b9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:22 -0400 Subject: [PATCH 018/514] update .Nm values in NAME --- libxo/xo_flush.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_flush.3 b/libxo/xo_flush.3 index b85e9f78..8f482a19 100644 --- a/libxo/xo_flush.3 +++ b/libxo/xo_flush.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_flush , xo_flush_h .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 9beb78976f5f3ed32c1f096c225434ae16eede35 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:23 -0400 Subject: [PATCH 019/514] update .Nm values in NAME --- libxo/xo_open_container.3 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libxo/xo_open_container.3 b/libxo/xo_open_container.3 index b327d33f..32962076 100644 --- a/libxo/xo_open_container.3 +++ b/libxo/xo_open_container.3 @@ -11,7 +11,8 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_open_container +.Nm xo_open_container , xo_open_container_h , xo_open_container_hd , xo_open_container_d +.Nm xo_close_container , xo_close_container_h , xo_close_container_hd , xo_close_container_d .Nd open (and close) container constructs .Sh LIBRARY .Lb libxo From 94d61bad659c28659e921fb034efb5474f5f2269 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:24 -0400 Subject: [PATCH 020/514] update .Nm values in NAME --- libxo/xo_open_list.3 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libxo/xo_open_list.3 b/libxo/xo_open_list.3 index 047af875..c7d20959 100644 --- a/libxo/xo_open_list.3 +++ b/libxo/xo_open_list.3 @@ -11,7 +11,10 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_open_list , xo_open_list_h , xo_open_list_hd , xo_open_list_d +.Nm xo_open_instance , xo_open_instance_h , xo_open_instance_hd , xo_open_instance_d +.Nm xo_close_container , xo_close_container_h , xo_close_container_hd , xo_close_container_d +.Nm xo_close_list , xo_close_list_h , xo_close_list_hd , xo_close_list_d .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 7f02890f41cf06bf283d35f54810b150f4210fa1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:26 -0400 Subject: [PATCH 021/514] update .Nm values in NAME --- libxo/xo_open_marker.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_open_marker.3 b/libxo/xo_open_marker.3 index d7a858c8..e42a97e4 100644 --- a/libxo/xo_open_marker.3 +++ b/libxo/xo_open_marker.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_open_marker +.Nm xo_open_marker , xo_open_marker_h , xo_close_marker , xo_close_marker_h .Nd prevent and allow closing of open constructs .Sh LIBRARY .Lb libxo From 75aa963753841344c40078bb47296784e4c0bfb3 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:27 -0400 Subject: [PATCH 022/514] update .Nm values in NAME --- libxo/xo_parse_args.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_parse_args.3 b/libxo/xo_parse_args.3 index f66546bd..72a8f0e6 100644 --- a/libxo/xo_parse_args.3 +++ b/libxo/xo_parse_args.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_parse_args +.Nm xo_parse_args , xo_set_program .Nd detect, parse, and remove arguments for libxo .Sh LIBRARY .Lb libxo From 37e5fde9725f11c9412f34bea949bd0c2244f279 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:29 -0400 Subject: [PATCH 023/514] update .Nm values in NAME --- libxo/xo_set_allocator.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_set_allocator.3 b/libxo/xo_set_allocator.3 index 70bfdd59..51c45a9e 100644 --- a/libxo/xo_set_allocator.3 +++ b/libxo/xo_set_allocator.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_set_allocator .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 247a40cd53a3005e083ec24cb37af7d1b987b29b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:30 -0400 Subject: [PATCH 024/514] update .Nm values in NAME --- libxo/xo_set_flags.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_set_flags.3 b/libxo/xo_set_flags.3 index 5017fa32..f9618f72 100644 --- a/libxo/xo_set_flags.3 +++ b/libxo/xo_set_flags.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_set_flags , xo_clear_flags .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 53afaabe6f3f2b889bfc61d97407d29319642ac4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:32 -0400 Subject: [PATCH 025/514] update .Nm values in NAME --- libxo/xo_set_info.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_set_info.3 b/libxo/xo_set_info.3 index 4f8c5877..cbde1ec5 100644 --- a/libxo/xo_set_info.3 +++ b/libxo/xo_set_info.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_set_info .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From d7565e5c547c9fd1c4a485fd776374dd4971e3fb Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:33 -0400 Subject: [PATCH 026/514] update .Nm values in NAME --- libxo/xo_set_style.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_set_style.3 b/libxo/xo_set_style.3 index f11f190b..fddf6069 100644 --- a/libxo/xo_set_style.3 +++ b/libxo/xo_set_style.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_set_style , xo_set_style_name .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From f9a87b1b640a5b0ccde0ca33a48b20c15f65539c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:35 -0400 Subject: [PATCH 027/514] update .Nm values in NAME --- libxo/xo_set_version.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_set_version.3 b/libxo/xo_set_version.3 index 888aef5e..9a78271c 100644 --- a/libxo/xo_set_version.3 +++ b/libxo/xo_set_version.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_set_version +.Nm xo_set_version , xo_set_version_h .Nd record content version information in encoded output .Sh LIBRARY .Lb libxo From 05c737651f64922f4d06b518b08fb9c72f938ced Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 10:09:36 -0400 Subject: [PATCH 028/514] update .Nm values in NAME --- libxo/xo_set_writer.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_set_writer.3 b/libxo/xo_set_writer.3 index 942bcc28..0f52eb92 100644 --- a/libxo/xo_set_writer.3 +++ b/libxo/xo_set_writer.3 @@ -11,7 +11,7 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit +.Nm xo_set_writer .Nd emit formatted output based on format string and arguments .Sh LIBRARY .Lb libxo From 06244583bbc08aa22fe5bca415aa5665deaa628b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:31:50 -0400 Subject: [PATCH 029/514] Add "%m" (prep for syslog); fix issue when mbrtowc() fails --- libxo/libxo.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 2ac6541a..3f178c4d 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -209,6 +209,7 @@ struct xo_handle_s { 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 */ + int xo_errno; /* Saved errno for "%m" */ }; /* Flags for formatting functions */ @@ -2097,7 +2098,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, ilen = xo_utf8_to_wc_len(cp); if (ilen < 0) { xo_failure(xop, "invalid UTF-8 character: %02hhx", *cp); - return -1; + return -1; /* Can't continue; we can't find the end */ } if (len > 0 && len < ilen) { @@ -2109,7 +2110,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, if (wc == (wchar_t) -1) { xo_failure(xop, "invalid UTF-8 character: %02hhx/%d", *cp, ilen); - return -1; + return -1; /* Can't continue; we can't find the end */ } cp += ilen; break; @@ -2119,8 +2120,10 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, ilen = mbrtowc(&wc, cp, ilen, &xop->xo_mbstate); if (ilen < 0) { /* Invalid data; skip */ xo_failure(xop, "invalid mbs char: %02hhx", *cp); - continue; + wc = L'?'; + ilen = 1; } + if (ilen == 0) { /* Hit a wide NUL character */ len = 0; continue; @@ -2235,6 +2238,7 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, xo_format_t *xfp) { static char null[] = "(null)"; + static char null_no_quotes[] = "null"; char *cp = NULL; wchar_t *wcp = NULL; @@ -2248,7 +2252,13 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, len = xfp->xf_width[XF_WIDTH_SIZE]; - if (xfp->xf_enc == XF_ENC_WIDE) { + if (xfp->xf_fc == 'm') { + cp = strerror(xop->xo_errno); + if (len < 0) + len = cp ? strlen(cp) : 0; + goto normal_string; + + } else if (xfp->xf_enc == XF_ENC_WIDE) { wcp = va_arg(xop->xo_vap, wchar_t *); if (xfp->xf_skip) return 0; @@ -2264,13 +2274,21 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, } else { cp = va_arg(xop->xo_vap, char *); /* UTF-8 or native */ + + normal_string: if (xfp->xf_skip) return 0; /* Echo "Dont' deref NULL" logic */ if (cp == NULL) { - cp = null; - len = sizeof(null) - 1; + if ((flags & XFF_NOQUOTE) && (xo_style(xop) == XO_STYLE_JSON + || xo_style(xop) == XO_STYLE_XML)) { + cp = null_no_quotes; + len = sizeof(null_no_quotes) - 1; + } else { + cp = null; + len = sizeof(null) - 1; + } } /* @@ -2524,7 +2542,7 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, } else if (*cp == '*') { xf.xf_stars += 1; xf.xf_star[xf.xf_dots] = 1; - } else if (strchr("diouxXDOUeEfFgGaAcCsSp", *cp) != NULL) + } else if (strchr("diouxXDOUeEfFgGaAcCsSpm", *cp) != NULL) break; else if (*cp == 'n' || *cp == 'v') { xo_failure(xop, "unsupported format: '%s'", fmt); @@ -2583,9 +2601,13 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, * correctly. So we have to handle this ourselves. */ if (xop->xo_formatter == NULL - && (xf.xf_fc == 's' || xf.xf_fc == 'S')) { - xf.xf_enc = (xf.xf_lflag || (xf.xf_fc == 'S')) - ? XF_ENC_WIDE : xf.xf_hflag ? XF_ENC_LOCALE : XF_ENC_UTF8; + && (xf.xf_fc == 's' || xf.xf_fc == 'S' + || xf.xf_fc == 'm')) { + + xf.xf_enc = (xf.xf_fc == 'm') ? XF_ENC_UTF8 + : (xf.xf_lflag || (xf.xf_fc == 'S')) ? XF_ENC_WIDE + : xf.xf_hflag ? XF_ENC_LOCALE : XF_ENC_UTF8; + rc = xo_format_string(xop, xbp, flags, &xf); if ((flags & XFF_TRIM_WS) @@ -2646,6 +2668,9 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, if (xf.xf_skip) va_arg(xop->xo_vap, char *); + } else if (xf.xf_fc == 'm') { + /* Nothing on the stack for "%m" */ + } else { int s; for (s = 0; s < XF_WIDTH_NUM; s++) { @@ -4133,6 +4158,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) int flush_line = (xop->xo_flags & XOF_FLUSH_LINE) ? 1 : 0; xop->xo_columns = 0; /* Always reset it */ + xop->xo_errno = errno; /* Save for "%m" */ for (cp = fmt; *cp; ) { if (*cp == '\n') { From 5c5467c438ccfd684000e2ddb6b4c00ae11f0d95 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:33:10 -0400 Subject: [PATCH 030/514] update test cases --- tests/core/saved/test_02.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out index 043c7044..23046bb6 100644 --- a/tests/core/saved/test_02.H.out +++ b/tests/core/saved/test_02.H.out @@ -1,3 +1,3 @@ -
20
30
40
file
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
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 +
length
abcdef
close
-1
returned
Bad file descriptor
good
close
-1
returned
Bad fi
good
20
30
40
file
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: Bad file descriptor
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
\ No newline at end of file From 33b901c3709d96bc9321e0a7e68996b221428240 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:33:11 -0400 Subject: [PATCH 031/514] update test cases --- tests/core/saved/test_02.HIPx.out | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out index 60733885..427e6ddb 100644 --- a/tests/core/saved/test_02.HIPx.out +++ b/tests/core/saved/test_02.HIPx.out @@ -1,3 +1,23 @@ +
+
length
+
abcdef
+
+
+
close
+
-1
+
returned
+
Bad file descriptor
+
+
good
+
+
+
close
+
-1
+
returned
+
Bad fi
+
+
good
+
20
@@ -112,6 +132,9 @@
three
+
+
(null)
+
1:
1000
@@ -145,7 +168,7 @@
tries
-
improper use of profanity; ten yard penalty; first down +
improper use of profanity; ten yard penalty; first down: Bad file descriptor
From 3b4207e2108b4a5ed2cf5f33e5b8bd46e07323ec Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:33:12 -0400 Subject: [PATCH 032/514] update test cases --- tests/core/saved/test_02.HP.out | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out index bc5701e0..7cefdfd1 100644 --- a/tests/core/saved/test_02.HP.out +++ b/tests/core/saved/test_02.HP.out @@ -1,3 +1,23 @@ +
+
length
+
abcdef
+
+
+
close
+
-1
+
returned
+
Bad file descriptor
+
+
good
+
+
+
close
+
-1
+
returned
+
Bad fi
+
+
good
+
20
@@ -112,6 +132,9 @@
three
+
+
(null)
+
1:
1000
@@ -145,7 +168,7 @@
tries
-
improper use of profanity; ten yard penalty; first down +
improper use of profanity; ten yard penalty; first down: Bad file descriptor
From 06234aea4464b504cb04060ee9a99b04ff19d5a6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:33:13 -0400 Subject: [PATCH 033/514] 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 b6ac0e30..164576e9 100644 --- a/tests/core/saved/test_02.J.out +++ b/tests/core/saved/test_02.J.out @@ -1,2 +1,2 @@ -{"top": {"data": {"lines":20,"words":30,"characters":40,"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":30,"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"],"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}} +{"top": {"data": {"length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40,"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":30,"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","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}} } From 1a7139c64df43c75c5d67357ff4bf04e8b7a4bba Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:33:14 -0400 Subject: [PATCH 034/514] update test cases --- tests/core/saved/test_02.JP.out | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out index 9f0edc7e..eb251c0c 100644 --- a/tests/core/saved/test_02.JP.out +++ b/tests/core/saved/test_02.JP.out @@ -1,6 +1,13 @@ { "top": { "data": { + "length": "abcdef", + "fd": -1, + "error": "Bad file descriptor", + "test": "good", + "fd": -1, + "error": "Bad fi", + "test": "good", "lines": 20, "words": 30, "characters": 40, @@ -39,6 +46,7 @@ "two", "three" ], + "works": null, "empty-tag": true, "t1": "1000", "t2": "test5000", From 6727c2ba7032dde7daedfbb9aa4a52997d278dd4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:34:03 -0400 Subject: [PATCH 035/514] update test cases --- tests/core/saved/test_02.T.out | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.T.out b/tests/core/saved/test_02.T.out index de8b230d..bf022662 100644 --- a/tests/core/saved/test_02.T.out +++ b/tests/core/saved/test_02.T.out @@ -1,3 +1,6 @@ +length abcdef +close -1 returned Bad file descriptor good +close -1 returned Bad fi good 20 30 40 file 10/20/30 mbufs <&> in use (current/cache/total) 50 miles from Boston @@ -13,6 +16,7 @@ string: 1011 (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 @@ -20,4 +24,4 @@ this is an warning two more warnings V1/V2 packets: 10 0004 tries -improper use of profanity; ten yard penalty; first down +improper use of profanity; ten yard penalty; first down: Bad file descriptor From 0b661adc3de833d9c2dd5694c41499ae0f23a8c9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:34:04 -0400 Subject: [PATCH 036/514] update test cases --- tests/core/saved/test_02.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index 988be8fe..c135bf76 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -1,3 +1,3 @@ -20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothree1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down +abcdef-1Bad file descriptorgood-1Bad figood20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down: Bad file descriptor Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> \ No newline at end of file From 843e5cc251336bf3d985bb14b8a4f25770ff4cdd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:34:23 -0400 Subject: [PATCH 037/514] update test cases --- tests/core/saved/test_02.XP.out | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index ce674212..d5448cce 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -1,5 +1,12 @@ + abcdef + -1 + Bad file descriptor + good + -1 + Bad fi + good 20 30 40 @@ -36,6 +43,7 @@ one two three + null 1000 test5000 @@ -55,7 +63,7 @@ 10 4 - improper use of profanity; ten yard penalty; first down + improper use of profanity; ten yard penalty; first down: Bad file descriptor Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> From e92526be1c29256c6a9179587f07a90fb177b393 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 11:34:26 -0400 Subject: [PATCH 038/514] update test cases --- tests/core/test_02.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/core/test_02.c b/tests/core/test_02.c index 8de81a4c..da2a6cbd 100644 --- a/tests/core/test_02.c +++ b/tests/core/test_02.c @@ -47,6 +47,13 @@ main (int argc, char **argv) xo_open_container("data"); + xo_emit("length {:length/%6.6s}\n", "abcdefghijklmnopqrstuvwxyz"); + + close(-1); + xo_emit("close {:fd/%d} returned {:error/%m} {:test}\n", -1, "good"); + close(-1); + xo_emit("close {:fd/%d} returned {:error/%6.6m} {:test}\n", -1, "good"); + xo_emit(" {:lines/%7ju} {:words/%7ju} " "{:characters/%7ju} {d:filename/%s}\n", 20, 30, 40, "file"); @@ -92,6 +99,8 @@ main (int argc, char **argv) xo_emit("{lq:flag/one} {lq:flag/two} {lq:flag/three}\n"); xo_close_list("flag"); + xo_emit("{n:works/%s}\n", NULL); + xo_emit("{e:empty-tag/}"); xo_emit("1:{qt:t1/%*d} 2:{qt:t2/test%-*u} " "3:{qt:t3/%10sx} 4:{qt:t4/x%-*.*s}\n", From 8696f5495e6075b48280db5fc4e703e7d6237243 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:11:47 -0400 Subject: [PATCH 039/514] Add xo_message_e, which clarifies the value of xo_message --- libxo/libxo.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 3f178c4d..e249addd 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -1463,7 +1463,7 @@ xo_message_c (int code, const char *fmt, ...) } void -xo_message (const char *fmt, ...) +xo_message_e (const char *fmt, ...) { int code = errno; va_list vap; @@ -1473,6 +1473,16 @@ xo_message (const char *fmt, ...) va_end(vap); } +void +xo_message (const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_message_hcv(NULL, 0, fmt, vap); + va_end(vap); +} + static void xo_failure (xo_handle_t *xop, const char *fmt, ...) { From cbd391767eadcc59320c2c8bcded239b2ab9c0b1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:11:49 -0400 Subject: [PATCH 040/514] Add xo_message_e, which clarifies the value of xo_message --- libxo/xo.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libxo/xo.h b/libxo/xo.h index 72b976f3..6c9f0420 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -314,6 +314,9 @@ xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4 void xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3); +void +xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2); + void xo_message (const char *fmt, ...) PRINTFLIKE(1, 2); From f7b484d6ae037c2a9a4bc7cc3ff5e78777421146 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:12:00 -0400 Subject: [PATCH 041/514] move xo_message to it's own man page --- libxo/xo_err.3 | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libxo/xo_err.3 b/libxo/xo_err.3 index f027b44b..fb91e77e 100644 --- a/libxo/xo_err.3 +++ b/libxo/xo_err.3 @@ -13,7 +13,6 @@ .Sh NAME .Nm xo_err , xo_errc , xo_errx .Nm xo_warn , xo_warnx , xo_warn_c , xo_warn_hc -.Nm xo_message , xo_message_c , xo_message_hc , xo_message_hcv .Nd emit errors and warnings in multiple formats .Sh LIBRARY .Lb libxo @@ -33,14 +32,6 @@ .Fn xo_errc "int eval" "int code" "const char *fmt" "..." .Ft void .Fn xo_errx "int eval" "const char *fmt" "..." -.Ft void -.Fn xo_message "const char *fmt" "..." -.Ft void -.Fn xo_message_c "int code" "const char *fmt" "..." -.Ft void -.Fn xo_message_hc "xo_handle_t *xop" "int code, const char *fmt" "..." -.Ft void -.Fn xo_message_hcv "xo_handle_t *xop" "int code" "const char *fmt" "va_list vap" .Sh DESCRIPTION Many programs make use of the standard library functions .Xr err 3 From 9286e00c2bde8a8812adaef79331d3c06d0ecc02 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:12:17 -0400 Subject: [PATCH 042/514] new man page --- libxo/xo_message.3 | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 libxo/xo_message.3 diff --git a/libxo/xo_message.3 b/libxo/xo_message.3 new file mode 100644 index 00000000..feee9aac --- /dev/null +++ b/libxo/xo_message.3 @@ -0,0 +1,92 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd December 4, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_message , xo_message_c , xo_message_hc , xo_message_hcv +.Nd emit messages in multiple formats +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_message "const char *fmt" "..." +.Ft void +.Fn xo_message_e "const char *fmt" "..." +.Ft void +.Fn xo_message_c "int code" "const char *fmt" "..." +.Ft void +.Fn xo_message_hc "xo_handle_t *xop" "int code, const char *fmt" "..." +.Ft void +.Fn xo_message_hcv "xo_handle_t *xop" "int code" "const char *fmt" "va_list vap" +.Sh DESCRIPTION +.Nm xo_message +generates text message which lack any sort of structure. +These functions should not be used under normal conditions, since +they completely defeat the value of using libxo. They are provided +for scenarios when the output's content is genuinely unknown and +unusable. +It is used in converting programs where err/warn where not used, +and error messages went to +.Nm stdout , +not +.Nm stderr . +Use of +.Nm xo_message +allows backwards compatibility with that output, but does not put +the error in a useful form. +.Pp +The +.Nm xo_message +function generates output strings using the printf-style format string +and arguments provided. +If the format string does not end in a newline, +.Nm xo_message_e +will appear a colon, a space, and the error associated with the current +.Nm errno +value. +.Nm xo_message_c behaves similarly for the value passed in the +.Fa code +parameter. +.Nm xo_message_hc +accepts a +.Fa handle +as opened by +.Xr xo_create 3 +and +.Nm xo_message_hcv accepts a va_list parameter of arguments. +.Sh ADDITIONAL DOCUMENTATION +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +.Nm libxo +lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of +.Nm libxo +is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Nm libxo +library was added in +.Fx 11.0 . +.Sh AUTHOR +Phil Shafer From 75adefb021401783b9641b42c7bf3b345dc78ebe Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:01 -0400 Subject: [PATCH 043/514] update test cases --- tests/core/saved/test_02.H.out | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out index 23046bb6..3d36f7f5 100644 --- a/tests/core/saved/test_02.H.out +++ b/tests/core/saved/test_02.H.out @@ -1,3 +1,5 @@ -
length
abcdef
close
-1
returned
Bad file descriptor
good
close
-1
returned
Bad fi
good
20
30
40
file
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: Bad file descriptor +
improper use of profanity; ten yard penalty; first down +
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
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! <>!,"!<>
\ No newline at end of file From 015f6b77a8aa3f5de888302f11fae37fc4689288 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:02 -0400 Subject: [PATCH 044/514] update test cases --- tests/core/saved/test_02.HIPx.out | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out index 427e6ddb..24acfb4f 100644 --- a/tests/core/saved/test_02.HIPx.out +++ b/tests/core/saved/test_02.HIPx.out @@ -1,3 +1,7 @@ +
+
improper use of profanity; ten yard penalty; first down +
+
length
abcdef
@@ -18,6 +22,10 @@
good
+
+
improper use of profanity; ten yard penalty; first down +
+
20
@@ -168,7 +176,7 @@
tries
-
improper use of profanity; ten yard penalty; first down: Bad file descriptor +
improper use of profanity; ten yard penalty; first down
From 7a6000f0fb354e8361f9e070c45a8e2d326faed0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:03 -0400 Subject: [PATCH 045/514] update test cases --- tests/core/saved/test_02.HP.out | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out index 7cefdfd1..a4c901b6 100644 --- a/tests/core/saved/test_02.HP.out +++ b/tests/core/saved/test_02.HP.out @@ -1,3 +1,7 @@ +
+
improper use of profanity; ten yard penalty; first down +
+
length
abcdef
@@ -18,6 +22,10 @@
good
+
+
improper use of profanity; ten yard penalty; first down +
+
20
@@ -168,7 +176,7 @@
tries
-
improper use of profanity; ten yard penalty; first down: Bad file descriptor +
improper use of profanity; ten yard penalty; first down
From 18332eb0b29d152f894f45b974c9088da80689c6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:04 -0400 Subject: [PATCH 046/514] update test cases --- tests/core/saved/test_02.T.out | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.T.out b/tests/core/saved/test_02.T.out index bf022662..9e7b1eee 100644 --- a/tests/core/saved/test_02.T.out +++ b/tests/core/saved/test_02.T.out @@ -1,6 +1,8 @@ +improper use of profanity; ten yard penalty; first down 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 10/20/30 mbufs <&> in use (current/cache/total) 50 miles from Boston @@ -24,4 +26,4 @@ this is an warning two more warnings V1/V2 packets: 10 0004 tries -improper use of profanity; ten yard penalty; first down: Bad file descriptor +improper use of profanity; ten yard penalty; first down From 6b603631d20bbaa8afffd4f8ba976a342cb648f7 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:05 -0400 Subject: [PATCH 047/514] = --- tests/core/saved/test_02.X.out | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index c135bf76..1caf327f 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -1,3 +1,5 @@ -abcdef-1Bad file descriptorgood-1Bad figood20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down: Bad file descriptor +improper use of profanity; ten yard penalty; first down +abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down +20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> \ No newline at end of file From 1e36e0aa1f32b708595e2cf1af3be387b7efed8e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:06 -0400 Subject: [PATCH 048/514] = --- tests/core/saved/test_02.XP.out | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index d5448cce..cd7ce04d 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -1,5 +1,6 @@ + improper use of profanity; ten yard penalty; first down abcdef -1 Bad file descriptor @@ -7,6 +8,7 @@ -1 Bad fi good + improper use of profanity; ten yard penalty; first down 20 30 40 @@ -63,7 +65,7 @@ 10 4 - improper use of profanity; ten yard penalty; first down: Bad file descriptor + improper use of profanity; ten yard penalty; first down Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> From 02ee19a472a7d738146de85f1906ee2570f972c8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 13 Jun 2015 17:13:12 -0400 Subject: [PATCH 049/514] update test cases --- tests/core/test_02.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/core/test_02.c b/tests/core/test_02.c index da2a6cbd..398d5253 100644 --- a/tests/core/test_02.c +++ b/tests/core/test_02.c @@ -47,6 +47,10 @@ main (int argc, char **argv) xo_open_container("data"); + + xo_message("improper use of profanity; %s; %s", + "ten yard penalty", "first down"); + xo_emit("length {:length/%6.6s}\n", "abcdefghijklmnopqrstuvwxyz"); close(-1); @@ -54,6 +58,10 @@ main (int argc, char **argv) close(-1); xo_emit("close {:fd/%d} returned {:error/%6.6m} {:test}\n", -1, "good"); + + xo_message("improper use of profanity; %s; %s", + "ten yard penalty", "first down"); + xo_emit(" {:lines/%7ju} {:words/%7ju} " "{:characters/%7ju} {d:filename/%s}\n", 20, 30, 40, "file"); From 608afc964c2862a885cdbb9547526bd714af9b16 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:27:47 -0400 Subject: [PATCH 050/514] fix close tag for xo_message --- libxo/libxo.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index e249addd..0705cc9f 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -1363,7 +1363,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) } va_end(va_local); - rc = xo_escape_xml(xbp, rc, 1); + rc = xo_escape_xml(xbp, rc, 0); xbp->xb_curp += rc; if (need_nl && code > 0) { @@ -1374,9 +1374,14 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) } } - xo_buf_append(xbp, msg_close, sizeof(msg_close) - 1); if (need_nl) - xo_buf_append(xbp, "\n", 2); /* Append newline and NUL to string */ + xo_buf_append(xbp, "\n", 1); /* Append newline and NUL to string */ + + xo_buf_append(xbp, msg_close, sizeof(msg_close) - 1); + + if (xop->xo_flags & XOF_PRETTY) + xo_buf_append(xbp, "\n", 1); /* Append newline and NUL to string */ + (void) xo_write(xop); break; @@ -1412,7 +1417,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) break; case XO_STYLE_JSON: - /* No meanings of representing messages in JSON */ + /* No means of representing messages in JSON */ break; case XO_STYLE_TEXT: @@ -2150,6 +2155,10 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, len = 0; } + /* We only print printable characters */ + if (!iswprint((wint_t) wc)) + continue; + /* * Find the width-in-columns of this character, which must be done * in wide characters, since we lack a mbswidth() function. If From 380b31f34edb1facc90558139eec62275ac064a6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:30:54 -0400 Subject: [PATCH 051/514] update test cases --- tests/core/saved/test_02.H.out | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out index 3d36f7f5..0c337a17 100644 --- a/tests/core/saved/test_02.H.out +++ b/tests/core/saved/test_02.H.out @@ -1,5 +1 @@ -
improper use of profanity; ten yard penalty; first down -
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
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! <>!,"!<> -
\ No newline at end of file +
abcdef
abcdef: Bad file descriptor
improper use of profanity; ten yard penalty; first down
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
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! <>!,"!<>
\ No newline at end of file From 4976dc311794c6962f493e23cb8dcdbf856feb72 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:30:55 -0400 Subject: [PATCH 052/514] update test cases --- tests/core/saved/test_02.HIPx.out | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out index 24acfb4f..199f1546 100644 --- a/tests/core/saved/test_02.HIPx.out +++ b/tests/core/saved/test_02.HIPx.out @@ -1,6 +1,11 @@
-
improper use of profanity; ten yard penalty; first down +
abcdef
+
+
abcdef: Bad file descriptor
+
+
+
improper use of profanity; ten yard penalty; first down
length
@@ -23,8 +28,7 @@
good
-
improper use of profanity; ten yard penalty; first down -
+
improper use of profanity; ten yard penalty; first down
@@ -176,10 +180,8 @@
tries
-
improper use of profanity; ten yard penalty; first down -
+
improper use of profanity; ten yard penalty; first down
-
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> -
+
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
From 688b00532a90a14a036809e37c75d019273ecdb0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:30:56 -0400 Subject: [PATCH 053/514] update test cases --- tests/core/saved/test_02.HP.out | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out index a4c901b6..8d96b652 100644 --- a/tests/core/saved/test_02.HP.out +++ b/tests/core/saved/test_02.HP.out @@ -1,6 +1,11 @@
-
improper use of profanity; ten yard penalty; first down +
abcdef
+
+
abcdef: Bad file descriptor
+
+
+
improper use of profanity; ten yard penalty; first down
length
@@ -23,8 +28,7 @@
good
-
improper use of profanity; ten yard penalty; first down -
+
improper use of profanity; ten yard penalty; first down
@@ -176,10 +180,8 @@
tries
-
improper use of profanity; ten yard penalty; first down -
+
improper use of profanity; ten yard penalty; first down
-
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> -
+
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
From b8b15e713c91c70b0d62691e780a5b36b40281ef Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:30:57 -0400 Subject: [PATCH 054/514] 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 164576e9..5af165bc 100644 --- a/tests/core/saved/test_02.J.out +++ b/tests/core/saved/test_02.J.out @@ -1,2 +1,2 @@ -{"top": {"data": {"length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40,"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":30,"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","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}} +{"top": {"data": {"length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40,"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":30,"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","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>"}}} } From 40cd82f488deb92df0e026c02f0f16817dffeae2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:30:58 -0400 Subject: [PATCH 055/514] update test cases --- tests/core/saved/test_02.JP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out index eb251c0c..aa916aa7 100644 --- a/tests/core/saved/test_02.JP.out +++ b/tests/core/saved/test_02.JP.out @@ -55,7 +55,7 @@ "count": 10, "test": 4, "error": { - "message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n" + "message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>" } } } From 1ec7f0f94b47eee760895c4b2cf5ddb7ad24a228 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:08 -0400 Subject: [PATCH 056/514] update test cases --- tests/core/saved/test_02.T.out | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/core/saved/test_02.T.out b/tests/core/saved/test_02.T.out index 9e7b1eee..5cfdce03 100644 --- a/tests/core/saved/test_02.T.out +++ b/tests/core/saved/test_02.T.out @@ -1,3 +1,5 @@ +abcdef +abcdef: Bad file descriptor improper use of profanity; ten yard penalty; first down length abcdef close -1 returned Bad file descriptor good From 766013d1addab2ae952a52744517dd62d9171078 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:11 -0400 Subject: [PATCH 057/514] update test cases --- tests/core/saved/test_02.X.out | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index 1caf327f..b9f63ba9 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -1,5 +1,6 @@ -improper use of profanity; ten yard penalty; first down -abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down -20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down -Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> - \ No newline at end of file +abcdef +abcdef: Bad file descriptor +improper use of profanity; ten yard penalty; first down +abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down +20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down +Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> \ No newline at end of file From c730ae66b2b191b2872ebc1044f12eb9c40c3132 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:12 -0400 Subject: [PATCH 058/514] update test cases --- tests/core/saved/test_02.XP.out | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index cd7ce04d..4fc5bda5 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -1,6 +1,11 @@ - improper use of profanity; ten yard penalty; first down + abcdef + + abcdef: Bad file descriptor + + improper use of profanity; ten yard penalty; first down + abcdef -1 Bad file descriptor @@ -8,7 +13,8 @@ -1 Bad fi good - improper use of profanity; ten yard penalty; first down + improper use of profanity; ten yard penalty; first down + 20 30 40 @@ -65,10 +71,10 @@ 10 4 - improper use of profanity; ten yard penalty; first down - - Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> + improper use of profanity; ten yard penalty; first down + + Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> From 0a758634d7f3ed9efb4a495955c3fca57eb044db Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:14 -0400 Subject: [PATCH 059/514] update test cases --- tests/core/saved/test_05.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.H.out b/tests/core/saved/test_05.H.out index 2e5417c0..e6a48ff5 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
7
[
]
Width
:
3
[
෴ණ්ණ
]
Width
:
6
[
1234
]
[
ර්‍ඝ
]
Width
:
5
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
110
20
\ No newline at end of file +
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
7
[
]
Width
:
3
[
෴ණ්ණ
]
Width
:
6
[
1234
]
[
ර්ඝ
]
Width
:
5
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
110
20
\ No newline at end of file From 1966e605d0c768816a9ea0e6d436314b6be2b937 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:15 -0400 Subject: [PATCH 060/514] update test cases --- tests/core/saved/test_05.HIPx.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index cb961fa4..327c2e98 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -56,7 +56,7 @@
[
-
ර්‍ඝ
+
ර්ඝ
]
From 8ea12e164b99ee6f27554108aaf030b896145ca6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:17 -0400 Subject: [PATCH 061/514] update test cases --- tests/core/saved/test_05.HP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index 489b486d..763fbc97 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -56,7 +56,7 @@
[
-
ර්‍ඝ
+
ර්ඝ
]
From 6696474a60038912528aa889c8d611b47d3badb1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:18 -0400 Subject: [PATCH 062/514] update test cases --- tests/core/saved/test_05.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.J.out b/tests/core/saved/test_05.J.out index 214ba23e..9e75d9c8 100644 --- a/tests/core/saved/test_05.J.out +++ b/tests/core/saved/test_05.J.out @@ -1,2 +1,2 @@ -{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":5,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":10,"not-sinhala":"123456","tag":"ර්‍ඝ","width":3, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Mon, 15 Jun 2015 23:31:18 -0400 Subject: [PATCH 063/514] update test cases --- tests/core/saved/test_05.JP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index f37a3622..73fa25a4 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -12,7 +12,7 @@ "sinhala": "෴ණ්ණ෴෴ණ්ණ෴", "width": 10, "not-sinhala": "123456", - "tag": "ර්‍ඝ", + "tag": "ර්ඝ", "width": 3, "employee": [ { From f2a3676c430f3782fd74d90532d24ea8c74766db Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:22 -0400 Subject: [PATCH 064/514] update test cases --- tests/core/saved/test_05.T.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index 8bf1ad11..47fc8098 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -8,7 +8,7 @@ Width: 3 [෴ණ්ණ] Width: 6 [1234] -[ර්‍ඝ] +[ර්ඝ] Width: 5 First Name Last Name Department Time (%) Jim ("რეგტ") გთხოვთ ახ 431 90 From 049fe261eef96bc7e2c7e73d53585739bb6acc6d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:23 -0400 Subject: [PATCH 065/514] update test cases --- tests/core/saved/test_05.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.X.out b/tests/core/saved/test_05.X.out index f553b05e..dc2246b7 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴51෴ණ්ණ෴෴ණ්ණ෴10123456ර්‍ඝ3Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file +γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴51෴ණ්ණ෴෴ණ්ණ෴10123456ර්ඝ3Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From c92837d4dba40c5add0126a8affb0a0315d9a069 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:25 -0400 Subject: [PATCH 066/514] update test cases --- tests/core/saved/test_05.XP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index ba6b1191..19e60caf 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -11,7 +11,7 @@ ෴ණ්ණ෴෴ණ්ණ෴ 10 123456 - ර්‍ඝ + ර්ඝ 3 Jim From 48a68f6593329604c57cf5ca6048e7c3e1947453 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:31:27 -0400 Subject: [PATCH 067/514] update test cases --- tests/core/test_02.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/core/test_02.c b/tests/core/test_02.c index 398d5253..aa431138 100644 --- a/tests/core/test_02.c +++ b/tests/core/test_02.c @@ -47,6 +47,9 @@ main (int argc, char **argv) xo_open_container("data"); + xo_message("abcdef"); + close(-1); + xo_message_e("abcdef"); xo_message("improper use of profanity; %s; %s", "ten yard penalty", "first down"); From 8b0bf07e1be74e56105915680bea8dc6b06504c9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 15 Jun 2015 23:34:08 -0400 Subject: [PATCH 068/514] newline is one character, not two. xo_write add a NUL already --- libxo/libxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 0705cc9f..26cb78de 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -1225,7 +1225,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn, } } - xo_buf_append(xbp, "\n", 2); /* Append newline and NUL to string */ + xo_buf_append(xbp, "\n", 1); /* Append newline and NUL to string */ (void) xo_write(xop); } else { From 0fd4681b7a9d3c7c9f81c7ed8c3df2235c487c96 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 17 Jun 2015 02:54:18 -0400 Subject: [PATCH 069/514] remove the aging unit test; unit tests live in test/ --- libxo/libxo.c | 131 -------------------------------------------------- 1 file changed, 131 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 26cb78de..2ea72190 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -5921,134 +5921,3 @@ xo_set_version (const char *version) { xo_set_version_h(NULL, version); } - -#ifdef UNIT_TEST -int -main (int argc, char **argv) -{ - static char base_grocery[] = "GRO"; - static char base_hardware[] = "HRD"; - struct item { - const char *i_title; - int i_sold; - int i_instock; - int i_onorder; - const char *i_sku_base; - int i_sku_num; - }; - struct item list[] = { - { "gum&this&that", 1412, 54, 10, base_grocery, 415 }, - { "", 85, 4, 2, base_hardware, 212 }, - { "ladder", 0, 2, 1, base_hardware, 517 }, - { "\"bolt\"", 4123, 144, 42, base_hardware, 632 }, - { "water\\blue", 17, 14, 2, base_grocery, 2331 }, - { NULL, 0, 0, 0, NULL, 0 } - }; - struct item list2[] = { - { "fish", 1321, 45, 1, base_grocery, 533 }, - { NULL, 0, 0, 0, NULL, 0 } - }; - struct item *ip; - xo_info_t info[] = { - { "in-stock", "number", "Number of items in stock" }, - { "name", "string", "Name of the item" }, - { "on-order", "number", "Number of items on order" }, - { "sku", "string", "Stock Keeping Unit" }, - { "sold", "number", "Number of items sold" }, - { NULL, NULL, NULL }, - }; - int info_count = (sizeof(info) / sizeof(info[0])) - 1; - - argc = xo_parse_args(argc, argv); - if (argc < 0) - exit(1); - - xo_set_info(NULL, info, info_count); - - xo_open_container_h(NULL, "top"); - - xo_open_container("data"); - xo_open_list("item"); - - xo_emit("{T:Item/%-15s}{T:Total Sold/%12s}{T:In Stock/%12s}" - "{T:On Order/%12s}{T:SKU/%5s}\n"); - - for (ip = list; ip->i_title; ip++) { - xo_open_instance("item"); - - xo_emit("{k:name/%-15s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}" - "{:on-order/%12u/%u} {q:sku/%5s-000-%u/%s-000-%u}\n", - ip->i_title, ip->i_sold, ip->i_instock, ip->i_onorder, - ip->i_sku_base, ip->i_sku_num); - - xo_close_instance("item"); - } - - xo_close_list("item"); - xo_close_container("data"); - - xo_emit("\n\n"); - - xo_open_container("data"); - xo_open_list("item"); - - for (ip = list; ip->i_title; ip++) { - xo_open_instance("item"); - - xo_attr("fancy", "%s%d", "item", ip - list); - xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); - xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}{e:percent/%u}\n", - ip->i_sold, ip->i_sold ? ".0" : "", 44); - xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); - xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); - xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", - ip->i_sku_base, ip->i_sku_num); - - xo_close_instance("item"); - } - - xo_close_list("item"); - xo_close_container("data"); - - xo_open_container("data"); - xo_open_list("item"); - - for (ip = list2; ip->i_title; ip++) { - xo_open_instance("item"); - - xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); - xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", - ip->i_sold, ip->i_sold ? ".0" : ""); - xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); - xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); - xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", - ip->i_sku_base, ip->i_sku_num); - - xo_open_list("month"); - - const char *months[] = { "Jan", "Feb", "Mar", NULL }; - int discounts[] = { 10, 20, 25, 0 }; - int i; - for (i = 0; months[i]; i++) { - xo_open_instance("month"); - xo_emit("{P: }" - "{Lwc:Month}{k:month}, {Lwc:Special}{:discount/%d}\n", - months[i], discounts[i]); - xo_close_instance("month"); - } - - xo_close_list("month"); - - xo_close_instance("item"); - } - - xo_close_list("item"); - xo_close_container("data"); - - xo_close_container_h(NULL, "top"); - - xo_finish(); - - return 0; -} -#endif /* UNIT_TEST */ From 3b0414727ca08e9ce34a5190d6e2d2896cf5c922 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 17 Jun 2015 11:22:38 -0400 Subject: [PATCH 070/514] Straight copy from freebsd --- libxo/xo_syslog.c | 457 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 libxo/xo_syslog.c diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c new file mode 100644 index 00000000..003f24dd --- /dev/null +++ b/libxo/xo_syslog.c @@ -0,0 +1,457 @@ +/* + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)syslog.c 8.5 (Berkeley) 4/29/95"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "un-namespace.h" + +#include "libc_private.h" + +static int LogFile = -1; /* fd for log */ +static int status; /* connection status */ +static int opened; /* have done openlog() */ +static int LogStat = 0; /* status bits, set by openlog() */ +static const char *LogTag = NULL; /* string to tag the entry with */ +static int LogFacility = LOG_USER; /* default facility code */ +static int LogMask = 0xff; /* mask of priorities to be logged */ +static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) _pthread_mutex_lock(&syslog_mutex); \ + } while(0) +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) _pthread_mutex_unlock(&syslog_mutex); \ + } while(0) + +static void disconnectlog(void); /* disconnect from syslogd */ +static void connectlog(void); /* (re)connect to syslogd */ +static void openlog_unlocked(const char *, int, int); + +enum { + NOCONN = 0, + CONNDEF, + CONNPRIV, +}; + +/* + * Format of the magic cookie passed through the stdio hook + */ +struct bufcookie { + char *base; /* start of buffer */ + int left; +}; + +/* + * stdio write hook for writing to a static string buffer + * XXX: Maybe one day, dynamically allocate it so that the line length + * is `unlimited'. + */ +static int +writehook(void *cookie, const char *buf, int len) +{ + struct bufcookie *h; /* private `handle' */ + + h = (struct bufcookie *)cookie; + if (len > h->left) { + /* clip in case of wraparound */ + len = h->left; + } + if (len > 0) { + (void)memcpy(h->base, buf, len); /* `write' it. */ + h->base += len; + h->left -= len; + } + return len; +} + +/* + * syslog, vsyslog -- + * print message on log file; output is intended for syslogd(8). + */ +void +syslog(int pri, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsyslog(pri, fmt, ap); + va_end(ap); +} + +void +vsyslog(int pri, const char *fmt, va_list ap) +{ + int cnt; + char ch, *p; + time_t now; + int fd, saved_errno; + char *stdp, tbuf[2048], fmt_cpy[1024], timbuf[26], errstr[64]; + FILE *fp, *fmt_fp; + struct bufcookie tbuf_cookie; + struct bufcookie fmt_cookie; + +#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID + /* Check for invalid bits. */ + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + syslog(INTERNALLOG, + "syslog: unknown facility/priority: %x", pri); + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + saved_errno = errno; + + THREAD_LOCK(); + + /* Check priority against setlogmask values. */ + if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) { + THREAD_UNLOCK(); + return; + } + + /* Set default facility if none specified. */ + if ((pri & LOG_FACMASK) == 0) + pri |= LogFacility; + + /* Create the primary stdio hook */ + tbuf_cookie.base = tbuf; + tbuf_cookie.left = sizeof(tbuf); + fp = fwopen(&tbuf_cookie, writehook); + if (fp == NULL) { + THREAD_UNLOCK(); + return; + } + + /* Build the message. */ + (void)time(&now); + (void)fprintf(fp, "<%d>", pri); + (void)fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); + if (LogStat & LOG_PERROR) { + /* Transfer to string buffer */ + (void)fflush(fp); + stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); + } + if (LogTag == NULL) + LogTag = _getprogname(); + if (LogTag != NULL) + (void)fprintf(fp, "%s", LogTag); + if (LogStat & LOG_PID) + (void)fprintf(fp, "[%d]", getpid()); + if (LogTag != NULL) { + (void)fprintf(fp, ": "); + } + + /* Check to see if we can skip expanding the %m */ + if (strstr(fmt, "%m")) { + + /* Create the second stdio hook */ + fmt_cookie.base = fmt_cpy; + fmt_cookie.left = sizeof(fmt_cpy) - 1; + fmt_fp = fwopen(&fmt_cookie, writehook); + if (fmt_fp == NULL) { + fclose(fp); + THREAD_UNLOCK(); + return; + } + + /* + * Substitute error message for %m. Be careful not to + * molest an escaped percent "%%m". We want to pass it + * on untouched as the format is later parsed by vfprintf. + */ + for ( ; (ch = *fmt); ++fmt) { + if (ch == '%' && fmt[1] == 'm') { + ++fmt; + strerror_r(saved_errno, errstr, sizeof(errstr)); + fputs(errstr, fmt_fp); + } else if (ch == '%' && fmt[1] == '%') { + ++fmt; + fputc(ch, fmt_fp); + fputc(ch, fmt_fp); + } else { + fputc(ch, fmt_fp); + } + } + + /* Null terminate if room */ + fputc(0, fmt_fp); + fclose(fmt_fp); + + /* Guarantee null termination */ + fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; + + fmt = fmt_cpy; + } + + (void)vfprintf(fp, fmt, ap); + (void)fclose(fp); + + cnt = sizeof(tbuf) - tbuf_cookie.left; + + /* Remove a trailing newline */ + if (tbuf[cnt - 1] == '\n') + cnt--; + + /* Output to stderr if requested. */ + if (LogStat & LOG_PERROR) { + struct iovec iov[2]; + struct iovec *v = iov; + + v->iov_base = stdp; + v->iov_len = cnt - (stdp - tbuf); + ++v; + v->iov_base = "\n"; + v->iov_len = 1; + (void)_writev(STDERR_FILENO, iov, 2); + } + + /* Get connected, output the message to the local logger. */ + if (!opened) + openlog_unlocked(LogTag, LogStat | LOG_NDELAY, 0); + connectlog(); + + /* + * If the send() fails, there are two likely scenarios: + * 1) syslogd was restarted + * 2) /var/run/log is out of socket buffer space, which + * in most cases means local DoS. + * If the error does not indicate a full buffer, we address + * case #1 by attempting to reconnect to /var/run/log[priv] + * and resending the message once. + * + * If we are working with a privileged socket, the retry + * attempts end there, because we don't want to freeze a + * critical application like su(1) or sshd(8). + * + * Otherwise, we address case #2 by repeatedly retrying the + * send() to give syslogd a chance to empty its socket buffer. + */ + + if (send(LogFile, tbuf, cnt, 0) < 0) { + if (errno != ENOBUFS) { + /* + * Scenario 1: syslogd was restarted + * reconnect and resend once + */ + disconnectlog(); + connectlog(); + if (send(LogFile, tbuf, cnt, 0) >= 0) { + THREAD_UNLOCK(); + return; + } + /* + * if the resend failed, fall through to + * possible scenario 2 + */ + } + while (errno == ENOBUFS) { + /* + * Scenario 2: out of socket buffer space + * possible DoS, fail fast on a privileged + * socket + */ + if (status == CONNPRIV) + break; + _usleep(1); + if (send(LogFile, tbuf, cnt, 0) >= 0) { + THREAD_UNLOCK(); + return; + } + } + } else { + THREAD_UNLOCK(); + return; + } + + /* + * Output the message to the console; try not to block + * as a blocking console should not stop other processes. + * Make sure the error reported is the one from the syslogd failure. + */ + if (LogStat & LOG_CONS && + (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK|O_CLOEXEC, 0)) >= + 0) { + struct iovec iov[2]; + struct iovec *v = iov; + + p = strchr(tbuf, '>') + 1; + v->iov_base = p; + v->iov_len = cnt - (p - tbuf); + ++v; + v->iov_base = "\r\n"; + v->iov_len = 2; + (void)_writev(fd, iov, 2); + (void)_close(fd); + } + + THREAD_UNLOCK(); +} + +/* Should be called with mutex acquired */ +static void +disconnectlog(void) +{ + /* + * If the user closed the FD and opened another in the same slot, + * that's their problem. They should close it before calling on + * system services. + */ + if (LogFile != -1) { + _close(LogFile); + LogFile = -1; + } + status = NOCONN; /* retry connect */ +} + +/* Should be called with mutex acquired */ +static void +connectlog(void) +{ + struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ + + if (LogFile == -1) { + if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, + 0)) == -1) + return; + } + if (LogFile != -1 && status == NOCONN) { + SyslogAddr.sun_len = sizeof(SyslogAddr); + SyslogAddr.sun_family = AF_UNIX; + + /* + * First try privileged socket. If no success, + * then try default socket. + */ + (void)strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV, + sizeof SyslogAddr.sun_path); + if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, + sizeof(SyslogAddr)) != -1) + status = CONNPRIV; + + if (status == NOCONN) { + (void)strncpy(SyslogAddr.sun_path, _PATH_LOG, + sizeof SyslogAddr.sun_path); + if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, + sizeof(SyslogAddr)) != -1) + status = CONNDEF; + } + + if (status == NOCONN) { + /* + * Try the old "/dev/log" path, for backward + * compatibility. + */ + (void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, + sizeof SyslogAddr.sun_path); + if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, + sizeof(SyslogAddr)) != -1) + status = CONNDEF; + } + + if (status == NOCONN) { + (void)_close(LogFile); + LogFile = -1; + } + } +} + +static void +openlog_unlocked(const char *ident, int logstat, int logfac) +{ + if (ident != NULL) + LogTag = ident; + LogStat = logstat; + if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) + LogFacility = logfac; + + if (LogStat & LOG_NDELAY) /* open immediately */ + connectlog(); + + opened = 1; /* ident and facility has been set */ +} + +void +openlog(const char *ident, int logstat, int logfac) +{ + THREAD_LOCK(); + openlog_unlocked(ident, logstat, logfac); + THREAD_UNLOCK(); +} + + +void +closelog(void) +{ + THREAD_LOCK(); + if (LogFile != -1) { + (void)_close(LogFile); + LogFile = -1; + } + LogTag = NULL; + status = NOCONN; + THREAD_UNLOCK(); +} + +/* setlogmask -- set the log mask level */ +int +setlogmask(int pmask) +{ + int omask; + + THREAD_LOCK(); + omask = LogMask; + if (pmask != 0) + LogMask = pmask; + THREAD_UNLOCK(); + return (omask); +} From ae040d9cbeb41ffac31823b3733523ffadb805a1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 17 Jun 2015 18:49:20 -0400 Subject: [PATCH 071/514] add xo_syslog.c --- libxo/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index 0047b632..d52c4cbb 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -24,7 +24,8 @@ libxoinc_HEADERS = \ xo.h libxo_la_SOURCES = \ - libxo.c + libxo.c \ + xo_syslog.c man_MANS = \ libxo.3 \ From ed821d5ec78849204cc37e2884f9a75f60e85ff5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 17 Jun 2015 18:49:28 -0400 Subject: [PATCH 072/514] add xo_syslog functions --- libxo/xo.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libxo/xo.h b/libxo/xo.h index 6c9f0420..d3b9e425 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -400,4 +400,10 @@ xo_set_version (const char *version); void xo_set_version_h (xo_handle_t *xop, const char *version); +void xo_closelog(void); +void xo_openlog(const char *ident, int logopt, int facility); +int xo_setlogmask(int maskpri); +void xo_syslog(int priority, const char *message, ...); +void xo_vsyslog(int priority, const char *message, va_list args); + #endif /* INCLUDE_XO_H */ From 20f5660c02b7313b4be0b9a030882e9554bf0e35 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 17 Jun 2015 18:49:42 -0400 Subject: [PATCH 073/514] prefix all symbols with "xo_" --- libxo/xo_syslog.c | 226 +++++++++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 102 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 003f24dd..6b95e957 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -33,7 +33,6 @@ static char sccsid[] = "@(#)syslog.c 8.5 (Berkeley) 4/29/95"; #include __FBSDID("$FreeBSD$"); -#include "namespace.h" #include #include #include @@ -50,33 +49,40 @@ __FBSDID("$FreeBSD$"); #include #include #include - #include -#include "un-namespace.h" -#include "libc_private.h" +#include "xo.h" + +#ifndef UNUSED +#define UNUSED __attribute__ ((__unused__)) +#endif /* UNUSED */ -static int LogFile = -1; /* fd for log */ -static int status; /* connection status */ -static int opened; /* have done openlog() */ -static int LogStat = 0; /* status bits, set by openlog() */ -static const char *LogTag = NULL; /* string to tag the entry with */ -static int LogFacility = LOG_USER; /* default facility code */ -static int LogMask = 0xff; /* mask of priorities to be logged */ -static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER; +static int xo_logfile = -1; /* fd for log */ +static int xo_status; /* connection xo_status */ +static int xo_opened; /* have done openlog() */ +static int xo_logstat = 0; /* xo_status bits, set by openlog() */ +static const char *xo_logtag = NULL; /* string to tag the entry with */ +static int xo_logfacility = LOG_USER; /* default facility code */ +static int xo_logmask = 0xff; /* mask of priorities to be logged */ +static pthread_mutex_t xo_syslog_mutex UNUSED = PTHREAD_MUTEX_INITIALIZER; +#if 0 #define THREAD_LOCK() \ do { \ - if (__isthreaded) _pthread_mutex_lock(&syslog_mutex); \ + if (__isthreaded) _pthread_mutex_lock(&xo_syslog_mutex); \ } while(0) #define THREAD_UNLOCK() \ do { \ - if (__isthreaded) _pthread_mutex_unlock(&syslog_mutex); \ + if (__isthreaded) _pthread_mutex_unlock(&xo_syslog_mutex); \ } while(0) +#else +#define THREAD_LOCK() +#define THREAD_UNLOCK() +#endif -static void disconnectlog(void); /* disconnect from syslogd */ -static void connectlog(void); /* (re)connect to syslogd */ -static void openlog_unlocked(const char *, int, int); +static void xo_disconnectlog(void); /* disconnect from syslogd */ +static void xo_connectlog(void); /* (re)connect to syslogd */ +static void xo_openlog_unlocked(const char *, int, int); enum { NOCONN = 0, @@ -98,17 +104,17 @@ struct bufcookie { * is `unlimited'. */ static int -writehook(void *cookie, const char *buf, int len) +xo_writehook (void *cookie, const char *buf, int len) { struct bufcookie *h; /* private `handle' */ - h = (struct bufcookie *)cookie; + h = (struct bufcookie *) cookie; if (len > h->left) { /* clip in case of wraparound */ len = h->left; } if (len > 0) { - (void)memcpy(h->base, buf, len); /* `write' it. */ + (void) memcpy(h->base, buf, len); /* `write' it. */ h->base += len; h->left -= len; } @@ -120,7 +126,7 @@ writehook(void *cookie, const char *buf, int len) * print message on log file; output is intended for syslogd(8). */ void -syslog(int pri, const char *fmt, ...) +xo_syslog (int pri, const char *fmt, ...) { va_list ap; @@ -130,7 +136,7 @@ syslog(int pri, const char *fmt, ...) } void -vsyslog(int pri, const char *fmt, va_list ap) +xo_vsyslog (int pri, const char *fmt, va_list ap) { int cnt; char ch, *p; @@ -154,41 +160,41 @@ vsyslog(int pri, const char *fmt, va_list ap) THREAD_LOCK(); /* Check priority against setlogmask values. */ - if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) { + if (!(LOG_MASK(LOG_PRI(pri)) & xo_logmask)) { THREAD_UNLOCK(); return; } /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) - pri |= LogFacility; + pri |= xo_logfacility; /* Create the primary stdio hook */ tbuf_cookie.base = tbuf; tbuf_cookie.left = sizeof(tbuf); - fp = fwopen(&tbuf_cookie, writehook); + fp = fwopen(&tbuf_cookie, xo_writehook); if (fp == NULL) { THREAD_UNLOCK(); return; } /* Build the message. */ - (void)time(&now); - (void)fprintf(fp, "<%d>", pri); - (void)fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); - if (LogStat & LOG_PERROR) { + (void) time(&now); + (void) fprintf(fp, "<%d>", pri); + (void) fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); + if (xo_logstat & LOG_PERROR) { /* Transfer to string buffer */ - (void)fflush(fp); + (void) fflush(fp); stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); } - if (LogTag == NULL) - LogTag = _getprogname(); - if (LogTag != NULL) - (void)fprintf(fp, "%s", LogTag); - if (LogStat & LOG_PID) - (void)fprintf(fp, "[%d]", getpid()); - if (LogTag != NULL) { - (void)fprintf(fp, ": "); + if (xo_logtag == NULL) + xo_logtag = getprogname(); + if (xo_logtag != NULL) + (void) fprintf(fp, "%s", xo_logtag); + if (xo_logstat & LOG_PID) + (void) fprintf(fp, "[%d]", getpid()); + if (xo_logtag != NULL) { + (void) fprintf(fp, ": "); } /* Check to see if we can skip expanding the %m */ @@ -197,7 +203,7 @@ vsyslog(int pri, const char *fmt, va_list ap) /* Create the second stdio hook */ fmt_cookie.base = fmt_cpy; fmt_cookie.left = sizeof(fmt_cpy) - 1; - fmt_fp = fwopen(&fmt_cookie, writehook); + fmt_fp = fwopen(&fmt_cookie, xo_writehook); if (fmt_fp == NULL) { fclose(fp); THREAD_UNLOCK(); @@ -233,8 +239,8 @@ vsyslog(int pri, const char *fmt, va_list ap) fmt = fmt_cpy; } - (void)vfprintf(fp, fmt, ap); - (void)fclose(fp); + (void) vfprintf(fp, fmt, ap); + (void) fclose(fp); cnt = sizeof(tbuf) - tbuf_cookie.left; @@ -243,22 +249,23 @@ vsyslog(int pri, const char *fmt, va_list ap) cnt--; /* Output to stderr if requested. */ - if (LogStat & LOG_PERROR) { + if (xo_logstat & LOG_PERROR) { struct iovec iov[2]; struct iovec *v = iov; + char newline[] = "\n"; v->iov_base = stdp; v->iov_len = cnt - (stdp - tbuf); ++v; - v->iov_base = "\n"; + v->iov_base = newline; v->iov_len = 1; - (void)_writev(STDERR_FILENO, iov, 2); + (void) writev(STDERR_FILENO, iov, 2); } /* Get connected, output the message to the local logger. */ - if (!opened) - openlog_unlocked(LogTag, LogStat | LOG_NDELAY, 0); - connectlog(); + if (!xo_opened) + xo_openlog_unlocked(xo_logtag, xo_logstat | LOG_NDELAY, 0); + xo_connectlog(); /* * If the send() fails, there are two likely scenarios: @@ -277,15 +284,15 @@ vsyslog(int pri, const char *fmt, va_list ap) * send() to give syslogd a chance to empty its socket buffer. */ - if (send(LogFile, tbuf, cnt, 0) < 0) { + if (send(xo_logfile, tbuf, cnt, 0) < 0) { if (errno != ENOBUFS) { /* * Scenario 1: syslogd was restarted * reconnect and resend once */ - disconnectlog(); - connectlog(); - if (send(LogFile, tbuf, cnt, 0) >= 0) { + xo_disconnectlog(); + xo_connectlog(); + if (send(xo_logfile, tbuf, cnt, 0) >= 0) { THREAD_UNLOCK(); return; } @@ -300,10 +307,10 @@ vsyslog(int pri, const char *fmt, va_list ap) * possible DoS, fail fast on a privileged * socket */ - if (status == CONNPRIV) + if (xo_status == CONNPRIV) break; - _usleep(1); - if (send(LogFile, tbuf, cnt, 0) >= 0) { + usleep(1); + if (send(xo_logfile, tbuf, cnt, 0) >= 0) { THREAD_UNLOCK(); return; } @@ -318,20 +325,25 @@ vsyslog(int pri, const char *fmt, va_list ap) * as a blocking console should not stop other processes. * Make sure the error reported is the one from the syslogd failure. */ - if (LogStat & LOG_CONS && - (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK|O_CLOEXEC, 0)) >= - 0) { + int flags = O_WRONLY | O_NONBLOCK; +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif /* O_CLOEXEC */ + + if (xo_logstat & LOG_CONS + && (fd = open(_PATH_CONSOLE, flags, 0)) >= 0) { struct iovec iov[2]; struct iovec *v = iov; + char crnl[] = "\r\n"; p = strchr(tbuf, '>') + 1; v->iov_base = p; v->iov_len = cnt - (p - tbuf); ++v; - v->iov_base = "\r\n"; + v->iov_base = crnl; v->iov_len = 2; - (void)_writev(fd, iov, 2); - (void)_close(fd); + (void) writev(fd, iov, 2); + (void) close(fd); } THREAD_UNLOCK(); @@ -339,32 +351,35 @@ vsyslog(int pri, const char *fmt, va_list ap) /* Should be called with mutex acquired */ static void -disconnectlog(void) +xo_disconnectlog (void) { /* * If the user closed the FD and opened another in the same slot, * that's their problem. They should close it before calling on * system services. */ - if (LogFile != -1) { - _close(LogFile); - LogFile = -1; + if (xo_logfile != -1) { + close(xo_logfile); + xo_logfile = -1; } - status = NOCONN; /* retry connect */ + xo_status = NOCONN; /* retry connect */ } /* Should be called with mutex acquired */ static void -connectlog(void) +xo_connectlog (void) { struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ - if (LogFile == -1) { - if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, - 0)) == -1) + if (xo_logfile == -1) { + int flags = SOCK_DGRAM; +#ifdef SOCK_CLOEXEC + flags |= SOCK_CLOEXEC; +#endif /* SOCK_CLOEXEC */ + if ((xo_logfile = socket(AF_UNIX, flags, 0)) == -1) return; } - if (LogFile != -1 && status == NOCONN) { + if (xo_logfile != -1 && xo_status == NOCONN) { SyslogAddr.sun_len = sizeof(SyslogAddr); SyslogAddr.sun_family = AF_UNIX; @@ -372,86 +387,93 @@ connectlog(void) * First try privileged socket. If no success, * then try default socket. */ - (void)strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV, + +#ifdef _PATH_LOG_PRIV + (void) strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV, sizeof SyslogAddr.sun_path); - if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, + if (connect(xo_logfile, (struct sockaddr *) &SyslogAddr, sizeof(SyslogAddr)) != -1) - status = CONNPRIV; + xo_status = CONNPRIV; +#endif /* _PATH_LOG_PRIV */ - if (status == NOCONN) { - (void)strncpy(SyslogAddr.sun_path, _PATH_LOG, +#ifdef _PATH_LOG + if (xo_status == NOCONN) { + (void) strncpy(SyslogAddr.sun_path, _PATH_LOG, sizeof SyslogAddr.sun_path); - if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, + if (connect(xo_logfile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) != -1) - status = CONNDEF; + xo_status = CONNDEF; } +#endif /* _PATH_LOG */ - if (status == NOCONN) { +#ifdef _PATH_OLDLOG + if (xo_status == NOCONN) { /* * Try the old "/dev/log" path, for backward * compatibility. */ - (void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, + (void) strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, sizeof SyslogAddr.sun_path); - if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, + if (connect(xo_logfile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) != -1) - status = CONNDEF; + xo_status = CONNDEF; } +#endif /* _PATH_OLDLOG */ - if (status == NOCONN) { - (void)_close(LogFile); - LogFile = -1; + if (xo_status == NOCONN) { + (void) close(xo_logfile); + xo_logfile = -1; } } } static void -openlog_unlocked(const char *ident, int logstat, int logfac) +xo_openlog_unlocked (const char *ident, int logstat, int logfac) { if (ident != NULL) - LogTag = ident; - LogStat = logstat; + xo_logtag = ident; + xo_logstat = logstat; if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) - LogFacility = logfac; + xo_logfacility = logfac; - if (LogStat & LOG_NDELAY) /* open immediately */ - connectlog(); + if (xo_logstat & LOG_NDELAY) /* open immediately */ + xo_connectlog(); - opened = 1; /* ident and facility has been set */ + xo_opened = 1; /* ident and facility has been set */ } void -openlog(const char *ident, int logstat, int logfac) +xo_openlog (const char *ident, int logstat, int logfac) { THREAD_LOCK(); - openlog_unlocked(ident, logstat, logfac); + xo_openlog_unlocked(ident, logstat, logfac); THREAD_UNLOCK(); } void -closelog(void) +xo_closelog (void) { THREAD_LOCK(); - if (LogFile != -1) { - (void)_close(LogFile); - LogFile = -1; + if (xo_logfile != -1) { + (void) close(xo_logfile); + xo_logfile = -1; } - LogTag = NULL; - status = NOCONN; + xo_logtag = NULL; + xo_status = NOCONN; THREAD_UNLOCK(); } /* setlogmask -- set the log mask level */ int -setlogmask(int pmask) +xo_setlogmask (int pmask) { int omask; THREAD_LOCK(); - omask = LogMask; + omask = xo_logmask; if (pmask != 0) - LogMask = pmask; + xo_logmask = pmask; THREAD_UNLOCK(); return (omask); } From c19cf5b8da863000b3f71bdb73929ef7bb3c7380 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 17 Jun 2015 18:51:11 -0400 Subject: [PATCH 074/514] change tabs to spaces --- libxo/xo_syslog.c | 640 +++++++++++++++++++++++----------------------- 1 file changed, 320 insertions(+), 320 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 6b95e957..34654918 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -67,35 +67,35 @@ static int xo_logmask = 0xff; /* mask of priorities to be logged */ static pthread_mutex_t xo_syslog_mutex UNUSED = PTHREAD_MUTEX_INITIALIZER; #if 0 -#define THREAD_LOCK() \ - do { \ - if (__isthreaded) _pthread_mutex_lock(&xo_syslog_mutex); \ - } while(0) -#define THREAD_UNLOCK() \ - do { \ - if (__isthreaded) _pthread_mutex_unlock(&xo_syslog_mutex); \ - } while(0) +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) _pthread_mutex_lock(&xo_syslog_mutex); \ + } while(0) +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) _pthread_mutex_unlock(&xo_syslog_mutex); \ + } while(0) #else -#define THREAD_LOCK() -#define THREAD_UNLOCK() +#define THREAD_LOCK() +#define THREAD_UNLOCK() #endif static void xo_disconnectlog(void); /* disconnect from syslogd */ -static void xo_connectlog(void); /* (re)connect to syslogd */ +static void xo_connectlog(void); /* (re)connect to syslogd */ static void xo_openlog_unlocked(const char *, int, int); enum { - NOCONN = 0, - CONNDEF, - CONNPRIV, + NOCONN = 0, + CONNDEF, + CONNPRIV, }; /* * Format of the magic cookie passed through the stdio hook */ struct bufcookie { - char *base; /* start of buffer */ - int left; + char *base; /* start of buffer */ + int left; }; /* @@ -106,374 +106,374 @@ struct bufcookie { static int xo_writehook (void *cookie, const char *buf, int len) { - struct bufcookie *h; /* private `handle' */ - - h = (struct bufcookie *) cookie; - if (len > h->left) { - /* clip in case of wraparound */ - len = h->left; - } - if (len > 0) { - (void) memcpy(h->base, buf, len); /* `write' it. */ - h->base += len; - h->left -= len; - } - return len; + struct bufcookie *h; /* private `handle' */ + + h = (struct bufcookie *) cookie; + if (len > h->left) { + /* clip in case of wraparound */ + len = h->left; + } + if (len > 0) { + (void) memcpy(h->base, buf, len); /* `write' it. */ + h->base += len; + h->left -= len; + } + return len; } /* * syslog, vsyslog -- - * print message on log file; output is intended for syslogd(8). + * print message on log file; output is intended for syslogd(8). */ void xo_syslog (int pri, const char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - vsyslog(pri, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vsyslog(pri, fmt, ap); + va_end(ap); } void xo_vsyslog (int pri, const char *fmt, va_list ap) { - int cnt; - char ch, *p; - time_t now; - int fd, saved_errno; - char *stdp, tbuf[2048], fmt_cpy[1024], timbuf[26], errstr[64]; - FILE *fp, *fmt_fp; - struct bufcookie tbuf_cookie; - struct bufcookie fmt_cookie; - -#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID - /* Check for invalid bits. */ - if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { - syslog(INTERNALLOG, - "syslog: unknown facility/priority: %x", pri); - pri &= LOG_PRIMASK|LOG_FACMASK; - } - - saved_errno = errno; - - THREAD_LOCK(); - - /* Check priority against setlogmask values. */ - if (!(LOG_MASK(LOG_PRI(pri)) & xo_logmask)) { - THREAD_UNLOCK(); - return; - } - - /* Set default facility if none specified. */ - if ((pri & LOG_FACMASK) == 0) - pri |= xo_logfacility; - - /* Create the primary stdio hook */ - tbuf_cookie.base = tbuf; - tbuf_cookie.left = sizeof(tbuf); - fp = fwopen(&tbuf_cookie, xo_writehook); - if (fp == NULL) { - THREAD_UNLOCK(); - return; - } - - /* Build the message. */ - (void) time(&now); - (void) fprintf(fp, "<%d>", pri); - (void) fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); - if (xo_logstat & LOG_PERROR) { - /* Transfer to string buffer */ - (void) fflush(fp); - stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); - } - if (xo_logtag == NULL) - xo_logtag = getprogname(); - if (xo_logtag != NULL) - (void) fprintf(fp, "%s", xo_logtag); - if (xo_logstat & LOG_PID) - (void) fprintf(fp, "[%d]", getpid()); - if (xo_logtag != NULL) { - (void) fprintf(fp, ": "); - } - - /* Check to see if we can skip expanding the %m */ - if (strstr(fmt, "%m")) { - - /* Create the second stdio hook */ - fmt_cookie.base = fmt_cpy; - fmt_cookie.left = sizeof(fmt_cpy) - 1; - fmt_fp = fwopen(&fmt_cookie, xo_writehook); - if (fmt_fp == NULL) { - fclose(fp); - THREAD_UNLOCK(); - return; - } - - /* - * Substitute error message for %m. Be careful not to - * molest an escaped percent "%%m". We want to pass it - * on untouched as the format is later parsed by vfprintf. - */ - for ( ; (ch = *fmt); ++fmt) { - if (ch == '%' && fmt[1] == 'm') { - ++fmt; - strerror_r(saved_errno, errstr, sizeof(errstr)); - fputs(errstr, fmt_fp); - } else if (ch == '%' && fmt[1] == '%') { - ++fmt; - fputc(ch, fmt_fp); - fputc(ch, fmt_fp); - } else { - fputc(ch, fmt_fp); - } - } - - /* Null terminate if room */ - fputc(0, fmt_fp); - fclose(fmt_fp); - - /* Guarantee null termination */ - fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; - - fmt = fmt_cpy; - } - - (void) vfprintf(fp, fmt, ap); - (void) fclose(fp); - - cnt = sizeof(tbuf) - tbuf_cookie.left; - - /* Remove a trailing newline */ - if (tbuf[cnt - 1] == '\n') - cnt--; - - /* Output to stderr if requested. */ - if (xo_logstat & LOG_PERROR) { - struct iovec iov[2]; - struct iovec *v = iov; - char newline[] = "\n"; - - v->iov_base = stdp; - v->iov_len = cnt - (stdp - tbuf); - ++v; - v->iov_base = newline; - v->iov_len = 1; - (void) writev(STDERR_FILENO, iov, 2); - } - - /* Get connected, output the message to the local logger. */ - if (!xo_opened) - xo_openlog_unlocked(xo_logtag, xo_logstat | LOG_NDELAY, 0); - xo_connectlog(); - - /* - * If the send() fails, there are two likely scenarios: - * 1) syslogd was restarted - * 2) /var/run/log is out of socket buffer space, which - * in most cases means local DoS. - * If the error does not indicate a full buffer, we address - * case #1 by attempting to reconnect to /var/run/log[priv] - * and resending the message once. - * - * If we are working with a privileged socket, the retry - * attempts end there, because we don't want to freeze a - * critical application like su(1) or sshd(8). - * - * Otherwise, we address case #2 by repeatedly retrying the - * send() to give syslogd a chance to empty its socket buffer. - */ - - if (send(xo_logfile, tbuf, cnt, 0) < 0) { - if (errno != ENOBUFS) { - /* - * Scenario 1: syslogd was restarted - * reconnect and resend once - */ - xo_disconnectlog(); - xo_connectlog(); - if (send(xo_logfile, tbuf, cnt, 0) >= 0) { - THREAD_UNLOCK(); - return; - } - /* - * if the resend failed, fall through to - * possible scenario 2 - */ - } - while (errno == ENOBUFS) { - /* - * Scenario 2: out of socket buffer space - * possible DoS, fail fast on a privileged - * socket - */ - if (xo_status == CONNPRIV) - break; - usleep(1); - if (send(xo_logfile, tbuf, cnt, 0) >= 0) { - THREAD_UNLOCK(); - return; - } - } - } else { - THREAD_UNLOCK(); - return; - } - - /* - * Output the message to the console; try not to block - * as a blocking console should not stop other processes. - * Make sure the error reported is the one from the syslogd failure. - */ - int flags = O_WRONLY | O_NONBLOCK; + int cnt; + char ch, *p; + time_t now; + int fd, saved_errno; + char *stdp, tbuf[2048], fmt_cpy[1024], timbuf[26], errstr[64]; + FILE *fp, *fmt_fp; + struct bufcookie tbuf_cookie; + struct bufcookie fmt_cookie; + +#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID + /* Check for invalid bits. */ + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + syslog(INTERNALLOG, + "syslog: unknown facility/priority: %x", pri); + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + saved_errno = errno; + + THREAD_LOCK(); + + /* Check priority against setlogmask values. */ + if (!(LOG_MASK(LOG_PRI(pri)) & xo_logmask)) { + THREAD_UNLOCK(); + return; + } + + /* Set default facility if none specified. */ + if ((pri & LOG_FACMASK) == 0) + pri |= xo_logfacility; + + /* Create the primary stdio hook */ + tbuf_cookie.base = tbuf; + tbuf_cookie.left = sizeof(tbuf); + fp = fwopen(&tbuf_cookie, xo_writehook); + if (fp == NULL) { + THREAD_UNLOCK(); + return; + } + + /* Build the message. */ + (void) time(&now); + (void) fprintf(fp, "<%d>", pri); + (void) fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); + if (xo_logstat & LOG_PERROR) { + /* Transfer to string buffer */ + (void) fflush(fp); + stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); + } + if (xo_logtag == NULL) + xo_logtag = getprogname(); + if (xo_logtag != NULL) + (void) fprintf(fp, "%s", xo_logtag); + if (xo_logstat & LOG_PID) + (void) fprintf(fp, "[%d]", getpid()); + if (xo_logtag != NULL) { + (void) fprintf(fp, ": "); + } + + /* Check to see if we can skip expanding the %m */ + if (strstr(fmt, "%m")) { + + /* Create the second stdio hook */ + fmt_cookie.base = fmt_cpy; + fmt_cookie.left = sizeof(fmt_cpy) - 1; + fmt_fp = fwopen(&fmt_cookie, xo_writehook); + if (fmt_fp == NULL) { + fclose(fp); + THREAD_UNLOCK(); + return; + } + + /* + * Substitute error message for %m. Be careful not to + * molest an escaped percent "%%m". We want to pass it + * on untouched as the format is later parsed by vfprintf. + */ + for ( ; (ch = *fmt); ++fmt) { + if (ch == '%' && fmt[1] == 'm') { + ++fmt; + strerror_r(saved_errno, errstr, sizeof(errstr)); + fputs(errstr, fmt_fp); + } else if (ch == '%' && fmt[1] == '%') { + ++fmt; + fputc(ch, fmt_fp); + fputc(ch, fmt_fp); + } else { + fputc(ch, fmt_fp); + } + } + + /* Null terminate if room */ + fputc(0, fmt_fp); + fclose(fmt_fp); + + /* Guarantee null termination */ + fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; + + fmt = fmt_cpy; + } + + (void) vfprintf(fp, fmt, ap); + (void) fclose(fp); + + cnt = sizeof(tbuf) - tbuf_cookie.left; + + /* Remove a trailing newline */ + if (tbuf[cnt - 1] == '\n') + cnt--; + + /* Output to stderr if requested. */ + if (xo_logstat & LOG_PERROR) { + struct iovec iov[2]; + struct iovec *v = iov; + char newline[] = "\n"; + + v->iov_base = stdp; + v->iov_len = cnt - (stdp - tbuf); + ++v; + v->iov_base = newline; + v->iov_len = 1; + (void) writev(STDERR_FILENO, iov, 2); + } + + /* Get connected, output the message to the local logger. */ + if (!xo_opened) + xo_openlog_unlocked(xo_logtag, xo_logstat | LOG_NDELAY, 0); + xo_connectlog(); + + /* + * If the send() fails, there are two likely scenarios: + * 1) syslogd was restarted + * 2) /var/run/log is out of socket buffer space, which + * in most cases means local DoS. + * If the error does not indicate a full buffer, we address + * case #1 by attempting to reconnect to /var/run/log[priv] + * and resending the message once. + * + * If we are working with a privileged socket, the retry + * attempts end there, because we don't want to freeze a + * critical application like su(1) or sshd(8). + * + * Otherwise, we address case #2 by repeatedly retrying the + * send() to give syslogd a chance to empty its socket buffer. + */ + + if (send(xo_logfile, tbuf, cnt, 0) < 0) { + if (errno != ENOBUFS) { + /* + * Scenario 1: syslogd was restarted + * reconnect and resend once + */ + xo_disconnectlog(); + xo_connectlog(); + if (send(xo_logfile, tbuf, cnt, 0) >= 0) { + THREAD_UNLOCK(); + return; + } + /* + * if the resend failed, fall through to + * possible scenario 2 + */ + } + while (errno == ENOBUFS) { + /* + * Scenario 2: out of socket buffer space + * possible DoS, fail fast on a privileged + * socket + */ + if (xo_status == CONNPRIV) + break; + usleep(1); + if (send(xo_logfile, tbuf, cnt, 0) >= 0) { + THREAD_UNLOCK(); + return; + } + } + } else { + THREAD_UNLOCK(); + return; + } + + /* + * Output the message to the console; try not to block + * as a blocking console should not stop other processes. + * Make sure the error reported is the one from the syslogd failure. + */ + int flags = O_WRONLY | O_NONBLOCK; #ifdef O_CLOEXEC - flags |= O_CLOEXEC; + flags |= O_CLOEXEC; #endif /* O_CLOEXEC */ - if (xo_logstat & LOG_CONS - && (fd = open(_PATH_CONSOLE, flags, 0)) >= 0) { - struct iovec iov[2]; - struct iovec *v = iov; - char crnl[] = "\r\n"; - - p = strchr(tbuf, '>') + 1; - v->iov_base = p; - v->iov_len = cnt - (p - tbuf); - ++v; - v->iov_base = crnl; - v->iov_len = 2; - (void) writev(fd, iov, 2); - (void) close(fd); - } - - THREAD_UNLOCK(); + if (xo_logstat & LOG_CONS + && (fd = open(_PATH_CONSOLE, flags, 0)) >= 0) { + struct iovec iov[2]; + struct iovec *v = iov; + char crnl[] = "\r\n"; + + p = strchr(tbuf, '>') + 1; + v->iov_base = p; + v->iov_len = cnt - (p - tbuf); + ++v; + v->iov_base = crnl; + v->iov_len = 2; + (void) writev(fd, iov, 2); + (void) close(fd); + } + + THREAD_UNLOCK(); } /* Should be called with mutex acquired */ static void xo_disconnectlog (void) { - /* - * If the user closed the FD and opened another in the same slot, - * that's their problem. They should close it before calling on - * system services. - */ - if (xo_logfile != -1) { - close(xo_logfile); - xo_logfile = -1; - } - xo_status = NOCONN; /* retry connect */ + /* + * If the user closed the FD and opened another in the same slot, + * that's their problem. They should close it before calling on + * system services. + */ + if (xo_logfile != -1) { + close(xo_logfile); + xo_logfile = -1; + } + xo_status = NOCONN; /* retry connect */ } /* Should be called with mutex acquired */ static void xo_connectlog (void) { - struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ + struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ - if (xo_logfile == -1) { - int flags = SOCK_DGRAM; + if (xo_logfile == -1) { + int flags = SOCK_DGRAM; #ifdef SOCK_CLOEXEC - flags |= SOCK_CLOEXEC; + flags |= SOCK_CLOEXEC; #endif /* SOCK_CLOEXEC */ - if ((xo_logfile = socket(AF_UNIX, flags, 0)) == -1) - return; - } - if (xo_logfile != -1 && xo_status == NOCONN) { - SyslogAddr.sun_len = sizeof(SyslogAddr); - SyslogAddr.sun_family = AF_UNIX; - - /* - * First try privileged socket. If no success, - * then try default socket. - */ + if ((xo_logfile = socket(AF_UNIX, flags, 0)) == -1) + return; + } + if (xo_logfile != -1 && xo_status == NOCONN) { + SyslogAddr.sun_len = sizeof(SyslogAddr); + SyslogAddr.sun_family = AF_UNIX; + + /* + * First try privileged socket. If no success, + * then try default socket. + */ #ifdef _PATH_LOG_PRIV - (void) strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV, - sizeof SyslogAddr.sun_path); - if (connect(xo_logfile, (struct sockaddr *) &SyslogAddr, - sizeof(SyslogAddr)) != -1) - xo_status = CONNPRIV; + (void) strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV, + sizeof SyslogAddr.sun_path); + if (connect(xo_logfile, (struct sockaddr *) &SyslogAddr, + sizeof(SyslogAddr)) != -1) + xo_status = CONNPRIV; #endif /* _PATH_LOG_PRIV */ #ifdef _PATH_LOG - if (xo_status == NOCONN) { - (void) strncpy(SyslogAddr.sun_path, _PATH_LOG, - sizeof SyslogAddr.sun_path); - if (connect(xo_logfile, (struct sockaddr *)&SyslogAddr, - sizeof(SyslogAddr)) != -1) - xo_status = CONNDEF; - } + if (xo_status == NOCONN) { + (void) strncpy(SyslogAddr.sun_path, _PATH_LOG, + sizeof SyslogAddr.sun_path); + if (connect(xo_logfile, (struct sockaddr *)&SyslogAddr, + sizeof(SyslogAddr)) != -1) + xo_status = CONNDEF; + } #endif /* _PATH_LOG */ #ifdef _PATH_OLDLOG - if (xo_status == NOCONN) { - /* - * Try the old "/dev/log" path, for backward - * compatibility. - */ - (void) strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, - sizeof SyslogAddr.sun_path); - if (connect(xo_logfile, (struct sockaddr *)&SyslogAddr, - sizeof(SyslogAddr)) != -1) - xo_status = CONNDEF; - } + if (xo_status == NOCONN) { + /* + * Try the old "/dev/log" path, for backward + * compatibility. + */ + (void) strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, + sizeof SyslogAddr.sun_path); + if (connect(xo_logfile, (struct sockaddr *)&SyslogAddr, + sizeof(SyslogAddr)) != -1) + xo_status = CONNDEF; + } #endif /* _PATH_OLDLOG */ - if (xo_status == NOCONN) { - (void) close(xo_logfile); - xo_logfile = -1; - } - } + if (xo_status == NOCONN) { + (void) close(xo_logfile); + xo_logfile = -1; + } + } } static void xo_openlog_unlocked (const char *ident, int logstat, int logfac) { - if (ident != NULL) - xo_logtag = ident; - xo_logstat = logstat; - if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) - xo_logfacility = logfac; + if (ident != NULL) + xo_logtag = ident; + xo_logstat = logstat; + if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) + xo_logfacility = logfac; - if (xo_logstat & LOG_NDELAY) /* open immediately */ - xo_connectlog(); + if (xo_logstat & LOG_NDELAY) /* open immediately */ + xo_connectlog(); - xo_opened = 1; /* ident and facility has been set */ + xo_opened = 1; /* ident and facility has been set */ } void xo_openlog (const char *ident, int logstat, int logfac) { - THREAD_LOCK(); - xo_openlog_unlocked(ident, logstat, logfac); - THREAD_UNLOCK(); + THREAD_LOCK(); + xo_openlog_unlocked(ident, logstat, logfac); + THREAD_UNLOCK(); } void xo_closelog (void) { - THREAD_LOCK(); - if (xo_logfile != -1) { - (void) close(xo_logfile); - xo_logfile = -1; - } - xo_logtag = NULL; - xo_status = NOCONN; - THREAD_UNLOCK(); + THREAD_LOCK(); + if (xo_logfile != -1) { + (void) close(xo_logfile); + xo_logfile = -1; + } + xo_logtag = NULL; + xo_status = NOCONN; + THREAD_UNLOCK(); } /* setlogmask -- set the log mask level */ int xo_setlogmask (int pmask) { - int omask; - - THREAD_LOCK(); - omask = xo_logmask; - if (pmask != 0) - xo_logmask = pmask; - THREAD_UNLOCK(); - return (omask); + int omask; + + THREAD_LOCK(); + omask = xo_logmask; + if (pmask != 0) + xo_logmask = pmask; + THREAD_UNLOCK(); + return (omask); } From bae0903fa3f274d499ad742d13acdff077e3a70c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:29:08 -0400 Subject: [PATCH 075/514] Add XO_STYLE_SDPARAMS for xo_syslog --- libxo/libxo.c | 155 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 141 insertions(+), 14 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 2ea72190..2140cf58 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -640,12 +640,13 @@ static char xo_xml_gt[] = ">"; static char xo_xml_quot[] = """; static int -xo_escape_xml (xo_buffer_t *xbp, int len, int attr) +xo_escape_xml (xo_buffer_t *xbp, int len, xo_xff_flags_t flags) { int slen; unsigned delta = 0; char *cp, *ep, *ip; const char *sp; + int attr = (flags & XFF_ATTR); for (cp = xbp->xb_curp, ep = cp + len; cp < ep; cp++) { /* We're subtracting 2: 1 for the NUL, 1 for the char we replace */ @@ -695,7 +696,7 @@ xo_escape_xml (xo_buffer_t *xbp, int len, int attr) } static int -xo_escape_json (xo_buffer_t *xbp, int len) +xo_escape_json (xo_buffer_t *xbp, int len, xo_xff_flags_t flags UNUSED) { unsigned delta = 0; char *cp, *ep, *ip; @@ -738,6 +739,46 @@ xo_escape_json (xo_buffer_t *xbp, int len) return len + delta; } +/* + * PARAM-VALUE = UTF-8-STRING ; characters '"', '\' and + * ; ']' MUST be escaped. + */ +static int +xo_escape_sdparams (xo_buffer_t *xbp, int len, xo_xff_flags_t flags UNUSED) +{ + unsigned delta = 0; + char *cp, *ep, *ip; + + for (cp = xbp->xb_curp, ep = cp + len; cp < ep; cp++) { + if (*cp == '\\' || *cp == '"' || *cp == ']') + delta += 1; + } + + if (delta == 0) /* Nothing to escape; bail */ + return len; + + if (!xo_buf_has_room(xbp, delta)) /* No room; bail, but don't append */ + return 0; + + ep = xbp->xb_curp; + cp = ep + len; + ip = cp + delta; + do { + cp -= 1; + ip -= 1; + + if (*cp == '\\' || *cp == '"' || *cp == ']') { + *ip-- = *cp; + *ip = '\\'; + } else { + *ip = *cp; + } + + } while (cp > ep && cp != ip); + + return len + delta; +} + /* * Append the given string to the given buffer */ @@ -778,11 +819,15 @@ xo_buf_escape (xo_handle_t *xop, xo_buffer_t *xbp, switch (xo_style(xop)) { case XO_STYLE_XML: case XO_STYLE_HTML: - len = xo_escape_xml(xbp, len, (flags & XFF_ATTR)); + len = xo_escape_xml(xbp, len, flags); break; case XO_STYLE_JSON: - len = xo_escape_json(xbp, len); + len = xo_escape_json(xbp, len, flags); + break; + + case XO_STYLE_SDPARAMS: + len = xo_escape_sdparams(xbp, len, flags); break; } @@ -1420,6 +1465,10 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) /* No means of representing messages in JSON */ break; + case XO_STYLE_SDPARAMS: + /* No means of representing messages in SDPARAMS */ + break; + case XO_STYLE_TEXT: rc = xo_printf_v(xop, fmt, vap); /* @@ -1611,10 +1660,22 @@ xo_name_to_style (const char *name) return XO_STYLE_TEXT; else if (strcmp(name, "html") == 0) return XO_STYLE_HTML; + else if (strcmp(name, "sdparams") == 0) + return XO_STYLE_SDPARAMS; return -1; } +static int +xo_style_is_encoding (xo_handle_t *xop) +{ + if (xo_style(xop) == XO_STYLE_JSON + || xo_style(xop) == XO_STYLE_XML + || xo_style(xop) == XO_STYLE_SDPARAMS) + return 1; + return 0; +} + /* Simple name-value mapping */ typedef struct xo_mapping_s { xo_xff_flags_t xm_value; @@ -1834,7 +1895,7 @@ xo_set_options (xo_handle_t *xop, const char *input) else xo_failure(xop, "missing value for indent option"); } else { - xo_warnx("unknown option: '%s'", cp); + xo_warnx("unknown libxo option value: '%s'", cp); rc = -1; } } @@ -2215,6 +2276,18 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, *xbp->xb_curp++ = wc; goto done_with_encoding; + + case XO_STYLE_SDPARAMS: + if (wc != '\\' && wc != '"' && wc != ']') + break; + + if (!xo_buf_has_room(xbp, 2)) + return -1; + + *xbp->xb_curp++ = '\\'; + wc = wc & 0x7f; + *xbp->xb_curp++ = wc; + goto done_with_encoding; } olen = xo_utf8_emit_len(wc); @@ -2300,8 +2373,7 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, /* Echo "Dont' deref NULL" logic */ if (cp == NULL) { - if ((flags & XFF_NOQUOTE) && (xo_style(xop) == XO_STYLE_JSON - || xo_style(xop) == XO_STYLE_XML)) { + if ((flags & XFF_NOQUOTE) && xo_style_is_encoding(xop)) { cp = null_no_quotes; len = sizeof(null_no_quotes) - 1; } else { @@ -2516,7 +2588,7 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, /* Hidden fields are only visible to JSON and XML */ if (xop->xo_flags & XFF_ENCODE_ONLY) { if (style != XO_STYLE_XML - && xo_style(xop) != XO_STYLE_JSON) + && !xo_style_is_encoding(xop)) xf.xf_skip = 1; } else if (xop->xo_flags & XFF_DISPLAY_ONLY) { if (style != XO_STYLE_TEXT @@ -2629,9 +2701,7 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, rc = xo_format_string(xop, xbp, flags, &xf); - if ((flags & XFF_TRIM_WS) - && (xo_style(xop) == XO_STYLE_XML - || xo_style(xop) == XO_STYLE_JSON)) + if ((flags & XFF_TRIM_WS) && xo_style_is_encoding(xop)) rc = xo_trim_ws(xbp, rc); } else { @@ -2653,7 +2723,13 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, case XO_STYLE_JSON: if (flags & XFF_TRIM_WS) columns = rc = xo_trim_ws(xbp, rc); - rc = xo_escape_json(xbp, rc); + rc = xo_escape_json(xbp, rc, 0); + break; + + case XO_STYLE_SDPARAMS: + if (flags & XFF_TRIM_WS) + columns = rc = xo_trim_ws(xbp, rc); + rc = xo_escape_sdparams(xbp, rc, 0); break; } @@ -3160,6 +3236,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, switch (xo_style(xop)) { case XO_STYLE_XML: case XO_STYLE_JSON: + case XO_STYLE_SDPARAMS: /* * Even though we don't care about text, we need to do * enough parsing work to skip over the right bits of xo_vap. @@ -3530,6 +3607,37 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, if (quote) xo_data_append(xop, "\"", 1); break; + + case XO_STYLE_SDPARAMS: + if (flags & XFF_DISPLAY_ONLY) { + flags |= XFF_NO_OUTPUT; + xo_format_data(xop, NULL, format, flen, flags); + break; + } + + if (encoding) { + format = encoding; + flen = elen; + } else { + char *enc = alloca(flen + 1); + memcpy(enc, format, flen); + enc[flen] = '\0'; + format = xo_fix_encoding(xop, enc); + flen = strlen(format); + } + + if (nlen == 0) { + static char missing[] = "missing-field-name"; + xo_failure(xop, "missing field name: %s", format); + name = missing; + nlen = sizeof(missing) - 1; + } + + xo_data_escape(xop, name, nlen); + xo_data_append(xop, "=\"", 2); + xo_format_data(xop, NULL, format, flen, flags); + xo_data_append(xop, "\" ", 2); + break; } } @@ -3577,6 +3685,7 @@ xo_format_content (xo_handle_t *xop, const char *class_name, break; case XO_STYLE_JSON: + case XO_STYLE_SDPARAMS: /* * Even though we don't care about labels, we need to do * enough parsing work to skip over the right bits of xo_vap. @@ -3884,8 +3993,7 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, xo_buffer_t xb; /* If the string is static and we've in an encoding style, bail */ - if (len != 0 - && (xo_style(xop) == XO_STYLE_XML || xo_style(xop) == XO_STYLE_JSON)) + if (len != 0 && xo_style_is_encoding(xop)) return; xo_buf_init(&xb); @@ -3935,6 +4043,7 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, case XO_STYLE_XML: case XO_STYLE_JSON: + case XO_STYLE_SDPARAMS: /* * Nothing to do; we did all that work just to clear the stack of * formatting arguments. @@ -4763,6 +4872,9 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) rc = xo_printf(xop, "%s%*s\"%s\": {%s", pre_nl, xo_indent(xop), "", name, ppn); break; + + case XO_STYLE_SDPARAMS: + break; } xo_depth_change(xop, name, 1, 1, XSS_OPEN_CONTAINER, @@ -4845,6 +4957,9 @@ xo_do_close_container (xo_handle_t *xop, const char *name) case XO_STYLE_TEXT: xo_depth_change(xop, name, -1, 0, XSS_CLOSE_CONTAINER, 0); break; + + case XO_STYLE_SDPARAMS: + break; } return rc; @@ -5126,6 +5241,9 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) rc = xo_printf(xop, "%s%*s{%s", pre_nl, xo_indent(xop), "", ppn); break; + + case XO_STYLE_SDPARAMS: + break; } xo_depth_change(xop, name, 1, 1, XSS_OPEN_INSTANCE, xo_stack_flags(flags)); @@ -5206,6 +5324,9 @@ xo_do_close_instance (xo_handle_t *xop, const char *name) case XO_STYLE_TEXT: xo_depth_change(xop, name, -1, 0, XSS_CLOSE_INSTANCE, 0); break; + + case XO_STYLE_SDPARAMS: + break; } return rc; @@ -5778,6 +5899,9 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) va_end(xop->xo_vap); bzero(&xop->xo_vap, sizeof(xop->xo_vap)); break; + + case XO_STYLE_SDPARAMS: + break; } } @@ -5895,6 +6019,9 @@ xo_set_version_h (xo_handle_t *xop, const char *version UNUSED) if (version == NULL || strchr(version, '"') != NULL) return; + if (!xo_style_is_encoding(xop)) + return; + switch (xo_style(xop)) { case XO_STYLE_XML: /* For XML, we record this as an attribute for the first tag */ From 25a222bdafb5b0da35b46a0817e35aa7ee8cf8a5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:29:18 -0400 Subject: [PATCH 076/514] Add xo_syslog and friends --- libxo/xo.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/libxo/xo.h b/libxo/xo.h index d3b9e425..98c088c8 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -45,6 +45,7 @@ typedef unsigned xo_style_t; #define XO_STYLE_XML 1 /** Generate XML output */ #define XO_STYLE_JSON 2 /** Generate JSON output */ #define XO_STYLE_HTML 3 /** Generate HTML output */ +#define XO_STYLE_SDPARAMS 4 /** Generate syslog structured data params */ /** Flags for libxo */ typedef unsigned long long xo_xof_flags_t; @@ -400,10 +401,31 @@ xo_set_version (const char *version); void xo_set_version_h (xo_handle_t *xop, const char *version); -void xo_closelog(void); -void xo_openlog(const char *ident, int logopt, int facility); -int xo_setlogmask(int maskpri); -void xo_syslog(int priority, const char *message, ...); -void xo_vsyslog(int priority, const char *message, va_list args); +void +xo_open_log (const char *ident, int logopt, int facility); + +void +xo_close_log (void); + +int +xo_set_logmask (int maskpri); + +void +xo_syslog (int priority, const char *id, const char *message, ...); + +void +xo_vsyslog (int priority, const char *id, const char *message, va_list args); + +typedef void (*xo_syslog_open_t)(void); +typedef void (*xo_syslog_send_t)(const char *full_msg, + const char *v0_hdr, const char *text_only); +typedef void (*xo_syslog_close_t)(void); + +void +xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func, + xo_syslog_close_t close_func); + +void +xo_set_syslog_enterprise_id (unsigned short eid); #endif /* INCLUDE_XO_H */ From 22794de6334fe9df70b2d668627a7b23bf227fe0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:29:24 -0400 Subject: [PATCH 077/514] initial version --- libxo/xo_syslog.c | 516 ++++++++++++++++++++++++++++++---------------- 1 file changed, 344 insertions(+), 172 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 34654918..86202a27 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -50,9 +50,33 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #include "xo.h" +/* + * SYSLOG (RFC 5424) requires an enterprise identifier. The kernel should + * support a sysctl to assign a custom enterprise-id. We default to the + * stock IANA assigned Enterprise ID value for FreeBSD. See + * https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers + */ +#define XO_SYSLOG_ENTERPRISE_ID "kern.syslog.enterprise_id" +#if defined(__FreeBSD__) +#define XO_DEFAULT_EID "2238" +#elseif defined(__macosx__) +#define XO_DEFAULT_EID "63" +#else +#define XO_DEFAULT_EID "32473" /* Bail; use "example" number */ +#endif + +#ifdef _SC_HOST_NAME_MAX +#define HOST_NAME_MAX _SC_HOST_NAME_MAX +#else +#define HOST_NAME_MAX 255 +#endif /* _SC_HOST_NAME_MAX */ + #ifndef UNUSED #define UNUSED __attribute__ ((__unused__)) #endif /* UNUSED */ @@ -80,9 +104,9 @@ static pthread_mutex_t xo_syslog_mutex UNUSED = PTHREAD_MUTEX_INITIALIZER; #define THREAD_UNLOCK() #endif -static void xo_disconnectlog(void); /* disconnect from syslogd */ -static void xo_connectlog(void); /* (re)connect to syslogd */ -static void xo_openlog_unlocked(const char *, int, int); +static void xo_disconnect_log(void); /* disconnect from syslogd */ +static void xo_connect_log(void); /* (re)connect to syslogd */ +static void xo_open_log_unlocked(const char *, int, int); enum { NOCONN = 0, @@ -91,181 +115,76 @@ enum { }; /* - * Format of the magic cookie passed through the stdio hook + * We can't see the real xo_buffer_t (for now), so we cons up a compatible + * version of it. */ -struct bufcookie { - char *base; /* start of buffer */ - int left; -}; +typedef struct xo_sbuffer_s { + char *xb_basep; /* start of buffer */ + char *xb_curp; /* start of buffer */ + int xb_size; +} xo_sbuffer_t; -/* - * stdio write hook for writing to a static string buffer - * XXX: Maybe one day, dynamically allocate it so that the line length - * is `unlimited'. - */ -static int -xo_writehook (void *cookie, const char *buf, int len) -{ - struct bufcookie *h; /* private `handle' */ +static xo_syslog_open_t xo_syslog_open; +static xo_syslog_send_t xo_syslog_send; +static xo_syslog_close_t xo_syslog_close; - h = (struct bufcookie *) cookie; - if (len > h->left) { - /* clip in case of wraparound */ - len = h->left; - } - if (len > 0) { - (void) memcpy(h->base, buf, len); /* `write' it. */ - h->base += len; - h->left -= len; - } - return len; -} +static char xo_syslog_enterprise_id[12]; /* - * syslog, vsyslog -- - * print message on log file; output is intended for syslogd(8). + * Record an enterprise ID, which functions as a namespace for syslog + * messages. The value is pre-formatted into a string. This allows + * applications to customize their syslog message set, when needed. */ void -xo_syslog (int pri, const char *fmt, ...) +xo_set_syslog_enterprise_id (unsigned short eid) { - va_list ap; - - va_start(ap, fmt); - vsyslog(pri, fmt, ap); - va_end(ap); + snprintf(xo_syslog_enterprise_id, sizeof(xo_syslog_enterprise_id), + "%u", eid); } -void -xo_vsyslog (int pri, const char *fmt, va_list ap) +static int +xo_sleft (xo_sbuffer_t *xbp) { - int cnt; - char ch, *p; - time_t now; - int fd, saved_errno; - char *stdp, tbuf[2048], fmt_cpy[1024], timbuf[26], errstr[64]; - FILE *fp, *fmt_fp; - struct bufcookie tbuf_cookie; - struct bufcookie fmt_cookie; - -#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID - /* Check for invalid bits. */ - if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { - syslog(INTERNALLOG, - "syslog: unknown facility/priority: %x", pri); - pri &= LOG_PRIMASK|LOG_FACMASK; - } - - saved_errno = errno; - - THREAD_LOCK(); - - /* Check priority against setlogmask values. */ - if (!(LOG_MASK(LOG_PRI(pri)) & xo_logmask)) { - THREAD_UNLOCK(); - return; - } - - /* Set default facility if none specified. */ - if ((pri & LOG_FACMASK) == 0) - pri |= xo_logfacility; - - /* Create the primary stdio hook */ - tbuf_cookie.base = tbuf; - tbuf_cookie.left = sizeof(tbuf); - fp = fwopen(&tbuf_cookie, xo_writehook); - if (fp == NULL) { - THREAD_UNLOCK(); - return; - } - - /* Build the message. */ - (void) time(&now); - (void) fprintf(fp, "<%d>", pri); - (void) fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4); - if (xo_logstat & LOG_PERROR) { - /* Transfer to string buffer */ - (void) fflush(fp); - stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); - } - if (xo_logtag == NULL) - xo_logtag = getprogname(); - if (xo_logtag != NULL) - (void) fprintf(fp, "%s", xo_logtag); - if (xo_logstat & LOG_PID) - (void) fprintf(fp, "[%d]", getpid()); - if (xo_logtag != NULL) { - (void) fprintf(fp, ": "); - } - - /* Check to see if we can skip expanding the %m */ - if (strstr(fmt, "%m")) { - - /* Create the second stdio hook */ - fmt_cookie.base = fmt_cpy; - fmt_cookie.left = sizeof(fmt_cpy) - 1; - fmt_fp = fwopen(&fmt_cookie, xo_writehook); - if (fmt_fp == NULL) { - fclose(fp); - THREAD_UNLOCK(); - return; - } - - /* - * Substitute error message for %m. Be careful not to - * molest an escaped percent "%%m". We want to pass it - * on untouched as the format is later parsed by vfprintf. - */ - for ( ; (ch = *fmt); ++fmt) { - if (ch == '%' && fmt[1] == 'm') { - ++fmt; - strerror_r(saved_errno, errstr, sizeof(errstr)); - fputs(errstr, fmt_fp); - } else if (ch == '%' && fmt[1] == '%') { - ++fmt; - fputc(ch, fmt_fp); - fputc(ch, fmt_fp); - } else { - fputc(ch, fmt_fp); - } - } - - /* Null terminate if room */ - fputc(0, fmt_fp); - fclose(fmt_fp); - - /* Guarantee null termination */ - fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; + return xbp->xb_size - (xbp->xb_curp - xbp->xb_basep); +} - fmt = fmt_cpy; +/* + * Handle the work of transmitting the syslog message + */ +static void +xo_send_syslog (char *full_msg, char *v0_hdr, + char *text_only) +{ + if (xo_syslog_send) { + xo_syslog_send(full_msg, v0_hdr, text_only); + return; } - (void) vfprintf(fp, fmt, ap); - (void) fclose(fp); - - cnt = sizeof(tbuf) - tbuf_cookie.left; - - /* Remove a trailing newline */ - if (tbuf[cnt - 1] == '\n') - cnt--; + int fd; + int full_len = strlen(full_msg); /* Output to stderr if requested. */ if (xo_logstat & LOG_PERROR) { - struct iovec iov[2]; + struct iovec iov[3]; struct iovec *v = iov; char newline[] = "\n"; - v->iov_base = stdp; - v->iov_len = cnt - (stdp - tbuf); - ++v; + v->iov_base = v0_hdr; + v->iov_len = strlen(v0_hdr); + v += 1; + v->iov_base = text_only; + v->iov_len = strlen(text_only); + v += 1; v->iov_base = newline; v->iov_len = 1; - (void) writev(STDERR_FILENO, iov, 2); + v += 1; + (void) writev(STDERR_FILENO, iov, 3); } /* Get connected, output the message to the local logger. */ if (!xo_opened) - xo_openlog_unlocked(xo_logtag, xo_logstat | LOG_NDELAY, 0); - xo_connectlog(); + xo_open_log_unlocked(xo_logtag, xo_logstat | LOG_NDELAY, 0); + xo_connect_log(); /* * If the send() fails, there are two likely scenarios: @@ -284,16 +203,15 @@ xo_vsyslog (int pri, const char *fmt, va_list ap) * send() to give syslogd a chance to empty its socket buffer. */ - if (send(xo_logfile, tbuf, cnt, 0) < 0) { + if (send(xo_logfile, full_msg, full_len, 0) < 0) { if (errno != ENOBUFS) { /* * Scenario 1: syslogd was restarted * reconnect and resend once */ - xo_disconnectlog(); - xo_connectlog(); - if (send(xo_logfile, tbuf, cnt, 0) >= 0) { - THREAD_UNLOCK(); + xo_disconnect_log(); + xo_connect_log(); + if (send(xo_logfile, full_msg, full_len, 0) >= 0) { return; } /* @@ -310,8 +228,7 @@ xo_vsyslog (int pri, const char *fmt, va_list ap) if (xo_status == CONNPRIV) break; usleep(1); - if (send(xo_logfile, tbuf, cnt, 0) >= 0) { - THREAD_UNLOCK(); + if (send(xo_logfile, full_msg, full_len, 0) >= 0) { return; } } @@ -335,24 +252,28 @@ xo_vsyslog (int pri, const char *fmt, va_list ap) struct iovec iov[2]; struct iovec *v = iov; char crnl[] = "\r\n"; + char *p; - p = strchr(tbuf, '>') + 1; + p = strchr(full_msg, '>') + 1; v->iov_base = p; - v->iov_len = cnt - (p - tbuf); + v->iov_len = full_len - (p - full_msg); ++v; v->iov_base = crnl; v->iov_len = 2; (void) writev(fd, iov, 2); (void) close(fd); } - - THREAD_UNLOCK(); } /* Should be called with mutex acquired */ static void -xo_disconnectlog (void) +xo_disconnect_log (void) { + if (xo_syslog_close) { + xo_syslog_close(); + return; + } + /* * If the user closed the FD and opened another in the same slot, * that's their problem. They should close it before calling on @@ -367,8 +288,13 @@ xo_disconnectlog (void) /* Should be called with mutex acquired */ static void -xo_connectlog (void) +xo_connect_log (void) { + if (xo_syslog_open) { + xo_syslog_open(); + return; + } + struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ if (xo_logfile == -1) { @@ -428,7 +354,7 @@ xo_connectlog (void) } static void -xo_openlog_unlocked (const char *ident, int logstat, int logfac) +xo_open_log_unlocked (const char *ident, int logstat, int logfac) { if (ident != NULL) xo_logtag = ident; @@ -437,22 +363,22 @@ xo_openlog_unlocked (const char *ident, int logstat, int logfac) xo_logfacility = logfac; if (xo_logstat & LOG_NDELAY) /* open immediately */ - xo_connectlog(); + xo_connect_log(); xo_opened = 1; /* ident and facility has been set */ } void -xo_openlog (const char *ident, int logstat, int logfac) +xo_open_log (const char *ident, int logstat, int logfac) { THREAD_LOCK(); - xo_openlog_unlocked(ident, logstat, logfac); + xo_open_log_unlocked(ident, logstat, logfac); THREAD_UNLOCK(); } void -xo_closelog (void) +xo_close_log (void) { THREAD_LOCK(); if (xo_logfile != -1) { @@ -464,9 +390,9 @@ xo_closelog (void) THREAD_UNLOCK(); } -/* setlogmask -- set the log mask level */ +/* xo_set_logmask -- set the log mask level */ int -xo_setlogmask (int pmask) +xo_set_logmask (int pmask) { int omask; @@ -477,3 +403,249 @@ xo_setlogmask (int pmask) THREAD_UNLOCK(); return (omask); } + +void +xo_set_syslog_handler (xo_syslog_open_t open_func, + xo_syslog_send_t send_func, + xo_syslog_close_t close_func) +{ + xo_syslog_open = open_func; + xo_syslog_send = send_func; + xo_syslog_close = close_func; +} + +static size_t +xo_snprintf (char *out, size_t outsize, const char *fmt, ...) +{ + int status; + size_t retval = 0; + va_list ap; + if (out && outsize) { + va_start(ap, fmt); + status = vsnprintf(out, outsize, fmt, ap); + if (status < 0) { /* this should never happen, */ + *out = 0; /* handle it in the safest way possible if it does */ + retval = 0; + } else { + retval = status; + retval = retval > outsize ? outsize : retval; + } + va_end(ap); + } + return retval; +} + +static int +xo_syslog_handle_write (void *opaque, const char *data) +{ + xo_sbuffer_t *xbp = opaque; + int len = strlen(data); + int left = xo_sleft(xbp); + + if (len > left - 1) + len = left - 1; + + memcpy(xbp->xb_curp, data, len); + xbp->xb_curp += len; + *xbp->xb_curp = '\0'; + + return len; +} + +static void +xo_syslog_handle_close (void *opaque UNUSED) +{ +} + +static int +xo_syslog_handle_flush (void *opaque UNUSED) +{ + return 0; +} + +void +xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) +{ + int saved_errno = errno; + char tbuf[2048]; + char *tp = NULL, *ep = NULL; + char *start_of_msg = NULL, *v0_hdr = NULL; + xo_sbuffer_t xb; + + /* Check for invalid bits */ + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + xo_syslog(LOG_ERR | LOG_CONS | LOG_PERROR | LOG_PID, + "syslog-unknown-priority", + "syslog: unknown facility/priority: %#x", pri); + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + THREAD_LOCK(); + + /* Check priority against setlogmask values. */ + if (!(LOG_MASK(LOG_PRI(pri)) & xo_logmask)) { + THREAD_UNLOCK(); + return; + } + + /* Set default facility if none specified. */ + if ((pri & LOG_FACMASK) == 0) + pri |= xo_logfacility; + + /* Create the primary stdio hook */ + xb.xb_basep = tbuf; + xb.xb_curp = tbuf; + xb.xb_size = sizeof(tbuf); + + xo_handle_t *xop = xo_create(XO_STYLE_SDPARAMS, 0); + if (xop == NULL) { + THREAD_UNLOCK(); + return; + } + + xo_set_writer(xop, &xb, xo_syslog_handle_write, xo_syslog_handle_close, + xo_syslog_handle_flush); + + /* Build the message; start by getting the time */ + struct tm tm; + struct timeval tv; + + gettimeofday(&tv, NULL); + (void) gmtime_r(&tv.tv_sec, &tm); + + if (xo_logstat & LOG_PERROR) { + /* + * For backwards compatibility, we need to make the old-style + * message. This message can be emitted to the console/tty. + */ + v0_hdr = alloca(2048); + tp = v0_hdr; + ep = v0_hdr + 2048; + + if (xo_logtag == NULL) + xo_logtag = getprogname(); + if (xo_logtag != NULL) + tp += xo_snprintf(tp, ep - tp, "%s", xo_logtag); + if (xo_logstat & LOG_PID) + tp += xo_snprintf(tp, ep - tp, "[%d]", getpid()); + if (xo_logtag) + tp += xo_snprintf(tp, ep - tp, ": "); + } + + /* Add PRI, PRIVAL, and VERSION */ + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "<%d>1 ", pri); + + /* Add TIMESTAMP with milliseconds and TZOFFSET */ + xb.xb_curp += strftime(xb.xb_curp, xo_sleft(&xb), "%FT%T", &tm); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), + ".%03.3u", tv.tv_usec / 1000); + xb.xb_curp += strftime(xb.xb_curp, xo_sleft(&xb), "%z ", &tm); + + /* + * Add HOSTNAME; we rely on gethostname and don't fluff with + * ip addresses. Might need to revisit..... + */ + char hostname[HOST_NAME_MAX]; + hostname[0] = '\0'; + (void) gethostname(hostname, sizeof(hostname)); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s ", + hostname[0] ? hostname : "-"); + + /* Add APP-NAME */ + if (xo_logtag == NULL) + xo_logtag = getprogname(); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s ", + xo_logtag ?: "-"); + + /* Add PROCID */ + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%d ", getpid()); + + /* + * Add MSGID. The user should provide us with a name, which we + * prefix with the current enterprise ID, as learned from the kernel. + * If the kernel won't tell us, we use the stock/builtin number. + */ + char *buf = NULL; + const char *eid = xo_syslog_enterprise_id; + const char *at_sign = "@"; + + if (id == NULL) { + id = "-"; + eid = at_sign = ""; + + } else if (*id == '@') { + /* Our convention is to prefix IANA-defined names with an "@" */ + id += 1; + eid = at_sign = ""; + + } else if (eid[0] == '\0') { + /* + * See if the kernel knows the sysctl for the enterprise ID + */ + size_t size = 0; + if (sysctlbyname(XO_SYSLOG_ENTERPRISE_ID, NULL, &size, NULL, 0) == 0 + && size > 0) { + buf = alloca(size); + if (sysctlbyname(XO_SYSLOG_ENTERPRISE_ID, buf, &size, NULL, 0) == 0 + && size > 0) + eid = buf; + } + } + + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "[%s%s%s ", + eid, at_sign, id); + + /* + * Now for the real content. We make two distinct passes thru the + * xo_emit engine, first for the SD-PARAMS and then for the text + * message. + */ + va_list ap; + va_copy(ap, vap); + + errno = saved_errno; /* Restore saved error value */ + xo_emit_hv(xop, fmt, ap); + xo_flush_h(xop); + + va_end(ap); + + /* Trim trailing space */ + if (xb.xb_curp[-1] == ' ') + xb.xb_curp[-1] -= 1; + + /* Close the structured data (SD-ELEMENT) */ + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "] "); + + /* Save the start of the message */ + if (xo_logstat & LOG_PERROR) + start_of_msg = xb.xb_curp; + + xo_set_style(xop, XO_STYLE_TEXT); + + errno = saved_errno; /* Restore saved error value */ + xo_emit_hv(xop, fmt, ap); + xo_flush_h(xop); + + /* Remove a trailing newline */ + if (xb.xb_curp[-1] == '\n') + *--xb.xb_curp = '\0'; + + xo_send_syslog(xb.xb_basep, v0_hdr, start_of_msg); + + xo_destroy(xop); + + THREAD_UNLOCK(); +} + +/* + * syslog - print message on log file; output is intended for syslogd(8). + */ +void +xo_syslog (int pri, const char *id, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xo_vsyslog(pri, id, fmt, ap); + va_end(ap); +} From ef56f56a764ad1a0d2de6cf4884da962834cab75 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:29:32 -0400 Subject: [PATCH 078/514] Add test_11 (xo_syslog) --- tests/core/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/Makefile.am b/tests/core/Makefile.am index 27d0c9c6..7e117e9c 100644 --- a/tests/core/Makefile.am +++ b/tests/core/Makefile.am @@ -21,7 +21,8 @@ test_06.c \ test_07.c \ test_08.c \ test_09.c \ -test_10.c +test_10.c \ +test_11.c test_01_test_SOURCES = test_01.c test_02_test_SOURCES = test_02.c @@ -33,6 +34,7 @@ test_07_test_SOURCES = test_07.c test_08_test_SOURCES = test_08.c test_09_test_SOURCES = test_09.c test_10_test_SOURCES = test_10.c +test_11_test_SOURCES = test_11.c # TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) From 6382b997bf93f86bda2f5c7d17f60196d58f1dc1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:29:39 -0400 Subject: [PATCH 079/514] initial version --- tests/core/test_11.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tests/core/test_11.c diff --git a/tests/core/test_11.c b/tests/core/test_11.c new file mode 100644 index 00000000..af09b536 --- /dev/null +++ b/tests/core/test_11.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xo.h" + +void +test_syslog_open (void) +{ + printf("syslog open\n"); +} + +void +test_syslog_close (void) +{ + printf("syslog close\n"); +} + +void +test_syslog_send (const char *full_msg, const char *v0_hdr, + const char *text_only) +{ + printf("{{%s}}\n{{%s}}\n{{%s}}\n\n", full_msg, v0_hdr, text_only); +} + +int +main (int argc, char **argv) +{ + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + xo_set_syslog_handler(test_syslog_open, test_syslog_send, + test_syslog_close); + + xo_open_log("test-program", LOG_PERROR, LOG_DAEMON); + + xo_set_version("3.1.4"); + xo_set_syslog_enterprise_id(42); /* SunOs */ + + xo_open_container_h(NULL, "top"); + + xo_syslog(LOG_INFO, "animal-status", + "The {:animal} is {:state}", "snake", "loose"); + xo_syslog(LOG_INFO, "animal-consumed", + "My {:animal} ate your {:pet}", "snake", "hamster"); + xo_syslog(LOG_NOTICE, "animal-talk", + "{:count/%d} {:animal} said {:quote}", 1, "owl", "\"e=m\\c[2]\""); + + xo_close_container_h(NULL, "top"); + + xo_finish(); + + return 0; +} From 28d13c69e0a2d604ae5707c8ee04d71af99455d6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:48 -0400 Subject: [PATCH 080/514] update test cases --- tests/core/saved/test_11.H.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.H.err diff --git a/tests/core/saved/test_11.H.err b/tests/core/saved/test_11.H.err new file mode 100644 index 00000000..e69de29b From 1faf651fd46113d01dcc160e0260870bd0b19262 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:49 -0400 Subject: [PATCH 081/514] update test cases --- tests/core/saved/test_11.H.out | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/core/saved/test_11.H.out diff --git a/tests/core/saved/test_11.H.out b/tests/core/saved/test_11.H.out new file mode 100644 index 00000000..b422c1ab --- /dev/null +++ b/tests/core/saved/test_11.H.out @@ -0,0 +1,12 @@ +{{<30>1 2015-06-23T18:29:58.960-0500 bock.juniper.net test-program 91048 [42@animal-status
The
snake
is
loose
] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.961-0500 bock.juniper.net test-program 91048 [42@animal-consumed
My
snake
ate your
hamster
] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.961-0500 bock.juniper.net test-program 91048 [42@animal-talk
1
owl
said
"e=m\c[2]"
] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + From 85dda001d4ad464f012adf20883fbab2bb66e10d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:50 -0400 Subject: [PATCH 082/514] update test cases --- tests/core/saved/test_11.HIPx.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.HIPx.err diff --git a/tests/core/saved/test_11.HIPx.err b/tests/core/saved/test_11.HIPx.err new file mode 100644 index 00000000..e69de29b From 914663899fcbe4ec67d62fab0a3a65d0a78a36f5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:51 -0400 Subject: [PATCH 083/514] update test cases --- tests/core/saved/test_11.HIPx.out | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/core/saved/test_11.HIPx.out diff --git a/tests/core/saved/test_11.HIPx.out b/tests/core/saved/test_11.HIPx.out new file mode 100644 index 00000000..5a4e8cf0 --- /dev/null +++ b/tests/core/saved/test_11.HIPx.out @@ -0,0 +1,31 @@ +{{<30>1 2015-06-23T18:29:58.980-0500 bock.juniper.net test-program 91066 [42@animal-status
+
The
+
snake
+
is
+
loose
+
+] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.980-0500 bock.juniper.net test-program 91066 [42@animal-consumed
+
My
+
snake
+
ate your
+
hamster
+
+] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.980-0500 bock.juniper.net test-program 91066 [42@animal-talk
+
1
+
+
owl
+
said
+
"e=m\c[2]"
+
+] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + From a0ad565758c1dbf6a08890572131ff5dd3bec330 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:51 -0400 Subject: [PATCH 084/514] update test cases --- tests/core/saved/test_11.HP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.HP.err diff --git a/tests/core/saved/test_11.HP.err b/tests/core/saved/test_11.HP.err new file mode 100644 index 00000000..e69de29b From f92369cc2d47359cb809b4c5c05e274647131087 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:52 -0400 Subject: [PATCH 085/514] update test cases --- tests/core/saved/test_11.HP.out | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/core/saved/test_11.HP.out diff --git a/tests/core/saved/test_11.HP.out b/tests/core/saved/test_11.HP.out new file mode 100644 index 00000000..5892ec89 --- /dev/null +++ b/tests/core/saved/test_11.HP.out @@ -0,0 +1,31 @@ +{{<30>1 2015-06-23T18:29:58.903-0500 bock.juniper.net test-program 90994 [42@animal-status
+
The
+
snake
+
is
+
loose
+
+] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.904-0500 bock.juniper.net test-program 90994 [42@animal-consumed
+
My
+
snake
+
ate your
+
hamster
+
+] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.904-0500 bock.juniper.net test-program 90994 [42@animal-talk
+
1
+
+
owl
+
said
+
"e=m\c[2]"
+
+] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + From 71118cdd4133b2cc9e6c7f1d92a4fe1ec112e13a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:53 -0400 Subject: [PATCH 086/514] update test cases --- tests/core/saved/test_11.J.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.J.err diff --git a/tests/core/saved/test_11.J.err b/tests/core/saved/test_11.J.err new file mode 100644 index 00000000..e69de29b From d05d27d80434757a20d8155eab7767ec71556925 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:53 -0400 Subject: [PATCH 087/514] update test cases --- tests/core/saved/test_11.J.out | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/core/saved/test_11.J.out diff --git a/tests/core/saved/test_11.J.out b/tests/core/saved/test_11.J.out new file mode 100644 index 00000000..adfdb82e --- /dev/null +++ b/tests/core/saved/test_11.J.out @@ -0,0 +1,14 @@ +{{<30>1 2015-06-23T18:29:58.941-0500 bock.juniper.net test-program 91030 [42@animal-status "animal":"snake","state":"loose"] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.941-0500 bock.juniper.net test-program 91030 [42@animal-consumed "animal":"snake","pet":"hamster"] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.941-0500 bock.juniper.net test-program 91030 [42@animal-talk "count":1,"animal":"owl","quote":"\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + +{"__version": "3.1.4", "top": {} +} From 888125f6d722b95ee62439a3df025d895a25167c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:54 -0400 Subject: [PATCH 088/514] update test cases --- tests/core/saved/test_11.JP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.JP.err diff --git a/tests/core/saved/test_11.JP.err b/tests/core/saved/test_11.JP.err new file mode 100644 index 00000000..e69de29b From de52664547fd5461bc7196f6d2d6431e06dcd158 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:54 -0400 Subject: [PATCH 089/514] update test cases --- tests/core/saved/test_11.JP.out | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/core/saved/test_11.JP.out diff --git a/tests/core/saved/test_11.JP.out b/tests/core/saved/test_11.JP.out new file mode 100644 index 00000000..7265412b --- /dev/null +++ b/tests/core/saved/test_11.JP.out @@ -0,0 +1,22 @@ +{{<30>1 2015-06-23T18:29:58.884-0500 bock.juniper.net test-program 90976 [42@animal-status "animal": "snake", +"state": "loose"] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.885-0500 bock.juniper.net test-program 90976 [42@animal-consumed "animal": "snake", +"pet": "hamster"] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.885-0500 bock.juniper.net test-program 90976 [42@animal-talk "count": 1, +"animal": "owl", +"quote": "\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + +{ + "__version": "3.1.4", + "top": { + + } +} From 8b570c1a9edfaa2c852a4e0a8ea6670f2e342e9b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:55 -0400 Subject: [PATCH 090/514] update test cases --- tests/core/saved/test_11.T.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.T.err diff --git a/tests/core/saved/test_11.T.err b/tests/core/saved/test_11.T.err new file mode 100644 index 00000000..e69de29b From fa9edbac0a26bfcb369ee14b40e5915315a42438 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:56 -0400 Subject: [PATCH 091/514] update test cases --- tests/core/saved/test_11.T.out | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/core/saved/test_11.T.out diff --git a/tests/core/saved/test_11.T.out b/tests/core/saved/test_11.T.out new file mode 100644 index 00000000..cae7523b --- /dev/null +++ b/tests/core/saved/test_11.T.out @@ -0,0 +1,12 @@ +{{<30>1 2015-06-23T18:29:58.846-0500 bock.juniper.net test-program 90940 [42@animal-status The snake is loose] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.847-0500 bock.juniper.net test-program 90940 [42@animal-consumed My snake ate your hamster] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.847-0500 bock.juniper.net test-program 90940 [42@animal-talk 1 owl said "e=m\c[2]"] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + From 9b8909c0eedbf77aa50b6b8f291b9658287981be Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:56 -0400 Subject: [PATCH 092/514] update test cases --- tests/core/saved/test_11.X.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.X.err diff --git a/tests/core/saved/test_11.X.err b/tests/core/saved/test_11.X.err new file mode 100644 index 00000000..e69de29b From 9b2fe5e8b7a7805eae3fe22b1d5ea0dc57e6a7e1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:57 -0400 Subject: [PATCH 093/514] update test cases --- tests/core/saved/test_11.X.out | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/core/saved/test_11.X.out diff --git a/tests/core/saved/test_11.X.out b/tests/core/saved/test_11.X.out new file mode 100644 index 00000000..7a277de9 --- /dev/null +++ b/tests/core/saved/test_11.X.out @@ -0,0 +1,13 @@ +{{<30>1 2015-06-23T18:29:58.922-0500 bock.juniper.net test-program 91012 [42@animal-status snakeloose] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.923-0500 bock.juniper.net test-program 91012 [42@animal-consumed snakehamster] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.923-0500 bock.juniper.net test-program 91012 [42@animal-talk 1owl"e=m\c[2]"] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + + \ No newline at end of file From c8f4bc01bb4ac23015ed30d8f4c1552c6bbfe6b6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:58 -0400 Subject: [PATCH 094/514] update test cases --- tests/core/saved/test_11.XP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.XP.err diff --git a/tests/core/saved/test_11.XP.err b/tests/core/saved/test_11.XP.err new file mode 100644 index 00000000..e69de29b From 001d9011f1af12a0753c2620d64573e5609840ae Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:30:58 -0400 Subject: [PATCH 095/514] update test cases --- tests/core/saved/test_11.XP.out | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/core/saved/test_11.XP.out diff --git a/tests/core/saved/test_11.XP.out b/tests/core/saved/test_11.XP.out new file mode 100644 index 00000000..46917e13 --- /dev/null +++ b/tests/core/saved/test_11.XP.out @@ -0,0 +1,21 @@ +{{<30>1 2015-06-23T18:29:58.866-0500 bock.juniper.net test-program 90958 [42@animal-status snake +loose +] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<30>1 2015-06-23T18:29:58.866-0500 bock.juniper.net test-program 90958 [42@animal-consumed snake +hamster +] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T18:29:58.866-0500 bock.juniper.net test-program 90958 [42@animal-talk 1 +owl +"e=m\c[2]" +] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + + + From 9cc7354cc243bd13bd0718f9648478d959b66ff1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 14:41:22 -0400 Subject: [PATCH 096/514] Linux hates (void)ing writev with -Werror=unused-result --- libxo/xo_syslog.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 86202a27..c17335b6 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -90,6 +90,9 @@ static int xo_logfacility = LOG_USER; /* default facility code */ static int xo_logmask = 0xff; /* mask of priorities to be logged */ static pthread_mutex_t xo_syslog_mutex UNUSED = PTHREAD_MUTEX_INITIALIZER; +#define REAL_VOID(_x) \ + do { int really_ignored = _x; if (really_ignored) { }} while (0) + #if 0 #define THREAD_LOCK() \ do { \ @@ -178,7 +181,7 @@ xo_send_syslog (char *full_msg, char *v0_hdr, v->iov_base = newline; v->iov_len = 1; v += 1; - (void) writev(STDERR_FILENO, iov, 3); + REAL_VOID(writev(STDERR_FILENO, iov, 3)); } /* Get connected, output the message to the local logger. */ @@ -260,7 +263,7 @@ xo_send_syslog (char *full_msg, char *v0_hdr, ++v; v->iov_base = crnl; v->iov_len = 2; - (void) writev(fd, iov, 2); + REAL_VOID(writev(fd, iov, 2)); (void) close(fd); } } From b7f326c1aca5c2f17f90dc72eeb45205dc0cae48 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:03:29 -0400 Subject: [PATCH 097/514] Add checks for sysctlbyname, getprogname, and sun_len --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index 81a728c5..b80fa2b5 100644 --- a/configure.ac +++ b/configure.ac @@ -54,10 +54,13 @@ AC_CHECK_FUNCS([sranddev srand strlcpy]) AC_CHECK_FUNCS([fdopen getrusage]) AC_CHECK_FUNCS([gettimeofday ctime]) AC_CHECK_FUNCS([getpass]) +AC_CHECK_FUNCS([getprogname]) AC_CHECK_FUNCS([sysctlbyname]) AC_CHECK_FUNCS([flock]) AC_CHECK_FUNCS([asprintf]) AC_CHECK_FUNCS([__flbf]) +AC_CHECK_FUNCS([sysctlbyname]) + AC_CHECK_HEADERS([dlfcn.h]) AC_CHECK_HEADERS([dlfcn.h]) @@ -91,6 +94,11 @@ AM_CONDITIONAL([HAVE_HUMANIZE_NUMBER], [test "$HAVE_HUMANIZE_NUMBER" = "yes"]) AC_CHECK_LIB([crypto], [MD5_Init]) AM_CONDITIONAL([HAVE_LIBCRYPTO], [test "$HAVE_LIBCRYPTO" != "no"]) +AC_CHECK_MEMBER([struct sockaddr_un.sun_len], + [HAVE_SUN_LEN=yes ; + AC_DEFINE([HAVE_SUN_LEN], [1], [Have struct sockaddr_un.sun_len])], + [HAS_SUN_LEN=no], [[#include ]]) + dnl dnl Some packages need to be checked against version numbers so we dnl define a function here for later use From 08257691c47aac8cc5ae45e226bc46c0d413ffab Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:03:40 -0400 Subject: [PATCH 098/514] add hook for unit test mode --- libxo/xo.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libxo/xo.h b/libxo/xo.h index 98c088c8..592a2bf9 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -410,6 +410,9 @@ xo_close_log (void); int xo_set_logmask (int maskpri); +void +xo_set_unit_test_mode (int value); + void xo_syslog (int priority, const char *id, const char *message, ...); From 8f9b667f40eb753c57ebaeaacad558eac6bc0cbc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:03:52 -0400 Subject: [PATCH 099/514] add unit test mode --- libxo/xo_syslog.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index c17335b6..353be20b 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 1983, 1988, 1993 + * Portions of this file are: + * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,12 +28,7 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)syslog.c 8.5 (Berkeley) 4/29/95"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD$"); - #include #include #include @@ -89,6 +85,7 @@ static const char *xo_logtag = NULL; /* string to tag the entry with */ static int xo_logfacility = LOG_USER; /* default facility code */ static int xo_logmask = 0xff; /* mask of priorities to be logged */ static pthread_mutex_t xo_syslog_mutex UNUSED = PTHREAD_MUTEX_INITIALIZER; +static int xo_unit_test; /* Fake data for unit test */ #define REAL_VOID(_x) \ do { int really_ignored = _x; if (really_ignored) { }} while (0) @@ -466,6 +463,12 @@ xo_syslog_handle_flush (void *opaque UNUSED) return 0; } +void +xo_set_unit_test_mode (int value) +{ + xo_unit_test = value; +} + void xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) { @@ -474,6 +477,10 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) char *tp = NULL, *ep = NULL; char *start_of_msg = NULL, *v0_hdr = NULL; xo_sbuffer_t xb; + static pid_t my_pid; + + if (my_pid == 0) + my_pid = xo_unit_test ? 222 : getpid(); /* Check for invalid bits */ if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { @@ -513,7 +520,13 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) struct tm tm; struct timeval tv; - gettimeofday(&tv, NULL); + /* Unit test hack: fake a fixed time */ + if (xo_unit_test) { + tv.tv_sec = 1435085229; + tv.tv_usec = 123; + } else + gettimeofday(&tv, NULL); + (void) gmtime_r(&tv.tv_sec, &tm); if (xo_logstat & LOG_PERROR) { @@ -525,12 +538,15 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) tp = v0_hdr; ep = v0_hdr + 2048; +#if HAVE_GETPROGNAME /* Linux lacks this */ if (xo_logtag == NULL) xo_logtag = getprogname(); +#endif + if (xo_logtag != NULL) tp += xo_snprintf(tp, ep - tp, "%s", xo_logtag); if (xo_logstat & LOG_PID) - tp += xo_snprintf(tp, ep - tp, "[%d]", getpid()); + tp += xo_snprintf(tp, ep - tp, "[%d]", my_pid); if (xo_logtag) tp += xo_snprintf(tp, ep - tp, ": "); } @@ -561,14 +577,14 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) xo_logtag ?: "-"); /* Add PROCID */ - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%d ", getpid()); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%d ", my_pid); /* * Add MSGID. The user should provide us with a name, which we * prefix with the current enterprise ID, as learned from the kernel. * If the kernel won't tell us, we use the stock/builtin number. */ - char *buf = NULL; + char *buf UNUSED = NULL; const char *eid = xo_syslog_enterprise_id; const char *at_sign = "@"; @@ -585,6 +601,7 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) /* * See if the kernel knows the sysctl for the enterprise ID */ +#ifdef HAVE_SYSCYLBYNAME size_t size = 0; if (sysctlbyname(XO_SYSLOG_ENTERPRISE_ID, NULL, &size, NULL, 0) == 0 && size > 0) { @@ -593,6 +610,7 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) && size > 0) eid = buf; } +#endif /* HAVE_SYSCYLBYNAME */ } xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "[%s%s%s ", From 3579235abaa9311107952db0bf576df41f20f8e4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:40 -0400 Subject: [PATCH 100/514] Add check for HAVE_SUN_LEN (linux) --- libxo/xo_syslog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 353be20b..d074e102 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -306,7 +306,9 @@ xo_connect_log (void) return; } if (xo_logfile != -1 && xo_status == NOCONN) { +#ifdef HAVE_SUN_LEN SyslogAddr.sun_len = sizeof(SyslogAddr); +#endif /* HAVE_SUN_LEN */ SyslogAddr.sun_family = AF_UNIX; /* From 4f55a9b109b71d11cf74346fcd4e6fbd2cd0110a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:44 -0400 Subject: [PATCH 101/514] update test cases --- tests/core/saved/test_11.H.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.H.out b/tests/core/saved/test_11.H.out index b422c1ab..dee4ecf2 100644 --- a/tests/core/saved/test_11.H.out +++ b/tests/core/saved/test_11.H.out @@ -1,12 +1,12 @@ -{{<30>1 2015-06-23T18:29:58.960-0500 bock.juniper.net test-program 91048 [42@animal-status
The
snake
is
loose
] The snake is loose}} +{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status
The
snake
is
loose
] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.961-0500 bock.juniper.net test-program 91048 [42@animal-consumed
My
snake
ate your
hamster
] My snake ate your hamster}} +{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed
My
snake
ate your
hamster
] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.961-0500 bock.juniper.net test-program 91048 [42@animal-talk
1
owl
said
"e=m\c[2]"
] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk
1
owl
said
"e=m\c[2]"
] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From bf7ec37789ecd844aa07c0454152347d93add08e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:45 -0400 Subject: [PATCH 102/514] update test cases --- tests/core/saved/test_11.HIPx.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.HIPx.out b/tests/core/saved/test_11.HIPx.out index 5a4e8cf0..26e0606d 100644 --- a/tests/core/saved/test_11.HIPx.out +++ b/tests/core/saved/test_11.HIPx.out @@ -1,4 +1,4 @@ -{{<30>1 2015-06-23T18:29:58.980-0500 bock.juniper.net test-program 91066 [42@animal-status
+{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status
The
snake
is
@@ -8,7 +8,7 @@ {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.980-0500 bock.juniper.net test-program 91066 [42@animal-consumed
+{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed
My
snake
ate your
@@ -18,7 +18,7 @@ {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.980-0500 bock.juniper.net test-program 91066 [42@animal-talk
+{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk
1
owl
From c75a50891e7a2d0d9ed7c401ba6067e1985d0f28 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:45 -0400 Subject: [PATCH 103/514] update test cases --- tests/core/saved/test_11.HP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.HP.out b/tests/core/saved/test_11.HP.out index 5892ec89..2e9adb30 100644 --- a/tests/core/saved/test_11.HP.out +++ b/tests/core/saved/test_11.HP.out @@ -1,4 +1,4 @@ -{{<30>1 2015-06-23T18:29:58.903-0500 bock.juniper.net test-program 90994 [42@animal-status
+{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status
The
snake
is
@@ -8,7 +8,7 @@ {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.904-0500 bock.juniper.net test-program 90994 [42@animal-consumed
+{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed
My
snake
ate your
@@ -18,7 +18,7 @@ {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.904-0500 bock.juniper.net test-program 90994 [42@animal-talk
+{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk
1
owl
From 1616e35fe71690466d087841cac9789ea90213e0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:46 -0400 Subject: [PATCH 104/514] update test cases --- tests/core/saved/test_11.J.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.J.out b/tests/core/saved/test_11.J.out index adfdb82e..02d994ad 100644 --- a/tests/core/saved/test_11.J.out +++ b/tests/core/saved/test_11.J.out @@ -1,12 +1,12 @@ -{{<30>1 2015-06-23T18:29:58.941-0500 bock.juniper.net test-program 91030 [42@animal-status "animal":"snake","state":"loose"] The snake is loose}} +{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status "animal":"snake","state":"loose"] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.941-0500 bock.juniper.net test-program 91030 [42@animal-consumed "animal":"snake","pet":"hamster"] My snake ate your hamster}} +{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed "animal":"snake","pet":"hamster"] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.941-0500 bock.juniper.net test-program 91030 [42@animal-talk "count":1,"animal":"owl","quote":"\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk "count":1,"animal":"owl","quote":"\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From 3e29f7c974c19de4891bc6fcebfa533994bcca4a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:46 -0400 Subject: [PATCH 105/514] update test cases --- tests/core/saved/test_11.JP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.JP.out b/tests/core/saved/test_11.JP.out index 7265412b..f5eb9206 100644 --- a/tests/core/saved/test_11.JP.out +++ b/tests/core/saved/test_11.JP.out @@ -1,14 +1,14 @@ -{{<30>1 2015-06-23T18:29:58.884-0500 bock.juniper.net test-program 90976 [42@animal-status "animal": "snake", +{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status "animal": "snake", "state": "loose"] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.885-0500 bock.juniper.net test-program 90976 [42@animal-consumed "animal": "snake", +{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed "animal": "snake", "pet": "hamster"] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.885-0500 bock.juniper.net test-program 90976 [42@animal-talk "count": 1, +{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk "count": 1, "animal": "owl", "quote": "\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} {{test-program: }} From 78a4ef8f3fc24e02fdad8eb6caa750829ad30408 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:47 -0400 Subject: [PATCH 106/514] update test cases --- tests/core/saved/test_11.T.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.T.out b/tests/core/saved/test_11.T.out index cae7523b..1dc2b348 100644 --- a/tests/core/saved/test_11.T.out +++ b/tests/core/saved/test_11.T.out @@ -1,12 +1,12 @@ -{{<30>1 2015-06-23T18:29:58.846-0500 bock.juniper.net test-program 90940 [42@animal-status The snake is loose] The snake is loose}} +{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status The snake is loose] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.847-0500 bock.juniper.net test-program 90940 [42@animal-consumed My snake ate your hamster] My snake ate your hamster}} +{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed My snake ate your hamster] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.847-0500 bock.juniper.net test-program 90940 [42@animal-talk 1 owl said "e=m\c[2]"] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk 1 owl said "e=m\c[2]"] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From 15cb4c0e13f7d1fb33ace4fb0bb9f0297fb22451 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:48 -0400 Subject: [PATCH 107/514] update test cases --- tests/core/saved/test_11.X.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.X.out b/tests/core/saved/test_11.X.out index 7a277de9..f5dc45ac 100644 --- a/tests/core/saved/test_11.X.out +++ b/tests/core/saved/test_11.X.out @@ -1,12 +1,12 @@ -{{<30>1 2015-06-23T18:29:58.922-0500 bock.juniper.net test-program 91012 [42@animal-status snakeloose] The snake is loose}} +{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status snakeloose] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.923-0500 bock.juniper.net test-program 91012 [42@animal-consumed snakehamster] My snake ate your hamster}} +{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed snakehamster] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.923-0500 bock.juniper.net test-program 91012 [42@animal-talk 1owl"e=m\c[2]"] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk 1owl"e=m\c[2]"] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From 8fb9ac449d7024523234c66bec77e3ccdfa0d458 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:48 -0400 Subject: [PATCH 108/514] update test cases --- tests/core/saved/test_11.XP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.XP.out b/tests/core/saved/test_11.XP.out index 46917e13..65dd3470 100644 --- a/tests/core/saved/test_11.XP.out +++ b/tests/core/saved/test_11.XP.out @@ -1,16 +1,16 @@ -{{<30>1 2015-06-23T18:29:58.866-0500 bock.juniper.net test-program 90958 [42@animal-status snake +{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status snake loose ] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<30>1 2015-06-23T18:29:58.866-0500 bock.juniper.net test-program 90958 [42@animal-consumed snake +{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed snake hamster ] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:29:58.866-0500 bock.juniper.net test-program 90958 [42@animal-talk 1 +{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk 1 owl "e=m\c[2]" ] 1 owl said "e=m\c[2]"}} From b70e5c0fbd1aa8ecf9306854f3d5e3c0784183d0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:05:49 -0400 Subject: [PATCH 109/514] update test cases --- tests/core/test_11.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/core/test_11.c b/tests/core/test_11.c index af09b536..d65b8fa1 100644 --- a/tests/core/test_11.c +++ b/tests/core/test_11.c @@ -48,18 +48,19 @@ main (int argc, char **argv) xo_set_syslog_handler(test_syslog_open, test_syslog_send, test_syslog_close); - xo_open_log("test-program", LOG_PERROR, LOG_DAEMON); + xo_set_unit_test_mode(1); + xo_open_log("test-program", LOG_PERROR, 0); xo_set_version("3.1.4"); xo_set_syslog_enterprise_id(42); /* SunOs */ xo_open_container_h(NULL, "top"); - xo_syslog(LOG_INFO, "animal-status", + xo_syslog(LOG_INFO | LOG_KERN, "animal-status", "The {:animal} is {:state}", "snake", "loose"); - xo_syslog(LOG_INFO, "animal-consumed", + xo_syslog(LOG_INFO | LOG_MAIL, "animal-consumed", "My {:animal} ate your {:pet}", "snake", "hamster"); - xo_syslog(LOG_NOTICE, "animal-talk", + xo_syslog(LOG_NOTICE | LOG_DAEMON, "animal-talk", "{:count/%d} {:animal} said {:quote}", 1, "owl", "\"e=m\\c[2]\""); xo_close_container_h(NULL, "top"); From c1085b47a22c8c7f092b93a0d5f5588fbe37040d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 15:16:30 -0400 Subject: [PATCH 110/514] Fix call to getprogname --- libxo/xo_syslog.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index d074e102..526d3120 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -515,6 +515,11 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) return; } +#ifdef HAVE_GETPROGNAME + if (xo_logtag == NULL) + xo_logtag = getprogname(); +#endif /* HAVE_GETPROGNAME */ + xo_set_writer(xop, &xb, xo_syslog_handle_write, xo_syslog_handle_close, xo_syslog_handle_flush); @@ -540,11 +545,6 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) tp = v0_hdr; ep = v0_hdr + 2048; -#if HAVE_GETPROGNAME /* Linux lacks this */ - if (xo_logtag == NULL) - xo_logtag = getprogname(); -#endif - if (xo_logtag != NULL) tp += xo_snprintf(tp, ep - tp, "%s", xo_logtag); if (xo_logstat & LOG_PID) @@ -573,8 +573,6 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) hostname[0] ? hostname : "-"); /* Add APP-NAME */ - if (xo_logtag == NULL) - xo_logtag = getprogname(); xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s ", xo_logtag ?: "-"); From 5dba1bac5a91f697f144a12ea210d897deb63915 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 19:04:02 -0400 Subject: [PATCH 111/514] fix 'make clean' --- doc/Makefile.am | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index c0c32719..4ba22f77 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -40,26 +40,27 @@ OXTRADOC_CMD = ${OX_CMD} OUTPUT = libxo-manual -INPUT = libxo.txt +INPUT = libxo EXTRA_DIST = \ - ${INPUT} \ + ${INPUT}.txt \ ${OUTPUT}.html \ ${OUTPUT}.txt doc docs: ${OUTPUT}.txt ${OUTPUT}.html -${OUTPUT}.txt: ${INPUT} ${OXTRADOC} xolint.txt +${OUTPUT}.txt: ${INPUT}.txt ${OXTRADOC} xolint.txt ${OXTRADOC_CMD} -m text -o $@ $< -${OUTPUT}.html: ${INPUT} ${OXTRADOC} ${XML2HTMLBIN} xolint.txt +${OUTPUT}.html: ${INPUT}.txt ${OXTRADOC} ${XML2HTMLBIN} xolint.txt ${OXTRADOC_CMD} -m html -o $@ $< xolint.txt: ${top_srcdir}/xolint/xolint.pl perl ${top_srcdir}/xolint/xolint.pl -D > xolint.txt CLEANFILES = \ -${OUTPUT}.xml \ -${OUTPUT}.txt \ -${OUTPUT}.fxml \ -${OUTPUT}.html +xolint.txt \ +${INPUT}.xml \ +${INPUT}.txt \ +${INPUT}.fxml \ +${INPUT}.html From d6ba49f8707af94df2a07cc71801feee940f8fc5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 19:04:20 -0400 Subject: [PATCH 112/514] add docs for xo_syslog and friends; still need man pages --- doc/libxo.txt | 190 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 3 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index f3173bbe..49a5b10d 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -1539,8 +1539,6 @@ style and usage expectations. } ] -** Additional Functionality - *** Parsing Command-line Arguments (xo_parse_args) The xo_parse_args() function is used to process a program's @@ -1734,6 +1732,192 @@ can do so by calling the xo_no_setlocale() function. void xo_no_setlocale (void); +** Emitting syslog Messages + +syslog is the system logging facility used in the unix world. +Messages are send from commands, applications, and daemons to a +central server, where they are filtered, saved, and forwarded based on +configuration behaviors. + +syslog is an older protocol, originally documented only in unix source +code. By the time RFC 3164 published, variation and mutation left +the leading "" string as only common content. RFC 5424 defines a +new version (version 1) of syslog and introduces structured data into +the messages. Structured data is a set of name/value pairs +transmitted distinctly from the text message, allowing filtering on +precise values instead of regular expressions. + +These name/value pairs are scoped by a two-part identifier; an +enterprise identifier names the party responsible for the message +catalog and a name identifying that message. Enterprise IDs are +defined by IANA, the Internet Assigned Numbers Authority: + +https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers + +Use the ^xo_set_syslog_enterprise_id^() function to set the Enterprise +ID, as needed. + +The message name should follow the conventions in ^good-field-names^, +as should the fields within the message. + + /* Both of these calls are optional */ + xo_set_syslog_enterprise_id(32473); + xo_open_log("my-program", 0, LOG_DAEMON); + + /* Generate a syslog message */ + xo_syslog(LOG_ERR, "upload-failed", + "error <%d> uploading file '{:filename}' " + "as '{:target/%s:%s}'", + code, filename, protocol, remote); + + xo_syslog(LOG_INFO, "poofd-invalid-state", + "state {:current/%u} is invalid {:connection/%u}", + state, conn); + +The developer should be aware that the message name may be used in the +future to allow access to further information, including +documentation. Care should be taken to choose quality, descriptive +names. + +*** Priority, Facility, and Flags @priority@ + +The xo_syslog, xo_vsyslog, and xo_open_log functions accept a set of +flags which provide the priority of the message, the source facility, +and some additional features. These values are OR'd together to +create a single integer argument: + + xo_syslog(LOG_ERR | LOG_AUTH, "login-failed", + "Login failed; user '{:user}' from host '{:address}'", + user, addr); + +These values are defined in . + +The priority value indicates the importance and potential impact of +each message. + +|-------------+-------------------------------------------------------| +| Priority | Description | +|-------------+-------------------------------------------------------| +| LOG_EMERG | A panic condition, normally broadcast to all users | +| LOG_ALERT | A condition that should be corrected immediately | +| LOG_CRIT | Critical conditions | +| LOG_ERR | Generic errors | +| LOG_WARNING | Warning messages | +| LOG_NOTICE | Non-error conditions that might need special handling | +| LOG_INFO | Informational messages | +| LOG_DEBUG | Developer-oriented messages | +|-------------+-------------------------------------------------------| + +The facility value indicates the source of message, in fairly generic +terms. + +|---------------+-------------------------------------------------| +| Facility | Description | +|---------------+-------------------------------------------------| +| LOG_AUTH | The authorization system (e.g. login(1)) | +| LOG_AUTHPRIV | As LOG_AUTH, but logged to a privileged file | +| LOG_CRON | The cron daemon: cron(8) | +| LOG_DAEMON | System daemons, not otherwise explicitly listed | +| LOG_FTP | The file transfer protocol daemons | +| LOG_KERN | Messages generated by the kernel | +| LOG_LPR | The line printer spooling system | +| LOG_MAIL | The mail system | +| LOG_NEWS | The network news system | +| LOG_SECURITY | Security subsystems, such as ipfw(4) | +| LOG_SYSLOG | Messages generated internally by syslogd(8) | +| LOG_USER | Messages generated by user processes (default) | +| LOG_UUCP | The uucp system | +| LOG_LOCAL0..7 | Reserved for local use | +|---------------+-------------------------------------------------| + +In addition to the values listed above, xo_open_log accepts a set of +addition flags requesting specific behaviors. + +|------------+----------------------------------------------------| +| Flag | Description | +|------------+----------------------------------------------------| +| LOG_CONS | If syslogd fails, attempt to write to /dev/console | +| LOG_NDELAY | Open the connection to syslogd(8) immediately | +| LOG_PERROR | Write the message also to standard error output | +| LOG_PID | Log the process id with each message | +|------------+----------------------------------------------------| + +*** xo_syslog + +Use the xo_syslog function to generate syslog messages by calling it +with a log priority and facility, a message name, a format string, and +a set of arguments. The priority/facility argument are discussed +above, as is the message name. + +The format string follows the same conventions as xo_emit's format +string, with each field being rendered as an SD-PARAM pair. + + xo_syslog(LOG_ERR, "poofd-missing-file", + "'{:filename}' not found: {:error/%m}", filename); + + ... [poofd-missing-file@32473 filename="/etc/poofd.conf" + error="Permission denied"] '/etc/poofd.conf' not + found: Permission denied + +*** Support functions + +**** xo_vsyslog + +xo_vsyslog is identical in function to xo_syslog, but takes the set of +arguments using a va_list. + + void my_log (const char *name, const char *fmt, ...) + { + va_list vap; + va_start(vap, fmt); + xo_vsyslog(LOG_ERR, name, fmt, vap); + va_end(vap); + } + +**** xo_open_log + +xo_open_log functions similar to openlog(3), allowing customization of +the program name, the log facility number, and the additional option +flags described in ^priority^. + + void + xo_open_log (const char *ident, int logopt, int facility); + +**** xo_close_log + +xo_close_log functions similar to closelog(3), closing the log file +and releasing any associated resources. + + void + xo_close_log (void); + +**** xo_set_logmask + +xo_set_logmask function similar to setlogmask(3), restricting the set +of generated log event to those whose associated bit is set in +maskpri. Use LOG_MASK(pri) to find the appropriate bit, or +LOG_UPTO(toppri) to create a mask for all priorities up to and +including toppri. + + int + xo_set_logmask (int maskpri); + + Example: + setlogmask(LOG_UPTO(LOG_WARN)); + +**** xo_set_syslog_enterprise_id + +Use the xo_set_syslog_enterprise_id to supply a platform- or +application-specific enterprise id. This value is used in any +future syslog messages. + +Ideally, the operating system should supply a default value via the +"kern.syslog.enterprise_id" sysctl value. Lacking that, the +application should provide a suitable value. + + void + xo_set_syslog_enterprise_id (unsigned short eid); + * The "xo" Utility The "xo" utility allows command line access to the functionality of @@ -2024,7 +2208,7 @@ be lost. libxo is a new implementation of these ideas and is distinct from the previous implementation in JUNOS. -*** What makes a good field name? +*** What makes a good field name? @good-field-names@ To make useful, consistent field names, follow these guidelines: From 67e29d185b6eacd2f688d78bad109a91e24dc6e2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 19:04:23 -0400 Subject: [PATCH 113/514] add docs for xo_syslog and friends; still need man pages --- libxo/xo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxo/xo.h b/libxo/xo.h index 592a2bf9..2cd5178f 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -414,10 +414,10 @@ void xo_set_unit_test_mode (int value); void -xo_syslog (int priority, const char *id, const char *message, ...); +xo_syslog (int priority, const char *name, const char *message, ...); void -xo_vsyslog (int priority, const char *id, const char *message, va_list args); +xo_vsyslog (int priority, const char *name, const char *message, va_list args); typedef void (*xo_syslog_open_t)(void); typedef void (*xo_syslog_send_t)(const char *full_msg, From 2d012f89046eabb2328c5acdbcfb54c27229b065 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 19:04:25 -0400 Subject: [PATCH 114/514] add docs for xo_syslog and friends; still need man pages --- libxo/xo_syslog.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 526d3120..465ad6a6 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -472,7 +472,7 @@ xo_set_unit_test_mode (int value) } void -xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) +xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) { int saved_errno = errno; char tbuf[2048]; @@ -588,13 +588,13 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) const char *eid = xo_syslog_enterprise_id; const char *at_sign = "@"; - if (id == NULL) { - id = "-"; + if (name == NULL) { + name = "-"; eid = at_sign = ""; - } else if (*id == '@') { + } else if (*name == '@') { /* Our convention is to prefix IANA-defined names with an "@" */ - id += 1; + name += 1; eid = at_sign = ""; } else if (eid[0] == '\0') { @@ -614,7 +614,7 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) } xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "[%s%s%s ", - eid, at_sign, id); + name, at_sign, eid); /* * Now for the real content. We make two distinct passes thru the @@ -662,11 +662,11 @@ xo_vsyslog (int pri, const char *id, const char *fmt, va_list vap) * syslog - print message on log file; output is intended for syslogd(8). */ void -xo_syslog (int pri, const char *id, const char *fmt, ...) +xo_syslog (int pri, const char *name, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - xo_vsyslog(pri, id, fmt, ap); + xo_vsyslog(pri, name, fmt, ap); va_end(ap); } From 1b396e583c389b7614044473d3e9eafdc7819f0c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:30 -0400 Subject: [PATCH 115/514] use localtime, not gmtime; have unit-test fix the hostname --- libxo/xo_syslog.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 465ad6a6..72157643 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -530,11 +530,11 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) /* Unit test hack: fake a fixed time */ if (xo_unit_test) { tv.tv_sec = 1435085229; - tv.tv_usec = 123; + tv.tv_usec = 123456; } else gettimeofday(&tv, NULL); - (void) gmtime_r(&tv.tv_sec, &tm); + (void) localtime_r(&tv.tv_sec, &tm); if (xo_logstat & LOG_PERROR) { /* @@ -568,7 +568,11 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) */ char hostname[HOST_NAME_MAX]; hostname[0] = '\0'; - (void) gethostname(hostname, sizeof(hostname)); + if (xo_unit_test) + strcpy(hostname, "worker-host"); + else + (void) gethostname(hostname, sizeof(hostname)); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s ", hostname[0] ? hostname : "-"); From 950e93aa093e798abf031406f22500e9778595d4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:35 -0400 Subject: [PATCH 116/514] update test cases --- tests/core/saved/test_11.H.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.H.out b/tests/core/saved/test_11.H.out index dee4ecf2..24883501 100644 --- a/tests/core/saved/test_11.H.out +++ b/tests/core/saved/test_11.H.out @@ -1,12 +1,12 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status
The
snake
is
loose
] The snake is loose}} +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42
The
snake
is
loose
] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed
My
snake
ate your
hamster
] My snake ate your hamster}} +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42
My
snake
ate your
hamster
] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk
1
owl
said
"e=m\c[2]"
] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42
1
owl
said
"e=m\c[2]"
] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From cf3f590685189d505bcc4e7cb535ffa2ecec2070 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:36 -0400 Subject: [PATCH 117/514] update test cases --- tests/core/saved/test_11.HIPx.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.HIPx.out b/tests/core/saved/test_11.HIPx.out index 26e0606d..c109a2a6 100644 --- a/tests/core/saved/test_11.HIPx.out +++ b/tests/core/saved/test_11.HIPx.out @@ -1,4 +1,4 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status
+{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42
The
snake
is
@@ -8,7 +8,7 @@ {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed
+{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42
My
snake
ate your
@@ -18,7 +18,7 @@ {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk
+{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42
1
owl
From de8ed755d527a9ef8e8ce2b741b9e703b738778c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:36 -0400 Subject: [PATCH 118/514] update test cases --- tests/core/saved/test_11.HP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.HP.out b/tests/core/saved/test_11.HP.out index 2e9adb30..f66e4144 100644 --- a/tests/core/saved/test_11.HP.out +++ b/tests/core/saved/test_11.HP.out @@ -1,4 +1,4 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status
+{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42
The
snake
is
@@ -8,7 +8,7 @@ {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed
+{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42
My
snake
ate your
@@ -18,7 +18,7 @@ {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk
+{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42
1
owl
From 7eb3959cd1a002e43b0b231aeec906706106f9c4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:37 -0400 Subject: [PATCH 119/514] update test cases --- tests/core/saved/test_11.J.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.J.out b/tests/core/saved/test_11.J.out index 02d994ad..c46cf7ef 100644 --- a/tests/core/saved/test_11.J.out +++ b/tests/core/saved/test_11.J.out @@ -1,12 +1,12 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status "animal":"snake","state":"loose"] The snake is loose}} +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42 "animal":"snake","state":"loose"] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed "animal":"snake","pet":"hamster"] My snake ate your hamster}} +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42 "animal":"snake","pet":"hamster"] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk "count":1,"animal":"owl","quote":"\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42 "count":1,"animal":"owl","quote":"\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From b1ff60ef20ff782ad3cf3f74c6a140016948f00e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:38 -0400 Subject: [PATCH 120/514] update test cases --- tests/core/saved/test_11.JP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.JP.out b/tests/core/saved/test_11.JP.out index f5eb9206..c78d42e5 100644 --- a/tests/core/saved/test_11.JP.out +++ b/tests/core/saved/test_11.JP.out @@ -1,14 +1,14 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status "animal": "snake", +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42 "animal": "snake", "state": "loose"] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed "animal": "snake", +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42 "animal": "snake", "pet": "hamster"] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk "count": 1, +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42 "count": 1, "animal": "owl", "quote": "\"e=m\\c[2]\""] 1 owl said "e=m\c[2]"}} {{test-program: }} From c6ac13753cfa83e1a2306c63705e2d6124de0c89 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:38 -0400 Subject: [PATCH 121/514] update test cases --- tests/core/saved/test_11.T.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.T.out b/tests/core/saved/test_11.T.out index 1dc2b348..19ac404a 100644 --- a/tests/core/saved/test_11.T.out +++ b/tests/core/saved/test_11.T.out @@ -1,12 +1,12 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status The snake is loose] The snake is loose}} +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42 The snake is loose] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed My snake ate your hamster] My snake ate your hamster}} +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42 My snake ate your hamster] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk 1 owl said "e=m\c[2]"] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42 1 owl said "e=m\c[2]"] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From ac55384ae719ed729a96b5e60a21cc0b634389da Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:39 -0400 Subject: [PATCH 122/514] update test cases --- tests/core/saved/test_11.X.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.X.out b/tests/core/saved/test_11.X.out index f5dc45ac..5e299849 100644 --- a/tests/core/saved/test_11.X.out +++ b/tests/core/saved/test_11.X.out @@ -1,12 +1,12 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status snakeloose] The snake is loose}} +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42 snakeloose] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed snakehamster] My snake ate your hamster}} +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42 snakehamster] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk 1owl"e=m\c[2]"] 1 owl said "e=m\c[2]"}} +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42 1owl"e=m\c[2]"] 1 owl said "e=m\c[2]"}} {{test-program: }} {{1 owl said "e=m\c[2]"}} From c9560e37856543ace0f5d77905fd052d8b57c95a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:40 -0400 Subject: [PATCH 123/514] update test cases --- tests/core/saved/test_11.XP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_11.XP.out b/tests/core/saved/test_11.XP.out index 65dd3470..a8defae3 100644 --- a/tests/core/saved/test_11.XP.out +++ b/tests/core/saved/test_11.XP.out @@ -1,16 +1,16 @@ -{{<14>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-status snake +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-status@42 snake loose ] The snake is loose}} {{test-program: }} {{The snake is loose}} -{{<22>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-consumed snake +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-consumed@42 snake hamster ] My snake ate your hamster}} {{test-program: }} {{My snake ate your hamster}} -{{<29>1 2015-06-23T18:47:09.000-0500 bock.juniper.net test-program 222 [42@animal-talk 1 +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 [animal-talk@42 1 owl "e=m\c[2]" ] 1 owl said "e=m\c[2]"}} From e9eac85abead4bb43756b77a39d89d61e96df2ce Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 21:13:41 -0400 Subject: [PATCH 124/514] update test cases --- tests/core/test_11.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/tests/core/test_11.c b/tests/core/test_11.c index d65b8fa1..f759cf99 100644 --- a/tests/core/test_11.c +++ b/tests/core/test_11.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -40,16 +41,35 @@ test_syslog_send (const char *full_msg, const char *v0_hdr, int main (int argc, char **argv) { - + int unit_test = 1; + int fire = 0; + const char *tzone = "EST"; + argc = xo_parse_args(argc, argv); if (argc < 0) return 1; - xo_set_syslog_handler(test_syslog_open, test_syslog_send, - test_syslog_close); + for (argc = 1; argv[argc]; argc++) { + if (strcmp(argv[argc], "full") == 0) + unit_test = 0; + else if (strcmp(argv[argc], "fire") == 0) + fire = 1; + else if (strcmp(argv[argc], "tz") == 0) + tzone = argv[++argc]; + } + + setenv("TZ", tzone, 1); + tzset(); + + if (!fire) { + xo_set_syslog_handler(test_syslog_open, test_syslog_send, + test_syslog_close); + } - xo_set_unit_test_mode(1); - xo_open_log("test-program", LOG_PERROR, 0); + if (unit_test) { + xo_set_unit_test_mode(1); + xo_open_log("test-program", LOG_PERROR, 0); + } xo_set_version("3.1.4"); xo_set_syslog_enterprise_id(42); /* SunOs */ From 00b69f4bbc4ebde0c56b2096f20f4b291bb8b111 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 23:20:43 -0400 Subject: [PATCH 125/514] Add check for __isthreaded --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index b80fa2b5..dcc0f733 100644 --- a/configure.ac +++ b/configure.ac @@ -99,6 +99,8 @@ AC_CHECK_MEMBER([struct sockaddr_un.sun_len], AC_DEFINE([HAVE_SUN_LEN], [1], [Have struct sockaddr_un.sun_len])], [HAS_SUN_LEN=no], [[#include ]]) +AC_CHECK_DECLS([__isthreaded], [], [], [#include ]) + dnl dnl Some packages need to be checked against version numbers so we dnl define a function here for later use From bf743384777d0ad4291c38440e54b71e82422ea8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 23:20:56 -0400 Subject: [PATCH 126/514] Churn docs --- doc/libxo.txt | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index 49a5b10d..c9fb4ba1 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -881,7 +881,17 @@ placed in a
with class "text".
extra small
.
-*** "%n" is Not Supported +*** "%m" Is Supported + +libxo supports the '%m' directive, which formats the error message +associated with the current value of "errno". It is the equivalent +of "%s" with the argument strerror(errno). + + xo_emit("{:filename} cannot be opened: {:error/%m}", filename); + xo_emit("{:filename} cannot be opened: {:error/%s}", + filename, strerror(errno)); + +*** "%n" Is Not Supported libxo does not support the '%n' directive. It's a bad idea and we just don't do it. @@ -1734,18 +1744,18 @@ can do so by calling the xo_no_setlocale() function. ** Emitting syslog Messages -syslog is the system logging facility used in the unix world. -Messages are send from commands, applications, and daemons to a -central server, where they are filtered, saved, and forwarded based on -configuration behaviors. - -syslog is an older protocol, originally documented only in unix source -code. By the time RFC 3164 published, variation and mutation left -the leading "" string as only common content. RFC 5424 defines a -new version (version 1) of syslog and introduces structured data into -the messages. Structured data is a set of name/value pairs -transmitted distinctly from the text message, allowing filtering on -precise values instead of regular expressions. +syslog is the system logging facility used throughout the unix world. +Messages are sent from commands, applications, and daemons to a +hierarchy of servers, where they are filtered, saved, and forwarded +based on configuration behaviors. + +syslog is an older protocol, originally documented only in source +code. By the time RFC 3164 published, variation and mutation left the +leading "" string as only common content. RFC 5424 defines a new +version (version 1) of syslog and introduces structured data into the +messages. Structured data is a set of name/value pairs transmitted +distinctly alongside the traditional text message, allowing filtering +on precise values instead of regular expressions. These name/value pairs are scoped by a two-part identifier; an enterprise identifier names the party responsible for the message From 0af5351442968878d2e3c448567e3e2d622aaaef Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 23 Jun 2015 23:21:35 -0400 Subject: [PATCH 127/514] fix xo_syslog_enterprise_id; add __isthreaded test --- libxo/xo_syslog.c | 69 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 72157643..1f09b899 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, June 2015 + */ + /* * Portions of this file are: * Copyright (c) 1983, 1988, 1993 @@ -35,7 +45,6 @@ #include #include #include - #include #include #include @@ -53,18 +62,33 @@ #include "xo.h" /* - * SYSLOG (RFC 5424) requires an enterprise identifier. The kernel should - * support a sysctl to assign a custom enterprise-id. We default to the - * stock IANA assigned Enterprise ID value for FreeBSD. See + * SYSLOG (RFC 5424) requires an enterprise identifier. This turns + * out to be a fickle little issue. For a single-vendor box, the + * system should have a single EID that all software can use. When + * VendorX turns FreeBSD into a product, all software (kernel and + * utilities) should report VendorX's EID. But when software is + * installed on top of an external operating system, the application + * should report it's own EID, distinct from the base OS. + * + * To make this happen, the kernel should support a sysctl to assign a + * custom enterprise-id ("kern.syslog.enterprise_id"). libxo then + * allows an application to set a custom EID to override that system + * wide value, if needed. + * + * We try to set the stock IANA assigned Enterprise ID value for the + * vendors we know about (FreeBSD, macosx), but fallback to the + * "example" EID defined by IANA. See: * https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers */ + #define XO_SYSLOG_ENTERPRISE_ID "kern.syslog.enterprise_id" + #if defined(__FreeBSD__) -#define XO_DEFAULT_EID "2238" +#define XO_DEFAULT_EID 2238 #elseif defined(__macosx__) -#define XO_DEFAULT_EID "63" +#define XO_DEFAULT_EID 63 #else -#define XO_DEFAULT_EID "32473" /* Bail; use "example" number */ +#define XO_DEFAULT_EID 32473 /* Bail; use "example" number */ #endif #ifdef _SC_HOST_NAME_MAX @@ -90,19 +114,18 @@ static int xo_unit_test; /* Fake data for unit test */ #define REAL_VOID(_x) \ do { int really_ignored = _x; if (really_ignored) { }} while (0) -#if 0 -#define THREAD_LOCK() \ - do { \ - if (__isthreaded) _pthread_mutex_lock(&xo_syslog_mutex); \ +#if !defined(HAVE_DECL___ISTHREADED) || !HAVE_DECL___ISTHREADED +#define __isthreaded 1 +#endif + +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) pthread_mutex_lock(&xo_syslog_mutex); \ } while(0) -#define THREAD_UNLOCK() \ - do { \ - if (__isthreaded) _pthread_mutex_unlock(&xo_syslog_mutex); \ +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) pthread_mutex_unlock(&xo_syslog_mutex); \ } while(0) -#else -#define THREAD_LOCK() -#define THREAD_UNLOCK() -#endif static void xo_disconnect_log(void); /* disconnect from syslogd */ static void xo_connect_log(void); /* (re)connect to syslogd */ @@ -602,10 +625,10 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) eid = at_sign = ""; } else if (eid[0] == '\0') { +#ifdef HAVE_SYSCTLBYNAME /* * See if the kernel knows the sysctl for the enterprise ID */ -#ifdef HAVE_SYSCYLBYNAME size_t size = 0; if (sysctlbyname(XO_SYSLOG_ENTERPRISE_ID, NULL, &size, NULL, 0) == 0 && size > 0) { @@ -614,7 +637,13 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) && size > 0) eid = buf; } -#endif /* HAVE_SYSCYLBYNAME */ +#endif /* HAVE_SYSCTLBYNAME */ + + if (eid[0] == '\0') { + /* Fallback to our base default */ + xo_set_syslog_enterprise_id(XO_DEFAULT_EID); + eid = xo_syslog_enterprise_id; + } } xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "[%s%s%s ", From 58bfe1e891d37a3ccc2be5be7591b4910029c232 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 24 Jun 2015 01:46:16 -0400 Subject: [PATCH 128/514] Tweak docs --- doc/libxo.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index c9fb4ba1..72527a39 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -8,7 +8,7 @@ # Phil Shafer, July 2014 # -* libxo +* Overview libxo - A Library for Generating Text, XML, JSON, and HTML Output @@ -101,7 +101,7 @@ as part of the FreeBSD operating system starting with release 11.0. Issues, problems, and bugs should be directly to the issues page on our github site. -* Overview +* Formatting with libxo Most unix commands emit text output aimed at humans. It is designed to be parsed and understood by a user. Humans are gifted at @@ -1549,6 +1549,8 @@ style and usage expectations. } ] +** Support Functions + *** Parsing Command-line Arguments (xo_parse_args) The xo_parse_args() function is used to process a program's From 37f719f7db775e5d81b9a7b5c865faa53966c269 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:41:03 -0400 Subject: [PATCH 129/514] add --with-gettext option --- bin/Zaliases | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/Zaliases b/bin/Zaliases index b8fb5dbe..2c04ae2e 100644 --- a/bin/Zaliases +++ b/bin/Zaliases @@ -6,6 +6,7 @@ set opts=' \ --enable-debug \ --enable-warnings \ --enable-printflike \ +--with-gettext=/opt/local \ --prefix ${HOME}/work/root \ ' set opts=`echo $opts` From 6ace371468afccbadc5c6b86f3ee1f5d6941266c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:41:09 -0400 Subject: [PATCH 130/514] add --with-gettext option --- configure.ac | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index dcc0f733..6160eaa3 100644 --- a/configure.ac +++ b/configure.ac @@ -83,7 +83,7 @@ AC_CHECK_LIB([util], [humanize_number], [HAVE_HUMANIZE_NUMBER=$ac_cv_header_libutil_h], [HAVE_HUMANIZE_NUMBER=no]) -AC_MSG_RESULT(Humanize is :${HAVE_HUMANIZE_NUMBER}:${ac_cv_header_libutil_h}:) +AC_MSG_RESULT(humanize_number results: :${HAVE_HUMANIZE_NUMBER}:${ac_cv_header_libutil_h}:) if test "$HAVE_HUMANIZE_NUMBER" = "yes"; then AC_DEFINE([HAVE_HUMANIZE_NUMBER], [1], [humanize_number(3)]) @@ -91,6 +91,43 @@ fi AM_CONDITIONAL([HAVE_HUMANIZE_NUMBER], [test "$HAVE_HUMANIZE_NUMBER" = "yes"]) +dnl Looking for gettext(), assumably in libintl +AC_ARG_WITH(gettext, + [ --with-gettext=[PFX] Specify location of gettext config], + [GETTEXT_PREFIX=$withval], + [GETTEXT_PREFIX=/usr], +) + +AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) + +_save_cflags="$CFLAGS" +CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" +AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] + [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], + [HAVE_GETTEXT=yes], + [HAVE_GETTEXT=no]) +CFLAGS="$_save_cflags" +AC_MSG_RESULT([$HAVE_GETTEXT]) + +if test "$HAVE_GETTEXT" = "yes"; then + AC_DEFINE([HAVE_GETTEXT], [1], [gettext(3)]) + GETTEXT_CFLAGS="-I${GETTEXT_PREFIX}/include" + GETTEXT_LIBS="-L${GETTEXT_PREFIX}/lib -lintl" +else + GETTEXT_CFLAGS= + GETTEXT_LIBS= +fi +AC_SUBST(GETTEXT_CFLAGS) +AC_SUBST(GETTEXT_LIBS) + +GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin +AC_SUBST(GETTEXT_BINDIR) +GETTEXT_LIBDIR=${GETTEXT_PREFIX}/lib +AC_SUBST(GETTEXT_LIBDIR) + +AM_CONDITIONAL([HAVE_GETTEXT], [test "$HAVE_GETTEXT" = "yes"]) + +dnl Looking for libcrypto.... AC_CHECK_LIB([crypto], [MD5_Init]) AM_CONDITIONAL([HAVE_LIBCRYPTO], [test "$HAVE_LIBCRYPTO" != "no"]) @@ -100,6 +137,7 @@ AC_CHECK_MEMBER([struct sockaddr_un.sun_len], [HAS_SUN_LEN=no], [[#include ]]) AC_CHECK_DECLS([__isthreaded], [], [], [#include ]) +HAVE_ISTHREADED=${ac_cv_have_decl___isthreaded} dnl dnl Some packages need to be checked against version numbers so we @@ -274,6 +312,7 @@ AC_CONFIG_FILES([ doc/Makefile tests/Makefile tests/core/Makefile + tests/gettext/Makefile tests/xo/Makefile packaging/libxo.spec packaging/libxo.rb.base @@ -301,4 +340,6 @@ AC_MSG_NOTICE([summary of build options: printf-like: ${HAVE_PRINTFLIKE:-no} libxo-options: ${LIBXO_OPTS:-no} text-only: ${LIBXO_TEXT_ONLY:-no} + gettext: ${HAVE_GETTEXT:-no} + isthreaded: ${HAVE_ISTHREADED:-no} ]) From ed0ac3e07f801382c156cbb76d5b5e108236aa6d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:41:15 -0400 Subject: [PATCH 131/514] add --with-gettext option --- libxo/Makefile.am | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index d52c4cbb..bd7698ef 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -16,10 +16,16 @@ include ${top_srcdir}/warnings.mk libxoincdir = ${includedir}/libxo -AM_CFLAGS = -I${top_srcdir} ${WARNINGS} +AM_CFLAGS = \ + -I${top_srcdir} \ + ${WARNINGS} \ + ${GETTEXT_CFLAGS} lib_LTLIBRARIES = libxo.la +LIBS = \ + ${GETTEXT_LIBS} + libxoinc_HEADERS = \ xo.h @@ -51,3 +57,7 @@ man_MANS = \ EXTRA_DIST = ${man_MANS} +call-graph: + ${RM} libxo.o + ${MAKE} CC="clang -Xclang -analyze -Xclang \ + -analyzer-checker=debug.ViewCallGraph" libxo.o From fc7656c063a3a4add2389a8704c00c404fa6d42c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:41:34 -0400 Subject: [PATCH 132/514] add hooks into gettext() and friends; checkpointing work --- libxo/libxo.c | 769 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 627 insertions(+), 142 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 2140cf58..12a1fe61 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -39,6 +39,10 @@ #include "xo_humanize.h" #endif /* HAVE_HUMANIZE_NUMBER */ +#ifdef HAVE_GETTEXT +#include +#endif /* HAVE_GETTEXT */ + const char xo_version[] = LIBXO_VERSION; const char xo_version_extra[] = LIBXO_VERSION_EXTRA; @@ -60,7 +64,7 @@ const char xo_version_extra[] = LIBXO_VERSION_EXTRA; typedef struct xo_buffer_s { char *xb_bufp; /* Buffer memory */ char *xb_curp; /* Current insertion point */ - int xb_size; /* Size of buffer */ + unsigned xb_size; /* Size of buffer */ } xo_buffer_t; /* Flags for the stack frame */ @@ -80,17 +84,17 @@ typedef unsigned xo_xsf_flags_t; /* XSF_* flags */ (XSF_NOT_FIRST | XSF_CONTENT | XSF_EMIT | XSF_EMIT_KEY | XSF_EMIT_LEAF_LIST ) /* - * A word about states: We're moving to a finite state machine (FMS) - * approach to help remove fragility from the caller's code. Instead - * of requiring a specific order of calls, we'll allow the caller more + * A word about states: We use a finite state machine (FMS) approach + * to help remove fragility from the caller's code. Instead of + * requiring a specific order of calls, we'll allow the caller more * flexibility and make the library responsible for recovering from - * missed steps. The goal is that the library should not be capable of - * emitting invalid xml or json, but the developer shouldn't need + * missed steps. The goal is that the library should not be capable + * of emitting invalid xml or json, but the developer shouldn't need * to know or understand all the details about these encodings. * - * You can think of states as either states or event, since they + * You can think of states as either states or events, since they * function rather like both. None of the XO_CLOSE_* events will - * persist as states, since their stack frame will be popped. + * persist as states, since the matching stack frame will be popped. * Same is true of XSS_EMIT, which is an event that asks us to * prep for emitting output fields. */ @@ -128,7 +132,11 @@ typedef struct xo_stack_s { char *xs_keys; /* XPath predicate for any key fields */ } xo_stack_t; -/* "colors" refers to fancy ansi codes */ +/* + * libxo supports colors and effects, for those who like them. + * XO_COL_* ("colors") refers to fancy ansi codes, while X__EFF_* + * ("effects") are bits since we need to maintain state. + */ #define XO_COL_DEFAULT 0 #define XO_COL_BLACK 1 #define XO_COL_RED 2 @@ -141,20 +149,19 @@ typedef struct xo_stack_s { #define XO_NUM_COLORS 9 -/* "effects" refers to fancy ansi codes */ /* * Yes, there's no blink. We're civilized. We like users. Blink * isn't something one does to someone you like. Friends don't let * friends use blink. On friends. You know what I mean. Blink is * like, well, it's like bursting into show tunes at a funeral. It's * just not done. Not something anyone wants. And on those rare - * instances where it might actually be appropriate, it's still wrong. - * It's likely done my the wrong person for the wrong reason. Just - * like blink. And if I implemented blink, I'd be like a funeral + * instances where it might actually be appropriate, it's still wrong, + * since it's likely done by the wrong person for the wrong reason. + * Just like blink. And if I implemented blink, I'd be like a funeral * director who adds "Would you like us to burst into show tunes?" on - * the list of questions asking while making funeral arrangements. + * the list of questions asked while making funeral arrangements. * It's formalizing wrongness in the wrong way. And we're just too - * civilized to do that. Hhhmph! + * civilized to do that. Hhhmph! */ #define XO_EFF_RESET (1<<0) #define XO_EFF_NORMAL (1<<1) @@ -174,11 +181,12 @@ typedef struct xo_colors_s { /* * xo_handle_t: this is the principle data structure for libxo. - * It's used as a store for state, options, and content. + * It's used as a store for state, options, content, and all manor + * of other information. */ struct xo_handle_s { xo_xof_flags_t xo_flags; /* Flags */ - unsigned short xo_style; /* XO_STYLE_* value */ + xo_style_t xo_style; /* XO_STYLE_* value */ unsigned short xo_indent; /* Indent level (if pretty) */ unsigned short xo_indent_by; /* Indent amount (tab stop) */ xo_write_func_t xo_write; /* Write callback */ @@ -210,6 +218,7 @@ struct xo_handle_s { xo_buffer_t xo_color_buf; /* HTML: buffer of colors and effects */ char *xo_version; /* Version string */ int xo_errno; /* Saved errno for "%m" */ + char *xo_gt_domain; /* Gettext domain, suitable for dgettext(3) */ }; /* Flags for formatting functions */ @@ -237,6 +246,12 @@ typedef unsigned long xo_xff_flags_t; #define XFF_HN_SPACE (1<<16) /* Humanize: put space before suffix */ #define XFF_HN_DECIMAL (1<<17) /* Humanize: add one decimal place if <10 */ #define XFF_HN_1000 (1<<18) /* Humanize: use 1000, not 1024 */ +#define XFF_GT_FIELD (1<<19) /* Call gettext() on a field */ + +#define XFF_GT_PLURAL (1<<20) /* Call dngettext to find plural form */ + +/* Flags to turn off when we don't want i18n processing */ +#define XFF_GT_FLAGS (XFF_GT_FIELD | XFF_GT_PLURAL) /* * Normal printf has width and precision, which for strings operate as @@ -304,9 +319,11 @@ typedef struct xo_format_s { } xo_format_t; /* - * We keep a default handle to allow callers to avoid having to + * We keep a 'default' handle to allow callers to avoid having to * allocate one. Passing NULL to any of our functions will use - * this default handle. + * this default handle. Most functions have a variant that doesn't + * require a handle at all, since most output is to stdout, which + * the default handle handles handily. */ static xo_handle_t xo_default_handle; static int xo_default_inited; @@ -345,7 +362,7 @@ xo_anchor_clear (xo_handle_t *xop); * trims our code nicely without needing to trampel perfectly readable * code with ifdefs. */ -static inline unsigned short +static inline xo_style_t xo_style (xo_handle_t *xop UNUSED) { #ifdef LIBXO_TEXT_ONLY @@ -409,7 +426,7 @@ xo_buf_reset (xo_buffer_t *xbp) } /* - * Reset the buffer to empty + * See if the buffer to empty */ static int xo_buf_is_empty (xo_buffer_t *xbp) @@ -417,6 +434,15 @@ xo_buf_is_empty (xo_buffer_t *xbp) return (xbp->xb_curp == xbp->xb_bufp); } +/* + * Return the current offset + */ +static unsigned +xo_buf_offset (xo_buffer_t *xbp) +{ + return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0; +} + /* * Initialize the contents of an xo_buffer_t. */ @@ -428,6 +454,34 @@ xo_buf_cleanup (xo_buffer_t *xbp) bzero(xbp, sizeof(*xbp)); } +#ifdef HAVE_GETTEXT +static inline const char * +xo_dgettext (const char *domainname, const char *str) +{ + return dgettext(domainname, str); +} + +static inline const char * +xo_dngettext (const char *domainname, const char *sing, const char *plural, + int n) +{ + return dngettext(domainname, sing, plural, n); +} +#else /* HAVE_GETTEXT */ +static inline const char * +xo_dgettext (const char *domainname UNUSED, const char *str) +{ + return str; +} + +static inline const char * +xo_dngettext (const char *domainname, const char *singular, const char *plural, + int n) +{ + return (n == 1) ? singular : plural; +} +#endif /* HAVE_GETTEXT */ + static int xo_depth_check (xo_handle_t *xop, int depth) { @@ -847,7 +901,8 @@ xo_write (xo_handle_t *xop) if (xbp->xb_curp != xbp->xb_bufp) { xo_buf_append(xbp, "", 1); /* Append ending NUL */ xo_anchor_clear(xop); - rc = xop->xo_write(xop->xo_opaque, xbp->xb_bufp); + if (xop->xo_write) + rc = xop->xo_write(xop->xo_opaque, xbp->xb_bufp); xbp->xb_curp = xbp->xb_bufp; } @@ -1181,7 +1236,9 @@ xo_buf_append_locale (xo_handle_t *xop, xo_buffer_t *xbp, } /* - * Append the given string to the given buffer + * Append the given string to the given buffer, without escaping or + * character set conversion. This is the straight copy to the data + * buffer with no fanciness. */ static void xo_data_append (xo_handle_t *xop, const char *str, int len) @@ -1931,6 +1988,24 @@ xo_get_flags (xo_handle_t *xop) return xop->xo_flags; } +/* + * strndup with a twist: len < 0 means strlen + */ +static char * +xo_strndup (const char *str, int len) +{ + if (len < 0) + len = strlen(str); + + char *cp = xo_realloc(NULL, len + 1); + if (cp) { + memcpy(cp, str, len); + cp[len] = '\0'; + } + + return cp; +} + /** * Record a leading prefix for the XPath we generate. This allows the * generated data to be placed within an XML hierarchy but still have @@ -1952,11 +2027,7 @@ xo_set_leading_xpath (xo_handle_t *xop, const char *path) if (path == NULL) return; - int len = strlen(path); - xop->xo_leading_xpath = xo_realloc(NULL, len + 1); - if (xop->xo_leading_xpath) { - memcpy(xop->xo_leading_xpath, path, len + 1); - } + xop->xo_leading_xpath = xo_strndup(path, -1); } /** @@ -2459,16 +2530,165 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, return 0; } +/* + * Look backwards in a buffer to find a numeric value + */ +static int +xo_buf_find_last_number (xo_buffer_t *xbp, int start_offset) +{ + int rc = 0; /* Fail with zero */ + int digit = 1; + char *sp = xbp->xb_bufp; + char *cp = sp + start_offset; + + while (--cp >= sp) + if (isdigit((int) *cp)) + break; + + for ( ; cp >= sp; cp--) { + if (!isdigit((int) *cp)) + break; + rc += (*cp - '0') * digit; + digit *= 10; + } + + return rc; +} + +static int +xo_count_utf8_cols (const char *str, int len) +{ + int tlen; + wchar_t wc; + int cols = 0; + const char *ep = str + len; + + while (str < ep) { + tlen = xo_utf8_to_wc_len(str); + if (tlen < 0) /* Broken input is very bad */ + return cols; + + wc = xo_utf8_char(str, tlen); + if (wc == (wchar_t) -1) + return cols; + + /* We only print printable characters */ + if (iswprint((wint_t) wc)) { + /* + * Find the width-in-columns of this character, which must be done + * in wide characters, since we lack a mbswidth() function. + */ + int width = wcwidth(wc); + if (width < 0) + width = iswcntrl(wc) ? 0 : 1; + + cols += width; + } + + str += tlen; + } + + return cols; +} + +/* + * This is really _re_formatting, since the normal format code has + * generated a beautiful string into xo_data, starting at + * start_offset. We need to see if it's plural, which means + * comma-separated options, or singular. Then we make the appropriate + * call to d[n]gettext() to get the locale-based version. Note that + * both input and output of gettext() this should be UTF-8. + */ +static int +xo_format_gettext (xo_handle_t *xop, xo_xff_flags_t flags, + int start_offset, int cols, int need_enc) +{ + xo_buffer_t *xbp = &xop->xo_data; + xo_buf_append(xbp, "", 1); /* NUL-terminate it */ + + char *cp = xbp->xb_bufp + start_offset; + int len = xbp->xb_curp - cp; + const char *newstr = NULL; + + /* + * The plural flag asks us to look backwards at the last numeric + * value rendered and disect the string into two pieces. + */ + if (flags & XFF_GT_PLURAL) { + int n = xo_buf_find_last_number(xbp, start_offset); + char *two = memchr(cp, (int) ',', len); + if (two == NULL) { + xo_failure(xop, "no comma in plural gettext field: '%s'", cp); + return cols; + } + + if (two == cp) { + xo_failure(xop, "nothing before comma in plural gettext " + "field: '%s'", cp); + return cols; + } + + if (two == xbp->xb_curp) { + xo_failure(xop, "nothing after comma in plural gettext " + "field: '%s'", cp); + return cols; + } + + *two++ = '\0'; + newstr = xo_dngettext(xop->xo_gt_domain, cp, two, n); + + /* + * If we returned the first string, optimize a bit by + * backing up over comma + */ + if (newstr == cp) { + xbp->xb_curp = two - 2; /* One for comma */ + /* + * If the caller wanted UTF8, we're done; nothing changed, + * but we need to count the columns used. + */ + if (need_enc == XF_ENC_UTF8) + return xo_count_utf8_cols(cp, xbp->xb_curp - cp); + } + + } else { + /* The simple case (singular) */ + newstr = xo_dgettext(xop->xo_gt_domain, cp); + + if (newstr == cp) { + /* If the caller wanted UTF8, we're done; nothing changed */ + if (need_enc == XF_ENC_UTF8) + return cols; + } + } + + /* + * Since the new string string might be in gettext's buffer or + * in the buffer (as the plural form), we make a copy. + */ + int nlen = strlen(newstr); + char *newcopy = alloca(nlen + 1); + memcpy(newcopy, newstr, nlen + 1); + + xbp->xb_curp = xbp->xb_bufp + start_offset; /* Reset the buffer */ + return xo_format_string_direct(xop, xbp, flags, NULL, newcopy, nlen, 0, + need_enc, XF_ENC_UTF8); +} + static void -xo_data_append_content (xo_handle_t *xop, const char *str, int len) +xo_data_append_content (xo_handle_t *xop, const char *str, int len, + xo_xff_flags_t flags) { int cols; int need_enc = (xo_style(xop) == XO_STYLE_TEXT) ? XF_ENC_LOCALE : XF_ENC_UTF8; + int start_offset = xo_buf_offset(&xop->xo_data); - cols = xo_format_string_direct(xop, &xop->xo_data, XFF_UNESCAPE, + cols = xo_format_string_direct(xop, &xop->xo_data, XFF_UNESCAPE | flags, NULL, str, len, -1, need_enc, XF_ENC_UTF8); + if (flags & XFF_GT_FIELD) + cols = xo_format_gettext(xop, flags, start_offset, cols, need_enc); if (xop->xo_flags & XOF_COLUMNS) xop->xo_columns += cols; @@ -2517,8 +2737,13 @@ xo_trim_ws (xo_buffer_t *xbp, int len) return len; } +/* + * Interface to format a single field. The arguments are in xo_vap, + * and the format is in 'fmt'. If 'xbp' is null, we use xop->xo_data; + * this is the most common case. + */ static int -xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, +xo_do_format_field (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, int flen, xo_xff_flags_t flags) { xo_format_t xf; @@ -2528,11 +2753,24 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, unsigned make_output = !(flags & XFF_NO_OUTPUT); int need_enc = (xo_style(xop) == XO_STYLE_TEXT) ? XF_ENC_LOCALE : XF_ENC_UTF8; - + int real_need_enc = need_enc; + int old_cols = xop->xo_columns; + + /* The gettext interface is UTF-8, so we'll need that for now */ + if (flags & XFF_GT_FIELD) + need_enc = XF_ENC_UTF8; + if (xbp == NULL) xbp = &xop->xo_data; + unsigned start_offset = xo_buf_offset(xbp); + for (cp = fmt, ep = fmt + flen; cp < ep; cp++) { + /* + * Since we're starting a new field, save the starting offset. + * We'll need this later for field-related operations. + */ + if (*cp != '%') { add_one: if (xp == NULL) @@ -2734,10 +2972,11 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, } /* - * We can assume all the data we've added is ASCII, so - * the columns and bytes are the same. xo_format_string - * handles all the fancy string conversions and updates - * xo_anchor_columns accordingly. + * We can assume all the non-%s data we've + * added is ASCII, so the columns and bytes are the + * same. xo_format_string handles all the fancy + * string conversions and updates xo_anchor_columns + * accordingly. */ if (xop->xo_flags & XOF_COLUMNS) xop->xo_columns += columns; @@ -2824,6 +3063,7 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, cols = xo_format_string_direct(xop, xbp, flags | XFF_UNESCAPE, NULL, xp, cp - xp, -1, need_enc, XF_ENC_UTF8); + if (xop->xo_flags & XOF_COLUMNS) xop->xo_columns += cols; if (xop->xo_flags & XOF_ANCHOR) @@ -2833,6 +3073,21 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, xp = NULL; } + if (flags & XFF_GT_FIELD) { + /* + * Handle gettext()ing the field by looking up the value + * and then copying it in, while converting to locale, if + * needed. + */ + int new_cols = xo_format_gettext(xop, flags, start_offset, + old_cols, real_need_enc); + + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += new_cols - old_cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += new_cols - old_cols; + } + return 0; } @@ -3024,7 +3279,9 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, elen = strlen(encoding); } - xo_format_data(xop, pbp, encoding, elen, XFF_XML | XFF_ATTR); + xo_xff_flags_t pflags = flags | XFF_XML | XFF_ATTR; + pflags &= ~(XFF_NO_OUTPUT | XFF_ENCODE_ONLY); + xo_do_format_field(xop, pbp, encoding, elen, pflags); xo_buf_append(pbp, "']", 2); @@ -3054,7 +3311,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, * work of formatting it to make sure the args are cleared * from xo_vap. */ - xo_format_data(xop, &xop->xo_data, encoding, elen, + xo_do_format_field(xop, NULL, encoding, elen, flags | XFF_NO_OUTPUT); return; } @@ -3094,9 +3351,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, xop->xo_units_offset = xop->xo_data.xb_curp -xop->xo_data.xb_bufp + 1; } - } - if (name) { if (xop->xo_flags & XOF_XPATH) { int i; xo_stack_t *xsp; @@ -3165,7 +3420,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_format_data(xop, NULL, value, vlen, 0); + xo_do_format_field(xop, NULL, value, vlen, flags); if (flags & XFF_HUMANIZE) { /* @@ -3187,6 +3442,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, if (xo_buf_has_room(xbp, div_len + olen)) { unsigned new_offset = xbp->xb_curp - xbp->xb_bufp; + /* Move the humanized string off to the left */ memmove(xbp->xb_bufp + base_offset + div_len + olen, xbp->xb_bufp + base_offset, new_offset - base_offset); @@ -3222,7 +3478,7 @@ xo_format_text (xo_handle_t *xop, const char *str, int len) static void xo_format_title (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen) + const char *fmt, int flen, xo_xff_flags_t flags) { static char div_open[] = "
"; @@ -3242,7 +3498,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, * enough parsing work to skip over the right bits of xo_vap. */ if (len == 0) - xo_format_data(xop, NULL, fmt, flen, XFF_NO_OUTPUT); + xo_do_format_field(xop, NULL, fmt, flen, flags | XFF_NO_OUTPUT); return; } @@ -3250,10 +3506,8 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, int start = xbp->xb_curp - xbp->xb_bufp; int left = xbp->xb_size - start; int rc; - int need_enc = XF_ENC_LOCALE; if (xo_style(xop) == XO_STYLE_HTML) { - need_enc = XF_ENC_UTF8; xo_line_ensure_open(xop, 0); if (xop->xo_flags & XOF_PRETTY) xo_buf_indent(xop, xop->xo_indent_by); @@ -3274,7 +3528,6 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, newstr[len] = '\0'; if (newstr[len - 1] == 's') { - int cols; char *bp; rc = snprintf(NULL, 0, newfmt, newstr); @@ -3285,14 +3538,8 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, */ bp = alloca(rc + 1); rc = snprintf(bp, rc + 1, newfmt, newstr); - cols = xo_format_string_direct(xop, xbp, 0, NULL, bp, rc, -1, - need_enc, XF_ENC_UTF8); - if (cols > 0) { - if (xop->xo_flags & XOF_COLUMNS) - xop->xo_columns += cols; - if (xop->xo_flags & XOF_ANCHOR) - xop->xo_anchor_columns += cols; - } + + xo_data_append_content(xop, bp, rc, flags); } goto move_along; @@ -3314,9 +3561,9 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, } } else { - xo_format_data(xop, NULL, fmt, flen, 0); + xo_do_format_field(xop, NULL, fmt, flen, flags); - /* xo_format_data moved curp, so we need to reset it */ + /* xo_do_format_field moved curp, so we need to reset it */ rc = xbp->xb_curp - (xbp->xb_bufp + start); xbp->xb_curp = xbp->xb_bufp + start; } @@ -3449,7 +3696,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, save.xhs_columns = xop->xo_columns; save.xhs_anchor_columns = xop->xo_anchor_columns; - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); if (flags & XFF_HUMANIZE) xo_format_humanize(xop, xbp, &save, flags); @@ -3470,7 +3717,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, */ if (flags & XFF_DISPLAY_ONLY) { flags |= XFF_NO_OUTPUT; - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); break; } @@ -3523,7 +3770,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, } xo_data_append(xop, ">", 1); - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); xo_data_append(xop, "", 1); @@ -3534,7 +3781,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, case XO_STYLE_JSON: if (flags & XFF_DISPLAY_ONLY) { flags |= XFF_NO_OUTPUT; - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); break; } @@ -3602,7 +3849,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, if (quote) xo_data_append(xop, "\"", 1); - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); if (quote) xo_data_append(xop, "\"", 1); @@ -3611,7 +3858,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, case XO_STYLE_SDPARAMS: if (flags & XFF_DISPLAY_ONLY) { flags |= XFF_NO_OUTPUT; - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); break; } @@ -3635,23 +3882,56 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, xo_data_escape(xop, name, nlen); xo_data_append(xop, "=\"", 2); - xo_format_data(xop, NULL, format, flen, flags); + xo_do_format_field(xop, NULL, format, flen, flags); xo_data_append(xop, "\" ", 2); break; } } +static void +xo_set_gettext_domain (xo_handle_t *xop, + const char *str, int len, const char *fmt, int flen) +{ + /* Start by discarding previous domain */ + if (xop->xo_gt_domain) { + xo_free(xop->xo_gt_domain); + xop->xo_gt_domain = NULL; + } + + /* An empty {G:} means no domainname */ + if (len == 0 && flen == 0) + return; + + int start_offset = -1; + if (len == 0 && flen != 0) { + /* Need to do format the data to get the domainname from args */ + start_offset = xop->xo_data.xb_curp - xop->xo_data.xb_bufp; + xo_do_format_field(xop, NULL, fmt, flen, 0); + + int end_offset = xop->xo_data.xb_curp - xop->xo_data.xb_bufp; + len = end_offset - start_offset; + str = xop->xo_data.xb_bufp + start_offset; + } + + xop->xo_gt_domain = xo_strndup(str, len); + + /* Reset the current buffer point to avoid emitting the name as output */ + if (start_offset >= 0) + xop->xo_data.xb_curp = xop->xo_data.xb_bufp + start_offset; +} + static void xo_format_content (xo_handle_t *xop, const char *class_name, - const char *xml_tag, int display_only, - const char *str, int len, const char *fmt, int flen) + const char *tag_name, + const char *str, int len, const char *fmt, int flen, + xo_xff_flags_t flags) { switch (xo_style(xop)) { case XO_STYLE_TEXT: - if (len) { - xo_data_append_content(xop, str, len); - } else - xo_format_data(xop, NULL, fmt, flen, 0); + if (len) + xo_data_append_content(xop, str, len, flags); + else + xo_do_format_field(xop, NULL, fmt, flen, flags); break; case XO_STYLE_HTML: @@ -3660,19 +3940,21 @@ xo_format_content (xo_handle_t *xop, const char *class_name, len = flen; } - xo_buf_append_div(xop, class_name, 0, NULL, 0, str, len, NULL, 0); + xo_buf_append_div(xop, class_name, flags, NULL, 0, str, len, NULL, 0); break; case XO_STYLE_XML: - if (xml_tag) { + case XO_STYLE_JSON: + case XO_STYLE_SDPARAMS: + if (tag_name) { if (len == 0) { str = fmt; len = flen; } - xo_open_container_h(xop, xml_tag); - xo_format_value(xop, "message", 7, str, len, NULL, 0, 0); - xo_close_container_h(xop, xml_tag); + xo_open_container_h(xop, tag_name); + xo_format_value(xop, "message", 7, str, len, NULL, 0, flags); + xo_close_container_h(xop, tag_name); } else { /* @@ -3680,23 +3962,10 @@ xo_format_content (xo_handle_t *xop, const char *class_name, * enough parsing work to skip over the right bits of xo_vap. */ if (len == 0) - xo_format_data(xop, NULL, fmt, flen, XFF_NO_OUTPUT); + xo_do_format_field(xop, NULL, fmt, flen, + flags | XFF_NO_OUTPUT); } break; - - case XO_STYLE_JSON: - case XO_STYLE_SDPARAMS: - /* - * 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 (display_only) { - if (len == 0) - xo_format_data(xop, NULL, fmt, flen, XFF_NO_OUTPUT); - break; - } - /* XXX need schem for representing errors in JSON */ - break; } } @@ -4001,7 +4270,7 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, if (len) xo_buf_append(&xb, str, len); else if (flen) - xo_format_data(xop, &xb, fmt, flen, 0); + xo_do_format_field(xop, &xb, fmt, flen, 0); else xo_buf_append(&xb, "reset", 6); /* Default if empty */ @@ -4057,13 +4326,13 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, static void xo_format_units (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen) + const char *fmt, int flen, xo_xff_flags_t flags) { static char units_start_xml[] = " units=\""; static char units_start_html[] = " data-units=\""; if (!(xop->xo_flags & XOF_UNITS_PENDING)) { - xo_format_content(xop, "units", NULL, 1, str, len, fmt, flen); + xo_format_content(xop, "units", NULL, str, len, fmt, flen, flags); return; } @@ -4079,9 +4348,9 @@ xo_format_units (xo_handle_t *xop, const char *str, int len, return; if (len) - xo_data_append(xop, str, len); + xo_data_escape(xop, str, len); else - xo_format_data(xop, NULL, fmt, flen, 0); + xo_do_format_field(xop, NULL, fmt, flen, flags); xo_buf_append(xbp, "\"", 1); @@ -4212,7 +4481,7 @@ xo_anchor_stop (xo_handle_t *xop, const char *str, int len, /* Make a suitable padding field and emit it */ char *buf = alloca(blen); memset(buf, ' ', blen); - xo_format_content(xop, "padding", NULL, 1, buf, blen, NULL, 0); + xo_format_content(xop, "padding", NULL, buf, blen, NULL, 0, 0); if (width < 0) /* Already left justified */ goto done; @@ -4240,6 +4509,32 @@ xo_anchor_stop (xo_handle_t *xop, const char *str, int len, xo_anchor_clear(xop); } +static const char * +xo_class_name (int ftype) +{ + switch (ftype) { + case 'D': return "decoration"; + case 'E': return "error"; + case 'L': return "label"; + case 'N': return "note"; + case 'P': return "padding"; + case 'W': return "warning"; + } + + return NULL; +} + +static const char * +xo_tag_name (int ftype) +{ + switch (ftype) { + case 'E': return "__error"; + case 'W': return "__warning"; + } + + return NULL; +} + static xo_mapping_t xo_role_names[] = { { 'C', "color" }, { 'D', "decoration" }, @@ -4284,6 +4579,9 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) char *newp = NULL; int flush = (xop->xo_flags & XOF_FLUSH) ? 1 : 0; int flush_line = (xop->xo_flags & XOF_FLUSH_LINE) ? 1 : 0; + int gettext_inuse = 0; + int gettext_changed = 0; + char *newfmt = NULL; xop->xo_columns = 0; /* Always reset it */ xop->xo_errno = errno; /* Save for "%m" */ @@ -4339,6 +4637,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) * Modifiers are optional and include the following field types: * 'D': decoration; something non-text and non-data (colons, commmas) * 'E': error message + * 'G': gettext() the entire string; optional domainname as content * 'L': label; text preceding data * 'N': note; text following data * 'P': padding; whitespace @@ -4352,10 +4651,12 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) * 'c': flag: emit a colon after the label * 'd': field is only emitted for display styles (text and html) * 'e': field is only emitted for encoding styles (xml and json) + * 'g': gettext() the field * 'h': humanize a numeric value (only for display styles) * 'k': this field is a key, suitable for XPath predicates * 'l': a leaf-list, a simple list of values * 'n': no quotes around this field + * 'p': the field has plural gettext semantics (ngettext) * 'q': add quotes around this field * 't': trim whitespace around the value * 'w': emit a blank after the label @@ -4364,7 +4665,8 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) * If the encode-fmt is not provided, it defaults to the print-fmt. * If the print-fmt is not provided, it defaults to 's'. */ - unsigned ftype = 0, flags = 0; + unsigned ftype = 0; + xo_xff_flags_t flags = 0; const char *content = NULL, *format = NULL, *encoding = NULL; int clen = 0, flen = 0, elen = 0; @@ -4412,6 +4714,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) case 'C': case 'D': case 'E': + case 'G': case 'L': case 'N': case 'P': @@ -4441,6 +4744,10 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) flags |= XFF_ENCODE_ONLY; break; + case 'g': + flags |= XFF_GT_FIELD; + break; + case 'h': flags |= XFF_HUMANIZE; break; @@ -4457,6 +4764,10 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) flags |= XFF_NOQUOTE; break; + case 'p': + flags |= XFF_GT_PLURAL; + break; + case 'q': flags |= XFF_QUOTE; break; @@ -4537,6 +4848,22 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) return -1; } + /* + * Notes and units need the 'w' flag handled before the content. + */ + if (ftype == 'N' || ftype == 'U') { + if (flags & XFF_WS) { + xo_format_content(xop, "padding", NULL, " ", 1, + NULL, 0, flags); + flags &= ~XFF_WS; + } + if (flags & XFF_COLON) { + xo_failure(xop, "colon modifier on 'N' or 'U' field ignored: " + "%s", fmt); + flags &= ~XFF_COLON; + } + } + if (ftype == 0 || ftype == 'V') { if (format == NULL) { /* Default format for value fields is '%s' */ @@ -4548,49 +4875,67 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) encoding, elen, flags); } else if (ftype == '[') - xo_anchor_start(xop, content, clen, format, flen); + xo_anchor_start(xop, content, clen, format, flen); else if (ftype == ']') - xo_anchor_stop(xop, content, clen, format, flen); + xo_anchor_stop(xop, content, clen, format, flen); else if (ftype == 'C') - xo_format_colors(xop, content, clen, format, flen); + xo_format_colors(xop, content, clen, format, flen); + + else if (ftype == 'G') { + /* + * A {G:domain} field; disect the domain name and translate + * the remaining portion of the input string. If the user + * didn't put the {G:} at the start of the format string, then + * assumably they just want us to translate the rest of it. + * Since gettext returns strings in a static buffer, we make + * a copy in newfmt. + */ + xo_set_gettext_domain(xop, content, clen, format, flen); + + if (!gettext_inuse) { /* Only translate once */ + gettext_inuse = 1; + if (newfmt) { + xo_free(newfmt); + newfmt = NULL; + } - else if (clen || format) { /* Need either content or format */ + const char *tempfmt = xo_dgettext(xop->xo_gt_domain, sp); + if (tempfmt != sp) { + gettext_changed = 1; + newfmt = xo_strndup(tempfmt, -1); + + cp = newfmt; + + /* XXX Need to support field reordering here */ + } + + continue; + } + + } else if (clen || format) { /* Need either content or format */ if (format == NULL) { /* Default format for value fields is '%s' */ format = "%s"; flen = 2; } - if (ftype == 'D') - xo_format_content(xop, "decoration", NULL, 1, - content, clen, format, flen); - else if (ftype == 'E') - xo_format_content(xop, "error", "error", 0, - content, clen, format, flen); - else if (ftype == 'L') - xo_format_content(xop, "label", NULL, 1, - content, clen, format, flen); - else if (ftype == 'N') - xo_format_content(xop, "note", NULL, 1, - content, clen, format, flen); - else if (ftype == 'P') - xo_format_content(xop, "padding", NULL, 1, - content, clen, format, flen); + const char *class_name = xo_class_name(ftype); + if (class_name) + xo_format_content(xop, class_name, xo_tag_name(ftype), + content, clen, format, flen, flags); else if (ftype == 'T') - xo_format_title(xop, content, clen, format, flen); - else if (ftype == 'U') { - if (flags & XFF_WS) - xo_format_content(xop, "padding", NULL, 1, " ", 1, NULL, 0); - xo_format_units(xop, content, clen, format, flen); - } else if (ftype == 'W') - xo_format_content(xop, "warning", "warning", 0, - content, clen, format, flen); + xo_format_title(xop, content, clen, format, flen, flags); + else if (ftype == 'U') + xo_format_units(xop, content, clen, format, flen, flags); + else + xo_failure(xop, "unknown field type: '%c'", ftype); } if (flags & XFF_COLON) - xo_format_content(xop, "decoration", NULL, 1, ":", 1, NULL, 0); - if (ftype != 'U' && (flags & XFF_WS)) - xo_format_content(xop, "padding", NULL, 1, " ", 1, NULL, 0); + xo_format_content(xop, "decoration", NULL, ":", 1, NULL, 0, 0); + + if (flags & XFF_WS) + xo_format_content(xop, "padding", NULL, " ", 1, NULL, 0, 0); cp += sp - basep + 1; if (newp) { @@ -4607,6 +4952,19 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) rc = -1; } + if (newfmt) + xo_free(newfmt); + + /* + * We've carried the gettext domainname inside our handle just for + * convenience, but we need to ensure it doesn't survive across + * xo_emit calls. + */ + if (xop->xo_gt_domain) { + xo_free(xop->xo_gt_domain); + xop->xo_gt_domain = NULL; + } + return (rc < 0) ? rc : (int) xop->xo_columns; } @@ -4748,12 +5106,7 @@ xo_depth_change (xo_handle_t *xop, const char *name, if (name == NULL) name = XO_FAILURE_NAME; - int len = strlen(name) + 1; - char *cp = xo_realloc(NULL, len); - if (cp) { - memcpy(cp, name, len); - xsp->xs_name = cp; - } + xsp->xs_name = xo_strndup(name, -1); } else { /* Pop operation */ if (xop->xo_depth == 0) { @@ -6029,16 +6382,11 @@ xo_set_version_h (xo_handle_t *xop, const char *version UNUSED) break; case XO_STYLE_JSON: - { - /* - * For XML, we record the version string in our handle, and emit - * it in xo_emit_top. - */ - int len = strlen(version) + 1; - xop->xo_version = xo_realloc(NULL, len); - if (xop->xo_version) - memcpy(xop->xo_version, version, len); - } + /* + * For JSON, we record the version string in our handle, and emit + * it in xo_emit_top. + */ + xop->xo_version = xo_strndup(version, -1); break; } } @@ -6048,3 +6396,140 @@ xo_set_version (const char *version) { xo_set_version_h(NULL, version); } + +/* + * Generate a warning. Normally, this is a text message written to + * standard error. If the XOF_WARN_XML flag is set, then we generate + * XMLified content on standard output. + */ +static void +xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code, int check_warn, + const char *fmt, va_list vap) +{ + xop = xo_default(xop); + if (check_warn && !(xop->xo_flags & XOF_WARN)) + return; + + if (fmt == NULL) + return; + + xo_open_marker_h(xop, "xo_emit_warn_hcv"); + xo_open_container_h(xop, as_warning ? "__warn" : "__error"); + + if (xo_program) + xo_emit("{wc:program}", xo_program); + + if (xo_style(xop) == XO_STYLE_XML || xo_style(xop) == XO_STYLE_JSON) { + va_list ap; + xo_handle_t temp; + + bzero(&temp, sizeof(temp)); + temp.xo_style = XO_STYLE_TEXT; + xo_buf_init(&temp.xo_data); + xo_depth_check(&temp, XO_DEPTH); + + va_copy(ap, vap); + (void) xo_emit_hv(&temp, fmt, ap); + va_end(ap); + + 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); + + xo_free(temp.xo_stack); + xo_buf_cleanup(src); + } + + (void) xo_emit_hv(xop, fmt, vap); + + int len = strlen(fmt); + if (len > 0 && fmt[len - 1] != '\n') { + if (code > 0) { + const char *msg = strerror(code); + if (msg) + xo_emit_h(xop, ": {G:strerror}{g:error/%s}", msg); + } + xo_emit("\n"); + } + + xo_close_marker_h(xop, "xo_emit_warn_hcv"); + xo_flush_h(xop); +} + +void +xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(xop, 1, code, 0, fmt, vap); + va_end(vap); +} + +void +xo_emit_warn_c (int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 1, code, 0, fmt, vap); + va_end(vap); +} + +void +xo_emit_warn (const char *fmt, ...) +{ + int code = errno; + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 1, code, 0, fmt, vap); + va_end(vap); +} + +void +xo_emit_warnx (const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 1, -1, 0, fmt, vap); + va_end(vap); +} + +void +xo_emit_err (int eval, const char *fmt, ...) +{ + int code = errno; + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 0, code, 0, fmt, vap); + va_end(vap); + xo_finish(); + exit(eval); +} + +void +xo_emit_errx (int eval, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 0, -1, 0, fmt, vap); + va_end(vap); + xo_finish(); + exit(eval); +} + +void +xo_emit_errc (int eval, int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 0, code, 0, fmt, vap); + va_end(vap); + xo_finish(); + exit(eval); +} From 34f30359c5d6eb6f625d821cd48b7dd4dbf7b905 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:41:36 -0400 Subject: [PATCH 133/514] add hooks into gettext() and friends; checkpointing work --- libxo/xo.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/libxo/xo.h b/libxo/xo.h index 2cd5178f..6dfa112f 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -40,7 +40,7 @@ #endif /* NO_PRINTFLIKE */ /** Formatting types */ -typedef unsigned xo_style_t; +typedef unsigned short xo_style_t; #define XO_STYLE_TEXT 0 /** Generate text output */ #define XO_STYLE_XML 1 /** Generate XML output */ #define XO_STYLE_JSON 2 /** Generate JSON output */ @@ -321,6 +321,27 @@ xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2); void xo_message (const char *fmt, ...) PRINTFLIKE(1, 2); +void +xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...); + +void +xo_emit_warn_c (int code, const char *fmt, ...); + +void +xo_emit_warn (const char *fmt, ...); + +void +xo_emit_warnx (const char *fmt, ...); + +void +xo_emit_err (int eval, const char *fmt, ...); + +void +xo_emit_errx (int eval, const char *fmt, ...); + +void +xo_emit_errc (int eval, int code, const char *fmt, ...); + void xo_no_setlocale (void); From c3ea97005b2f7dd92f2401c1b892e38c5c4b33c4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:41:39 -0400 Subject: [PATCH 134/514] add hooks into gettext() and friends; checkpointing work --- tests/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index c69d5116..42bd437e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,7 +6,7 @@ # using the SOFTWARE, you agree to be bound by the terms of that # LICENSE. -SUBDIRS=core xo +SUBDIRS=core gettext xo test tests: @(cur=`pwd` ; for dir in $(SUBDIRS) ; do \ From ec0286cbd086b36f42014d4d5b08faa8148afdfa Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:42:09 -0400 Subject: [PATCH 135/514] initial version --- tests/gettext/Makefile.am | 209 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 tests/gettext/Makefile.am diff --git a/tests/gettext/Makefile.am b/tests/gettext/Makefile.am new file mode 100644 index 00000000..ad464170 --- /dev/null +++ b/tests/gettext/Makefile.am @@ -0,0 +1,209 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +AM_CFLAGS = \ + -I${top_srcdir} \ + -I${top_srcdir}/libxo \ + ${GETTEXT_CFLAGS} + +# Ick: maintained by hand! +TEST_CASES = \ +gt_01.c + +gt_01_test_SOURCES = gt_01.c + +# TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) + +noinst_PROGRAMS = ${TEST_CASES:.c=.test} + +LDADD = \ + ${top_builddir}/libxo/libxo.la + +if HAVE_HUMANIZE_NUMBER +LDADD += -lutil +endif + +EXTRA_DIST = \ + ${TEST_CASES} \ + ${addprefix saved/, ${TEST_CASES:.c=.T.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.T.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.XP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.XP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.X.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.X.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.J.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.J.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.H.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.H.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HIPx.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HIPx.out}} + +S2O = | ${SED} '1,/@@/d' + +all: + +valgrind: + @echo '## Running the regression tests under Valgrind' + ${MAKE} CHECKER='valgrind -q' tests + +#TEST_TRACE = set -x ; + +TEST_ONE = \ + LIBXO_OPTIONS=:W$$fmt \ + ${CHECKER} ./$$base.test ${TEST_OPTS} \ + > out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O} + +TEST_FORMATS = T XP JP HP X J H HIPx + +test tests: ${bin_PROGRAMS} build-mo-files + @${MKDIR} -p out + -@ ${TEST_TRACE} (for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .c` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${TEST_ONE}; \ + true; \ + done) \ + done) + +one: + -@(test=${TEST_CASE}; data=${TEST_DATA}; ${TEST_ONE} ; true) + +accept: + -@(for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .c` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${CP} out/$$base.$$fmt.out ${srcdir}/saved/$$base.$$fmt.out ; \ + ${CP} out/$$base.$$fmt.err ${srcdir}/saved/$$base.$$fmt.err ; \ + done) \ + done) + +.c.test: + $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -o $@ $< + +CLEANFILES = ${TEST_CASES:.c=.test} +CLEANDIRS = out + +clean-local: + rm -rf ${CLEANDIRS} + +XGETTEXT = xgettext +MSGFMT = msgfmt +MSGMERGE = msgmerge +ECHO = echo +DB=set -x; +XOMSGMERGE = ${MSGMERGE} --no-wrap + +LANGUAGES = \ + es \ + fr \ + pig_latin + +# ldns is fake; used only for a gettext domain +FAKE_FILES = ldns strerror +MO_BASE_FILES = ${TEST_CASES:.c=} ${FAKE_FILES} + +build-pot-files: + for file in ${TEST_CASES} ; do set -x ;\ + base=`${BASENAME} $$file .c` ; \ + ${XGETTEXT} --default-domain=$$base \ + --directory=${srcdir} --no-wrap \ + --add-comments --keyword=xo_emit --keyword=xo_emit_h \ + --keyword=xo_emit_warn \ + -C -E -n --foreign-user \ + -o $$base.pot.new $$base.c ; \ + done + +accept-pot-files: + for base in ${MO_BASE_FILES} ; do set -x ;\ + ${CP} $$base.pot.new ${srcdir}/$$base.pot ; \ + done + +merge-po-files: + for base in ${MO_BASE_FILES} ; do set -x ;\ + for lang in ${LANGUAGES} ; do \ + if [ -f po/$$lang/$$base.po ]; then \ + ${ECHO} "merging $$base.pot into po/$$lang/$$base.po ..." ; \ + if ${XOMSGMERGE} po/$$lang/$$base.po \ + ${srcdir}/$$base.pot \ + -o po/$$lang/$$base.new.po; then \ + ${MV} po/$$lang/$$base.po \ + po/$$lang/$$base.po.old ; \ + ${MV} po/$$lang/$$base.new.po \ + po/$$lang/$$base.po ; \ + else \ + echo "error: msgmerge for $$base failed"; \ + fi ; \ + elif [ -f ${srcdir}/po/$$lang/$$base.po ]; then \ + ${ECHO} "merging (srcdir) $$base.pot into po/$$lang/$$base.po ..." ; \ + if ${XOMSGMERGE} ${srcdir}/po/$$lang/$$base.po \ + ${srcdir}/$$base.pot \ + -o po/$$lang/$$base.new.po; then \ + ${MV} po/$$lang/$$base.po \ + po/$$lang/$$base.po.old ; \ + ${MV} po/$$lang/$$base.new.po \ + po/$$lang/$$base.po ; \ + else \ + echo "error: msgmerge for $$base failed"; \ + fi ; \ + fi ; \ + done ; \ + done + +accept-po-files: + @(for base in ${MO_BASE_FILES} ; do \ + for lang in ${LANGUAGES} ; do \ + if [ -f po/$$lang/$$base.po ]; then \ + ${MKDIR} -p ${srcdir}/po/$$lang ; \ + (${DB} ${CP} po/$$lang/$$base.po ${srcdir}/po/$$lang/$$base.po ); \ + fi ; \ + done ; \ + done) + +new-po-file: + @(for base in ${MO_BASE_FILES} ; do set -x ;\ + for lang in ${LANGUAGES} ; do \ + if [ ! -f po/$$lang/$$base.po ]; then \ + ${MKDIR} -p po/$$lang ; \ + (${DB} ${CP} $$base.pot po/$$lang/$$base.po ); \ + fi ; \ + done ; \ + done + +delta-files: + for base in ${MO_BASE_FILES} ; do set -x ;\ + ${DIFF} ${srcdir}/$$base.pot $$base.pot ; \ + for lang in ${LANGUAGES} ; do \ + if [ -f po/$$lang/$$base.po ] ; then \ + ${DIFF} ${srcdir}/po/$$lang/$$base.po po/$$lang/$$base.po ; \ + fi ; \ + done ; \ + done + +build-mo-files: + @(for base in ${MO_BASE_FILES} ; do \ + for lang in ${LANGUAGES} ; do \ + ${MKDIR} -p po/$$lang/LC_MESSAGES ; \ + if [ -f po/$$lang/$$base.po ] ; then \ + (${DB} ${MSGFMT} -o po/$$lang/LC_MESSAGES/$$base.mo \ + po/$$lang/$$base.po ); \ + elif [ -f ${srcdir}/po/$$lang/$$base.po ]; then \ + (${DB} ${MSGFMT} -o po/$$lang/LC_MESSAGES/$$base.mo \ + ${srcdir}/po/$$lang/$$base.po ;) \ + fi ; \ + done ; \ + done ) From ac3db10baae998af7a5b486975b45c506df796bb Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:12 -0400 Subject: [PATCH 136/514] initial version --- tests/gettext/gt_01.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 tests/gettext/gt_01.c diff --git a/tests/gettext/gt_01.c b/tests/gettext/gt_01.c new file mode 100644 index 00000000..e0de3b7f --- /dev/null +++ b/tests/gettext/gt_01.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, June 2015 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xo.h" + +int +main (int argc, char **argv) +{ + static char domainname[] = "gt_01"; + char path[MAXPATHLEN]; + const char *tzone = "EST"; + const char *lang = "pig_latin"; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + for (argc = 1; argv[argc]; argc++) { + if (strcmp(argv[argc], "tz") == 0) + tzone = argv[++argc]; + else if (strcmp(argv[argc], "lang") == 0) + lang = argv[++argc]; + } + + setenv("LANG", lang, 1); + setenv("TZ", tzone, 1); + + getcwd(path, sizeof(path)); + strncat(path, "/po", 4); + + setlocale(LC_ALL, ""); + bindtextdomain(domainname, path); + bindtextdomain("ldns", path); + bindtextdomain("strerror", path); + textdomain(domainname); + tzset(); + + xo_open_container("top"); + + for (int i = 0; i < 5; i++) + xo_emit("{w:bytes/%d}{Ngp:byte,bytes}\n", i); + + xo_emit("{G:}{L:total} {:total/%u}\n", 1234); + + xo_emit("{G:ldns}Received {:received/%zu} {Ngp:byte,bytes} " + "from {:from/%s}#{:port/%d} in {:time/%d} ms\n", + (size_t) 1234, "foop", 4321, 32); + + struct timeval tv; + tv.tv_sec = 1435085229; + tv.tv_usec = 123456; + + struct tm tm; + (void) gmtime_r(&tv.tv_sec, &tm); + + char date[64]; + strftime(date, sizeof(date), "%+", &tm); + + xo_emit("{G:}Only {:marzlevanes/%d} {Ngp:marzlevane,marzlevanes} " + "are functioning correctly\n", 3); + + xo_emit("{G:}Version {:version} {:date}\n", "1.2.3", date); + + errno = EACCES; + xo_emit_warn("{G:}Unable to {g:verb/objectulate} forward velociping"); + xo_emit_warn("{G:}{g:style/automatic} synchronization of {g:type/cardinal} " + "{g:target/grammeters} failed"); + xo_emit("{G:}{Lwcg:hydrocoptic marzlevanes}{:marzlevanes/%d}\n", 6); + + xo_emit("{G:}{Lwcg:Windings}{g:windings}\n", "lotus-o-delta"); + + xo_close_container("top"); + xo_finish(); + + return 0; +} From 17731ab34e9371a22f68cd5e06cb403cd5bc66bb Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:13 -0400 Subject: [PATCH 137/514] initial version --- tests/gettext/gt_01.pot | 78 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tests/gettext/gt_01.pot diff --git a/tests/gettext/gt_01.pot b/tests/gettext/gt_01.pot new file mode 100644 index 00000000..45d3b39c --- /dev/null +++ b/tests/gettext/gt_01.pot @@ -0,0 +1,78 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gt_01.c:42 +#, c-format +msgid "{w:bytes/%d}{Ngp:byte,bytes}\n" +msgstr "" + +#: gt_01.c:44 +#, c-format +msgid "{L:total} {:total/%u}\n" +msgstr "" + +#: gt_01.c:60 +#, c-format +msgid "Only {:marzlevanes/%d} {Ngp:marzlevane,marzlevanes} are functioning correctly\n" +msgstr "" + +#: gt_01.c:63 +msgid "Version {:version} {:date}\n" +msgstr "" + +#: gt_01.c:66 +msgid "Unable to {g:verb/objectulate} forward velociping" +msgstr "" + +#: gt_01.c:67 +msgid "{g:style/automatic} synchronization of {g:type/cardinal} {g:target/grammeters} failed" +msgstr "" + +#: gt_01.c:69 +#, c-format +msgid "{Lwcg:hydrocoptic marzlevanes}{:marzlevanes/%d}\n" +msgstr "" + +#: gt_01.c:71 +msgid "{Lwcg:Windings}{g:windings}\n" +msgstr "" + +msgid "byte" +msgid_plural "bytes" +msgstr[0] "" +msgstr[1] "" + +msgid "marzlevane" +msgid_plural "marzlevanes" +msgstr[0] "" +msgstr[1] "" + +msgid "lotus-o-delta" +msgstr "" + +msgid "cardinal" +msgstr "" + +msgid "automatic" +msgstr "" + +msgid "grammeters" +msgstr "" + +msgid "objectulate" +msgstr "" From 4cb6dc0f07b1e6194f9670025fe0ecd1c7874f1a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:14 -0400 Subject: [PATCH 138/514] initial version --- tests/gettext/ldns.pot | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/gettext/ldns.pot diff --git a/tests/gettext/ldns.pot b/tests/gettext/ldns.pot new file mode 100644 index 00000000..2f7e147c --- /dev/null +++ b/tests/gettext/ldns.pot @@ -0,0 +1,28 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gt_01.c:46 +#, c-format +msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgstr "" + +msgid "byte" +msgstr "" + +msgid "bytes" +msgstr "" From e2016d414c6c11c1f60aec9124f03ad54e35185d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:14 -0400 Subject: [PATCH 139/514] initial version --- tests/gettext/po/pig_latin/gt_01.po | 84 +++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/gettext/po/pig_latin/gt_01.po diff --git a/tests/gettext/po/pig_latin/gt_01.po b/tests/gettext/po/pig_latin/gt_01.po new file mode 100644 index 00000000..7f9a3c4a --- /dev/null +++ b/tests/gettext/po/pig_latin/gt_01.po @@ -0,0 +1,84 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: libxo unit test\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: 2015-07-01 18:47-0500\n" +"Last-Translator: P.S. \n" +"Language-Team: Self-inflicted \n" +"Language: teo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.1\n" +"Plural-Forms: nplurals=3; plural=(n==0) ? 0 : (n==1) ? 1 : 2;\n" +"X-Poedit-SourceCharset: iso-8859-1\n" + +#: gt_01.c:42 +#, c-format +msgid "{w:bytes/%d}{Ngp:byte,bytes}\n" +msgstr "{w:bytes/%d}{Ngp:ytebay,ytesbay,}\n" + +#: gt_01.c:44 +#, c-format +msgid "{L:total} {:total/%u}\n" +msgstr "{L:otaltay} {:total/%u}\n" + +#: gt_01.c:60 +#, c-format +msgid "Only {:marzlevanes/%d} {Ngp:marzlevane,marzlevanes} are functioning correctly\n" +msgstr "Onlyay {:marzlevanes/%d} {Ngp:arzlevanemay,arzlevanesmay} areyay unctioningfay orrectlycay\n" + +#: gt_01.c:63 +msgid "Version {:version} {:date}\n" +msgstr "Ersionvay {:version} {:date}\n" + +#: gt_01.c:66 +msgid "Unable to {g:verb/objectulate} forward velociping" +msgstr "Nableuay otay {g:verb/objectulate} orwardfay elocipingvay" + +#: gt_01.c:67 +msgid "{g:style/automatic} synchronization of {g:type/cardinal} {g:target/grammeters} failed" +msgstr "{g:style/automatic} ynchronizationsay ofyay {g:type/cardinal} {g:target/grammeters} ailedfay" + +#: gt_01.c:69 +#, c-format +msgid "{Lwcg:hydrocoptic marzlevanes}{:marzlevanes/%d}\n" +msgstr "{Lwcg:ydrocoptichay arzlevanesmay}{:marzlevanes/%d}\n" + +#: gt_01.c:71 +msgid "{Lwcg:Windings}{g:windings}\n" +msgstr "{Lwcg:Indingsway}{g:windings}\n" + +#, c-format +msgid "byte" +msgid_plural "bytes" +msgstr[0] "yebay" +msgstr[1] "yesbay" +msgstr[2] "yezbay" + +#, c-format +msgid "marzlevane" +msgid_plural "marzlevanes" +msgstr[0] "arzlevanemay" +msgstr[1] "arzlevanesmay" +msgstr[2] "arzlevanezmay" + +msgid "lotus-o-delta" +msgstr "otuslay-oyay-eltayay" + +msgid "cardinal" +msgstr "ardinalyay" + +msgid "automatic" +msgstr "automaticyay" + +msgid "grammeters" +msgstr "ammetersgray" + +msgid "objectulate" +msgstr "ectulatobjay" From 86031d5c4c6390e297fecf956cfa963616010b7d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:15 -0400 Subject: [PATCH 140/514] initial version --- tests/gettext/po/pig_latin/ldns.po | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/gettext/po/pig_latin/ldns.po diff --git a/tests/gettext/po/pig_latin/ldns.po b/tests/gettext/po/pig_latin/ldns.po new file mode 100644 index 00000000..19878328 --- /dev/null +++ b/tests/gettext/po/pig_latin/ldns.po @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: libxo unit test\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: 2015-07-01 18:47-0500\n" +"Last-Translator: P.S. \n" +"Language-Team: Self-inflicted \n" +"Language: teo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.1\n" +"Plural-Forms: nplurals=3; plural=(n==0) ? 0 : (n==1) ? 1 : 2;\n" +"X-Poedit-SourceCharset: iso-8859-1\n" + +#: gt_01.c:46 +#, c-format +msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgstr "Eceivedray {:received/%zu} {Ngp:ytebay,ytesbay} omfray {:from/%s}#{:port/%d} inyay {:time/%d} msyay\n" + +msgid "byte" +msgstr "" + +msgid "bytes" +msgstr "" From 56427664c2d7d571345b32cf9277c230e257b199 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:16 -0400 Subject: [PATCH 141/514] initial version --- tests/gettext/po/pig_latin/strerror.po | 462 +++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100644 tests/gettext/po/pig_latin/strerror.po diff --git a/tests/gettext/po/pig_latin/strerror.po b/tests/gettext/po/pig_latin/strerror.po new file mode 100644 index 00000000..f0a27563 --- /dev/null +++ b/tests/gettext/po/pig_latin/strerror.po @@ -0,0 +1,462 @@ +# +# Copyright (c) 1982, 1985, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# List of system errors ala strerror() and sys_errlist +# Phil Shafer , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: libxo test\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: 2015-07-02 00:37-0500\n" +"Language: teo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==0) ? 0 : (n==1) ? 1 : 2;\n" +"Last-Translator: P.S. \n" +"Language-Team: self inflicted \n" +"X-Generator: Poedit 1.8.1\n" +"X-Poedit-SourceCharset: iso-8859-1\n" + +msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgstr "" + +# 0 - ENOERROR +msgid "No error: 0" +msgstr "Onyay erroryay" + +# 1 - EPERM +msgid "Operation not permitted" +msgstr "Operationyay otnay ermittedpay" + +# 2 - ENOENT +msgid "No such file or directory" +msgstr "Onay uchsay ilefay oryay irectoryday" + +# 3 - ESRCH +msgid "No such process" +msgstr "Onay uchsay ocesspray" + +# 4 - EINTR +msgid "Interrupted system call" +msgstr "Interruptedyay ystemsay allcay" + +# 5 - EIO +msgid "Input/output error" +msgstr "Input/outputyay erroryay" + +# 6 - ENXIO +msgid "Device not configured" +msgstr "Eviceday otnay onfiguredcay" + +# 7 - E2BIG +msgid "Argument list too long" +msgstr "Argumentyay istlay ootay onglay" + +# 8 - ENOEXEC +msgid "Exec format error" +msgstr "" + +# 9 - EBADF +msgid "Bad file descriptor" +msgstr "" + +# 10 - ECHILD +msgid "No child processes" +msgstr "" + +# 11 - EDEADLK +msgid "Resource deadlock avoided" +msgstr "" + +# 12 - ENOMEM +msgid "Cannot allocate memory" +msgstr "" + +# 13 - EACCES +msgid "Permission denied" +msgstr "Ermissionpay eniedday" + +# 14 - EFAULT +msgid "Bad address" +msgstr "" + +# 15 - ENOTBLK +msgid "Block device required" +msgstr "" + +# 16 - EBUSY +msgid "Device busy" +msgstr "" + +# 17 - EEXIST +msgid "File exists" +msgstr "" + +# 18 - EXDEV +msgid "Cross-device link" +msgstr "" + +# 19 - ENODEV +msgid "Operation not supported by device" +msgstr "" + +# 20 - ENOTDIR +msgid "Not a directory" +msgstr "" + +# 21 - EISDIR +msgid "Is a directory" +msgstr "" + +# 22 - EINVAL +msgid "Invalid argument" +msgstr "" + +# 23 - ENFILE +msgid "Too many open files in system" +msgstr "" + +# 24 - EMFILE +msgid "Too many open files" +msgstr "" + +# 25 - ENOTTY +msgid "Inappropriate ioctl for device" +msgstr "" + +# 26 - ETXTBSY +msgid "Text file busy" +msgstr "" + +# 27 - EFBIG +msgid "File too large" +msgstr "" + +# 28 - ENOSPC +msgid "No space left on device" +msgstr "" + +# 29 - ESPIPE +msgid "Illegal seek" +msgstr "" + +# 30 - EROFS +msgid "Read-only file system" +msgstr "" + +# 31 - EMLINK +msgid "Too many links" +msgstr "" + +# 32 - EPIPE +msgid "Broken pipe" +msgstr "" + +# +# math software +# +# 33 - EDOM +msgid "Numerical argument out of domain" +msgstr "" + +# 34 - ERANGE +msgid "Result too large" +msgstr "" + +# +# non-blocking and interrupt i/o +# +# 35 - EAGAIN +# 35 - EWOULDBLOCK +msgid "Resource temporarily unavailable" +msgstr "" + +# 36 - EINPROGRESS +msgid "Operation now in progress" +msgstr "" + +# 37 - EALREADY +msgid "Operation already in progress" +msgstr "" + +# +# ipc/network software -- argument errors +# +# 38 - ENOTSOCK +msgid "Socket operation on non-socket" +msgstr "" + +# 39 - EDESTADDRREQ +msgid "Destination address required" +msgstr "" + +# 40 - EMSGSIZE +msgid "Message too long" +msgstr "" + +# 41 - EPROTOTYPE +msgid "Protocol wrong type for socket" +msgstr "" + +# 42 - ENOPROTOOPT +msgid "Protocol not available" +msgstr "" + +# 43 - EPROTONOSUPPORT +msgid "Protocol not supported" +msgstr "" + +# 44 - ESOCKTNOSUPPORT +msgid "Socket type not supported" +msgstr "" + +# 45 - EOPNOTSUPP +msgid "Operation not supported" +msgstr "" + +# 46 - EPFNOSUPPORT +msgid "Protocol family not supported" +msgstr "" + +# 47 - EAFNOSUPPORT +msgid "Address family not supported by protocol family" +msgstr "" + +# 48 - EADDRINUSE +msgid "Address already in use" +msgstr "" + +# 49 - EADDRNOTAVAIL +msgid "Can't assign requested address" +msgstr "" + +# +# ipc/network software -- operational errors +# +# 50 - ENETDOWN +msgid "Network is down" +msgstr "" + +# 51 - ENETUNREACH +msgid "Network is unreachable" +msgstr "" + +# 52 - ENETRESET +msgid "Network dropped connection on reset" +msgstr "" + +# 53 - ECONNABORTED +msgid "Software caused connection abort" +msgstr "" + +# 54 - ECONNRESET +msgid "Connection reset by peer" +msgstr "" + +# 55 - ENOBUFS +msgid "No buffer space available" +msgstr "" + +# 56 - EISCONN +msgid "Socket is already connected" +msgstr "" + +# 57 - ENOTCONN +msgid "Socket is not connected" +msgstr "" + +# 58 - ESHUTDOWN +msgid "Can't send after socket shutdown" +msgstr "" + +# 59 - ETOOMANYREFS +msgid "Too many references: can't splice" +msgstr "" + +# 60 - ETIMEDOUT +msgid "Operation timed out" +msgstr "" + +# 61 - ECONNREFUSED +msgid "Connection refused" +msgstr "" + +# 62 - ELOOP +msgid "Too many levels of symbolic links" +msgstr "" + +# 63 - ENAMETOOLONG +msgid "File name too long" +msgstr "" + +# +# should be rearranged +# +# 64 - EHOSTDOWN +msgid "Host is down" +msgstr "" + +# 65 - EHOSTUNREACH +msgid "No route to host" +msgstr "" + +# 66 - ENOTEMPTY +msgid "Directory not empty" +msgstr "" + +# +# quotas & mush +# +# 67 - EPROCLIM +msgid "Too many processes" +msgstr "" + +# 68 - EUSERS +msgid "Too many users" +msgstr "" + +# 69 - EDQUOT +msgid "Disc quota exceeded" +msgstr "" + +# +# Network File System +# +# 70 - ESTALE +msgid "Stale NFS file handle" +msgstr "" + +# 71 - EREMOTE +msgid "Too many levels of remote in path" +msgstr "" + +# 72 - EBADRPC +msgid "RPC struct is bad" +msgstr "" + +# 73 - ERPCMISMATCH +msgid "RPC version wrong" +msgstr "" + +# 74 - EPROGUNAVAIL +msgid "RPC prog. not avail" +msgstr "" + +# 75 - EPROGMISMATCH +msgid "Program version wrong" +msgstr "" + +# 76 - EPROCUNAVAIL +msgid "Bad procedure for program" +msgstr "" + +# 77 - ENOLCK +msgid "No locks available" +msgstr "" + +# 78 - ENOSYS +msgid "Function not implemented" +msgstr "" + +# 79 - EFTYPE +msgid "Inappropriate file type or format" +msgstr "" + +# 80 - EAUTH +msgid "Authentication error" +msgstr "" + +# 81 - ENEEDAUTH +msgid "Need authenticator" +msgstr "" + +# 82 - EIDRM +msgid "Identifier removed" +msgstr "" + +# 83 - ENOMSG +msgid "No message of desired type" +msgstr "" + +# 84 - EOVERFLOW +msgid "Value too large to be stored in data type" +msgstr "" + +# 85 - ECANCELED +msgid "Operation canceled" +msgstr "" + +# 86 - EILSEQ +msgid "Illegal byte sequence" +msgstr "" + +# 87 - ENOATTR +msgid "Attribute not found" +msgstr "" + +# +# General +# +# 88 - EDOOFUS +msgid "Programming error" +msgstr "" + +# 89 - EBADMSG +msgid "Bad message" +msgstr "" + +# 90 - EMULTIHOP +msgid "Multihop attempted" +msgstr "" + +# 91 - ENOLINK +msgid "Link has been severed" +msgstr "" + +# 92 - EPROTO +msgid "Protocol error" +msgstr "" + +# 93 - ENOTCAPABLE +msgid "Capabilities insufficient" +msgstr "" + +# 94 - ECAPMODE +msgid "Not permitted in capability mode" +msgstr "" + +# 95 - ENOTRECOVERABLE +msgid "State not recoverable" +msgstr "" + +# 96 - EOWNERDEAD +msgid "Previous owner died" +msgstr "" From aa7be8b9d1849a2902c228195639b2b9cd7df8ec Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 15:43:16 -0400 Subject: [PATCH 142/514] initial version --- tests/gettext/strerror.pot | 468 +++++++++++++++++++++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 tests/gettext/strerror.pot diff --git a/tests/gettext/strerror.pot b/tests/gettext/strerror.pot new file mode 100644 index 00000000..c7d38cb2 --- /dev/null +++ b/tests/gettext/strerror.pot @@ -0,0 +1,468 @@ +# +# Copyright (c) 1982, 1985, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# List of system errors ala strerror() and sys_errlist +# Phil Shafer , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgstr "" + +# 0 - ENOERROR +msgid "No error: 0" +msgstr "" + +# 1 - EPERM +msgid "Operation not permitted" +msgstr "" + +# 2 - ENOENT +msgid "No such file or directory" +msgstr "" + +# 3 - ESRCH +msgid "No such process" +msgstr "" + +# 4 - EINTR +msgid "Interrupted system call" +msgstr "" + +# 5 - EIO +msgid "Input/output error" +msgstr "" + +# 6 - ENXIO +msgid "Device not configured" +msgstr "" + +# 7 - E2BIG +msgid "Argument list too long" +msgstr "" + +# 8 - ENOEXEC +msgid "Exec format error" +msgstr "" + +# 9 - EBADF +msgid "Bad file descriptor" +msgstr "" + +# 10 - ECHILD +msgid "No child processes" +msgstr "" + +# 11 - EDEADLK +msgid "Resource deadlock avoided" +msgstr "" + +# 12 - ENOMEM +msgid "Cannot allocate memory" +msgstr "" + +# 13 - EACCES +msgid "Permission denied" +msgstr "" + +# 14 - EFAULT +msgid "Bad address" +msgstr "" + +# 15 - ENOTBLK +msgid "Block device required" +msgstr "" + +# 16 - EBUSY +msgid "Device busy" +msgstr "" + +# 17 - EEXIST +msgid "File exists" +msgstr "" + +# 18 - EXDEV +msgid "Cross-device link" +msgstr "" + +# 19 - ENODEV +msgid "Operation not supported by device" +msgstr "" + +# 20 - ENOTDIR +msgid "Not a directory" +msgstr "" + +# 21 - EISDIR +msgid "Is a directory" +msgstr "" + +# 22 - EINVAL +msgid "Invalid argument" +msgstr "" + +# 23 - ENFILE +msgid "Too many open files in system" +msgstr "" + +# 24 - EMFILE +msgid "Too many open files" +msgstr "" + +# 25 - ENOTTY +msgid "Inappropriate ioctl for device" +msgstr "" + +# 26 - ETXTBSY +msgid "Text file busy" +msgstr "" + +# 27 - EFBIG +msgid "File too large" +msgstr "" + +# 28 - ENOSPC +msgid "No space left on device" +msgstr "" + +# 29 - ESPIPE +msgid "Illegal seek" +msgstr "" + +# 30 - EROFS +msgid "Read-only file system" +msgstr "" + +# 31 - EMLINK +msgid "Too many links" +msgstr "" + +# 32 - EPIPE +msgid "Broken pipe" +msgstr "" + +# +# math software +# + +# 33 - EDOM +msgid "Numerical argument out of domain" +msgstr "" + +# 34 - ERANGE +msgid "Result too large" +msgstr "" + +# +# non-blocking and interrupt i/o +# + +# 35 - EAGAIN +# 35 - EWOULDBLOCK +msgid "Resource temporarily unavailable" +msgstr "" + +# 36 - EINPROGRESS +msgid "Operation now in progress" +msgstr "" + +# 37 - EALREADY +msgid "Operation already in progress" +msgstr "" + + +# +# ipc/network software -- argument errors +# + +# 38 - ENOTSOCK +msgid "Socket operation on non-socket" +msgstr "" + +# 39 - EDESTADDRREQ +msgid "Destination address required" +msgstr "" + +# 40 - EMSGSIZE +msgid "Message too long" +msgstr "" + +# 41 - EPROTOTYPE +msgid "Protocol wrong type for socket" +msgstr "" + +# 42 - ENOPROTOOPT +msgid "Protocol not available" +msgstr "" + +# 43 - EPROTONOSUPPORT +msgid "Protocol not supported" +msgstr "" + +# 44 - ESOCKTNOSUPPORT +msgid "Socket type not supported" +msgstr "" + +# 45 - EOPNOTSUPP +msgid "Operation not supported" +msgstr "" + +# 46 - EPFNOSUPPORT +msgid "Protocol family not supported" +msgstr "" + +# 47 - EAFNOSUPPORT +msgid "Address family not supported by protocol family" +msgstr "" + +# 48 - EADDRINUSE +msgid "Address already in use" +msgstr "" + +# 49 - EADDRNOTAVAIL +msgid "Can't assign requested address" +msgstr "" + +# +# ipc/network software -- operational errors +# + +# 50 - ENETDOWN +msgid "Network is down" +msgstr "" + +# 51 - ENETUNREACH +msgid "Network is unreachable" +msgstr "" + +# 52 - ENETRESET +msgid "Network dropped connection on reset" +msgstr "" + +# 53 - ECONNABORTED +msgid "Software caused connection abort" +msgstr "" + +# 54 - ECONNRESET +msgid "Connection reset by peer" +msgstr "" + +# 55 - ENOBUFS +msgid "No buffer space available" +msgstr "" + +# 56 - EISCONN +msgid "Socket is already connected" +msgstr "" + +# 57 - ENOTCONN +msgid "Socket is not connected" +msgstr "" + +# 58 - ESHUTDOWN +msgid "Can't send after socket shutdown" +msgstr "" + +# 59 - ETOOMANYREFS +msgid "Too many references: can't splice" +msgstr "" + +# 60 - ETIMEDOUT +msgid "Operation timed out" +msgstr "" + +# 61 - ECONNREFUSED +msgid "Connection refused" +msgstr "" + +# 62 - ELOOP +msgid "Too many levels of symbolic links" +msgstr "" + +# 63 - ENAMETOOLONG +msgid "File name too long" +msgstr "" + +# +# should be rearranged +# + +# 64 - EHOSTDOWN +msgid "Host is down" +msgstr "" + +# 65 - EHOSTUNREACH +msgid "No route to host" +msgstr "" + +# 66 - ENOTEMPTY +msgid "Directory not empty" +msgstr "" + +# +# quotas & mush +# + +# 67 - EPROCLIM +msgid "Too many processes" +msgstr "" + +# 68 - EUSERS +msgid "Too many users" +msgstr "" + +# 69 - EDQUOT +msgid "Disc quota exceeded" +msgstr "" + +# +# Network File System +# + +# 70 - ESTALE +msgid "Stale NFS file handle" +msgstr "" + +# 71 - EREMOTE +msgid "Too many levels of remote in path" +msgstr "" + +# 72 - EBADRPC +msgid "RPC struct is bad" +msgstr "" + +# 73 - ERPCMISMATCH +msgid "RPC version wrong" +msgstr "" + +# 74 - EPROGUNAVAIL +msgid "RPC prog. not avail" +msgstr "" + +# 75 - EPROGMISMATCH +msgid "Program version wrong" +msgstr "" + +# 76 - EPROCUNAVAIL +msgid "Bad procedure for program" +msgstr "" + +# 77 - ENOLCK +msgid "No locks available" +msgstr "" + +# 78 - ENOSYS +msgid "Function not implemented" +msgstr "" + +# 79 - EFTYPE +msgid "Inappropriate file type or format" +msgstr "" + +# 80 - EAUTH +msgid "Authentication error" +msgstr "" + +# 81 - ENEEDAUTH +msgid "Need authenticator" +msgstr "" + +# 82 - EIDRM +msgid "Identifier removed" +msgstr "" + +# 83 - ENOMSG +msgid "No message of desired type" +msgstr "" + +# 84 - EOVERFLOW +msgid "Value too large to be stored in data type" +msgstr "" + +# 85 - ECANCELED +msgid "Operation canceled" +msgstr "" + +# 86 - EILSEQ +msgid "Illegal byte sequence" +msgstr "" + +# 87 - ENOATTR +msgid "Attribute not found" +msgstr "" + +# +# General +# + +# 88 - EDOOFUS +msgid "Programming error" +msgstr "" + +# 89 - EBADMSG +msgid "Bad message" +msgstr "" + +# 90 - EMULTIHOP +msgid "Multihop attempted" +msgstr "" + +# 91 - ENOLINK +msgid "Link has been severed" +msgstr "" + +# 92 - EPROTO +msgid "Protocol error" +msgstr "" + +# 93 - ENOTCAPABLE +msgid "Capabilities insufficient" +msgstr "" + +# 94 - ECAPMODE +msgid "Not permitted in capability mode" +msgstr "" + +# 95 - ENOTRECOVERABLE +msgid "State not recoverable" +msgstr "" + +# 96 - EOWNERDEAD +msgid "Previous owner died" +msgstr "" From 98f732b697d915e3e2fdf068d55eba88f05f8c1e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:01 -0400 Subject: [PATCH 143/514] fix truncated output (gettext); use "__warning" consistently --- libxo/libxo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 12a1fe61..d99d5933 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -2604,7 +2604,11 @@ xo_format_gettext (xo_handle_t *xop, xo_xff_flags_t flags, int start_offset, int cols, int need_enc) { xo_buffer_t *xbp = &xop->xo_data; - xo_buf_append(xbp, "", 1); /* NUL-terminate it */ + + if (!xo_buf_has_room(xbp, 1)) + return cols; + + xbp->xb_curp[0] = '\0'; /* NUL-terminate the input string */ char *cp = xbp->xb_bufp + start_offset; int len = xbp->xb_curp - cp; @@ -6414,7 +6418,7 @@ xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code, int check_warn, return; xo_open_marker_h(xop, "xo_emit_warn_hcv"); - xo_open_container_h(xop, as_warning ? "__warn" : "__error"); + xo_open_container_h(xop, as_warning ? "__warning" : "__error"); if (xo_program) xo_emit("{wc:program}", xo_program); From 88f3519a6c5e8de52f15636ea32a8bd23ee946f2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:07 -0400 Subject: [PATCH 144/514] 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 5af165bc..6af25ab1 100644 --- a/tests/core/saved/test_02.J.out +++ b/tests/core/saved/test_02.J.out @@ -1,2 +1,2 @@ -{"top": {"data": {"length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40,"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":30,"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","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>"}}} +{"top": {"data": {"length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40,"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":30,"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! <>!,\"!<>"}}} } From 16673bb91b25c6f90d6ca63de56ff297f7c7564f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:08 -0400 Subject: [PATCH 145/514] 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 aa916aa7..3a31972e 100644 --- a/tests/core/saved/test_02.JP.out +++ b/tests/core/saved/test_02.JP.out @@ -52,6 +52,18 @@ "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": { From 826dc615af06dd167aedfd9ad3c696a6bdfb8a02 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:09 -0400 Subject: [PATCH 146/514] update test cases --- tests/core/saved/test_02.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index b9f63ba9..a3510cda 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -2,5 +2,5 @@ abcdef: Bad file descriptor improper use of profanity; ten yard penalty; first down abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down -20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtestthis is an errortwo more errorsthis is an warningtwo more warnings104improper use of profanity; ten yard penalty; first down +20304010203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-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! <>!,"!<> \ No newline at end of file From 735391d9e3fe3dd2757991e06936c0db50de9c3e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:10 -0400 Subject: [PATCH 147/514] update test cases --- tests/core/saved/test_02.XP.out | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index 4fc5bda5..9bef58e0 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -57,18 +57,18 @@ test5000 ten-longx xtest - + <__error> this is an error - - + + <__error> two more errors - - + + <__warning> this is an warning - - + + <__warning> two more warnings - + 10 4 improper use of profanity; ten yard penalty; first down From 1df8e5116decdb9d6b291884546581ae282118d4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:10 -0400 Subject: [PATCH 148/514] update test cases --- tests/gettext/Makefile.am | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/gettext/Makefile.am b/tests/gettext/Makefile.am index ad464170..855ec2c7 100644 --- a/tests/gettext/Makefile.am +++ b/tests/gettext/Makefile.am @@ -49,6 +49,18 @@ EXTRA_DIST = \ ${addprefix saved/, ${TEST_CASES:.c=.HIPx.err}} \ ${addprefix saved/, ${TEST_CASES:.c=.HIPx.out}} +POT_FILES = \ + gt_01.pot \ + ldns.pot \ + strerror.pot + +PO_FILES = \ + po/pig_latin/gt_01.po \ + po/pig_latin/ldns.po \ + po/pig_latin/strerror.po + +EXTRA_DIST += ${POT_FILES} ${PO_FILES} + S2O = | ${SED} '1,/@@/d' all: From b3bb7174557d195c294d5544c283feb5acd1f40d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:11 -0400 Subject: [PATCH 149/514] update test cases --- tests/gettext/saved/gt_01.H.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.H.err diff --git a/tests/gettext/saved/gt_01.H.err b/tests/gettext/saved/gt_01.H.err new file mode 100644 index 00000000..e69de29b From 3b55e875119aeb028a9deab1615827da64917395 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:12 -0400 Subject: [PATCH 150/514] update test cases --- tests/gettext/saved/gt_01.H.out | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/gettext/saved/gt_01.H.out diff --git a/tests/gettext/saved/gt_01.H.out b/tests/gettext/saved/gt_01.H.out new file mode 100644 index 00000000..a68b4c91 --- /dev/null +++ b/tests/gettext/saved/gt_01.H.out @@ -0,0 +1 @@ +
0
yebay
1
yesbay
2
yezbay
3
yezbay
4
yezbay
otaltay
1234
Eceivedray
1234
ytesbay
omfray
foop
#
4321
inyay
32
msyay
Onlyay
3
arzlevanesmay
areyay unctioningfay orrectlycay
Ersionvay
1.2.3
Tue Jun 23 18:47:09 UTC 2015
gt_01.test
:
Nableuay otay
ectulatobjay
orwardfay elocipingvay
:
Ermissionpay eniedday
gt_01.test
:
automaticyay
ynchronizationsay ofyay
ardinalyay
ammetersgray
ailedfay
:
Ermissionpay eniedday
ydrocoptichay arzlevanesmay
:
6
Indingsway
:
otuslay-oyay-eltayay
\ No newline at end of file From bf1cddb85f1d75d6b87d19500efe9d095e37c74c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:12 -0400 Subject: [PATCH 151/514] update test cases --- tests/gettext/saved/gt_01.HIPx.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.HIPx.err diff --git a/tests/gettext/saved/gt_01.HIPx.err b/tests/gettext/saved/gt_01.HIPx.err new file mode 100644 index 00000000..e69de29b From 84b17f0a000b333090a7cf0558d4ccf2123654d0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:13 -0400 Subject: [PATCH 152/514] update test cases --- tests/gettext/saved/gt_01.HIPx.out | 91 ++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/gettext/saved/gt_01.HIPx.out diff --git a/tests/gettext/saved/gt_01.HIPx.out b/tests/gettext/saved/gt_01.HIPx.out new file mode 100644 index 00000000..122c33ef --- /dev/null +++ b/tests/gettext/saved/gt_01.HIPx.out @@ -0,0 +1,91 @@ +
+
0
+
+
yebay
+
+
+
1
+
+
yesbay
+
+
+
2
+
+
yezbay
+
+
+
3
+
+
yezbay
+
+
+
4
+
+
yezbay
+
+
+
otaltay
+
+
1234
+
+
+
Eceivedray
+
1234
+
+
ytesbay
+
omfray
+
foop
+
#
+
4321
+
inyay
+
32
+
msyay
+
+
+
Onlyay
+
3
+
+
arzlevanesmay
+
areyay unctioningfay orrectlycay
+
+
+
Ersionvay
+
1.2.3
+
+
Tue Jun 23 18:47:09 UTC 2015
+
+
+
gt_01.test
+
:
+
+
Nableuay otay
+
ectulatobjay
+
orwardfay elocipingvay
+
:
+
Ermissionpay eniedday
+
+
+
gt_01.test
+
:
+
+
automaticyay
+
ynchronizationsay ofyay
+
ardinalyay
+
+
ammetersgray
+
ailedfay
+
:
+
Ermissionpay eniedday
+
+
+
ydrocoptichay arzlevanesmay
+
:
+
+
6
+
+
+
Indingsway
+
:
+
+
otuslay-oyay-eltayay
+
From db4cd3e58de39f1b0770914771097051457d0060 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:14 -0400 Subject: [PATCH 153/514] update test cases --- tests/gettext/saved/gt_01.HP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.HP.err diff --git a/tests/gettext/saved/gt_01.HP.err b/tests/gettext/saved/gt_01.HP.err new file mode 100644 index 00000000..e69de29b From 77bc86f3d35ffe2c7ee44e8f9068cfd3a4dfef00 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:14 -0400 Subject: [PATCH 154/514] update test cases --- tests/gettext/saved/gt_01.HP.out | 91 ++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/gettext/saved/gt_01.HP.out diff --git a/tests/gettext/saved/gt_01.HP.out b/tests/gettext/saved/gt_01.HP.out new file mode 100644 index 00000000..a77c10ef --- /dev/null +++ b/tests/gettext/saved/gt_01.HP.out @@ -0,0 +1,91 @@ +
+
0
+
+
yebay
+
+
+
1
+
+
yesbay
+
+
+
2
+
+
yezbay
+
+
+
3
+
+
yezbay
+
+
+
4
+
+
yezbay
+
+
+
otaltay
+
+
1234
+
+
+
Eceivedray
+
1234
+
+
ytesbay
+
omfray
+
foop
+
#
+
4321
+
inyay
+
32
+
msyay
+
+
+
Onlyay
+
3
+
+
arzlevanesmay
+
areyay unctioningfay orrectlycay
+
+
+
Ersionvay
+
1.2.3
+
+
Tue Jun 23 18:47:09 UTC 2015
+
+
+
gt_01.test
+
:
+
+
Nableuay otay
+
ectulatobjay
+
orwardfay elocipingvay
+
:
+
Ermissionpay eniedday
+
+
+
gt_01.test
+
:
+
+
automaticyay
+
ynchronizationsay ofyay
+
ardinalyay
+
+
ammetersgray
+
ailedfay
+
:
+
Ermissionpay eniedday
+
+
+
ydrocoptichay arzlevanesmay
+
:
+
+
6
+
+
+
Indingsway
+
:
+
+
otuslay-oyay-eltayay
+
From c7c3fdda3fbdcdd5785d9c5eabc4db4da5f38bec Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:15 -0400 Subject: [PATCH 155/514] update test cases --- tests/gettext/saved/gt_01.J.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.J.err diff --git a/tests/gettext/saved/gt_01.J.err b/tests/gettext/saved/gt_01.J.err new file mode 100644 index 00000000..e69de29b From 79d2086eacae523c57dfb1c0455bfd5436916315 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:16 -0400 Subject: [PATCH 156/514] update test cases --- tests/gettext/saved/gt_01.J.out | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/gettext/saved/gt_01.J.out diff --git a/tests/gettext/saved/gt_01.J.out b/tests/gettext/saved/gt_01.J.out new file mode 100644 index 00000000..d6c61c4d --- /dev/null +++ b/tests/gettext/saved/gt_01.J.out @@ -0,0 +1,2 @@ +{"top": {"bytes":0,"bytes":1,"bytes":2,"bytes":3,"bytes":4,"total":1234,"received":1234,"from":"foop","port":4321,"time":32,"marzlevanes":3,"version":"1.2.3","date":"Tue Jun 23 18:47:09 UTC 2015", "__warning": {"program":"gt_01.test","message":"Nableuay otay ectulatobjay orwardfay elocipingvay","verb":ectulatobjay,"error":"Ermissionpay eniedday"}, "__warning": {"program":"gt_01.test","message":"automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay","style":automaticyay,"type":"ardinalyay","target":"ammetersgray","error":"Ermissionpay eniedday"},"marzlevanes":6,"windings":"otuslay-oyay-eltayay"} +} From c1484baf5a61530e27a1cd341c19acd68818227f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:17 -0400 Subject: [PATCH 157/514] update test cases --- tests/gettext/saved/gt_01.JP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.JP.err diff --git a/tests/gettext/saved/gt_01.JP.err b/tests/gettext/saved/gt_01.JP.err new file mode 100644 index 00000000..e69de29b From 31130c34f32b2151275a676dcb3ce604d7ffde80 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:17 -0400 Subject: [PATCH 158/514] update test cases --- tests/gettext/saved/gt_01.JP.out | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/gettext/saved/gt_01.JP.out diff --git a/tests/gettext/saved/gt_01.JP.out b/tests/gettext/saved/gt_01.JP.out new file mode 100644 index 00000000..44de1506 --- /dev/null +++ b/tests/gettext/saved/gt_01.JP.out @@ -0,0 +1,33 @@ +{ + "top": { + "bytes": 0, + "bytes": 1, + "bytes": 2, + "bytes": 3, + "bytes": 4, + "total": 1234, + "received": 1234, + "from": "foop", + "port": 4321, + "time": 32, + "marzlevanes": 3, + "version": "1.2.3", + "date": "Tue Jun 23 18:47:09 UTC 2015", + "__warning": { + "program": "gt_01.test", + "message": "Nableuay otay ectulatobjay orwardfay elocipingvay", + "verb": ectulatobjay, + "error": "Ermissionpay eniedday" + }, + "__warning": { + "program": "gt_01.test", + "message": "automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay", + "style": automaticyay, + "type": "ardinalyay", + "target": "ammetersgray", + "error": "Ermissionpay eniedday" + }, + "marzlevanes": 6, + "windings": "otuslay-oyay-eltayay" + } +} From dc15899c145197f70ebb982b275054011b336fa6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:18 -0400 Subject: [PATCH 159/514] update test cases --- tests/gettext/saved/gt_01.T.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.T.err diff --git a/tests/gettext/saved/gt_01.T.err b/tests/gettext/saved/gt_01.T.err new file mode 100644 index 00000000..e69de29b From 4f5e70ac783163869df0bf83b262be5de1ffd9e6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:19 -0400 Subject: [PATCH 160/514] update test cases --- tests/gettext/saved/gt_01.T.out | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/gettext/saved/gt_01.T.out diff --git a/tests/gettext/saved/gt_01.T.out b/tests/gettext/saved/gt_01.T.out new file mode 100644 index 00000000..e4224b87 --- /dev/null +++ b/tests/gettext/saved/gt_01.T.out @@ -0,0 +1,13 @@ +0 yebay +1 yesbay +2 yezbay +3 yezbay +4 yezbay +otaltay 1234 +Eceivedray 1234 ytesbay omfray foop#4321 inyay 32 msyay +Onlyay 3 arzlevanesmay areyay unctioningfay orrectlycay +Ersionvay 1.2.3 Tue Jun 23 18:47:09 UTC 2015 +gt_01.test: Nableuay otay ectulatobjay orwardfay elocipingvay: Ermissionpay eniedday +gt_01.test: automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay: Ermissionpay eniedday +ydrocoptichay arzlevanesmay: 6 +Indingsway: otuslay-oyay-eltayay From fe296de9e1106b77dfe9a392b9e07d6afaeb3856 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:19 -0400 Subject: [PATCH 161/514] update test cases --- tests/gettext/saved/gt_01.X.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.X.err diff --git a/tests/gettext/saved/gt_01.X.err b/tests/gettext/saved/gt_01.X.err new file mode 100644 index 00000000..e69de29b From d9c1e9cbd72da1feb20ee97e68ddcfae60affad0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:20 -0400 Subject: [PATCH 162/514] update test cases --- tests/gettext/saved/gt_01.X.out | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/gettext/saved/gt_01.X.out diff --git a/tests/gettext/saved/gt_01.X.out b/tests/gettext/saved/gt_01.X.out new file mode 100644 index 00000000..06f4750a --- /dev/null +++ b/tests/gettext/saved/gt_01.X.out @@ -0,0 +1 @@ +0123412341234foop432131.2.3Tue Jun 23 18:47:09 UTC 2015<__warning>gt_01.testNableuay otay ectulatobjay orwardfay elocipingvayectulatobjayErmissionpay eniedday<__warning>gt_01.testautomaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfayardinalyayammetersgrayErmissionpay eniedday6otuslay-oyay-eltayay \ No newline at end of file From c33e198c64d14c6ac8c2abf20d252e4424fe297c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:21 -0400 Subject: [PATCH 163/514] update test cases --- tests/gettext/saved/gt_01.XP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/gettext/saved/gt_01.XP.err diff --git a/tests/gettext/saved/gt_01.XP.err b/tests/gettext/saved/gt_01.XP.err new file mode 100644 index 00000000..e69de29b From 07505bc883011b33bae0b6d6143fb5cfa430973f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 16:27:22 -0400 Subject: [PATCH 164/514] update test cases --- tests/gettext/saved/gt_01.XP.out | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/gettext/saved/gt_01.XP.out diff --git a/tests/gettext/saved/gt_01.XP.out b/tests/gettext/saved/gt_01.XP.out new file mode 100644 index 00000000..89fde70a --- /dev/null +++ b/tests/gettext/saved/gt_01.XP.out @@ -0,0 +1,31 @@ + + 0 + 1 + 2 + 3 + 4 + 1234 + 1234 + foop + 4321 + + 3 + 1.2.3 + Tue Jun 23 18:47:09 UTC 2015 + <__warning> + gt_01.test + Nableuay otay ectulatobjay orwardfay elocipingvay + ectulatobjay + Ermissionpay eniedday + + <__warning> + gt_01.test + automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay + + ardinalyay + ammetersgray + Ermissionpay eniedday + + 6 + otuslay-oyay-eltayay + From 5139ce271b6397085d8555dc2b577c8915c9b9df Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 17:22:07 -0400 Subject: [PATCH 165/514] EXTRA_DIST needs xo_humanize.h --- libxo/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index bd7698ef..0839b0c5 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -55,7 +55,9 @@ man_MANS = \ xo_set_version.3 \ xo_set_writer.3 -EXTRA_DIST = ${man_MANS} +EXTRA_DIST = \ + ${man_MANS} \ + xo_humanize.h call-graph: ${RM} libxo.o From d6a7349318765cd7c3a62ab7f85e61a3d2da49df Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 17:23:04 -0400 Subject: [PATCH 166/514] domainname is UNUSED for !HAVE_GETTEXT --- libxo/libxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index d99d5933..91d3dcfc 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -475,8 +475,8 @@ xo_dgettext (const char *domainname UNUSED, const char *str) } static inline const char * -xo_dngettext (const char *domainname, const char *singular, const char *plural, - int n) +xo_dngettext (const char *domainname UNUSED, const char *singular, + const char *plural, int n) { return (n == 1) ? singular : plural; } From 6f61ed997f064940700c2a52f3f27b03cd1417a5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 2 Jul 2015 17:23:21 -0400 Subject: [PATCH 167/514] don't touch gettext/ w/o HAVE_GETTEXT --- tests/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 42bd437e..b6d3e719 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,7 +6,11 @@ # using the SOFTWARE, you agree to be bound by the terms of that # LICENSE. -SUBDIRS=core gettext xo +SUBDIRS = core xo + +if HAVE_GETTEXT +SUBDIRS += gettext +endif test tests: @(cur=`pwd` ; for dir in $(SUBDIRS) ; do \ From b6497764743a60537e1b9fccc054e543341c4370 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:01:07 -0400 Subject: [PATCH 168/514] Add xopo utility (for manging .po files) --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 710298ce..6212b766 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,7 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libxo xo xolint xohtml tests doc +SUBDIRS = libxo xo xopo xolint xohtml tests doc bin_SCRIPTS=libxo-config dist_doc_DATA = Copyright From dc9289e6c117af788bf3053233fcc1ef2b95a024 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:01:09 -0400 Subject: [PATCH 169/514] Add xopo utility (for manging .po files) --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 6160eaa3..154fe998 100644 --- a/configure.ac +++ b/configure.ac @@ -308,6 +308,7 @@ AC_CONFIG_FILES([ xo/Makefile xolint/Makefile xohtml/Makefile + xopo/Makefile packaging/libxo.pc doc/Makefile tests/Makefile From b1b655941f66873a28d776a1f6bd169e5b14b84d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:01:35 -0400 Subject: [PATCH 170/514] +xo_simplify_format() for viewing simplified messages (for .po files) --- libxo/libxo.c | 1029 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 767 insertions(+), 262 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 91d3dcfc..1fb6ab71 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -318,6 +318,29 @@ typedef struct xo_format_s { unsigned char xf_star[XF_WIDTH_NUM]; /* Seen one or more '*'s */ } xo_format_t; +/* + * This structure represents the parsed field information, suitable for + * processing by xo_do_emit and anything else that needs to parse fields. + * Note that all pointers point to the main format string. + * + * XXX This is a first step toward compilable or cachable format + * strings. We can also cache the results of dgettext when no format + * is used, assuming the 'p' modifier has _not_ been set. + */ +typedef struct xo_field_info_s { + xo_xff_flags_t xfi_flags; /* Flags for this field */ + unsigned xfi_ftype; /* Field type, as character (e.g. 'V') */ + const char *xfi_start; /* Start of field in the format string */ + const char *xfi_content; /* Field's content */ + const char *xfi_format; /* Field's Format */ + const char *xfi_encoding; /* Field's encoding format */ + const char *xfi_next; /* Next character in format string */ + unsigned xfi_len; /* Length of field */ + unsigned xfi_clen; /* Content length */ + unsigned xfi_flen; /* Format length */ + unsigned xfi_elen; /* Encoding length */ +} xo_field_info_t; + /* * We keep a 'default' handle to allow callers to avoid having to * allocate one. Passing NULL to any of our functions will use @@ -454,29 +477,88 @@ xo_buf_cleanup (xo_buffer_t *xbp) bzero(xbp, sizeof(*xbp)); } +/* + * Use a rotating stock of buffers to make a printable string + */ +static const char * +xo_printable (const char *str) +{ + const int NUMBUFS = 8; + const int SMBUFSZ = 128; + static char bufset[NUMBUFS][SMBUFSZ]; + static int bufnum = 0; + + if (str == NULL) + return ""; + + if (++bufnum == NUMBUFS) /* Not thread safe */ + bufnum = 0; + + char *res = bufset[bufnum], *cp, *ep; + + for (cp = res, ep = res + SMBUFSZ - 1; *str && cp < ep; cp++, str++) { + if (*str == '\n') { + *cp++ = '\\'; + *cp = 'n'; + } else if (*str == '\r') { + *cp++ = '\\'; + *cp = 'r'; + } else if (*str == '\"') { + *cp++ = '\\'; + *cp = '"'; + } else + *cp = *str; + } + + *cp = '\0'; + return res; +} + #ifdef HAVE_GETTEXT static inline const char * -xo_dgettext (const char *domainname, const char *str) +xo_dgettext (xo_handle_t *xop, const char *str) { - return dgettext(domainname, str); + const char *domainname = xop->xo_gt_domain; + const char *res; + + res = dgettext(domainname, str); + + if (xop->xo_flags & XOF_LOG_GETTEXT) + fprintf(stderr, "xo: gettext: %s%s%smsgid \"%s\" returns \"%s\"\n", + domainname ? "domain \"" : "", xo_printable(domainname), + domainname ? "\", " : "", xo_printable(str), xo_printable(res)); + + return res; } static inline const char * -xo_dngettext (const char *domainname, const char *sing, const char *plural, - int n) +xo_dngettext (xo_handle_t *xop, const char *sing, const char *plural, + unsigned long int n) { - return dngettext(domainname, sing, plural, n); + const char *domainname = xop->xo_gt_domain; + const char *res; + + res = dngettext(domainname, sing, plural, n); + if (xop->xo_flags & XOF_LOG_GETTEXT) + fprintf(stderr, "xo: gettext: %s%s%s" + "msgid \"%s\", msgid_plural \"%s\" (%lu) returns \"%s\"\n", + domainname ? "domain \"" : "", + xo_printable(domainname), domainname ? "\", " : "", + xo_printable(sing), + xo_printable(plural), n, xo_printable(res)); + + return res; } #else /* HAVE_GETTEXT */ static inline const char * -xo_dgettext (const char *domainname UNUSED, const char *str) +xo_dgettext (xo_handle_t *xop UNUSED, const char *str) { return str; } static inline const char * -xo_dngettext (const char *domainname UNUSED, const char *singular, - const char *plural, int n) +xo_dngettext (xo_handle_t *xop UNUSED, const char *singular, + const char *plural, unsigned long int n) { return (n == 1) ? singular : plural; } @@ -1774,6 +1856,7 @@ static xo_mapping_t xo_xof_names[] = { { XOF_IGNORE_CLOSE, "ignore-close" }, { XOF_INFO, "info" }, { XOF_KEYS, "keys" }, + { XOF_LOG_GETTEXT, "log-gettext" }, { XOF_NO_HUMANIZE, "no-humanize" }, { XOF_NO_LOCALE, "no-locale" }, { XOF_NO_TOP, "no-top" }, @@ -1855,6 +1938,10 @@ xo_set_options (xo_handle_t *xop, const char *input) xop->xo_flags |= XOF_FLUSH_LINE; break; + case 'g': + xop->xo_flags |= XOF_LOG_GETTEXT; + break; + case 'H': xop->xo_style = XO_STYLE_HTML; break; @@ -2639,7 +2726,7 @@ xo_format_gettext (xo_handle_t *xop, xo_xff_flags_t flags, } *two++ = '\0'; - newstr = xo_dngettext(xop->xo_gt_domain, cp, two, n); + newstr = xo_dngettext(xop, cp, two, n); /* * If we returned the first string, optimize a bit by @@ -2657,7 +2744,7 @@ xo_format_gettext (xo_handle_t *xop, xo_xff_flags_t flags, } else { /* The simple case (singular) */ - newstr = xo_dgettext(xop->xo_gt_domain, cp); + newstr = xo_dgettext(xop, cp); if (newstr == cp) { /* If the caller wanted UTF8, we're done; nothing changed */ @@ -3481,9 +3568,14 @@ xo_format_text (xo_handle_t *xop, const char *str, int len) } static void -xo_format_title (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen, xo_xff_flags_t flags) +xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip) { + const char *str = xfip->xfi_content; + unsigned len = xfip->xfi_clen; + const char *fmt = xfip->xfi_format; + unsigned flen = xfip->xfi_flen; + xo_xff_flags_t flags = xfip->xfi_flags; + static char div_open[] = "
"; static char div_close[] = "
"; @@ -3613,8 +3705,8 @@ xo_arg (xo_handle_t *xop) static void xo_format_value (xo_handle_t *xop, const char *name, int nlen, - const char *format, int flen, - const char *encoding, int elen, xo_xff_flags_t flags) + const char *format, int flen, + const char *encoding, int elen, xo_xff_flags_t flags) { int pretty = (xop->xo_flags & XOF_PRETTY); int quote; @@ -3893,9 +3985,13 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, } static void -xo_set_gettext_domain (xo_handle_t *xop, - const char *str, int len, const char *fmt, int flen) +xo_set_gettext_domain (xo_handle_t *xop, xo_field_info_t *xfip) { + const char *str = xfip->xfi_content; + unsigned len = xfip->xfi_clen; + const char *fmt = xfip->xfi_format; + unsigned flen = xfip->xfi_flen; + /* Start by discarding previous domain */ if (xop->xo_gt_domain) { xo_free(xop->xo_gt_domain); @@ -4260,9 +4356,13 @@ xo_colors_handle_html (xo_handle_t *xop, xo_colors_t *newp) } static void -xo_format_colors (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen) +xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip) { + const char *str = xfip->xfi_content; + unsigned len = xfip->xfi_clen; + const char *fmt = xfip->xfi_format; + unsigned flen = xfip->xfi_flen; + xo_buffer_t xb; /* If the string is static and we've in an encoding style, bail */ @@ -4329,9 +4429,14 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, } static void -xo_format_units (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen, xo_xff_flags_t flags) +xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip) { + const char *str = xfip->xfi_content; + unsigned len = xfip->xfi_clen; + const char *fmt = xfip->xfi_format; + unsigned flen = xfip->xfi_flen; + xo_xff_flags_t flags = xfip->xfi_flags; + static char units_start_xml[] = " units=\""; static char units_start_html[] = " data-units=\""; @@ -4379,9 +4484,13 @@ xo_format_units (xo_handle_t *xop, const char *str, int len, } static int -xo_find_width (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen) +xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip) { + const char *str = xfip->xfi_content; + unsigned len = xfip->xfi_clen; + const char *fmt = xfip->xfi_format; + unsigned flen = xfip->xfi_flen; + long width = 0; char *bp; char *cp; @@ -4425,8 +4534,7 @@ xo_anchor_clear (xo_handle_t *xop) * format it when the end anchor tag is seen. */ static void -xo_anchor_start (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen) +xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip) { if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML) return; @@ -4443,12 +4551,11 @@ xo_anchor_start (xo_handle_t *xop, const char *str, int len, * 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, str, len, fmt, flen); + xop->xo_anchor_min_width = xo_find_width(xop, xfip); } static void -xo_anchor_stop (xo_handle_t *xop, const char *str, int len, - const char *fmt, int flen) +xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip) { if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML) return; @@ -4460,7 +4567,7 @@ xo_anchor_stop (xo_handle_t *xop, const char *str, int len, xop->xo_flags &= ~XOF_UNITS_PENDING; - int width = xo_find_width(xop, str, len, fmt, flen); + int width = xo_find_width(xop, xfip); if (width == 0) width = xop->xo_anchor_min_width; @@ -4539,6 +4646,21 @@ xo_tag_name (int ftype) return NULL; } +static int +xo_role_wants_default_format (int ftype) +{ + switch (ftype) { + /* These roles can be completely empty and/or without formatting */ + case 'C': + case 'G': + case '[': + case ']': + return 0; + } + + return 1; +} + static xo_mapping_t xo_role_names[] = { { 'C', "color" }, { 'D', "decoration" }, @@ -4555,6 +4677,10 @@ static xo_mapping_t xo_role_names[] = { { 0, NULL } }; +#define XO_ROLE_EBRACE '{' /* Escaped braces */ +#define XO_ROLE_TEXT '+' +#define XO_ROLE_NEWLINE '\n' + static xo_mapping_t xo_modifier_names[] = { { XFF_COLON, "colon" }, { XFF_COMMA, "comma" }, @@ -4576,30 +4702,222 @@ static xo_mapping_t xo_modifier_names[] = { }; static int -xo_do_emit (xo_handle_t *xop, const char *fmt) +xo_count_fields (xo_handle_t *xop UNUSED, const char *fmt) { - int rc = 0; + int rc = 1; + const char *cp; + + for (cp = fmt; *cp; cp++) + if (*cp == '{' || *cp == '\n') + rc += 1; + + return rc * 2 + 1; +} + +/* + * The field format is: + * '{' modifiers ':' content [ '/' print-fmt [ '/' encode-fmt ]] '}' + * Roles are optional and include the following field types: + * 'D': decoration; something non-text and non-data (colons, commmas) + * 'E': error message + * 'G': gettext() the entire string; optional domainname as content + * 'L': label; text preceding data + * 'N': note; text following data + * 'P': padding; whitespace + * 'T': Title, where 'content' is a column title + * 'U': Units, where 'content' is the unit label + * 'V': value, where 'content' is the name of the field (the default) + * 'W': warning message + * '[': start a section of anchored text + * ']': end a section of anchored text + * The following modifiers are also supported: + * 'c': flag: emit a colon after the label + * 'd': field is only emitted for display styles (text and html) + * 'e': field is only emitted for encoding styles (xml and json) + * 'g': gettext() the field + * 'h': humanize a numeric value (only for display styles) + * 'k': this field is a key, suitable for XPath predicates + * 'l': a leaf-list, a simple list of values + * 'n': no quotes around this field + * 'p': the field has plural gettext semantics (ngettext) + * 'q': add quotes around this field + * 't': trim whitespace around the value + * 'w': emit a blank after the label + * The print-fmt and encode-fmt strings is the printf-style formating + * for this data. JSON and XML will use the encoding-fmt, if present. + * If the encode-fmt is not provided, it defaults to the print-fmt. + * If the print-fmt is not provided, it defaults to 's'. + */ +static const char * +xo_parse_roles (xo_handle_t *xop, const char *fmt, + const char *basep, xo_field_info_t *xfip) +{ + const char *sp; + unsigned ftype = 0; + xo_xff_flags_t flags = 0; + + for (sp = basep; sp; sp++) { + if (*sp == ':' || *sp == '/' || *sp == '}') + break; + + if (*sp == '\\') { + if (sp[1] == '\0') { + xo_failure(xop, "backslash at the end of string"); + return NULL; + } + + /* Anything backslashed is ignored */ + sp += 1; + continue; + } + + if (*sp == ',') { + const char *np; + for (np = ++sp; *np; np++) + if (*np == ':' || *np == '/' || *np == '}' || *np == ',') + break; + + int slen = np - sp; + if (slen > 0) { + xo_xff_flags_t value; + + value = xo_name_lookup(xo_role_names, sp, slen); + if (value) + ftype = value; + else { + value = xo_name_lookup(xo_modifier_names, sp, slen); + if (value) + flags |= value; + else + xo_failure(xop, "unknown keyword ignored: '%.*s'", + slen, sp); + } + } + + sp = np - 1; + continue; + } + + switch (*sp) { + case 'C': + case 'D': + case 'E': + case 'G': + case 'L': + case 'N': + case 'P': + case 'T': + case 'U': + case 'V': + case 'W': + case '[': + case ']': + if (ftype != 0) { + xo_failure(xop, "field descriptor uses multiple types: '%s'", + xo_printable(fmt)); + return NULL; + } + ftype = *sp; + break; + + case 'c': + flags |= XFF_COLON; + break; + + case 'd': + flags |= XFF_DISPLAY_ONLY; + break; + + case 'e': + flags |= XFF_ENCODE_ONLY; + break; + + case 'g': + flags |= XFF_GT_FIELD; + break; + + case 'h': + flags |= XFF_HUMANIZE; + break; + + case 'k': + flags |= XFF_KEY; + break; + + case 'l': + flags |= XFF_LEAF_LIST; + break; + + case 'n': + flags |= XFF_NOQUOTE; + break; + + case 'p': + flags |= XFF_GT_PLURAL; + break; + + case 'q': + flags |= XFF_QUOTE; + break; + + case 't': + flags |= XFF_TRIM_WS; + break; + + case 'w': + flags |= XFF_WS; + break; + + default: + xo_failure(xop, "field descriptor uses unknown modifier: '%s'", + xo_printable(fmt)); + /* + * No good answer here; a bad format will likely + * mean a core file. We just return and hope + * the caller notices there's no output, and while + * that seems, well, bad, there's nothing better. + */ + return NULL; + } + + if (ftype == 'N' || ftype == 'U') { + if (flags & XFF_COLON) { + xo_failure(xop, "colon modifier on 'N' or 'U' field ignored: " + "'%s'", xo_printable(fmt)); + flags &= ~XFF_COLON; + } + } + } + + xfip->xfi_flags = flags; + xfip->xfi_ftype = ftype ?: 'V'; + + return sp; +} + +static int +xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields, + unsigned num_fields, const char *fmt) +{ + static const char default_format[] = "%s"; const char *cp, *sp, *ep, *basep; - char *newp = NULL; - int flush = (xop->xo_flags & XOF_FLUSH) ? 1 : 0; - int flush_line = (xop->xo_flags & XOF_FLUSH_LINE) ? 1 : 0; - int gettext_inuse = 0; - int gettext_changed = 0; - char *newfmt = NULL; + unsigned field = 0; + xo_field_info_t *xfip = fields; - xop->xo_columns = 0; /* Always reset it */ - xop->xo_errno = errno; /* Save for "%m" */ + for (cp = fmt; *cp && field < num_fields; field++, xfip++) { + xfip->xfi_start = cp; - for (cp = fmt; *cp; ) { if (*cp == '\n') { - xo_line_close(xop); - if (flush_line && xo_flush_h(xop) < 0) - return -1; + xfip->xfi_ftype = XO_ROLE_NEWLINE; + xfip->xfi_len = 1; cp += 1; continue; + } - } else if (*cp == '{') { + if (*cp == '{') { if (cp[1] == '{') { /* Start of {{escaped braces}} */ + xfip->xfi_start = cp + 1; /* Start at second brace */ + xfip->xfi_ftype = XO_ROLE_EBRACE; cp += 2; /* Skip over _both_ characters */ for (sp = cp; *sp; sp++) { @@ -4607,16 +4925,18 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) break; } if (*sp == '\0') { - xo_failure(xop, "missing closing '}}': %s", fmt); + xo_failure(xop, "missing closing '}}': '%s'", + xo_printable(fmt)); return -1; } - xo_format_text(xop, cp, sp - cp); + xfip->xfi_len = sp - xfip->xfi_start + 1; /* Move along the string, but don't run off the end */ if (*sp == '}' && sp[1] == '}') sp += 2; cp = *sp ? sp + 1 : sp; + xfip->xfi_next = cp; continue; } /* Else fall thru to the code below */ @@ -4627,176 +4947,35 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) if (*sp == '{' || *sp == '\n') break; } - xo_format_text(xop, cp, sp - cp); + + xfip->xfi_ftype = XO_ROLE_TEXT; + xfip->xfi_content = cp; + xfip->xfi_clen = sp - cp; + xfip->xfi_next = sp; cp = sp; continue; } - basep = cp + 1; + /* We are looking at the start of a field definition */ + xfip->xfi_start = basep = cp + 1; - /* - * We are looking at the start of a field definition. The format is: - * '{' modifiers ':' content [ '/' print-fmt [ '/' encode-fmt ]] '}' - * Modifiers are optional and include the following field types: - * 'D': decoration; something non-text and non-data (colons, commmas) - * 'E': error message - * 'G': gettext() the entire string; optional domainname as content - * 'L': label; text preceding data - * 'N': note; text following data - * 'P': padding; whitespace - * 'T': Title, where 'content' is a column title - * 'U': Units, where 'content' is the unit label - * 'V': value, where 'content' is the name of the field (the default) - * 'W': warning message - * '[': start a section of anchored text - * ']': end a section of anchored text - * The following flags are also supported: - * 'c': flag: emit a colon after the label - * 'd': field is only emitted for display styles (text and html) - * 'e': field is only emitted for encoding styles (xml and json) - * 'g': gettext() the field - * 'h': humanize a numeric value (only for display styles) - * 'k': this field is a key, suitable for XPath predicates - * 'l': a leaf-list, a simple list of values - * 'n': no quotes around this field - * 'p': the field has plural gettext semantics (ngettext) - * 'q': add quotes around this field - * 't': trim whitespace around the value - * 'w': emit a blank after the label - * The print-fmt and encode-fmt strings is the printf-style formating - * for this data. JSON and XML will use the encoding-fmt, if present. - * If the encode-fmt is not provided, it defaults to the print-fmt. - * If the print-fmt is not provided, it defaults to 's'. - */ unsigned ftype = 0; xo_xff_flags_t flags = 0; - const char *content = NULL, *format = NULL, *encoding = NULL; - int clen = 0, flen = 0, elen = 0; - - for (sp = basep; sp; sp++) { - if (*sp == ':' || *sp == '/' || *sp == '}') - break; - - if (*sp == '\\') { - if (sp[1] == '\0') { - xo_failure(xop, "backslash at the end of string"); - return -1; - } - sp += 1; - continue; - } - - if (*sp == ',') { - const char *np; - for (np = ++sp; *np; np++) - if (*np == ':' || *np == '/' || *np == '}' || *np == ',') - break; - - int slen = np - sp; - if (slen > 0) { - xo_xff_flags_t value; - - value = xo_name_lookup(xo_role_names, sp, slen); - if (value) - ftype = value; - else { - value = xo_name_lookup(xo_modifier_names, sp, slen); - if (value) - flags |= value; - else - xo_failure(xop, "unknown keyword ignored: '%.*s'", - slen, sp); - } - } - - sp = np - 1; - continue; - } - - switch (*sp) { - case 'C': - case 'D': - case 'E': - case 'G': - case 'L': - case 'N': - case 'P': - case 'T': - case 'U': - case 'V': - case 'W': - case '[': - case ']': - if (ftype != 0) { - xo_failure(xop, "field descriptor uses multiple types: %s", - fmt); - return -1; - } - ftype = *sp; - break; - - case 'c': - flags |= XFF_COLON; - break; - - case 'd': - flags |= XFF_DISPLAY_ONLY; - break; - - case 'e': - flags |= XFF_ENCODE_ONLY; - break; - - case 'g': - flags |= XFF_GT_FIELD; - break; - - case 'h': - flags |= XFF_HUMANIZE; - break; - - case 'k': - flags |= XFF_KEY; - break; - - case 'l': - flags |= XFF_LEAF_LIST; - break; - - case 'n': - flags |= XFF_NOQUOTE; - break; - - case 'p': - flags |= XFF_GT_PLURAL; - break; - - case 'q': - flags |= XFF_QUOTE; - break; + const char *format = NULL; + int flen = 0; - case 't': - flags |= XFF_TRIM_WS; - break; - - case 'w': - flags |= XFF_WS; - break; - - default: - xo_failure(xop, "field descriptor uses unknown modifier: %s", - fmt); - /* - * No good answer here; a bad format will likely - * mean a core file. We just return and hope - * the caller notices there's no output, and while - * that seems, well, bad. There's nothing better. - */ - return -1; - } + /* Looking at roles and modifiers */ + sp = xo_parse_roles(xop, fmt, basep, xfip); + if (sp == NULL) { + /* xo_failure has already been called */ + return -1; } + ftype = xfip->xfi_ftype; + flags = xfip->xfi_flags; + + /* Looking at content */ if (*sp == ':') { for (ep = ++sp; *sp; sp++) { if (*sp == '}' || *sp == '/') @@ -4811,14 +4990,15 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) } } if (ep != sp) { - clen = sp - ep; - content = ep; + xfip->xfi_clen = sp - ep; + xfip->xfi_content = ep; } } else { - xo_failure(xop, "missing content (':'): %s", fmt); + xo_failure(xop, "missing content (':'): '%s'", xo_printable(fmt)); return -1; } + /* Looking at main (display) format */ if (*sp == '/') { for (ep = ++sp; *sp; sp++) { if (*sp == '}' || *sp == '/') @@ -4836,22 +5016,301 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) format = ep; } + /* Looking at encoding format */ if (*sp == '/') { for (ep = ++sp; *sp; sp++) { if (*sp == '}') break; } - elen = sp - ep; - encoding = ep; + + xfip->xfi_encoding = ep; + xfip->xfi_elen = sp - ep; } - if (*sp == '}') { - sp += 1; - } else { - xo_failure(xop, "missing closing '}': %s", fmt); + if (*sp != '}') { + xo_failure(xop, "missing closing '}': %s", xo_printable(fmt)); return -1; } + xfip->xfi_len = sp - xfip->xfi_start; + xfip->xfi_next = ++sp; + + /* If we have content, then we have a default format */ + if (xfip->xfi_clen || format) { + if (format) { + xfip->xfi_format = format; + xfip->xfi_flen = flen; + } else if (xo_role_wants_default_format(ftype)) { + xfip->xfi_format = default_format; + xfip->xfi_flen = 2; + } + } + + cp = sp; + } + + return 0; +} + +/* + * We are passed a pointer to a format string just past the "{G:}" + * field. We build a simplified version of the format string. + */ +static int +xo_do_simplify_format (xo_handle_t *xop UNUSED, + xo_buffer_t *xbp, + xo_field_info_t *fields, + int this_field, + const char *fmt UNUSED, + xo_simplify_field_func_t field_cb) +{ + unsigned ftype; + xo_xff_flags_t flags; + int field = this_field + 1; + xo_field_info_t *xfip; + char ch; + + for (xfip = &fields[field]; xfip->xfi_ftype; xfip++, field++) { + ftype = xfip->xfi_ftype; + flags = xfip->xfi_flags; + + if ((flags & XFF_GT_FIELD) && xfip->xfi_content && ftype != 'V') { + if (field_cb) + field_cb(xfip->xfi_content, xfip->xfi_clen, + (flags & XFF_GT_PLURAL) ? 1 : 0); + } + + switch (ftype) { + case 'G': + /* Ignore gettext roles */ + break; + + case XO_ROLE_NEWLINE: + xo_buf_append(xbp, "\n", 1); + break; + + case XO_ROLE_EBRACE: + xo_buf_append(xbp, "{", 1); + xo_buf_append(xbp, xfip->xfi_content, xfip->xfi_clen); + xo_buf_append(xbp, "}", 1); + break; + + case XO_ROLE_TEXT: + xo_buf_append(xbp, xfip->xfi_content, xfip->xfi_clen); + break; + + default: + xo_buf_append(xbp, "{", 1); + if (ftype != 'V') { + ch = ftype; + xo_buf_append(xbp, &ch, 1); + } + xo_buf_append(xbp, ":", 1); + xo_buf_append(xbp, xfip->xfi_content, xfip->xfi_clen); + xo_buf_append(xbp, "}", 1); + } + } + + xo_buf_append(xbp, "", 1); + return 0; +} + +void +xo_dump_fields (xo_field_info_t *); +void +xo_dump_fields (xo_field_info_t *fields) +{ + xo_field_info_t *xfip; + + for (xfip = fields; xfip->xfi_ftype; xfip++) { + printf("%ld: [%c/%u] [%.*s] [%.*s] [%.*s]\n", + xfip - fields, + isprint((int) xfip->xfi_ftype) ? xfip->xfi_ftype : ' ', + xfip->xfi_ftype, + xfip->xfi_clen, xfip->xfi_content ?: "", + xfip->xfi_flen, xfip->xfi_format ?: "", + xfip->xfi_elen, xfip->xfi_encoding ?: ""); + } +} + +/* + * We've got two lists of fields, the old list from the original + * format string and the new one from the parsed gettext reply. The + * new list has the localized words, where the old list has the + * formatting information. We need to combine them into a single list + * (the new list). + * + * If the list needs to be reordered, then we've got more serious work + * to do. + */ +static int +xo_gettext_combine_formats (xo_handle_t *xop, const char *fmt UNUSED, + const char *gtfmt, xo_field_info_t *old_fields, + xo_field_info_t *new_fields, int *reorderedp) +{ + int reordered = 0; + xo_field_info_t *newp, *oldp, *startp = old_fields; + + for (newp = new_fields; newp->xfi_ftype; newp++) { + if (newp->xfi_ftype != 'V') + continue; + + for (oldp = startp; oldp->xfi_ftype; oldp++) { + if (oldp->xfi_ftype != 'V') + continue; + if (newp->xfi_clen != oldp->xfi_clen + || strncmp(newp->xfi_content, oldp->xfi_content, + oldp->xfi_clen) != 0) { + reordered = 1; + continue; + } + startp = oldp + 1; + break; + } + + /* Didn't find it on the first pass (starting from last position) */ + if (oldp->xfi_ftype == 0) { + for (oldp = old_fields; oldp < startp; oldp++) { + if (oldp->xfi_ftype != 'V') + continue; + if (newp->xfi_clen != oldp->xfi_clen) + continue; + if (strncmp(newp->xfi_content, oldp->xfi_content, + oldp->xfi_clen) != 0) + continue; + reordered = 1; + break; + } + if (oldp == startp) { + /* Field not found */ + xo_failure(xop, "post-gettext format can't find field '%.*s' " + "in format '%s'", + newp->xfi_clen, newp->xfi_content, + xo_printable(gtfmt)); + return -1; + } + } + + /* + * Found a match; copy over appropriate fields + */ + newp->xfi_flags = oldp->xfi_flags; + newp->xfi_format = oldp->xfi_format; + newp->xfi_flen = oldp->xfi_flen; + newp->xfi_encoding = oldp->xfi_encoding; + newp->xfi_elen = oldp->xfi_elen; + } + + *reorderedp = reordered; + return 0; +} + +/* + * We don't want to make gettext() calls here with a complete format + * string, since that means changing a flag would mean a + * labor-intensive re-translation expense. Instead we build a + * simplified form with a reduced level of detail, perform a lookup on + * that string and then re-insert the formating info. + * + * So something like: + * xo_emit("{G:}close {:fd/%ld} returned {g:error/%m} {:test/%6.6s}\n", ...) + * would have a lookup string of: + * "close {:fd} returned {:error} {:test}\n" + * + * We also need to handling reordering of fields, where the gettext() + * reply string uses fields in a different order than the original + * format string: + * "cluse-a {:fd} retoorned {:test}. Bork {:error} Bork. Bork.\n" + * If we have to reorder fields within the message, then things get + * complicated. We have to change styles to XO_STYLE_GTPARAMS, and + * build name/value pairs. Then we reformat the entire content to + * match the new format. + * + * Summary: i18n aighn't cheap. + */ +static const char * +xo_build_gettext_format (xo_handle_t *xop UNUSED, xo_field_info_t *fields, + int this_field, + const char *fmt, char **new_fmtp) +{ +#ifdef HAVE_GETTEXT + if (xo_style_is_encoding(xop)) + goto bail; + + xo_buffer_t xb; + xo_buf_init(&xb); + + if (xo_do_simplify_format(xop, &xb, fields, + this_field, fmt, NULL)) + goto bail2; + + const char *gtfmt = xo_dgettext(xop, xb.xb_bufp); + 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; + + *new_fmtp = new_fmt; + return new_fmt; + + bail2: + xo_buf_cleanup(&xb); + bail: +#endif /* HAVE_GETTEXT */ + *new_fmtp = NULL; + return fmt; +} + +static int +xo_do_emit (xo_handle_t *xop, const char *fmt) +{ + int rc = 0; + int flush = (xop->xo_flags & XOF_FLUSH) ? 1 : 0; + int flush_line = (xop->xo_flags & XOF_FLUSH_LINE) ? 1 : 0; + int gettext_inuse = 0; + int gettext_changed = 0; + char *new_fmt = NULL; + xo_field_info_t *new_fields = NULL; + + xop->xo_columns = 0; /* Always reset it */ + xop->xo_errno = errno; /* Save for "%m" */ + + unsigned max_fields = xo_count_fields(xop, fmt), field; + xo_field_info_t fields[max_fields], *xfip; + + bzero(fields, max_fields * sizeof(fields[0])); + + if (xo_parse_fields(xop, fields, max_fields, fmt)) + return -1; /* Warning already displayed */ + + unsigned ftype; + xo_xff_flags_t flags; + + for (xfip = fields, field = 0; xfip->xfi_ftype && field < max_fields; + xfip++, field++) { + ftype = xfip->xfi_ftype; + flags = xfip->xfi_flags; + + if (ftype == XO_ROLE_NEWLINE) { + xo_line_close(xop); + if (flush_line && xo_flush_h(xop) < 0) + return -1; + continue; + + } else if (ftype == XO_ROLE_EBRACE) { + xo_format_text(xop, xfip->xfi_start, xfip->xfi_len); + continue; + + } else if (ftype == XO_ROLE_TEXT) { + /* Normal text */ + xo_format_text(xop, xfip->xfi_content, xfip->xfi_clen); + continue; + } + /* * Notes and units need the 'w' flag handled before the content. */ @@ -4859,31 +5318,20 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) if (flags & XFF_WS) { xo_format_content(xop, "padding", NULL, " ", 1, NULL, 0, flags); - flags &= ~XFF_WS; - } - if (flags & XFF_COLON) { - xo_failure(xop, "colon modifier on 'N' or 'U' field ignored: " - "%s", fmt); - flags &= ~XFF_COLON; + flags &= ~XFF_WS; /* Block later handling of this */ } } - if (ftype == 0 || ftype == 'V') { - if (format == NULL) { - /* Default format for value fields is '%s' */ - format = "%s"; - flen = 2; - } - - xo_format_value(xop, content, clen, format, flen, - encoding, elen, flags); - - } else if (ftype == '[') - xo_anchor_start(xop, content, clen, format, flen); + if (ftype == 'V') + xo_format_value(xop, xfip->xfi_content, xfip->xfi_clen, + xfip->xfi_format, xfip->xfi_flen, + xfip->xfi_encoding, xfip->xfi_elen, flags); + else if (ftype == '[') + xo_anchor_start(xop, xfip); else if (ftype == ']') - xo_anchor_stop(xop, content, clen, format, flen); + xo_anchor_stop(xop, xfip); else if (ftype == 'C') - xo_format_colors(xop, content, clen, format, flen); + xo_format_colors(xop, xfip); else if (ftype == 'G') { /* @@ -4892,45 +5340,69 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) * didn't put the {G:} at the start of the format string, then * assumably they just want us to translate the rest of it. * Since gettext returns strings in a static buffer, we make - * a copy in newfmt. + * a copy in new_fmt. */ - xo_set_gettext_domain(xop, content, clen, format, flen); + xo_set_gettext_domain(xop, xfip); if (!gettext_inuse) { /* Only translate once */ gettext_inuse = 1; - if (newfmt) { - xo_free(newfmt); - newfmt = NULL; + if (new_fmt) { + xo_free(new_fmt); + new_fmt = NULL; } - const char *tempfmt = xo_dgettext(xop->xo_gt_domain, sp); - if (tempfmt != sp) { + xo_build_gettext_format(xop, fields, field, + xfip->xfi_next, &new_fmt); + if (new_fmt) { gettext_changed = 1; - newfmt = xo_strndup(tempfmt, -1); + /* XXX Need to support field reordering here */ - cp = newfmt; + unsigned new_max_fields = xo_count_fields(xop, new_fmt); - /* XXX Need to support field reordering here */ - } + if (++new_max_fields < max_fields) + new_max_fields = max_fields; - continue; - } + /* Leave a blank slot at the beginning */ + int sz = (new_max_fields + 1) * sizeof(xo_field_info_t); + new_fields = alloca(sz); + bzero(new_fields, sz); - } else if (clen || format) { /* Need either content or format */ - if (format == NULL) { - /* Default format for value fields is '%s' */ - format = "%s"; - flen = 2; + if (!xo_parse_fields(xop, new_fields + 1, + new_max_fields, new_fmt)) { + int reordered = 0; + + if (!xo_gettext_combine_formats(xop, fmt, new_fmt, + fields, new_fields + 1, &reordered)) { + + field = 0; /* Will be incremented at top of loop */ + xfip = new_fields; + max_fields = new_max_fields; + + if (reordered) { + /* XXX Underimplemented */ + xo_failure(xop, "gettext finds reordered " + "fields in '%s' and '%s'\n", + xo_printable(fmt), + xo_printable(new_fmt)); + goto bail2; + } + } + } + } } + continue; + + } else if (xfip->xfi_clen || xfip->xfi_format) { const char *class_name = xo_class_name(ftype); if (class_name) xo_format_content(xop, class_name, xo_tag_name(ftype), - content, clen, format, flen, flags); + xfip->xfi_content, xfip->xfi_clen, + xfip->xfi_format, xfip->xfi_flen, flags); else if (ftype == 'T') - xo_format_title(xop, content, clen, format, flen, flags); + xo_format_title(xop, xfip); else if (ftype == 'U') - xo_format_units(xop, content, clen, format, flen, flags); + xo_format_units(xop, xfip); else xo_failure(xop, "unknown field type: '%c'", ftype); } @@ -4940,12 +5412,6 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) if (flags & XFF_WS) xo_format_content(xop, "padding", NULL, " ", 1, NULL, 0, 0); - - cp += sp - basep + 1; - if (newp) { - xo_free(newp); - newp = NULL; - } } /* If we don't have an anchor, write the text out */ @@ -4956,8 +5422,13 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) rc = -1; } - if (newfmt) - xo_free(newfmt); + if (0) { + bail2: + rc = -1; + } + + if (new_fmt) + xo_free(new_fmt); /* * We've carried the gettext domainname inside our handle just for @@ -4969,9 +5440,43 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) xop->xo_gt_domain = NULL; } + if (gettext_changed) { + /* XXX Do something amazing here */ + } + return (rc < 0) ? rc : (int) xop->xo_columns; } +/* + * Rebuild a format string in a gettext-friendly format. This function + * is exposed to tools can perform this function. See xo(1). + */ +char * +xo_simplify_format (xo_handle_t *xop, const char *fmt, + xo_simplify_field_func_t field_cb) +{ + xop = xo_default(xop); + + xop->xo_columns = 0; /* Always reset it */ + xop->xo_errno = errno; /* Save for "%m" */ + + unsigned max_fields = xo_count_fields(xop, fmt); + xo_field_info_t fields[max_fields]; + + bzero(fields, max_fields * sizeof(fields[0])); + + if (xo_parse_fields(xop, fields, max_fields, fmt)) + return NULL; /* Warning already displayed */ + + xo_buffer_t xb; + xo_buf_init(&xb); + + if (xo_do_simplify_format(xop, &xb, fields, -1, fmt, field_cb)) + return NULL; + + return xb.xb_bufp; +} + int xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap) { From 04168dc3478f6337b342fb2a85a31ee92db9f009 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:01:38 -0400 Subject: [PATCH 171/514] +xo_simplify_format() for viewing simplified messages (for .po files) --- libxo/xo.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libxo/xo.h b/libxo/xo.h index 6dfa112f..37a79496 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -85,6 +85,8 @@ typedef unsigned long long xo_xof_flags_t; #define XOF_COLOR XOF_BIT(26) /** Enable color and effects */ #define XOF_NO_HUMANIZE XOF_BIT(27) /** Block the {h:} modifier */ +#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log gettext lookup strings (stderr) */ + /* * The xo_info_t structure provides a mapping between names and * additional data emitted via HTML. @@ -452,4 +454,10 @@ xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func, void xo_set_syslog_enterprise_id (unsigned short eid); +typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int); + +char * +xo_simplify_format (xo_handle_t *xop, const char *fmt, + xo_simplify_field_func_t field_cb); + #endif /* INCLUDE_XO_H */ From 277d8e42297f62fbb1dea5442bc6df66a89a9e4f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:01:45 -0400 Subject: [PATCH 172/514] add -v to msgfmt --- tests/gettext/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gettext/Makefile.am b/tests/gettext/Makefile.am index 855ec2c7..63e33043 100644 --- a/tests/gettext/Makefile.am +++ b/tests/gettext/Makefile.am @@ -114,7 +114,7 @@ clean-local: rm -rf ${CLEANDIRS} XGETTEXT = xgettext -MSGFMT = msgfmt +MSGFMT = msgfmt -v MSGMERGE = msgmerge ECHO = echo DB=set -x; From 1035834d04aa726f044fc205f5926c9b75ec1cb0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:01:58 -0400 Subject: [PATCH 173/514] add "po" option --- tests/gettext/gt_01.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/gettext/gt_01.c b/tests/gettext/gt_01.c index e0de3b7f..76fef09c 100644 --- a/tests/gettext/gt_01.c +++ b/tests/gettext/gt_01.c @@ -39,13 +39,17 @@ main (int argc, char **argv) tzone = argv[++argc]; else if (strcmp(argv[argc], "lang") == 0) lang = argv[++argc]; + else if (strcmp(argv[argc], "po") == 0) + strlcpy(path, argv[++argc], sizeof(path)); } setenv("LANG", lang, 1); setenv("TZ", tzone, 1); - getcwd(path, sizeof(path)); - strncat(path, "/po", 4); + if (path[0] == 0) { + getcwd(path, sizeof(path)); + strlcat(path, "/po", sizeof(path)); + } setlocale(LC_ALL, ""); bindtextdomain(domainname, path); From 779608b93e2155ade203add5f37e8678c2f3e7dc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:02:13 -0400 Subject: [PATCH 174/514] remove formating info from messages --- tests/gettext/gt_01.pot | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/gettext/gt_01.pot b/tests/gettext/gt_01.pot index 45d3b39c..380f742c 100644 --- a/tests/gettext/gt_01.pot +++ b/tests/gettext/gt_01.pot @@ -18,17 +18,17 @@ msgstr "" #: gt_01.c:42 #, c-format -msgid "{w:bytes/%d}{Ngp:byte,bytes}\n" +msgid "{:bytes}{N:byte,bytes}\n" msgstr "" #: gt_01.c:44 #, c-format -msgid "{L:total} {:total/%u}\n" +msgid "{L:total} {:total}\n" msgstr "" #: gt_01.c:60 #, c-format -msgid "Only {:marzlevanes/%d} {Ngp:marzlevane,marzlevanes} are functioning correctly\n" +msgid "Only {:marzlevanes} {N:marzlevane,marzlevanes} are functioning correctly\n" msgstr "" #: gt_01.c:63 @@ -36,20 +36,20 @@ msgid "Version {:version} {:date}\n" msgstr "" #: gt_01.c:66 -msgid "Unable to {g:verb/objectulate} forward velociping" +msgid "Unable to {:verb} forward velociping" msgstr "" #: gt_01.c:67 -msgid "{g:style/automatic} synchronization of {g:type/cardinal} {g:target/grammeters} failed" +msgid "{:style} synchronization of {:type} {:target} failed" msgstr "" #: gt_01.c:69 #, c-format -msgid "{Lwcg:hydrocoptic marzlevanes}{:marzlevanes/%d}\n" +msgid "{L:hydrocoptic marzlevanes}{:marzlevanes}\n" msgstr "" #: gt_01.c:71 -msgid "{Lwcg:Windings}{g:windings}\n" +msgid "{L:Windings}{:windings}\n" msgstr "" msgid "byte" @@ -76,3 +76,10 @@ msgstr "" msgid "objectulate" msgstr "" + +msgid "hydrocoptic marzlevanes" +msgstr "" + +msgid "Windings" +msgstr "" + From 76d990ca6a068ed681092b25185964b2f47a6786 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:02:36 -0400 Subject: [PATCH 175/514] remove formating info from messages --- tests/gettext/ldns.pot | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/gettext/ldns.pot b/tests/gettext/ldns.pot index 2f7e147c..6e3df201 100644 --- a/tests/gettext/ldns.pot +++ b/tests/gettext/ldns.pot @@ -18,11 +18,11 @@ msgstr "" #: gt_01.c:46 #, c-format -msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgid "Received {:received} {N:byte,bytes} from {:from}#{:port} in {:time} ms\n" msgstr "" msgid "byte" -msgstr "" +msgid_plural "bytes" +msgstr[0] "" +msgstr[1] "" -msgid "bytes" -msgstr "" From ba03df8bf9c618ebe42c8bb99aa5c20549410c05 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:02:39 -0400 Subject: [PATCH 176/514] remove formating info from messages --- tests/gettext/po/pig_latin/gt_01.po | 43 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/tests/gettext/po/pig_latin/gt_01.po b/tests/gettext/po/pig_latin/gt_01.po index 7f9a3c4a..22dc5a9f 100644 --- a/tests/gettext/po/pig_latin/gt_01.po +++ b/tests/gettext/po/pig_latin/gt_01.po @@ -20,38 +20,38 @@ msgstr "" #: gt_01.c:42 #, c-format -msgid "{w:bytes/%d}{Ngp:byte,bytes}\n" -msgstr "{w:bytes/%d}{Ngp:ytebay,ytesbay,}\n" +msgid "{:bytes}{N:byte,bytes}\n" +msgstr "{:bytes}{N:ytebay,ytesbay}\n" #: gt_01.c:44 #, c-format -msgid "{L:total} {:total/%u}\n" -msgstr "{L:otaltay} {:total/%u}\n" +msgid "{L:total} {:total}\n" +msgstr "{L:otaltay} {:total}\n" #: gt_01.c:60 #, c-format -msgid "Only {:marzlevanes/%d} {Ngp:marzlevane,marzlevanes} are functioning correctly\n" -msgstr "Onlyay {:marzlevanes/%d} {Ngp:arzlevanemay,arzlevanesmay} areyay unctioningfay orrectlycay\n" +msgid "Only {:marzlevanes} {N:marzlevane,marzlevanes} are functioning correctly\n" +msgstr "Onlyay {:marzlevanes} {N:arzlevanemay,arzlevanesmay} areyay unctioningfay orrectlycay\n" #: gt_01.c:63 msgid "Version {:version} {:date}\n" msgstr "Ersionvay {:version} {:date}\n" #: gt_01.c:66 -msgid "Unable to {g:verb/objectulate} forward velociping" -msgstr "Nableuay otay {g:verb/objectulate} orwardfay elocipingvay" +msgid "Unable to {:verb} forward velociping" +msgstr "Nableuay otay {g:verb} orwardfay elocipingvay" #: gt_01.c:67 -msgid "{g:style/automatic} synchronization of {g:type/cardinal} {g:target/grammeters} failed" -msgstr "{g:style/automatic} ynchronizationsay ofyay {g:type/cardinal} {g:target/grammeters} ailedfay" +msgid "{:style} synchronization of {:type} {:target} failed" +msgstr "{g:style} ynchronizationsay ofyay {g:type} {g:target} ailedfay" #: gt_01.c:69 #, c-format -msgid "{Lwcg:hydrocoptic marzlevanes}{:marzlevanes/%d}\n" -msgstr "{Lwcg:ydrocoptichay arzlevanesmay}{:marzlevanes/%d}\n" +msgid "{L:hydrocoptic marzlevanes}{:marzlevanes}\n" +msgstr "{L:ydrocoptichay arzlevanesmay}{:marzlevanes}\n" #: gt_01.c:71 -msgid "{Lwcg:Windings}{g:windings}\n" +msgid "{L:Windings}{:windings}\n" msgstr "{Lwcg:Indingsway}{g:windings}\n" #, c-format @@ -82,3 +82,20 @@ msgstr "ammetersgray" msgid "objectulate" msgstr "ectulatobjay" + +msgid "byte" +msgid_plural "bytes" +msgstr[0] "" +msgstr[1] "" + +msgid "marzlevane" +msgid_plural "marzlevanes" +msgstr[0] "" +msgstr[1] "" + +msgid "hydrocoptic marzlevanes" +msgstr "" + +msgid "Windings" +msgstr "" + From b160e25cb536f0b60341c8e6353cdb39d9c72c00 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:02:41 -0400 Subject: [PATCH 177/514] remove formating info from messages --- tests/gettext/po/pig_latin/ldns.po | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/gettext/po/pig_latin/ldns.po b/tests/gettext/po/pig_latin/ldns.po index 19878328..ca9645bb 100644 --- a/tests/gettext/po/pig_latin/ldns.po +++ b/tests/gettext/po/pig_latin/ldns.po @@ -20,11 +20,17 @@ msgstr "" #: gt_01.c:46 #, c-format -msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" -msgstr "Eceivedray {:received/%zu} {Ngp:ytebay,ytesbay} omfray {:from/%s}#{:port/%d} inyay {:time/%d} msyay\n" +msgid "Received {:received} {N:byte,bytes} from {:from}#{:port} in {:time} ms\n" +msgstr "Eceivedray {:received} {N:ytebay,ytesbay} omfray {:from}#{:port} inyay {:time} msyay\n" msgid "byte" msgstr "" msgid "bytes" msgstr "" + +msgid "byte" +msgid_plural "bytes" +msgstr[0] "" +msgstr[1] "" + From 19fbac50820dd442ebf1daad284f456faee4a248 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:02:42 -0400 Subject: [PATCH 178/514] remove formating info from messages --- tests/gettext/po/pig_latin/strerror.po | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/gettext/po/pig_latin/strerror.po b/tests/gettext/po/pig_latin/strerror.po index f0a27563..8b605668 100644 --- a/tests/gettext/po/pig_latin/strerror.po +++ b/tests/gettext/po/pig_latin/strerror.po @@ -45,7 +45,7 @@ msgstr "" "X-Generator: Poedit 1.8.1\n" "X-Poedit-SourceCharset: iso-8859-1\n" -msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgid "Received {:received} {N:byte,bytes} from {:from}#{:port} in {:time} ms\n" msgstr "" # 0 - ENOERROR @@ -460,3 +460,9 @@ msgstr "" # 96 - EOWNERDEAD msgid "Previous owner died" msgstr "" + +msgid "byte" +msgid_plural "bytes" +msgstr[0] "" +msgstr[1] "" + From 5d0228a1b17c3662093cc2a712d33950521ea56d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:02:44 -0400 Subject: [PATCH 179/514] remove formating info from messages --- tests/gettext/strerror.pot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gettext/strerror.pot b/tests/gettext/strerror.pot index c7d38cb2..c63e6bdb 100644 --- a/tests/gettext/strerror.pot +++ b/tests/gettext/strerror.pot @@ -42,7 +42,7 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -msgid "Received {:received/%zu} {Ngp:byte,bytes} from {:from/%s}#{:port/%d} in {:time/%d} ms\n" +msgid "Received {:received} {N:byte,bytes} from {:from}#{:port} in {:time} ms\n" msgstr "" # 0 - ENOERROR From a9b84737d79aa9494c4b10e49cfcd904347f9479 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 7 Jul 2015 15:03:01 -0400 Subject: [PATCH 180/514] expose --option option --- xo/xo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xo/xo.c b/xo/xo.c index e57bada6..e113c7fc 100644 --- a/xo/xo.c +++ b/xo/xo.c @@ -202,6 +202,7 @@ print_help (void) " --leading-xpath OR -l " "Add a prefix to generated XPaths (HTML)\n" " --open Open tags for the given path\n" +" --option -or -O Give formatting options\n" " --pretty OR -p Make 'pretty' output (add indent, newlines)\n" " --style ardinalyayammetersgrayErmissionpay eniedday6otuslay-oyay-eltayay \ No newline at end of file +amingflayordswayurningbayymayouchmay0123412341234foop43211234foop43211234foop432131.2.3Tue Jun 23 18:47:09 UTC 2015<__warning>gt_01.testNableuay otay ectulatobjay orwardfay elocipingvayectulatobjayErmissionpay eniedday<__warning>gt_01.testautomaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfayardinalyayammetersgrayErmissionpay eniedday6otuslay-oyay-eltayay \ No newline at end of file From ff026fb1d297336398255a9f5a4d0147c9f36f54 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Jul 2015 00:32:37 -0400 Subject: [PATCH 298/514] update test cases --- tests/gettext/saved/gt_01.XP.out | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/gettext/saved/gt_01.XP.out b/tests/gettext/saved/gt_01.XP.out index 89fde70a..f9198016 100644 --- a/tests/gettext/saved/gt_01.XP.out +++ b/tests/gettext/saved/gt_01.XP.out @@ -1,4 +1,9 @@ + amingflay + ordsway + urningbay + ymay + ouchmay 0 1 2 @@ -9,6 +14,14 @@ foop 4321 + 1234 + foop + 4321 + + 1234 + foop + 4321 + 3 1.2.3 Tue Jun 23 18:47:09 UTC 2015 From 53904dc27c5de827ba50c1e10902d364dbdcbf84 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Jul 2015 00:32:39 -0400 Subject: [PATCH 299/514] update test cases --- xopo/xopo.c | 62 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/xopo/xopo.c b/xopo/xopo.c index 7d694457..2d0bb275 100644 --- a/xopo/xopo.c +++ b/xopo/xopo.c @@ -27,48 +27,49 @@ #endif /* UNUSED */ static int opt_warn; /* Enable warnings */ +static int opt_numbers; /* Number our fields */ -typedef struct xopo_field_s { - TAILQ_ENTRY(xopo_field_s) xf_link; - char *xf_plural; - char xf_field[0]; -} xopo_field_t; +typedef struct xopo_msg_s { + TAILQ_ENTRY(xopo_msg_s) xm_link; + char *xm_plural; /* If plural, points to the second part */ + char xm_data[0]; /* Start of data */ +} xopo_msg_t; -typedef TAILQ_HEAD(xopo_field_list_s, xopo_field_s) xopo_field_list_t; +typedef TAILQ_HEAD(xopo_msg_list_s, xopo_msg_s) xopo_msg_list_t; -xopo_field_list_t field_list; +static xopo_msg_list_t field_list; static void -xopo_field_cb (const char *str, unsigned len, int plural) +xopo_msg_cb (const char *str, unsigned len, int plural) { - int sz = sizeof(xopo_field_t) + len + 1; - xopo_field_t *xfp = malloc(sz); - if (xfp == NULL) + int sz = sizeof(xopo_msg_t) + len + 1; + xopo_msg_t *xmp = malloc(sz); + if (xmp == NULL) return; - bzero(xfp, sz); - memcpy(xfp->xf_field, str, len); - xfp->xf_field[len] = '\0'; + bzero(xmp, sz); + memcpy(xmp->xm_data, str, len); + xmp->xm_data[len] = '\0'; if (plural) { - char *cp = strchr(xfp->xf_field, ','); + char *cp = strchr(xmp->xm_data, ','); if (cp) { *cp++ = '\0'; - xfp->xf_plural = cp; + xmp->xm_plural = cp; } } - xopo_field_t *xfp2; + xopo_msg_t *xmp2; - TAILQ_FOREACH(xfp2, &field_list, xf_link) { - if (strcmp(xfp->xf_field, xfp2->xf_field) == 0) { + TAILQ_FOREACH(xmp2, &field_list, xm_link) { + if (strcmp(xmp->xm_data, xmp2->xm_data) == 0) { /* Houston, we have a negative on that trajectory */ - free(xfp); + free(xmp); return; } } - TAILQ_INSERT_TAIL(&field_list, xfp, xf_link); + TAILQ_INSERT_TAIL(&field_list, xmp, xm_link); } static void @@ -102,6 +103,7 @@ static struct opts { static struct option long_opts[] = { { "help", no_argument, &opts.o_help, 1 }, + { "number", no_argument, NULL, 'n' }, { "option", required_argument, NULL, 'O' }, { "output", required_argument, NULL, 'o' }, { "po", required_argument, NULL, 'f' }, @@ -124,13 +126,17 @@ main (int argc UNUSED, char **argv) if (argc < 0) return 1; - while ((rc = getopt_long(argc, argv, "f:o:O:s:W", + while ((rc = getopt_long(argc, argv, "f:no:O:s:W", long_opts, NULL)) != -1) { switch (rc) { case 'f': opt_input = optarg; break; + case 'n': + opt_numbers = 1; + break; + case 'o': opt_output = optarg; break; @@ -253,7 +259,7 @@ main (int argc UNUSED, char **argv) *ep = '\0'; - cp = xo_simplify_format(NULL, cp, xopo_field_cb); + cp = xo_simplify_format(NULL, cp, xopo_msg_cb); if (cp) { fprintf(outfile, "msgid \"%s\"\n", cp); free(cp); @@ -263,16 +269,16 @@ main (int argc UNUSED, char **argv) if (!blank) fprintf(outfile, "\n"); - xopo_field_t *xfp; - TAILQ_FOREACH(xfp, &field_list, xf_link) { - if (xfp->xf_plural) { + xopo_msg_t *xmp; + TAILQ_FOREACH(xmp, &field_list, xm_link) { + if (xmp->xm_plural) { fprintf(outfile, "msgid \"%s\"\n" "msgid_plural \"%s\"\n" "msgstr[0] \"\"\n" "msgstr[1] \"\"\n\n", - xfp->xf_field, xfp->xf_plural); + xmp->xm_data, xmp->xm_plural); } else { - fprintf(outfile, "msgid \"%s\"\nmsgstr \"\"\n\n", xfp->xf_field); + fprintf(outfile, "msgid \"%s\"\nmsgstr \"\"\n\n", xmp->xm_data); } } From 010dd9050d6d859f1b933b9d9c95d78485d021d1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Jul 2015 23:40:41 -0400 Subject: [PATCH 300/514] start w/ xo_render; fix gcc gettext_changed warning --- libxo/libxo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 7b6960a0..06f11344 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -258,6 +258,8 @@ struct xo_handle_s { char *xo_version; /* Version string */ int xo_errno; /* Saved errno for "%m" */ char *xo_gt_domain; /* Gettext domain, suitable for dgettext(3) */ + xo_render_t *xo_render; /* Rendered field information */ + unsigned xo_num_render; /* Length of xo_render array */ }; /* Flag operations */ @@ -1821,6 +1823,9 @@ xo_destroy (xo_handle_t *xop_arg) xo_buf_cleanup(&xop->xo_attrs); xo_buf_cleanup(&xop->xo_color_buf); + if (xop->xo_render) + xo_free(xop->xo_render); + if (xop->xo_version) xo_free(xop->xo_version); @@ -5646,7 +5651,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) xop->xo_gt_domain = NULL; } - if (reordered) { + if (gettext_changed && reordered) { /* XXX Do something amazing here */ } From 09e4c5f5e3b9fbd1f4cc1a996952f931f775ee01 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 19:59:20 -0400 Subject: [PATCH 301/514] Add mm and mmi aliases --- bin/Zaliases | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/Zaliases b/bin/Zaliases index 2c04ae2e..04cdec77 100644 --- a/bin/Zaliases +++ b/bin/Zaliases @@ -23,3 +23,7 @@ cd build alias xx 'cc -I.. -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Werror -Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wformat -Wimplicit -Wmissing-declarations -Wnested-externs -Wparentheses -Wreturn-type -Wshadow -Wswitch -Wtrigraphs -Wuninitialized -Wunused -Wwrite-strings -fno-inline-functions-called-once -g -O2 -o xtest -DUNIT_TEST libxo.c' + +alias mm "make CFLAGS='-O0 -g'" + +alias mmi 'mm && mi' From b9a4147a2767dd1d326fe3254b08174c478bf8ca Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 19:59:33 -0400 Subject: [PATCH 302/514] add missing flags; use EXIT_FAILURE --- doc/libxo.txt | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index 6d397a92..1e66fcdb 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -773,11 +773,15 @@ they are often used to give to distinct views of the underlying data. **** The Gettext Modifier ({g:}) @gettext-modifier@ The gettext modifier is used to translate individual fields using the -current domain and language settings. Once libxo renders the field -value, it is passed to gettext(3), where it is used as a key to find -the native language translation. +gettext domain (typically set using the "{G:}" role) and current +language settings. Once libxo renders the field value, it is passed +to gettext(3), where it is used as a key to find the native language +translation. - xo_emit("{Lgwc:State}{g:state}\n", state); +In the following example, the strings "State" and "full" are passed +to gettext() to find locale-based translated strings. + + xo_emit("{Lgwc:State}{g:state}\n", "full"); See ^gettext-role^, ^plural-modifier^, and ^howto-i18n^ for additional details. @@ -1168,13 +1172,15 @@ styles, flags, or features: | info | Add info attributes (HTML) | | json | Emit JSON output | | keys | Emit the key attribute for keys (XML) | +| log-gettext | Log (via stderr) each gettext(3) string lookup | +| log-syslog | Log (via stderr) each syslog message (via xo_syslog) | | no-humanize | Ignore the {h:} modifier (TEXT, HTML) | | no-locale | Do not initialize the locale setting | | no-top | Do not emit a top set of braces (JSON) | | not-first | Pretend the 1st output item was not 1st (JSON) | | pretty | Emit pretty-printed output | | text | Emit TEXT output | -| underscores | Replace XML-friendly "-"s with JSON friendly "_"s e | +| underscores | Replace XML-friendly "-"s with JSON friendly "_"s e | | units | Add the 'units' (XML) or 'data-units (HTML) attribute | | warn | Emit warnings when libxo detects bad calls | | warn-xml | Emit warnings in XML | @@ -1769,7 +1775,7 @@ is returned. On failure, a message it emitted and -1 is returned. argc = xo_parse_args(argc, argv); if (argc < 0) - exit(1); + exit(EXIT_FAILURE); Following the call to xo_parse_args, the application can process the remaining arguments in a normal manner. See ^command-line-arguments^ @@ -2924,7 +2930,7 @@ Here is the unit test example: argc = xo_parse_args(argc, argv); if (argc < 0) - exit(1); + exit(EXIT_FAILURE); xo_set_info(NULL, info, info_count); From e3d0f5e9216c73740c5521793bda578ed517baa2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 19:59:59 -0400 Subject: [PATCH 303/514] finish gettext() esp. reordering --- libxo/libxo.c | 429 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 315 insertions(+), 114 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 06f11344..130052d6 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -203,20 +203,6 @@ typedef struct xo_colors_s { xo_color_t xoc_col_bg; /* Background color */ } xo_colors_t; -/* - * Reordering fields is required for gettext-based translation, where - * the target language might use words in a different order. Due to - * the way we render our fields, we need to allow rendering in normal - * (old) order, and then when rendering is complete, we reorder the - * fields into the proper (new) order. To facilitate this, we reorder - * the start and end of each field as we render them. - */ -typedef struct xo_render_s { /* Rendered field information */ - unsigned xr_fnum; /* Field number (1 origin) */ - unsigned xr_start; /* Offset of field start */ - unsigned xr_end; /* Offset of field end */ -} xo_render_t; - /* * xo_handle_t: this is the principle data structure for libxo. * It's used as a store for state, options, content, and all manor @@ -258,8 +244,6 @@ struct xo_handle_s { char *xo_version; /* Version string */ int xo_errno; /* Saved errno for "%m" */ char *xo_gt_domain; /* Gettext domain, suitable for dgettext(3) */ - xo_render_t *xo_render; /* Rendered field information */ - unsigned xo_num_render; /* Length of xo_render array */ }; /* Flag operations */ @@ -276,7 +260,7 @@ struct xo_handle_s { #define XOIF_CLEAR(_xop, _bit) XOF_BIT_CLEAR(_xop->xo_iflags, _bit) /* Internal flags */ -#define XOIF_REORDERING XOF_BIT(0) /* Reordering fields; record xo_render[] */ +#define XOIF_REORDER XOF_BIT(0) /* Reordering fields; record field info */ #define XOIF_DIV_OPEN XOF_BIT(1) /* A
is open */ #define XOIF_TOP_EMITTED XOF_BIT(2) /* The top JSON braces have been emitted */ #define XOIF_ANCHOR XOF_BIT(3) /* An anchor is in place */ @@ -402,7 +386,7 @@ typedef struct xo_field_info_s { unsigned xfi_flen; /* Format length */ unsigned xfi_elen; /* Encoding length */ unsigned xfi_fnum; /* Field number (if used; 0 otherwise) */ - unsigned xfi_renum; /* Reordered number */ + unsigned xfi_renum; /* Reordered number (0 == no renumbering) */ } xo_field_info_t; /* @@ -579,56 +563,6 @@ xo_printable (const char *str) return res; } -#ifdef HAVE_GETTEXT -static inline const char * -xo_dgettext (xo_handle_t *xop, const char *str) -{ - const char *domainname = xop->xo_gt_domain; - const char *res; - - res = dgettext(domainname, str); - - if (XOF_ISSET(xop, XOF_LOG_GETTEXT)) - fprintf(stderr, "xo: gettext: %s%s%smsgid \"%s\" returns \"%s\"\n", - domainname ? "domain \"" : "", xo_printable(domainname), - domainname ? "\", " : "", xo_printable(str), xo_printable(res)); - - return res; -} - -static inline const char * -xo_dngettext (xo_handle_t *xop, const char *sing, const char *plural, - unsigned long int n) -{ - const char *domainname = xop->xo_gt_domain; - const char *res; - - res = dngettext(domainname, sing, plural, n); - if (XOF_ISSET(xop, XOF_LOG_GETTEXT)) - fprintf(stderr, "xo: gettext: %s%s%s" - "msgid \"%s\", msgid_plural \"%s\" (%lu) returns \"%s\"\n", - domainname ? "domain \"" : "", - xo_printable(domainname), domainname ? "\", " : "", - xo_printable(sing), - xo_printable(plural), n, xo_printable(res)); - - return res; -} -#else /* HAVE_GETTEXT */ -static inline const char * -xo_dgettext (xo_handle_t *xop UNUSED, const char *str) -{ - return str; -} - -static inline const char * -xo_dngettext (xo_handle_t *xop UNUSED, const char *singular, - const char *plural, unsigned long int n) -{ - return (n == 1) ? singular : plural; -} -#endif /* HAVE_GETTEXT */ - static int xo_depth_check (xo_handle_t *xop, int depth) { @@ -1823,9 +1757,6 @@ xo_destroy (xo_handle_t *xop_arg) xo_buf_cleanup(&xop->xo_attrs); xo_buf_cleanup(&xop->xo_color_buf); - if (xop->xo_render) - xo_free(xop->xo_render); - if (xop->xo_version) xo_free(xop->xo_version); @@ -1941,6 +1872,7 @@ static xo_mapping_t xo_xof_names[] = { { XOF_INFO, "info" }, { XOF_KEYS, "keys" }, { XOF_LOG_GETTEXT, "log-gettext" }, + { XOF_LOG_SYSLOG, "log-syslog" }, { XOF_NO_HUMANIZE, "no-humanize" }, { XOF_NO_LOCALE, "no-locale" }, { XOF_NO_TOP, "no-top" }, @@ -2774,6 +2706,56 @@ xo_count_utf8_cols (const char *str, int len) return cols; } +#ifdef HAVE_GETTEXT +static inline const char * +xo_dgettext (xo_handle_t *xop, const char *str) +{ + const char *domainname = xop->xo_gt_domain; + const char *res; + + res = dgettext(domainname, str); + + if (XOF_ISSET(xop, XOF_LOG_GETTEXT)) + fprintf(stderr, "xo: gettext: %s%s%smsgid \"%s\" returns \"%s\"\n", + domainname ? "domain \"" : "", xo_printable(domainname), + domainname ? "\", " : "", xo_printable(str), xo_printable(res)); + + return res; +} + +static inline const char * +xo_dngettext (xo_handle_t *xop, const char *sing, const char *plural, + unsigned long int n) +{ + const char *domainname = xop->xo_gt_domain; + const char *res; + + res = dngettext(domainname, sing, plural, n); + if (XOF_ISSET(xop, XOF_LOG_GETTEXT)) + fprintf(stderr, "xo: gettext: %s%s%s" + "msgid \"%s\", msgid_plural \"%s\" (%lu) returns \"%s\"\n", + domainname ? "domain \"" : "", + xo_printable(domainname), domainname ? "\", " : "", + xo_printable(sing), + xo_printable(plural), n, xo_printable(res)); + + return res; +} +#else /* HAVE_GETTEXT */ +static inline const char * +xo_dgettext (xo_handle_t *xop UNUSED, const char *str) +{ + return str; +} + +static inline const char * +xo_dngettext (xo_handle_t *xop UNUSED, const char *singular, + const char *plural, unsigned long int n) +{ + return (n == 1) ? singular : plural; +} +#endif /* HAVE_GETTEXT */ + /* * This is really _re_formatting, since the normal format code has * generated a beautiful string into xo_data, starting at @@ -5031,6 +5013,63 @@ xo_parse_roles (xo_handle_t *xop, const char *fmt, return sp; } +/* + * Number any remaining fields that need numbers. Note that some + * field types (text, newline, escaped braces) never get numbers. + */ +static void +xo_gettext_finish_numbering_fields (xo_handle_t *xop UNUSED, + const char *fmt UNUSED, + xo_field_info_t *fields) +{ + xo_field_info_t *xfip; + unsigned fnum, max_fields; + uint64_t bits = 0; + + /* First make a list of add the explicitly used bits */ + for (xfip = fields, fnum = 0; xfip->xfi_ftype; xfip++) { + switch (xfip->xfi_ftype) { + case XO_ROLE_NEWLINE: /* Don't get numbered */ + case XO_ROLE_TEXT: + case XO_ROLE_EBRACE: + case 'G': + continue; + } + + fnum += 1; + if (fnum >= 63) + break; + + if (xfip->xfi_fnum) + bits |= 1 << xfip->xfi_fnum; + } + + max_fields = fnum; + + for (xfip = fields, fnum = 0; xfip->xfi_ftype; xfip++) { + switch (xfip->xfi_ftype) { + case XO_ROLE_NEWLINE: /* Don't get numbered */ + case XO_ROLE_TEXT: + case XO_ROLE_EBRACE: + case 'G': + continue; + } + + if (xfip->xfi_fnum != 0) + continue; + + /* Find the next unassigned field */ + for (fnum++; bits & (1 << fnum); fnum++) + continue; + + if (fnum > max_fields) + break; + + xfip->xfi_fnum = fnum; /* Mark the field number */ + bits |= 1 << fnum; /* Mark it used */ + } +} + /* * The format string uses field numbers, so we need to whiffle thru it * and make sure everything's sane and lovely. @@ -5234,7 +5273,7 @@ xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields, * field. We build a simplified version of the format string. */ static int -xo_do_simplify_format (xo_handle_t *xop UNUSED, +xo_gettext_simplify_format (xo_handle_t *xop UNUSED, xo_buffer_t *xbp, xo_field_info_t *fields, int this_field, @@ -5319,6 +5358,67 @@ xo_dump_fields (xo_field_info_t *fields) } } +#ifdef HAVE_GETTEXT +/* + * Find the field that matches the given field number + */ +static xo_field_info_t * +xo_gettext_find_field (xo_field_info_t *fields, unsigned fnum) +{ + xo_field_info_t *xfip; + + for (xfip = fields; xfip->xfi_ftype; xfip++) + if (xfip->xfi_fnum == fnum) + return xfip; + + return NULL; +} + +/* + * At this point, we need to consider if the fields have been reordered, + * such as "The {:adjective} {:noun}" to "La {:noun} {:adjective}". + * + * We need to rewrite the new_fields using the old fields order, + * so that we can render the message using the arguments as they + * appear on the stack. It's a lot of work, but we don't really + * want to (eventually) fall into the standard printf code which + * means using the arguments straight (and in order) from the + * varargs we were originally passed. + */ +static void +xo_gettext_rewrite_fields (xo_handle_t *xop UNUSED, + xo_field_info_t *fields, unsigned max_fields) +{ + xo_field_info_t tmp[max_fields]; + bzero(tmp, max_fields * sizeof(tmp[0])); + + unsigned fnum = 0; + xo_field_info_t *newp, *outp, *zp; + for (newp = fields, outp = tmp; newp->xfi_ftype; newp++, outp++) { + switch (newp->xfi_ftype) { + case XO_ROLE_NEWLINE: /* Don't get numbered */ + case XO_ROLE_TEXT: + case XO_ROLE_EBRACE: + case 'G': + *outp = *newp; + outp->xfi_renum = 0; + continue; + } + + zp = xo_gettext_find_field(fields, ++fnum); + if (zp == NULL) { /* Should not occur */ + *outp = *newp; + outp->xfi_renum = 0; + continue; + } + + *outp = *zp; + outp->xfi_renum = newp->xfi_fnum; + } + + memcpy(fields, tmp, max_fields * sizeof(tmp[0])); +} + /* * We've got two lists of fields, the old list from the original * format string and the new one from the parsed gettext reply. The @@ -5331,12 +5431,15 @@ xo_dump_fields (xo_field_info_t *fields) */ static int xo_gettext_combine_formats (xo_handle_t *xop, const char *fmt UNUSED, - const char *gtfmt, xo_field_info_t *old_fields, - xo_field_info_t *new_fields, int *reorderedp) + const char *gtfmt, xo_field_info_t *old_fields, + xo_field_info_t *new_fields, unsigned new_max_fields, + int *reorderedp) { int reordered = 0; xo_field_info_t *newp, *oldp, *startp = old_fields; + xo_gettext_finish_numbering_fields(xop, fmt, old_fields); + for (newp = new_fields; newp->xfi_ftype; newp++) { switch (newp->xfi_ftype) { case XO_ROLE_NEWLINE: @@ -5402,6 +5505,7 @@ xo_gettext_combine_formats (xo_handle_t *xop, const char *fmt UNUSED, */ copy_it: newp->xfi_flags = oldp->xfi_flags; + newp->xfi_fnum = oldp->xfi_fnum; newp->xfi_format = oldp->xfi_format; newp->xfi_flen = oldp->xfi_flen; newp->xfi_encoding = oldp->xfi_encoding; @@ -5409,6 +5513,11 @@ xo_gettext_combine_formats (xo_handle_t *xop, const char *fmt UNUSED, } *reorderedp = reordered; + if (reordered) { + xo_gettext_finish_numbering_fields(xop, fmt, new_fields); + xo_gettext_rewrite_fields(xop, new_fields, new_max_fields); + } + return 0; } @@ -5429,14 +5538,12 @@ xo_gettext_combine_formats (xo_handle_t *xop, const char *fmt UNUSED, * format string: * "cluse-a {:fd} retoorned {:test}. Bork {:error} Bork. Bork.\n" * If we have to reorder fields within the message, then things get - * complicated. We have to change styles to XO_STYLE_GTPARAMS, and - * build name/value pairs. Then we reformat the entire content to - * match the new format. + * complicated. See xo_gettext_rewrite_fields. * * Summary: i18n aighn't cheap. */ static const char * -xo_build_gettext_format (xo_handle_t *xop UNUSED, +xo_gettext_build_format (xo_handle_t *xop UNUSED, xo_field_info_t *fields UNUSED, int this_field UNUSED, const char *fmt, char **new_fmtp) @@ -5448,8 +5555,8 @@ xo_build_gettext_format (xo_handle_t *xop UNUSED, xo_buffer_t xb; xo_buf_init(&xb); - if (xo_do_simplify_format(xop, &xb, fields, - this_field, fmt, NULL)) + if (xo_gettext_simplify_format(xop, &xb, fields, + this_field, fmt, NULL)) goto bail2; const char *gtfmt = xo_dgettext(xop, xb.xb_bufp); @@ -5473,18 +5580,77 @@ xo_build_gettext_format (xo_handle_t *xop UNUSED, return fmt; } +static void +xo_gettext_rebuild_content (xo_handle_t *xop, xo_field_info_t *fields, + unsigned *fstart, unsigned min_fstart, + unsigned *fend, unsigned max_fend) +{ + xo_field_info_t *xfip; + char *buf; + unsigned base = fstart[min_fstart]; + unsigned blen = fend[max_fend] - base; + xo_buffer_t *xbp = &xop->xo_data; + + if (blen == 0) + return; + + buf = xo_realloc(NULL, blen); + if (buf == NULL) + return; + + memcpy(buf, xbp->xb_bufp + fstart[min_fstart], blen); /* Copy our data */ + + unsigned field = min_fstart, soff, doff = base, len, fnum; + xo_field_info_t *zp; + + /* + * Be aware there are two competing views of "field number": we + * want the user to thing in terms of "The {1:size}" where {G:}, + * newlines, escaped braces, and text don't have numbers. But is + * also the internal view, where we have an array of + * xo_field_info_t and every field have an index. fnum, fstart[] + * and fend[] are the latter, but xfi_renum is the former. + */ + for (xfip = fields + field; xfip->xfi_ftype; xfip++, field++) { + fnum = field; + if (xfip->xfi_renum) { + zp = xo_gettext_find_field(fields, xfip->xfi_renum); + fnum = zp ? zp - fields : field; + } + + soff = fstart[fnum]; + len = fend[fnum] - soff; + + if (len > 0) { + soff -= base; + memcpy(xbp->xb_bufp + doff, buf + soff, len); + doff += len; + } + } + + xo_free(buf); +} +#endif /* HAVE_GETTEXT */ + static int xo_do_emit (xo_handle_t *xop, const char *fmt) { +#ifdef HAVE_GETTEXT + int gettext_inuse = 0; + int gettext_changed = 0; + int gettext_reordered = 0; + xo_field_info_t *new_fields = NULL; +#else /* HAVE_GETTEXT */ + const int gettext_reordered = 0; +#endif /* HAVE_GETTEXT */ + int rc = 0; int flush = XOF_ISSET(xop, XOF_FLUSH); int flush_line = XOF_ISSET(xop, XOF_FLUSH_LINE); - int gettext_inuse = 0; - int gettext_changed = 0; - int reordered = 0; char *new_fmt = NULL; - xo_field_info_t *new_fields = NULL; - unsigned new_max_fields = 0; + + if (XOIF_ISSET(xop, XOIF_REORDER)) + flush_line = 0; xop->xo_columns = 0; /* Always reset it */ xop->xo_errno = errno; /* Save for "%m" */ @@ -5500,25 +5666,47 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) unsigned ftype; xo_xff_flags_t flags; + /* + * Some overhead for gettext; if the fields in the msgstr returned + * by gettext are reordered, then we need to record start and end + * for each field. We'll go ahead and render the fields in the + * normal order, but later we can then reconstruct the reordered + * fields using these fstart/fend values. + */ + unsigned flimit = max_fields * 2; /* Pessimistic limit */ + unsigned min_fstart = flimit - 1; + unsigned max_fend = 0; /* Highest recorded fend[] entry */ + unsigned fstart[flimit]; + bzero(fstart, flimit * sizeof(fstart[0])); + unsigned fend[flimit]; + bzero(fend, flimit * sizeof(fend[0])); + for (xfip = fields, field = 0; xfip->xfi_ftype && field < max_fields; xfip++, field++) { ftype = xfip->xfi_ftype; flags = xfip->xfi_flags; + /* Record field start offset */ + if (gettext_reordered) { + fstart[field] = xo_buf_offset(&xop->xo_data); + if (min_fstart > field) + min_fstart = field; + } + if (ftype == XO_ROLE_NEWLINE) { xo_line_close(xop); if (flush_line && xo_flush_h(xop) < 0) return -1; - continue; + goto bottom; } else if (ftype == XO_ROLE_EBRACE) { xo_format_text(xop, xfip->xfi_start, xfip->xfi_len); - continue; + goto bottom; } else if (ftype == XO_ROLE_TEXT) { /* Normal text */ xo_format_text(xop, xfip->xfi_content, xfip->xfi_clen); - continue; + goto bottom; } /* @@ -5554,6 +5742,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) */ xo_set_gettext_domain(xop, xfip); +#ifdef HAVE_GETTEXT if (!gettext_inuse) { /* Only translate once */ gettext_inuse = 1; if (new_fmt) { @@ -5561,13 +5750,12 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) new_fmt = NULL; } - xo_build_gettext_format(xop, fields, field, + xo_gettext_build_format(xop, fields, field, xfip->xfi_next, &new_fmt); if (new_fmt) { gettext_changed = 1; - /* XXX Need to support field reordering here */ - new_max_fields = xo_count_fields(xop, new_fmt); + unsigned new_max_fields = xo_count_fields(xop, new_fmt); if (++new_max_fields < max_fields) new_max_fields = max_fields; @@ -5579,28 +5767,30 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) if (!xo_parse_fields(xop, new_fields + 1, new_max_fields, new_fmt)) { - reordered = 0; + gettext_reordered = 0; if (!xo_gettext_combine_formats(xop, fmt, new_fmt, - fields, new_fields + 1, &reordered)) { - - if (reordered) { - /* XXX Underimplemented */ - xo_failure(xop, "gettext finds reordered " - "fields in '%s' and '%s'", - xo_printable(fmt), - xo_printable(new_fmt)); - flush_line = 0; - goto bail2; + fields, new_fields + 1, + new_max_fields, &gettext_reordered)) { + + if (gettext_reordered) { + if (XOF_ISSET(xop, XOF_LOG_GETTEXT)) + xo_failure(xop, "gettext finds reordered " + "fields in '%s' and '%s'", + xo_printable(fmt), + xo_printable(new_fmt)); + flush_line = 0; /* Must keep at content */ + XOIF_SET(xop, XOIF_REORDER); } - field = 0; /* Will be incremented at top of loop */ + field = -1; /* Will be incremented at top of loop */ xfip = new_fields; max_fields = new_max_fields; } } } } +#endif /* HAVE_GETTEXT */ continue; } else if (xfip->xfi_clen || xfip->xfi_format) { @@ -5623,7 +5813,24 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) if (flags & XFF_WS) xo_format_content(xop, "padding", NULL, " ", 1, NULL, 0, 0); + + bottom: + /* Record the end-of-field offset */ + if (gettext_reordered) { + fend[field] = xo_buf_offset(&xop->xo_data); + max_fend = field; + } + } + +#ifdef HAVE_GETTEXT + if (gettext_changed && gettext_reordered) { + /* Final step: rebuild the content using the rendered fields */ + xo_gettext_rebuild_content(xop, new_fields + 1, fstart, min_fstart, + fend, max_fend); } +#endif /* HAVE_GETTEXT */ + + XOIF_CLEAR(xop, XOIF_REORDER); /* If we don't have an anchor, write the text out */ if (flush && !XOIF_ISSET(xop, XOIF_ANCHOR)) { @@ -5633,11 +5840,6 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) rc = -1; } - if (0) { - bail2: - rc = -1; - } - if (new_fmt) xo_free(new_fmt); @@ -5651,10 +5853,6 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) xop->xo_gt_domain = NULL; } - if (gettext_changed && reordered) { - /* XXX Do something amazing here */ - } - return (rc < 0) ? rc : (int) xop->xo_columns; } @@ -5663,7 +5861,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) * is exposed to tools can perform this function. See xo(1). */ char * -xo_simplify_format (xo_handle_t *xop, const char *fmt, +xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers, xo_simplify_field_func_t field_cb) { xop = xo_default(xop); @@ -5682,7 +5880,10 @@ xo_simplify_format (xo_handle_t *xop, const char *fmt, xo_buffer_t xb; xo_buf_init(&xb); - if (xo_do_simplify_format(xop, &xb, fields, -1, fmt, field_cb)) + if (with_numbers) + xo_gettext_finish_numbering_fields(xop, fmt, fields); + + if (xo_gettext_simplify_format(xop, &xb, fields, -1, fmt, field_cb)) return NULL; return xb.xb_bufp; From 92373d4507ff3a1be1a4fa221c500bebfba6842e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:15 -0400 Subject: [PATCH 304/514] add LOG_SYSLOG and LOG_GETTEXT --- libxo/xo.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libxo/xo.h b/libxo/xo.h index f40004ba..9d8aa8fd 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -53,7 +53,7 @@ typedef unsigned long long xo_xof_flags_t; #define XOF_BIT(_n) ((xo_xof_flags_t) 1 << (_n)) #define XOF_CLOSE_FP XOF_BIT(0) /** Close file pointer on xo_close() */ #define XOF_PRETTY XOF_BIT(1) /** Make 'pretty printed' output */ -#define XOF_RESV2 XOF_BIT(2) /* Unused */ +#define XOF_LOG_SYSLOG XOF_BIT(2) /** Log (on stderr) our syslog content */ #define XOF_RESV3 XOF_BIT(3) /* Unused */ #define XOF_WARN XOF_BIT(4) /** Generate warnings for broken calls */ @@ -86,7 +86,7 @@ typedef unsigned long long xo_xof_flags_t; #define XOF_COLOR XOF_BIT(26) /** Enable color and effects */ #define XOF_NO_HUMANIZE XOF_BIT(27) /** Block the {h:} modifier */ -#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log gettext lookup strings (stderr) */ +#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */ #define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */ /* @@ -462,7 +462,7 @@ xo_set_syslog_enterprise_id (unsigned short eid); typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int); char * -xo_simplify_format (xo_handle_t *xop, const char *fmt, +xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers, xo_simplify_field_func_t field_cb); #endif /* INCLUDE_XO_H */ From 2f05e243de59c7533c514abbeba1cfbd7f6ef5a9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:20 -0400 Subject: [PATCH 305/514] add missing flags --- libxo/xo_parse_args.3 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libxo/xo_parse_args.3 b/libxo/xo_parse_args.3 index 72a8f0e6..e39e88c9 100644 --- a/libxo/xo_parse_args.3 +++ b/libxo/xo_parse_args.3 @@ -35,7 +35,7 @@ On failure, a message it emitted and -1 is returned. .Bd -literal -offset indent argc = xo_parse_args(argc, argv); if (argc < 0) - exit(1); + exit(EXIT_FAILURE); .Ed .Pp Following the call to @@ -72,6 +72,15 @@ Add info attributes (HTML) Emit JSON output .It Dv keys Emit the key attribute for keys (XML) +.It Dv log-gettext +Log (via stderr) each +.Xr gettext 3 +string lookup +.It Dv log-syslog +Log (via stderr) each syslog message (via +.Xr xo_syslog 3 ) +.If Dv no-humanize +Ignore the {h:} modifier (TEXT, HTML) .It Dv no-locale Do not initialize the locale setting .It Dv no-top @@ -82,6 +91,8 @@ Pretend the 1st output item was not 1st (JSON) Emit pretty-printed output .It Dv text Emit TEXT output +.If Dv underscores +Replace XML-friendly "-"s with JSON friendly "_"s e .It Dv units Add the 'units' (XML) or 'data-units (HTML) attribute .It Dv warn From 66a0baf18302de49e35165466829bb886fcafa48 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:21 -0400 Subject: [PATCH 306/514] add missing flags --- libxo/xo_set_flags.3 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libxo/xo_set_flags.3 b/libxo/xo_set_flags.3 index c0615f24..afcac54c 100644 --- a/libxo/xo_set_flags.3 +++ b/libxo/xo_set_flags.3 @@ -50,6 +50,13 @@ Allow color and effects if the output device is a terminal. Display info data attributes (HTML) .It Dv XOF_KEYS Emit the key attribute (XML) +.It Dv XOF_LOG_GETTEXT +Log (via stderr) each +.Xr gettext 3 +string lookup +.It Dv XOF_LOG_SYSLOG +Log (via stderr) each syslog message (via +.Xr xo_syslog 3 ) .It Dv XOF_NO_ENV Do not use the .Ev LIBXO_OPTIONS From 810f2410ce1db2f27bc38a5fb9cecc2d10bb58e4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:38 -0400 Subject: [PATCH 307/514] add support for XOF_LOG_SYSLOG --- libxo/xo_syslog.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 7c49914c..9e60c069 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -500,9 +500,11 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) int saved_errno = errno; char tbuf[2048]; char *tp = NULL, *ep = NULL; - char *start_of_msg = NULL, *v0_hdr = NULL; + unsigned start_of_msg = 0; + char *v0_hdr = NULL; xo_sbuffer_t xb; static pid_t my_pid; + unsigned log_offset; if (my_pid == 0) my_pid = xo_unit_test ? 222 : getpid(); @@ -576,6 +578,8 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) tp += xo_snprintf(tp, ep - tp, ": "); } + log_offset = xb.xb_curp - xb.xb_basep; + /* Add PRI, PRIVAL, and VERSION */ xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "<%d>1 ", pri); @@ -679,7 +683,7 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) /* Save the start of the message */ if (xo_logstat & LOG_PERROR) - start_of_msg = xb.xb_curp; + start_of_msg = xb.xb_curp - xb.xb_basep; xo_set_style(xop, XO_STYLE_TEXT); xo_set_flags(xop, XOF_UTF8); @@ -692,7 +696,10 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) if (xb.xb_curp[-1] == '\n') *--xb.xb_curp = '\0'; - xo_send_syslog(xb.xb_basep, v0_hdr, start_of_msg); + if (xo_get_flags(xop) & XOF_LOG_SYSLOG) + fprintf(stderr, "xo: syslog: %s\n", xb.xb_basep + log_offset); + + xo_send_syslog(xb.xb_basep, v0_hdr, xb.xb_basep + start_of_msg); xo_destroy(xop); From a42bcdaae912066e85394bd889fe1e58d3e67a88 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:46 -0400 Subject: [PATCH 308/514] gettext testing --- tests/gettext/gt_01.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/gettext/gt_01.c b/tests/gettext/gt_01.c index fc355645..a0200c29 100644 --- a/tests/gettext/gt_01.c +++ b/tests/gettext/gt_01.c @@ -63,6 +63,10 @@ main (int argc, char **argv) xo_emit("{G:}Your {qg:adjective} {g:noun} is {g:verb} {qg:owner} {g:target}\n", "flaming", "sword", "burning", "my", "couch"); + xo_emit("{G:}The {qg:adjective} {g:noun} was {g:verb} {qg:owner} {g:target}\n", + "flaming", "sword", "burning", "my", "couch"); + + int i; for (i = 0; i < 5; i++) xo_emit("{lw:bytes/%d}{Ngp:byte,bytes}\n", i); From 6ecc5dcc9bad9660178d02dd946d64210b447e3d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:49 -0400 Subject: [PATCH 309/514] gettext testing --- tests/gettext/gt_01.pot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/gettext/gt_01.pot b/tests/gettext/gt_01.pot index 9a4d8282..1d09223e 100644 --- a/tests/gettext/gt_01.pot +++ b/tests/gettext/gt_01.pot @@ -86,6 +86,9 @@ msgstr "" msgid "Your {:adjective} {:noun} is {:verb} {:owner} {:target}\n" msgstr "" +msgid "The {:adjective} {:noun} was {:verb} {:owner} {:target}\n" +msgstr "" + msgid "flaming" msgstr "" From 9fd7e58f93274064de84e66e0c13e4f0492744c1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:50 -0400 Subject: [PATCH 310/514] gettext testing --- tests/gettext/po/pig_latin/gt_01.po | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/gettext/po/pig_latin/gt_01.po b/tests/gettext/po/pig_latin/gt_01.po index 456d37cc..269bad54 100644 --- a/tests/gettext/po/pig_latin/gt_01.po +++ b/tests/gettext/po/pig_latin/gt_01.po @@ -35,7 +35,7 @@ msgstr "Onlyay {:marzlevanes} {N:marzlevane,marzlevanes} areyay unctioningfay or #: gt_01.c:63 msgid "Version {:version} {:date}\n" -msgstr "Ersionvay {:version} {:date}\n" +msgstr "Ersionvay {:date} {:version}\n" #: gt_01.c:66 msgid "Unable to {:verb} forward velociping" @@ -88,7 +88,10 @@ msgid "Windings" msgstr "Indingsway" msgid "Your {:adjective} {:noun} is {:verb} {:owner} {:target}\n" -msgstr "Ouryay {:adjective} {:noun} isyay {:verb} {:owner} {:target}\n" +msgstr "Ouryay {:noun} {:adjective} isyay {:owner}{:target} bubbly-bubbly {:verb}\n" + +msgid "The {:adjective} {:noun} was {:verb} {:owner} {:target}\n" +msgstr "Ethay {:noun} asway '{:owner}{:adjective}{:target}' {:verb}\n" msgid "flaming" msgstr "amingflay" @@ -103,4 +106,4 @@ msgid "my" msgstr "ymay" msgid "couch" -msgstr "ouchmay" +msgstr "ouchcay" From 055a98f5442f784a9db6bf8c475faaa0d5286e82 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:55 -0400 Subject: [PATCH 311/514] update test cases --- tests/gettext/saved/gt_01.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gettext/saved/gt_01.H.out b/tests/gettext/saved/gt_01.H.out index 7fa05da0..13606bf7 100644 --- a/tests/gettext/saved/gt_01.H.out +++ b/tests/gettext/saved/gt_01.H.out @@ -1 +1 @@ -
Ouryay
amingflay
ordsway
isyay
urningbay
ymay
ouchmay
0
yebay
1
yesbay
2
yezbay
3
yezbay
4
yezbay
otaltay
1234
Eceivedray
1234
ldb2
omfray
foop
#
4321
inyay
32
msyay
Received
1234
yezbay
from
foop
#
4321
in
32
ms
Eceivedray
1234
ldb2
omfray
foop
#
4321
inyay
32
msyay
Onlyay
3
arzlevanezmay
areyay unctioningfay orrectlycay
Ersionvay
1.2.3
Tue Jun 23 18:47:09 UTC 2015
gt_01.test
:
Nableuay otay
ectulatobjay
orwardfay elocipingvay
:
Ermissionpay eniedday
gt_01.test
:
automaticyay
ynchronizationsay ofyay
ardinalyay
ammetersgray
ailedfay
:
Ermissionpay eniedday
ydrocoptichay arzlevanesmay
:
6
Dude,
Indingsway
:
otuslay-oyay-eltayay
\ No newline at end of file +
Ouryay
ordsway
amingflay
isyay
ymay
ouchcay
bubbly-bubbly
urningbay
Ethay
ordsway
asway '
ymay
amingflay
ouchcay
'
urningbay
0
yebay
1
yesbay
2
yezbay
3
yezbay
4
yezbay
otaltay
1234
Eceivedray
1234
ldb2
omfray
foop
#
4321
inyay
32
msyay
Received
1234
yezbay
from
foop
#
4321
in
32
ms
Eceivedray
1234
ldb2
omfray
foop
#
4321
inyay
32
msyay
Onlyay
3
arzlevanezmay
areyay unctioningfay orrectlycay
Ersionvay
Tue Jun 23 18:47:09 UTC 2015
1.2.3
gt_01.test
:
Nableuay otay
ectulatobjay
orwardfay elocipingvay
:
Ermissionpay eniedday
gt_01.test
:
automaticyay
ynchronizationsay ofyay
ardinalyay
ammetersgray
ailedfay
:
Ermissionpay eniedday
ydrocoptichay arzlevanesmay
:
6
Dude,
Indingsway
:
otuslay-oyay-eltayay
\ No newline at end of file From 6261d8c242427fbb8b448f77a6b588996c3f2993 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:56 -0400 Subject: [PATCH 312/514] update test cases --- tests/gettext/saved/gt_01.HIPx.out | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/gettext/saved/gt_01.HIPx.out b/tests/gettext/saved/gt_01.HIPx.out index 1c218793..06b6a3c3 100644 --- a/tests/gettext/saved/gt_01.HIPx.out +++ b/tests/gettext/saved/gt_01.HIPx.out @@ -1,14 +1,23 @@
Ouryay
-
amingflay
-
ordsway
+
+
amingflay
isyay
+
ymay
+
ouchcay
+
bubbly-bubbly
urningbay
-
+
+
+
Ethay
+
ordsway
+
asway '
ymay
-
-
ouchmay
+
amingflay
+
ouchcay
+
'
+
urningbay
0
@@ -88,9 +97,9 @@
Ersionvay
-
1.2.3
-
Tue Jun 23 18:47:09 UTC 2015
+
+
1.2.3
gt_01.test
From 760a69852cda408a8946b1df4c710cb6d62e0bbf Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:56 -0400 Subject: [PATCH 313/514] update test cases --- tests/gettext/saved/gt_01.HP.out | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/gettext/saved/gt_01.HP.out b/tests/gettext/saved/gt_01.HP.out index 312ec22e..573d7b38 100644 --- a/tests/gettext/saved/gt_01.HP.out +++ b/tests/gettext/saved/gt_01.HP.out @@ -1,14 +1,23 @@
Ouryay
-
amingflay
-
ordsway
+
+
amingflay
isyay
+
ymay
+
ouchcay
+
bubbly-bubbly
urningbay
-
+
+
+
Ethay
+
ordsway
+
asway '
ymay
-
-
ouchmay
+
amingflay
+
ouchcay
+
'
+
urningbay
0
@@ -88,9 +97,9 @@
Ersionvay
-
1.2.3
-
Tue Jun 23 18:47:09 UTC 2015
+
+
1.2.3
gt_01.test
From e04fad8d7aa80a6dff39d5dc030c5a0a38ceadf9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:57 -0400 Subject: [PATCH 314/514] update test cases --- tests/gettext/saved/gt_01.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gettext/saved/gt_01.J.out b/tests/gettext/saved/gt_01.J.out index f9840233..86527d14 100644 --- a/tests/gettext/saved/gt_01.J.out +++ b/tests/gettext/saved/gt_01.J.out @@ -1,2 +1,2 @@ -{"top": {"adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchmay", "bytes": [0,1,2,3,4],"total":1234,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"marzlevanes":3,"version":"1.2.3","date":"Tue Jun 23 18:47:09 UTC 2015", "__warning": {"program":"gt_01.test","message":"Nableuay otay ectulatobjay orwardfay elocipingvay","verb":ectulatobjay,"error":"Ermissionpay eniedday"}, "__warning": {"program":"gt_01.test","message":"automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay","style":automaticyay,"type":"ardinalyay","target":"ammetersgray","error":"Ermissionpay eniedday"},"marzlevanes":6,"windings":"otuslay-oyay-eltayay"} +{"top": {"adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchcay","adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchcay", "bytes": [0,1,2,3,4],"total":1234,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"marzlevanes":3,"version":"1.2.3","date":"Tue Jun 23 18:47:09 UTC 2015", "__warning": {"program":"gt_01.test","message":"Nableuay otay ectulatobjay orwardfay elocipingvay","verb":ectulatobjay,"error":"Ermissionpay eniedday"}, "__warning": {"program":"gt_01.test","message":"automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay","style":automaticyay,"type":"ardinalyay","target":"ammetersgray","error":"Ermissionpay eniedday"},"marzlevanes":6,"windings":"otuslay-oyay-eltayay"} } From b269d7d89db2589274c1c227221461969acf8966 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:58 -0400 Subject: [PATCH 315/514] update test cases --- tests/gettext/saved/gt_01.JP.out | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/gettext/saved/gt_01.JP.out b/tests/gettext/saved/gt_01.JP.out index b99b6d44..537ab213 100644 --- a/tests/gettext/saved/gt_01.JP.out +++ b/tests/gettext/saved/gt_01.JP.out @@ -4,7 +4,12 @@ "noun": "ordsway", "verb": "urningbay", "owner": "ymay", - "target": "ouchmay", + "target": "ouchcay", + "adjective": "amingflay", + "noun": "ordsway", + "verb": "urningbay", + "owner": "ymay", + "target": "ouchcay", "bytes": [ 0, 1, From 40794d41a928433fd3d37d92c353428afa43edd0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:00:59 -0400 Subject: [PATCH 316/514] update test cases --- tests/gettext/saved/gt_01.T.out | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/gettext/saved/gt_01.T.out b/tests/gettext/saved/gt_01.T.out index efd9437c..440d9a5b 100644 --- a/tests/gettext/saved/gt_01.T.out +++ b/tests/gettext/saved/gt_01.T.out @@ -1,4 +1,5 @@ -Ouryay amingflay ordsway isyay urningbay ymay ouchmay +Ouryay ordsway amingflay isyay ymayouchcay bubbly-bubbly urningbay +Ethay ordsway asway 'ymayamingflayouchcay' urningbay 0 yebay 1 yesbay 2 yezbay @@ -9,7 +10,7 @@ Eceivedray 1234 ldb2 omfray foop#4321 inyay 32 msyay Received 1234 yezbay from foop#4321 in 32 ms Eceivedray 1234 ldb2 omfray foop#4321 inyay 32 msyay Onlyay 3 arzlevanezmay areyay unctioningfay orrectlycay -Ersionvay 1.2.3 Tue Jun 23 18:47:09 UTC 2015 +Ersionvay Tue Jun 23 18:47:09 UTC 2015 1.2.3 gt_01.test: Nableuay otay ectulatobjay orwardfay elocipingvay: Ermissionpay eniedday gt_01.test: automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay: Ermissionpay eniedday ydrocoptichay arzlevanesmay: 6 From 5021487c30999d63c5bd7deb4a00dec1bbc0e81a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:01:01 -0400 Subject: [PATCH 317/514] update test cases --- tests/gettext/saved/gt_01.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gettext/saved/gt_01.X.out b/tests/gettext/saved/gt_01.X.out index 6924b6f7..4eb46223 100644 --- a/tests/gettext/saved/gt_01.X.out +++ b/tests/gettext/saved/gt_01.X.out @@ -1 +1 @@ -amingflayordswayurningbayymayouchmay0123412341234foop43211234foop43211234foop432131.2.3Tue Jun 23 18:47:09 UTC 2015<__warning>gt_01.testNableuay otay ectulatobjay orwardfay elocipingvayectulatobjayErmissionpay eniedday<__warning>gt_01.testautomaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfayardinalyayammetersgrayErmissionpay eniedday6otuslay-oyay-eltayay \ No newline at end of file +amingflayordswayurningbayymayouchcayamingflayordswayurningbayymayouchcay0123412341234foop43211234foop43211234foop432131.2.3Tue Jun 23 18:47:09 UTC 2015<__warning>gt_01.testNableuay otay ectulatobjay orwardfay elocipingvayectulatobjayErmissionpay eniedday<__warning>gt_01.testautomaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfayardinalyayammetersgrayErmissionpay eniedday6otuslay-oyay-eltayay \ No newline at end of file From edd30b27d4dd781eee235e16129aaebef957c50e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:01:01 -0400 Subject: [PATCH 318/514] update test cases --- tests/gettext/saved/gt_01.XP.out | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/gettext/saved/gt_01.XP.out b/tests/gettext/saved/gt_01.XP.out index f9198016..eac42845 100644 --- a/tests/gettext/saved/gt_01.XP.out +++ b/tests/gettext/saved/gt_01.XP.out @@ -3,7 +3,12 @@ ordsway urningbay ymay - ouchmay + ouchcay + amingflay + ordsway + urningbay + ymay + ouchcay 0 1 2 From 4bd5ea53353d3630f24aeb9f033d52f9b003f352 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:01:03 -0400 Subject: [PATCH 319/514] update test cases --- xopo/xopo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xopo/xopo.c b/xopo/xopo.c index 2d0bb275..37a94c09 100644 --- a/xopo/xopo.c +++ b/xopo/xopo.c @@ -193,7 +193,7 @@ main (int argc UNUSED, char **argv) fmt = *argv++; if (opt_simplify) { - fmt = xo_simplify_format(NULL, opt_simplify, NULL); + fmt = xo_simplify_format(NULL, opt_simplify, opt_numbers, NULL); if (fmt) { xo_emit("{:format}\n", fmt); free(fmt); @@ -259,7 +259,7 @@ main (int argc UNUSED, char **argv) *ep = '\0'; - cp = xo_simplify_format(NULL, cp, xopo_msg_cb); + cp = xo_simplify_format(NULL, cp, opt_numbers, xopo_msg_cb); if (cp) { fprintf(outfile, "msgid \"%s\"\n", cp); free(cp); From c98c61cc7328ebee99234a8be2155a0229ebd007 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 20:37:01 -0400 Subject: [PATCH 320/514] Add {G:}, {g:}, and {p:}. Need to invent a .man backend for oxtradoc so this isn't manual. --- libxo/xo_format.5 | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index f2185f50..23550ca1 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -204,6 +204,42 @@ can use CSS to direct their display parameters. .Bd -literal -offset indent xo_emit("{D:((}{:name}{D:))}\\n", name); .Ed +.Ss The Gettext Role ({G:}) +.Nm libxo +supports internationalization (i18n) through its use of +.Xr gettext 3 . +Use the "{G:}" role to request that the remaining part of +the format string, following the "{G:}" field, be handled using +.Fn gettext . +Since +.Fn gettext +uses the string as the key into the message catalog, +.Nm libxo +uses a simplified version of the format string that removes +unimportant field formatting and modifiers, stopping minor formatting +changes from impacting the expensive translation process. +A developer +change such as changing "/%06d" to "/%08d" should not force hand +inspection of all .po files. +.Pp +The simplified version can be generated for a single message using the +"xopo -s " command, or an entire .pot can be translated using +the "xopo -f -o " command. +.Bd -literal -offset indent + xo_emit("{G:}Invalid token\n"); +.Ed +The {G:} role allows a domain name to be set. +.Fn gettext +calls will +continue to use that domain name until the current format string +processing is complete, enabling a library function to emit strings +using it's own catalog. +The domain name can be either static as the +content of the field, or a format can be used to get the domain name +from the arguments. +.Bd -literal -offset indent + xo_emit("{G:libc}Service unavailable in restricted mode\n"); +.Ed .Ss The Label Role ({L:}) Labels are text that appears before a value. .Bd -literal -offset indent @@ -432,6 +468,23 @@ In the HTML style, the original numeric value is rendered in the
96M
.Ed +.Ss The Gettext Modifier ({g:}) +The gettext modifier is used to translate individual fields using the +gettext domain (typically set using the "{G:}" role) and current +language settings. +Once libxo renders the field value, it is passed +to +.Xr gettext 3 , +where it is used as a key to find the native language +translation. +.Pp +In the following example, the strings "State" and "full" are passed +to +.Fn gettext +to find locale-based translated strings. +.Bd -literal -offset indent + xo_emit("{Lgwc:State}{g:state}\n", "full"); +.Ed .Ss The Key Modifier ({k:}) The key modifier is used to indicate that a particular field helps uniquely identify an instance of list data. @@ -483,6 +536,28 @@ needed, but often this needs to be controlled by the caller. JSON: "fancy": true .Ed +.Ss The Plural Modifier ({p:}) +The plural modifier selects the appropriate plural form of an +expression based on the most recent number emitted and the current +language settings. +The contents of the field should be the singular +and plural English values, separated by a comma: +.Bd -literal -offset indent + xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes); +.Ed +The plural modifier is meant to work with the gettext modifier ({g:}) +but can work independently. +.Pp +When used without the gettext modifier or when the message does not +appear in the message catalog, the first token is chosen when the last +numeric value is equal to 1; otherwise the second value is used, +mimicking the simple pluralization rules of English. +.Pp +When used with the gettext modifier, the +.Xrngettext 3 +function is +called to handle the heavy lifting, using the message catalog to +convert the singular and plural forms into the native language. .Ss The Quotes Modifier ({q:}) The quotes modifier (and its twin, the 'no-quotes' modifier) affect the quoting of values in the JSON output style. From 0f7a86f39a1f448647fa31e6fad7fc86135b57e7 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 21:15:10 -0400 Subject: [PATCH 321/514] Add --disable-gettext --- configure.ac | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index 7ef46f05..8fb402ac 100644 --- a/configure.ac +++ b/configure.ac @@ -92,6 +92,11 @@ fi AM_CONDITIONAL([HAVE_HUMANIZE_NUMBER], [test "$HAVE_HUMANIZE_NUMBER" = "yes"]) +AC_ARG_ENABLE([gettext], + [ --disable-gettext Turn off support for gettext], + [GETTEXT_ENABLE=$enableval], + [GETTEXT_ENABLE=yes]) + dnl Looking for gettext(), assumably in libintl AC_ARG_WITH(gettext, [ --with-gettext=[PFX] Specify location of gettext installation], @@ -99,31 +104,36 @@ AC_ARG_WITH(gettext, [GETTEXT_PREFIX=/usr], ) -AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) +HAVE_GETTEXT=no + +if test "$GETTEXT_ENABLE" != "no"; then -_save_cflags="$CFLAGS" -CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" -AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] - [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], - [HAVE_GETTEXT=yes], - [HAVE_GETTEXT=no]) -CFLAGS="$_save_cflags" + AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) -AC_MSG_RESULT([$HAVE_GETTEXT]) + _save_cflags="$CFLAGS" + CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] + [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], + [HAVE_GETTEXT=yes], + [HAVE_GETTEXT=no]) + CFLAGS="$_save_cflags" -if test "$HAVE_GETTEXT" != "yes"; then - GETTEXT_PREFIX=/opt/local - AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) + AC_MSG_RESULT([$HAVE_GETTEXT]) - _save_cflags="$CFLAGS" - CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" - AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] - [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], - [HAVE_GETTEXT=yes], - [HAVE_GETTEXT=no]) - CFLAGS="$_save_cflags" + if test "$HAVE_GETTEXT" != "yes"; then + GETTEXT_PREFIX=/opt/local + AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) - AC_MSG_RESULT([$HAVE_GETTEXT]) + _save_cflags="$CFLAGS" + CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] + [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], + [HAVE_GETTEXT=yes], + [HAVE_GETTEXT=no]) + CFLAGS="$_save_cflags" + + AC_MSG_RESULT([$HAVE_GETTEXT]) + fi fi if test "$HAVE_GETTEXT" = "yes"; then From cd4123186e5d3f32d6434d3f12520241acc2d6bd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 31 Jul 2015 21:15:43 -0400 Subject: [PATCH 322/514] nuke as much of the 'ifdef HAVE_GETTEXT' cruft as possible --- libxo/libxo.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 130052d6..c4572dc0 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -5548,7 +5548,6 @@ xo_gettext_build_format (xo_handle_t *xop UNUSED, int this_field UNUSED, const char *fmt, char **new_fmtp) { -#ifdef HAVE_GETTEXT if (xo_style_is_encoding(xop)) goto bail; @@ -5575,7 +5574,6 @@ xo_gettext_build_format (xo_handle_t *xop UNUSED, bail2: xo_buf_cleanup(&xb); bail: -#endif /* HAVE_GETTEXT */ *new_fmtp = NULL; return fmt; } @@ -5630,19 +5628,48 @@ xo_gettext_rebuild_content (xo_handle_t *xop, xo_field_info_t *fields, xo_free(buf); } +#else /* HAVE_GETTEXT */ +static const char * +xo_gettext_build_format (xo_handle_t *xop UNUSED, + xo_field_info_t *fields UNUSED, + int this_field UNUSED, + const char *fmt UNUSED, char **new_fmtp) +{ + *new_fmtp = NULL; + return fmt; +} + +static int +xo_gettext_combine_formats (xo_handle_t *xop UNUSED, const char *fmt UNUSED, + const char *gtfmt UNUSED, + xo_field_info_t *old_fields UNUSED, + xo_field_info_t *new_fields UNUSED, + unsigned new_max_fields UNUSED, + int *reorderedp UNUSED) +{ + return -1; +} + +static void +xo_gettext_rebuild_content (xo_handle_t *xop UNUSED, + xo_field_info_t *fields UNUSED, + unsigned *fstart UNUSED, unsigned min_fstart UNUSED, + unsigned *fend UNUSED, unsigned max_fend UNUSED) +{ + return; +} #endif /* HAVE_GETTEXT */ +/* + * The central function for emitting libxo output. + */ static int xo_do_emit (xo_handle_t *xop, const char *fmt) { -#ifdef HAVE_GETTEXT int gettext_inuse = 0; int gettext_changed = 0; int gettext_reordered = 0; xo_field_info_t *new_fields = NULL; -#else /* HAVE_GETTEXT */ - const int gettext_reordered = 0; -#endif /* HAVE_GETTEXT */ int rc = 0; int flush = XOF_ISSET(xop, XOF_FLUSH); @@ -5742,7 +5769,6 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) */ xo_set_gettext_domain(xop, xfip); -#ifdef HAVE_GETTEXT if (!gettext_inuse) { /* Only translate once */ gettext_inuse = 1; if (new_fmt) { @@ -5790,7 +5816,6 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) } } } -#endif /* HAVE_GETTEXT */ continue; } else if (xfip->xfi_clen || xfip->xfi_format) { @@ -5822,13 +5847,11 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) } } -#ifdef HAVE_GETTEXT if (gettext_changed && gettext_reordered) { /* Final step: rebuild the content using the rendered fields */ xo_gettext_rebuild_content(xop, new_fields + 1, fstart, min_fstart, fend, max_fend); } -#endif /* HAVE_GETTEXT */ XOIF_CLEAR(xop, XOIF_REORDER); From 675b4b111378eb576ad7d6e1d5121cd8e29197be Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:05 -0400 Subject: [PATCH 323/514] update test cases --- tests/core/saved/test_05.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.H.out b/tests/core/saved/test_05.H.out index e6a48ff5..021f78a2 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
7
[
]
Width
:
3
[
෴ණ්ණ
]
Width
:
6
[
1234
]
[
ර්ඝ
]
Width
:
5
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
110
20
\ No newline at end of file +
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 1
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 1
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
7
[
]
Width
:
3
[
෴ණ්ණ
]
Width
:
6
[
1234
]
[
ර්ඝ
]
Width
:
5
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
110
20
\ No newline at end of file From b249477ef890d7e3d6422a03b5a1a6f31fe63c07 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:06 -0400 Subject: [PATCH 324/514] update test cases --- tests/core/saved/test_05.HIPx.out | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index 327c2e98..9326b203 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -1,3 +1,27 @@ +
+
Wide char:
+
෴ - 0xdf4 - 1
+
+
+
Wide char:
+
ණ - 0xdab - 1
+
+
+
Wide char:
+
් - 0xdca - 1
+
+
+
Wide char:
+
ණ - 0xdab - 1
+
+
+
Wide char:
+
្ - 0x17d2 - 1
+
+
+
Wide char:
+
෴ - 0xdf4 - 1
+
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
From 33c66713a28639f772b4c8541c6b12db3ab85025 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:08 -0400 Subject: [PATCH 325/514] update test cases --- tests/core/saved/test_05.HP.out | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index 763fbc97..a6244aa7 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -1,3 +1,27 @@ +
+
Wide char:
+
෴ - 0xdf4 - 1
+
+
+
Wide char:
+
ණ - 0xdab - 1
+
+
+
Wide char:
+
් - 0xdca - 1
+
+
+
Wide char:
+
ණ - 0xdab - 1
+
+
+
Wide char:
+
្ - 0x17d2 - 1
+
+
+
Wide char:
+
෴ - 0xdf4 - 1
+
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
From 2af56045c982211ea4df29ffbe8c388c65dc4583 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:09 -0400 Subject: [PATCH 326/514] update test cases --- tests/core/saved/test_05.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.J.out b/tests/core/saved/test_05.J.out index 9e75d9c8..aec598c8 100644 --- a/tests/core/saved/test_05.J.out +++ b/tests/core/saved/test_05.J.out @@ -1,2 +1,2 @@ -{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":5,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":10,"not-sinhala":"123456","tag":"ර්ඝ","width":3, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Sat, 1 Aug 2015 01:00:10 -0400 Subject: [PATCH 327/514] update test cases --- tests/core/saved/test_05.JP.out | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index 73fa25a4..a1a14182 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -1,5 +1,13 @@ { "employees": { + "wc": [ + "෴ - 0xdf4 - 1", + "ණ - 0xdab - 1", + "් - 0xdca - 1", + "ණ - 0xdab - 1", + "្ - 0x17d2 - 1", + "෴ - 0xdf4 - 1" + ], "v1": "γιγνώσκειν", "v2": "ὦ ἄνδρες ᾿Αθηναῖοι", "v1": "ახლავე გაიაროთ რეგისტრაცია", From f574755fe23cbff2db93d83b6f6b23bb41933d1e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:15 -0400 Subject: [PATCH 328/514] update test cases --- tests/core/saved/test_05.T.out | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index 47fc8098..faafc287 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -1,3 +1,9 @@ +Wide char: ෴ - 0xdf4 - 1 +Wide char: ණ - 0xdab - 1 +Wide char: ් - 0xdca - 1 +Wide char: ණ - 0xdab - 1 +Wide char: ្ - 0x17d2 - 1 +Wide char: ෴ - 0xdf4 - 1 Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო Width: 63 From e8a28b90d6a4aaca71f7ea859f0fb1842adfd793 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:17 -0400 Subject: [PATCH 329/514] update test cases --- tests/core/saved/test_05.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.X.out b/tests/core/saved/test_05.X.out index dc2246b7..76a68288 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴51෴ණ්ණ෴෴ණ්ණ෴10123456ර්ඝ3Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file +෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 1ණ - 0xdab - 1្ - 0x17d2 - 1෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴51෴ණ්ණ෴෴ණ්ණ෴10123456ර්ඝ3Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From b89502db11537f483ec0c0fecd6e0eecd5d7a726 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:18 -0400 Subject: [PATCH 330/514] update test cases --- tests/core/saved/test_05.XP.out | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index 19e60caf..de5e4dd7 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -1,4 +1,10 @@ + ෴ - 0xdf4 - 1 + ණ - 0xdab - 1 + ් - 0xdca - 1 + ණ - 0xdab - 1 + ្ - 0x17d2 - 1 + ෴ - 0xdf4 - 1 γιγνώσκειν ὦ ἄνδρες ᾿Αθηναῖοι ახლავე გაიაროთ რეგისტრაცია From 7a9b870e9bf686d9748b728d9ba28cf305fa5b1f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 1 Aug 2015 01:00:33 -0400 Subject: [PATCH 331/514] add some wcwidth test cases --- tests/core/test_05.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index 66964945..9136dc03 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "xo.h" @@ -43,7 +44,7 @@ main (int argc, char **argv) "෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴", 110, 20 }, { NULL, NULL } }, *ep = employees; - int rc; + int rc, i; argc = xo_parse_args(argc, argv); if (argc < 0) @@ -54,6 +55,11 @@ main (int argc, char **argv) xo_open_container("employees"); + wchar_t wc[] = { L'෴', L'ණ', L'්', L'ණ', L'\u17D2', L'෴', 0 }; + for (i = 0; wc[i]; i++) + xo_emit("Wide char: {lq:wc/%lc - %#lx - %d}\n", + wc[i], (unsigned long) wc[i], wcwidth(wc[i])); + xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); From d00cf5fea6a7763ac98317ac3ff8fcc3c0608464 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:41 -0400 Subject: [PATCH 332/514] checkpoint encoder work --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 6212b766..e050bc46 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,7 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libxo xo xopo xolint xohtml tests doc +SUBDIRS = libxo xo xopo xolint xohtml tests doc encoder bin_SCRIPTS=libxo-config dist_doc_DATA = Copyright From f34f6e7746756808eb73e23071b6ef0781f7a850 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:42 -0400 Subject: [PATCH 333/514] checkpoint encoder work --- configure.ac | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/configure.ac b/configure.ac index 8fb402ac..a36b008e 100644 --- a/configure.ac +++ b/configure.ac @@ -313,13 +313,16 @@ AM_CONDITIONAL([NO_LIBXO_OPTIONS], [test "$LIBXO_OPTS" != "yes"]) case $host_os in darwin*) LIBTOOL=glibtool + XO_LIBEXT=dylib ;; Linux*|linux*) CFLAGS="-D_GNU_SOURCE $CFLAGS" LDFLAGS=-ldl + XO_LIBEXT=so ;; cygwin*|CYGWIN*) LDFLAGS=-no-undefined + XO_LIBEXT=ddl ;; esac @@ -339,6 +342,14 @@ AC_SUBST(XO_SRCDIR) AC_SUBST(XO_LIBDIR) AC_SUBST(XO_BINDIR) AC_SUBST(XO_INCLUDEDIR) +AC_SUBST(XO_LIBEXT) + +AC_ARG_WITH(extensions-dir, + [ --with-extensions-dir=[DIR] Specify location of extension libraries], + [XO_EXTDIR=$withval], + [XO_EXTDIR=$libdir/libxo/extensions] +) +AC_SUBST(XO_EXTDIR) AC_ARG_WITH(share-dir, [ --with-share-dir=[DIR] Specify location of shared files], @@ -375,6 +386,8 @@ AC_CONFIG_FILES([ xohtml/xohtml.sh libxo/Makefile libxo/xoversion.h + encoder/Makefile + encoder/cbr/Makefile xo/Makefile xolint/Makefile xohtml/Makefile @@ -400,6 +413,7 @@ AC_MSG_NOTICE([summary of build options: bindir: ${XO_BINDIR} includedir: ${XO_INCLUDEDIR} share dir: ${XO_SHAREDIR} + extensions dir: ${XO_EXTDIR} oxtradoc dir: ${SLAX_OXTRADOCDIR} compiler: ${CC} (${HAVE_GCC:-no}) From 94a26bb28bc8bd08b93e244683540d0b8ac526a4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:44 -0400 Subject: [PATCH 334/514] checkpoint encoder work --- encoder/Makefile.am | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 encoder/Makefile.am diff --git a/encoder/Makefile.am b/encoder/Makefile.am new file mode 100644 index 00000000..283cfaa0 --- /dev/null +++ b/encoder/Makefile.am @@ -0,0 +1,9 @@ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +SUBDIRS = cbr From 356661edaf54c3f64385e2aefa8d41ea41db84dc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:46 -0400 Subject: [PATCH 335/514] checkpoint encoder work --- encoder/cbr/Makefile.am | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 encoder/cbr/Makefile.am diff --git a/encoder/cbr/Makefile.am b/encoder/cbr/Makefile.am new file mode 100644 index 00000000..b6bd185b --- /dev/null +++ b/encoder/cbr/Makefile.am @@ -0,0 +1,51 @@ +# +# $Id$ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +if HAVE_GCC +GCC_WARNINGS = yes +endif +include ${top_srcdir}/warnings.mk + +enc_cbrincdir = ${includedir}/libxo + +AM_CFLAGS = \ + -I${top_srcdir}/libxo \ + -I${top_builddir}/libxo \ + ${WARNINGS} + +LIBNAME = libenc_cbr +pkglib_LTLIBRARIES = libenc_cbr.la +LIBS = \ + -L${top_builddir}/libxo -lxo + +LDADD = ${top_builddir}/libxo/libxo.la + +libenc_cbr_la_SOURCES = \ + enc_cbr.c + +pkglibdir = ${XO_EXTDIR} + +UGLY_NAME = cbr.enc + +install-exec-hook: + @DLNAME=`sh -c '. ./libenc_cbr.la ; echo $$dlname'` ; \ + if [ x"$$DLNAME" = x ]; \ + then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \ + if [ "$(build_os)" = "cygwin" ]; \ + then DLNAME="../bin/$$DLNAME"; fi ; \ + echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \ + mkdir -p ${DESTDIR}${XO_EXTDIR} ; \ + cd ${DESTDIR}${XO_EXTDIR} \ + && chmod +w . \ + && rm -f ${UGLY_NAME} \ + && ${LN_S} $$DLNAME ${UGLY_NAME} From 7d52f8c6b8c2cebf1fee47c11aa4e5c45edf994c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:49 -0400 Subject: [PATCH 336/514] checkpoint encoder work --- encoder/cbr/enc_cbr.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 encoder/cbr/enc_cbr.c diff --git a/encoder/cbr/enc_cbr.c b/encoder/cbr/enc_cbr.c new file mode 100644 index 00000000..28bdcb71 --- /dev/null +++ b/encoder/cbr/enc_cbr.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +#include "xo.h" +#include "xo_encoder.h" + +static int +cbr_handler (XO_ENCODER_HANDLER_ARGS) +{ + return 0; +} + +int +xo_encoder_library_init (XO_ENCODER_INIT_ARGS) +{ + arg->xei_handler = cbr_handler; + + return 0; +} From 54695131c34966c53b6f0dd8854d4c3b506e6384 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:50 -0400 Subject: [PATCH 337/514] checkpoint encoder work --- libxo/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index 351751d9..50798f9f 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -31,6 +31,7 @@ libxoinc_HEADERS = \ libxo_la_SOURCES = \ libxo.c \ + xo_encoder.c \ xo_syslog.c man_MANS = \ From a4c6531ea7da9cf041e6c1f181fa89d8a57985d2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:52 -0400 Subject: [PATCH 338/514] checkpoint encoder work --- libxo/libxo.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index c4572dc0..2d83f559 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -26,6 +26,7 @@ #include "xoconfig.h" #include "xo.h" +#include "xo_encoder.h" #include "xoversion.h" #ifdef HAVE_STDIO_EXT_H @@ -244,6 +245,8 @@ struct xo_handle_s { char *xo_version; /* Version string */ int xo_errno; /* Saved errno for "%m" */ char *xo_gt_domain; /* Gettext domain, suitable for dgettext(3) */ + xo_encoder_func_t xo_encoder; /* Encoding function */ + void *xo_private; /* Private data for external encoders */ }; /* Flag operations */ @@ -405,8 +408,8 @@ static const char *xo_program; * To allow libxo to be used in diverse environment, we allow the * caller to give callbacks for memory allocation. */ -static xo_realloc_func_t xo_realloc = realloc; -static xo_free_func_t xo_free = free; +xo_realloc_func_t xo_realloc = realloc; +xo_free_func_t xo_free = free; /* Forward declarations */ static void @@ -7483,3 +7486,33 @@ xo_emit_errc (int eval, int code, const char *fmt, ...) xo_finish(); exit(eval); } + +void * +xo_get_private (xo_handle_t *xop) +{ + xop = xo_default(xop); + return xop->xo_private; +} + +void +xo_set_private (xo_handle_t *xop, void *opaque) +{ + xop = xo_default(xop); + xop->xo_private = opaque; +} + +xo_encoder_func_t +xo_get_encoder (xo_handle_t *xop) +{ + xop = xo_default(xop); + return xop->xo_encoder; +} + +void +xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t encoder) +{ + xop = xo_default(xop); + + xop->xo_style = XO_STYLE_ENCODER; + xop->xo_encoder = encoder; +} From d3f1269df1067544344fa5e02669ff52b7a9fe43 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:53 -0400 Subject: [PATCH 339/514] checkpoint encoder work --- libxo/xo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/xo.h b/libxo/xo.h index 9d8aa8fd..596a3682 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -47,6 +47,7 @@ typedef unsigned short xo_style_t; #define XO_STYLE_JSON 2 /** Generate JSON output */ #define XO_STYLE_HTML 3 /** Generate HTML output */ #define XO_STYLE_SDPARAMS 4 /* Generate syslog structured data params */ +#define XO_STYLE_ENCODER 5 /* Generate calls to external encoder */ /** Flags for libxo */ typedef unsigned long long xo_xof_flags_t; From 2e1a9c0da3585c62aed1c5906688755ea164a0db Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:57 -0400 Subject: [PATCH 340/514] checkpoint encoder work --- libxo/xo_encoder.c | 314 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 libxo/xo_encoder.c diff --git a/libxo/xo_encoder.c b/libxo/xo_encoder.c new file mode 100644 index 00000000..bced996f --- /dev/null +++ b/libxo/xo_encoder.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +/** + * libxo includes a number of fixed encoding styles. But other + * external encoders are need to deal with new encoders. Rather + * than expose a swarm of libxo internals, we create a distinct + * API, with a simpler API than we use internally. + */ + +#include +#include +#include +#include +#include +#include + +#include "xo.h" +#include "xo_encoder.h" + +#ifdef HAVE_DLFCN_H +#include +#if !defined(HAVE_DLFUNC) +#define dlfunc(_p, _n) dlsym(_p, _n) +#endif +#else /* HAVE_DLFCN_H */ +#define dlopen(_n, _f) NULL /* Fail */ +#define dlsym(_p, _n) NULL /* Fail */ +#define dlfunc(_p, _n) NULL /* Fail */ +#endif /* HAVE_DLFCN_H */ + +/* + * Need a simple string collection + */ +typedef struct xo_string_node_s { + TAILQ_ENTRY(xo_string_node_s) xs_link; /* Next string */ + char xs_data[0]; /* String data */ +} xo_string_node_t; + +typedef TAILQ_HEAD(xo_string_list_s, xo_string_node_s) xo_string_list_t; + +static inline void +xo_string_list_init (xo_string_list_t *listp) +{ + if (listp->tqh_last == NULL) + TAILQ_INIT(listp); +} + +static inline xo_string_node_t * +xo_string_add (xo_string_list_t *listp, const char *str) +{ + if (listp == NULL || str == NULL) + return NULL; + + xo_string_list_init(listp); + size_t len = strlen(str); + xo_string_node_t *xsp; + + xsp = xo_realloc(NULL, sizeof(*xsp) + len + 1); + if (xsp) { + memcpy(xsp->xs_data, str, len); + xsp->xs_data[len] = '\0'; + TAILQ_INSERT_TAIL(listp, xsp, xs_link); + } + + return xsp; +} + +#define XO_STRING_LIST_FOREACH(_xsp, _listp) \ + xo_string_list_init(_listp); \ + TAILQ_FOREACH(_xsp, _listp, xs_link) + +static inline void +xo_string_list_clean (xo_string_list_t *listp) +{ + xo_string_node_t *xsp; + + xo_string_list_init(listp); + + for (;;) { + xsp = TAILQ_FIRST(listp); + if (xsp == NULL) + break; + TAILQ_REMOVE(listp, xsp, xs_link); + xo_free(xsp); + } +} + +static xo_string_list_t xo_encoder_path; + +void +xo_encoder_path_add (const char *path) +{ + if (path) + xo_string_add(&xo_encoder_path, path); +} + +/* ---------------------------------------------------------------------- */ + +typedef struct xo_encoder_node_s { + TAILQ_ENTRY(xo_encoder_node_s) xe_link; /* Next session */ + char *xe_name; /* Name for this encoder */ + xo_encoder_func_t xe_handler; /* Callback function */ + void *xe_dlhandle; /* dlopen handle */ +} xo_encoder_node_t; + +typedef TAILQ_HEAD(xo_encoder_list_s, xo_encoder_node_s) xo_encoder_list_t; + +#define XO_ENCODER_LIST_FOREACH(_xep, _listp) \ + xo_encoder_list_init(_listp); \ + TAILQ_FOREACH(_xep, _listp, xe_link) + +static xo_encoder_list_t xo_encoders; + +static void +xo_encoder_list_init (xo_encoder_list_t *listp) +{ + if (listp->tqh_last == NULL) + TAILQ_INIT(listp); +} + +static xo_encoder_node_t * +xo_encoder_list_add (const char *name) +{ + if (name == NULL) + return NULL; + + xo_encoder_node_t *xep = xo_realloc(NULL, sizeof(*xep)); + if (xep) { + int len = strlen(name) + 1; + xep->xe_name = xo_realloc(NULL, len); + if (xep->xe_name == NULL) { + xo_free(xep); + return NULL; + } + + memcpy(xep->xe_name, name, len); + + TAILQ_INSERT_TAIL(&xo_encoders, xep, xe_link); + } + + return xep; +} + +void +xo_encoders_clean (void) +{ + xo_encoder_node_t *xep; + + xo_encoder_list_init(&xo_encoders); + + for (;;) { + xep = TAILQ_FIRST(&xo_encoders); + if (xep == NULL) + break; + + TAILQ_REMOVE(&xo_encoders, xep, xe_link); + + if (xep->xe_dlhandle) + dlclose(xep->xe_dlhandle); + + xo_free(xep); + } + + xo_string_list_clean(&xo_encoder_path); +} + +static xo_encoder_node_t * +xo_encoder_find (const char *name) +{ + xo_encoder_node_t *xep; + + xo_encoder_list_init(&xo_encoders); + + XO_ENCODER_LIST_FOREACH(xep, &xo_encoders) { + if (strcmp(xep->xe_name, name) == 0) + return xep; + } + + return NULL; +} + +static xo_encoder_node_t * +xo_encoder_discover (const char *name) +{ + void *dlp = NULL; + char buf[MAXPATHLEN]; + xo_string_node_t *xsp; + xo_encoder_node_t *xep = NULL; + + XO_STRING_LIST_FOREACH(xsp, &xo_encoder_path) { + static const char fmt[] = "%s/%s.enc"; + char *dir = xsp->xs_data; + size_t len = snprintf(buf, sizeof(buf), fmt, dir, name); + + if (len > sizeof(buf)) /* Should not occur */ + continue; + + dlp = dlopen((const char *) buf, RTLD_NOW); + if (dlp) + break; + } + + if (dlp) { + /* + * If the library exists, find the initializer function and + * call it. + */ + xo_encoder_init_func_t func; + + func = (xo_encoder_init_func_t) dlfunc(dlp, XO_ENCODER_INIT_NAME); + if (func) { + xo_encoder_init_args_t xei; + + bzero(&xei, sizeof(xei)); + + xei.xei_version = XO_ENCODER_VERSION; + int rc = func(&xei); + if (rc == 0 && xei.xei_handler) { + xep = xo_encoder_list_add(name); + if (xep) { + xep->xe_handler = xei.xei_handler; + xep->xe_dlhandle = dlp; + } + } + } + dlclose(dlp); + } + + return xep; +} + +void +xo_encoder_register (const char *name, xo_encoder_func_t func) +{ + xo_encoder_node_t *xep = xo_encoder_find(name); + + if (xep) /* "We alla-ready got one" */ + return; + + xep = xo_encoder_list_add(name); + if (xep) + xep->xe_handler = func; +} + +void +xo_encoder_unregister (const char *name) +{ + xo_encoder_node_t *xep = xo_encoder_find(name); + if (xep) { + TAILQ_REMOVE(&xo_encoders, xep, xe_link); + xo_free(xep); + } +} + +int +xo_encoder_init (xo_handle_t *xop, const char *name) +{ + /* + * First we look on the list of known (registered) encoders. + * If we don't find it, we follow the set of paths to find + * the encoding library. + */ + xo_encoder_node_t *xep = xo_encoder_find(name); + if (xep == NULL) { + xep = xo_encoder_discover(name); + if (xep == NULL) + return -1; + } + + xo_set_encoder(xop, xep->xe_handler); + return 0; +} + +/* + * A couple of function varieties here, to allow for multiple + * use cases. This varient is for when the main program knows + * its own encoder needs. + */ +xo_handle_t * +xo_encoder_create (const char *name, xo_xof_flags_t flags) +{ + xo_handle_t *xop; + + xop = xo_create(XO_STYLE_ENCODER, flags); + if (xop) { + if (xo_encoder_init(xop, name)) { + xo_destroy(xop); + xop = NULL; + } + } + + return xop; +} + +int +xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op, + const char *name, const char *value) +{ + void *private = xo_get_private(xop); + xo_encoder_func_t func = xo_get_encoder(xop); + + if (func == NULL) + return -1; + + return func(xop, op, name, value, private); +} From ae5aaa9847c03677f19a36e393d07880a9f376a5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Mon, 3 Aug 2015 19:23:58 -0400 Subject: [PATCH 341/514] checkpoint encoder work --- libxo/xo_encoder.h | 105 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 libxo/xo_encoder.h diff --git a/libxo/xo_encoder.h b/libxo/xo_encoder.h new file mode 100644 index 00000000..8536897c --- /dev/null +++ b/libxo/xo_encoder.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +/* + * NOTE WELL: This file is needed to software that implements an + * external encoder for libxo that allows libxo data to be encoded in + * new and bizarre formats. General libxo code should _never_ + * include this header file. + */ + +#ifndef XO_ENCODER_H +#define XO_ENCODER_H + +/* + * Expose libxo's memory allocation functions + */ +extern xo_realloc_func_t xo_realloc; +extern xo_free_func_t xo_free; + +typedef unsigned xo_encoder_op_t; + +/* Encoder operations */ +#define XO_OP_UNKNOWN 0 +#define XO_OP_CREATE 1 +#define XO_OP_OPEN_CONTAINER 2 +#define XO_OP_CLOSE_CONTAINER 3 +#define XO_OP_OPEN_LIST 4 +#define XO_OP_CLOSE_LIST 5 +#define XO_OP_OPEN_LEAF_LIST 6 +#define XO_OP_CLOSE_LEAF_LIST 7 +#define XO_OP_STRING 8 /* Quoted UTF-8 string */ +#define XO_OP_CONTENT 9 /* Other content */ +#define XO_OP_DESTROY 10 /* Clean up function */ + +#define XO_ENCODER_HANDLER_ARGS \ + xo_handle_t *xop __attribute__ ((__unused__)), \ + xo_encoder_op_t op __attribute__ ((__unused__)), \ + const char *name __attribute__ ((__unused__)), \ + const char *value __attribute__ ((__unused__)), \ + void *private __attribute__ ((__unused__)) + +typedef int (*xo_encoder_func_t)(XO_ENCODER_HANDLER_ARGS); + +typedef struct xo_encoder_init_args_s { + unsigned xei_version; /* Current version */ + xo_encoder_func_t xei_handler; /* Encoding handler */ +} xo_encoder_init_args_t; + +#define XO_ENCODER_VERSION 1 /* Current version */ + +#define XO_ENCODER_INIT_ARGS \ + xo_encoder_init_args_t *arg __attribute__ ((__unused__)) + +typedef int (*xo_encoder_init_func_t)(XO_ENCODER_INIT_ARGS); +/* + * Each encoder library must define a function named xo_encoder_init + * that takes the arguments defined in XO_ENCODER_INIT_ARGS. It + * should return zero for success. + */ +#define XO_ENCODER_INIT_NAME_TOKEN xo_encoder_library_init +#define XO_ENCODER_INIT_NAME "" ## XO_ENCODER_INIT_NAME_TOKEN +extern int XO_ENCODER_INIT_NAME_TOKEN (XO_ENCODER_INIT_ARGS); + +void +xo_encoder_register (const char *name, xo_encoder_func_t func); + +void +xo_encoder_unregister (const char *name); + +void * +xo_get_private (xo_handle_t *xop); + +void +xo_encoder_path_add (const char *path); + +void +xo_set_private (xo_handle_t *xop, void *opaque); + +xo_encoder_func_t +xo_get_encoder (xo_handle_t *xop); + +void +xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t encoder); + +int +xo_encoder_init (xo_handle_t *xop, const char *name); + +xo_handle_t * +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); + +void +xo_encoders_clean (void); + +#endif /* XO_ENCODER_H */ From 4801d31137760edb49bf96496deddf9aef448e0f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:34:41 -0400 Subject: [PATCH 342/514] Add encoder test jig --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index a36b008e..a030616f 100644 --- a/configure.ac +++ b/configure.ac @@ -388,6 +388,7 @@ AC_CONFIG_FILES([ libxo/xoversion.h encoder/Makefile encoder/cbr/Makefile + encoder/test/Makefile xo/Makefile xolint/Makefile xohtml/Makefile From 4319cea20383bf0a1a6e1860b761b5e504b337d2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:34:44 -0400 Subject: [PATCH 343/514] Add encoder test jig --- encoder/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/encoder/Makefile.am b/encoder/Makefile.am index 283cfaa0..fe846be5 100644 --- a/encoder/Makefile.am +++ b/encoder/Makefile.am @@ -6,4 +6,4 @@ # using the SOFTWARE, you agree to be bound by the terms of that # LICENSE. -SUBDIRS = cbr +SUBDIRS = cbr test From d5c4d1fb7e270c7a46c1dcaa3480f677d32001fd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:35:03 -0400 Subject: [PATCH 344/514] encoder libs are published to XO_EXTDIR --- libxo/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index 50798f9f..ec8309cc 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -21,6 +21,9 @@ AM_CFLAGS = \ ${WARNINGS} \ ${GETTEXT_CFLAGS} +AM_CFLAGS += \ + -DXO_EXTDIR=\"${XO_EXTDIR}\" + lib_LTLIBRARIES = libxo.la LIBS = \ From 59aea93108c345aa9119b350a3b57292166591b5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:35:31 -0400 Subject: [PATCH 345/514] Add xo_encoder_handle calls --- libxo/libxo.c | 244 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 206 insertions(+), 38 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 2d83f559..45337333 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -269,6 +269,7 @@ struct xo_handle_s { #define XOIF_ANCHOR XOF_BIT(3) /* An anchor is in place */ #define XOIF_UNITS_PENDING XOF_BIT(4) /* We have a units-insertion pending */ +#define XOIF_INIT_IN_PROGRESS XOF_BIT(5) /* Init of handle is in progress */ /* Flags for formatting functions */ typedef unsigned long xo_xff_flags_t; @@ -517,6 +518,14 @@ xo_buf_offset (xo_buffer_t *xbp) return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0; } +static char * +xo_buf_data (xo_buffer_t *xbp, unsigned offset) +{ + if (xbp == NULL) + return NULL; + return xbp->xb_bufp + offset; +} + /* * Initialize the contents of an xo_buffer_t. */ @@ -666,6 +675,10 @@ xo_init_handle (xo_handle_t *xop) xo_buf_init(&xop->xo_data); xo_buf_init(&xop->xo_fmt); + if (XOIF_ISSET(xop, XOIF_INIT_IN_PROGRESS)) + return; + XOIF_SET(xop, XOIF_INIT_IN_PROGRESS); + xop->xo_indent_by = XO_INDENT_BY; xo_depth_check(xop, XO_DEPTH); @@ -674,8 +687,11 @@ xo_init_handle (xo_handle_t *xop) char *env = getenv("LIBXO_OPTIONS"); if (env) xo_set_options(xop, env); + } #endif /* NO_GETENV */ + + XOIF_CLEAR(xop, XOIF_INIT_IN_PROGRESS); } /* @@ -1603,12 +1619,10 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) break; case XO_STYLE_JSON: - /* No means of representing messages in JSON */ - break; - case XO_STYLE_SDPARAMS: - /* No means of representing messages in SDPARAMS */ - break; + case XO_STYLE_ENCODER: + /* No means of representing messages */ + return; case XO_STYLE_TEXT: rc = xo_printf_v(xop, fmt, vap); @@ -1798,6 +1812,8 @@ xo_name_to_style (const char *name) return XO_STYLE_XML; else if (strcmp(name, "json") == 0) return XO_STYLE_JSON; + else if (strcmp(name, "encoder") == 0) + return XO_STYLE_ENCODER; else if (strcmp(name, "text") == 0) return XO_STYLE_TEXT; else if (strcmp(name, "html") == 0) @@ -1813,7 +1829,8 @@ xo_style_is_encoding (xo_handle_t *xop) { if (xo_style(xop) == XO_STYLE_JSON || xo_style(xop) == XO_STYLE_XML - || xo_style(xop) == XO_STYLE_SDPARAMS) + || xo_style(xop) == XO_STYLE_SDPARAMS + || xo_style(xop) == XO_STYLE_ENCODER) return 1; return 0; } @@ -2039,8 +2056,12 @@ xo_set_options (xo_handle_t *xop, const char *input) continue; } + /* + * For options, we don't allow "encoder" since we want to + * handle it explicitly below as "encoder=xxx". + */ new_style = xo_name_to_style(cp); - if (new_style >= 0) { + if (new_style >= 0 && new_style != XO_STYLE_ENCODER) { if (style >= 0) xo_warnx("ignoring multiple styles: '%s'", cp); else @@ -2057,6 +2078,16 @@ xo_set_options (xo_handle_t *xop, const char *input) 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; @@ -3144,6 +3175,11 @@ xo_do_format_field (xo_handle_t *xop, xo_buffer_t *xbp, columns = rc = xo_trim_ws(xbp, rc); rc = xo_escape_sdparams(xbp, rc, 0); break; + + case XO_STYLE_ENCODER: + if (flags & XFF_TRIM_WS) + columns = rc = xo_trim_ws(xbp, rc); + break; } /* @@ -3673,6 +3709,7 @@ xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip) case XO_STYLE_XML: case XO_STYLE_JSON: case XO_STYLE_SDPARAMS: + case XO_STYLE_ENCODER: /* * Even though we don't care about text, we need to do * enough parsing work to skip over the right bits of xo_vap. @@ -4065,6 +4102,58 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, xo_do_format_field(xop, NULL, format, 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); + break; + } + + if (flags & XFF_QUOTE) + quote = 1; + else if (flags & XFF_NOQUOTE) + quote = 0; + else if (flen == 0) { + quote = 0; + format = "true"; /* JSON encodes empty tags as a boolean true */ + flen = 4; + } else if (strchr("diouxXDOUeEfFgGaAcCp", format[flen - 1]) == NULL) + quote = 1; + else + quote = 0; + + if (encoding) { + format = encoding; + flen = elen; + } else { + char *enc = alloca(flen + 1); + memcpy(enc, format, flen); + enc[flen] = '\0'; + format = xo_fix_encoding(xop, enc); + flen = strlen(format); + } + + if (nlen == 0) { + static char missing[] = "missing-field-name"; + xo_failure(xop, "missing field name: %s", format); + name = missing; + nlen = sizeof(missing) - 1; + } + + unsigned name_offset = xo_buf_offset(&xop->xo_data); + xo_data_append(xop, name, nlen); + xo_data_append(xop, "", 1); + + unsigned value_offset = xo_buf_offset(&xop->xo_data); + xo_do_format_field(xop, NULL, format, 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_reset(&xop->xo_data); + break; } } @@ -4501,6 +4590,7 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip) case XO_STYLE_XML: case XO_STYLE_JSON: case XO_STYLE_SDPARAMS: + case XO_STYLE_ENCODER: /* * Nothing to do; we did all that work just to clear the stack of * formatting arguments. @@ -5679,7 +5769,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) int flush_line = XOF_ISSET(xop, XOF_FLUSH_LINE); char *new_fmt = NULL; - if (XOIF_ISSET(xop, XOIF_REORDER)) + if (XOIF_ISSET(xop, XOIF_REORDER) || xo_style(xop) == XO_STYLE_ENCODER) flush_line = 0; xop->xo_columns = 0; /* Always reset it */ @@ -5963,35 +6053,55 @@ xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap) const int extra = 5; /* space, equals, quote, quote, and nul */ xop = xo_default(xop); - if (xo_style(xop) != XO_STYLE_XML) - return 0; - + int rc = 0; int nlen = strlen(name); xo_buffer_t *xbp = &xop->xo_attrs; + unsigned name_offset, value_offset; - if (!xo_buf_has_room(xbp, nlen + extra)) - return -1; + switch (xo_style(xop)) { + case XO_STYLE_XML: + if (!xo_buf_has_room(xbp, nlen + extra)) + return -1; - *xbp->xb_curp++ = ' '; - memcpy(xbp->xb_curp, name, nlen); - xbp->xb_curp += nlen; - *xbp->xb_curp++ = '='; - *xbp->xb_curp++ = '"'; + *xbp->xb_curp++ = ' '; + memcpy(xbp->xb_curp, name, nlen); + xbp->xb_curp += nlen; + *xbp->xb_curp++ = '='; + *xbp->xb_curp++ = '"'; - int rc = xo_vsnprintf(xop, xbp, fmt, vap); + rc = xo_vsnprintf(xop, xbp, fmt, vap); - if (rc > 0) { - rc = xo_escape_xml(xbp, rc, 1); - xbp->xb_curp += rc; - } + if (rc >= 0) { + rc = xo_escape_xml(xbp, rc, 1); + xbp->xb_curp += rc; + } - if (!xo_buf_has_room(xbp, 2)) - return -1; + if (!xo_buf_has_room(xbp, 2)) + return -1; + + *xbp->xb_curp++ = '"'; + *xbp->xb_curp = '\0'; - *xbp->xb_curp++ = '"'; - *xbp->xb_curp = '\0'; + rc += nlen + extra; + break; + + case XO_STYLE_ENCODER: + name_offset = xo_buf_offset(xbp); + xo_buf_append(xbp, name, nlen); + xo_buf_append(xbp, "", 1); - return rc + nlen + extra; + value_offset = xo_buf_offset(xbp); + rc = xo_vsnprintf(xop, xbp, fmt, vap); + if (rc >= 0) { + xbp->xb_curp += rc; + *xbp->xb_curp = '\0'; + rc = xo_encoder_handle(xop, XO_OP_ATTR, + xo_buf_data(xbp, name_offset), + xo_buf_data(xbp, value_offset)); + } + } + + return rc; } int @@ -6175,6 +6285,10 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) case XO_STYLE_SDPARAMS: break; + + case XO_STYLE_ENCODER: + rc = xo_encoder_handle(xop, XO_OP_OPEN_CONTAINER, name, NULL); + break; } xo_depth_change(xop, name, 1, 1, XSS_OPEN_CONTAINER, @@ -6260,6 +6374,11 @@ xo_do_close_container (xo_handle_t *xop, const char *name) case XO_STYLE_SDPARAMS: break; + + 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); + break; } return rc; @@ -6297,9 +6416,11 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) xop = xo_default(xop); - if (xo_style(xop) == XO_STYLE_JSON) { - const char *ppn = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : ""; - const char *pre_nl = ""; + const char *ppn = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + + switch (xo_style(xop)) { + case XO_STYLE_JSON: indent = 1; if (!XOF_ISSET(xop, XOF_NO_TOP) @@ -6319,6 +6440,11 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) rc = xo_printf(xop, "%s%*s\"%s\": [%s", pre_nl, xo_indent(xop), "", name, ppn); + break; + + case XO_STYLE_ENCODER: + rc = xo_encoder_handle(xop, XO_OP_OPEN_LIST, name, NULL); + break; } xo_depth_change(xop, name, 1, indent, XSS_OPEN_LIST, @@ -6379,7 +6505,8 @@ xo_do_close_list (xo_handle_t *xop, const char *name) } } - if (xo_style(xop) == XO_STYLE_JSON) { + switch (xo_style(xop)) { + case XO_STYLE_JSON: if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : ""; xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; @@ -6387,10 +6514,17 @@ xo_do_close_list (xo_handle_t *xop, const char *name) xo_depth_change(xop, name, -1, -1, XSS_CLOSE_LIST, XSF_LIST); rc = xo_printf(xop, "%s%*s]", pre_nl, xo_indent(xop), ""); xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + break; - } else { + 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); + break; + + default: xo_depth_change(xop, name, -1, 0, XSS_CLOSE_LIST, XSF_LIST); xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + break; } return rc; @@ -6428,10 +6562,11 @@ xo_do_open_leaf_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) xop = xo_default(xop); - if (xo_style(xop) == XO_STYLE_JSON) { - const char *ppn = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : ""; - const char *pre_nl = ""; + const char *ppn = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + switch (xo_style(xop)) { + case XO_STYLE_JSON: indent = 1; if (!XOF_ISSET(xop, XOF_NO_TOP)) { @@ -6454,6 +6589,11 @@ xo_do_open_leaf_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) rc = xo_printf(xop, "%s%*s\"%s\": [%s", pre_nl, xo_indent(xop), "", name, ppn); + break; + + case XO_STYLE_ENCODER: + rc = xo_encoder_handle(xop, XO_OP_OPEN_LEAF_LIST, name, NULL); + break; } xo_depth_change(xop, name, 1, indent, XSS_OPEN_LEAF_LIST, @@ -6484,7 +6624,8 @@ xo_do_close_leaf_list (xo_handle_t *xop, const char *name) } } - if (xo_style(xop) == XO_STYLE_JSON) { + switch (xo_style(xop)) { + case XO_STYLE_JSON: if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : ""; xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; @@ -6492,10 +6633,16 @@ xo_do_close_leaf_list (xo_handle_t *xop, const char *name) xo_depth_change(xop, name, -1, -1, XSS_CLOSE_LEAF_LIST, XSF_LIST); rc = xo_printf(xop, "%s%*s]", pre_nl, xo_indent(xop), ""); xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + break; - } else { + case XO_STYLE_ENCODER: + rc = xo_encoder_handle(xop, XO_OP_CLOSE_LEAF_LIST, name, NULL); + /*fallthru*/ + + default: xo_depth_change(xop, name, -1, 0, XSS_CLOSE_LEAF_LIST, XSF_LIST); xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + break; } return rc; @@ -6544,6 +6691,10 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) case XO_STYLE_SDPARAMS: break; + + case XO_STYLE_ENCODER: + rc = xo_encoder_handle(xop, XO_OP_OPEN_INSTANCE, name, NULL); + break; } xo_depth_change(xop, name, 1, 1, XSS_OPEN_INSTANCE, xo_stack_flags(flags)); @@ -6627,6 +6778,11 @@ xo_do_close_instance (xo_handle_t *xop, const char *name) case XO_STYLE_SDPARAMS: break; + + 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); + break; } return rc; @@ -7102,6 +7258,9 @@ xo_flush_h (xo_handle_t *xop) xo_data_append(xop, "\n", 1); } break; + + case XO_STYLE_ENCODER: + xo_encoder_handle(xop, XO_OP_FLUSH, NULL, NULL); } rc = xo_write(xop); @@ -7137,6 +7296,10 @@ xo_finish_h (xo_handle_t *xop) xo_printf(xop, "%*s%s}\n",xo_indent(xop), "", cp); } break; + + case XO_STYLE_ENCODER: + xo_encoder_handle(xop, XO_OP_FINISH, NULL, NULL); + break; } return xo_flush_h(xop); @@ -7207,6 +7370,7 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) break; case XO_STYLE_SDPARAMS: + case XO_STYLE_ENCODER: break; } } @@ -7341,6 +7505,10 @@ xo_set_version_h (xo_handle_t *xop, const char *version UNUSED) */ xop->xo_version = xo_strndup(version, -1); break; + + case XO_STYLE_ENCODER: + xo_encoder_handle(xop, XO_OP_VERSION, NULL, version); + break; } } From 15677c2ee551e6074c096a2a95588a1603acb4fd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:35:51 -0400 Subject: [PATCH 346/514] Add +xo_encoder_op_name and xo_encoder_setup --- libxo/xo_encoder.c | 65 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/libxo/xo_encoder.c b/libxo/xo_encoder.c index bced996f..399cdc70 100644 --- a/libxo/xo_encoder.c +++ b/libxo/xo_encoder.c @@ -22,6 +22,7 @@ #include #include +#include "xoconfig.h" #include "xo.h" #include "xo_encoder.h" @@ -36,6 +37,8 @@ #define dlfunc(_p, _n) NULL /* Fail */ #endif /* HAVE_DLFCN_H */ +static void xo_encoder_setup (void); /* Forward decl */ + /* * Need a simple string collection */ @@ -98,6 +101,8 @@ static xo_string_list_t xo_encoder_path; void xo_encoder_path_add (const char *path) { + xo_encoder_setup(); + if (path) xo_string_add(&xo_encoder_path, path); } @@ -154,7 +159,7 @@ xo_encoders_clean (void) { xo_encoder_node_t *xep; - xo_encoder_list_init(&xo_encoders); + xo_encoder_setup(); for (;;) { xep = TAILQ_FIRST(&xo_encoders); @@ -172,6 +177,20 @@ xo_encoders_clean (void) xo_string_list_clean(&xo_encoder_path); } +static void +xo_encoder_setup (void) +{ + static int initted; + if (!initted) { + initted = 1; + + xo_string_list_init(&xo_encoder_path); + xo_encoder_list_init(&xo_encoders); + + xo_encoder_path_add(XO_EXTDIR); + } +} + static xo_encoder_node_t * xo_encoder_find (const char *name) { @@ -231,7 +250,9 @@ xo_encoder_discover (const char *name) } } } - dlclose(dlp); + + if (xep == NULL) + dlclose(dlp); } return xep; @@ -240,6 +261,8 @@ xo_encoder_discover (const char *name) void xo_encoder_register (const char *name, xo_encoder_func_t func) { + xo_encoder_setup(); + xo_encoder_node_t *xep = xo_encoder_find(name); if (xep) /* "We alla-ready got one" */ @@ -253,6 +276,8 @@ xo_encoder_register (const char *name, xo_encoder_func_t func) void xo_encoder_unregister (const char *name) { + xo_encoder_setup(); + xo_encoder_node_t *xep = xo_encoder_find(name); if (xep) { TAILQ_REMOVE(&xo_encoders, xep, xe_link); @@ -263,7 +288,9 @@ xo_encoder_unregister (const char *name) int xo_encoder_init (xo_handle_t *xop, const char *name) { - /* + xo_encoder_setup(); + + /* * First we look on the list of known (registered) encoders. * If we don't find it, we follow the set of paths to find * the encoding library. @@ -276,7 +303,8 @@ xo_encoder_init (xo_handle_t *xop, const char *name) } xo_set_encoder(xop, xep->xe_handler); - return 0; + + return xo_encoder_handle(xop, XO_OP_CREATE, NULL, NULL); } /* @@ -312,3 +340,32 @@ xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op, return func(xop, op, name, value, private); } + +const char * +xo_encoder_op_name (xo_encoder_op_t op) +{ + static const char *names[] = { + /* 0 */ "unknown", + /* 1 */ "create", + /* 2 */ "open_container", + /* 3 */ "close_container", + /* 4 */ "open_list", + /* 5 */ "close_list", + /* 6 */ "open_leaf_list", + /* 7 */ "close_leaf_list", + /* 8 */ "open_instance", + /* 9 */ "close_instance", + /* 10 */ "string", + /* 11 */ "content", + /* 12 */ "flush", + /* 13 */ "finish", + /* 14 */ "destroy", + /* 15 */ "attr", + /* 16 */ "version", + }; + + if (op > sizeof(names) / sizeof(names[0])) + return "unknown"; + + return names[op]; +} From f167e91024c3ee7d121cb046114411c62aef6283 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:35:53 -0400 Subject: [PATCH 347/514] Add +xo_encoder_op_name and xo_encoder_setup --- libxo/xo_encoder.h | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libxo/xo_encoder.h b/libxo/xo_encoder.h index 8536897c..c44a244a 100644 --- a/libxo/xo_encoder.h +++ b/libxo/xo_encoder.h @@ -28,16 +28,22 @@ typedef unsigned xo_encoder_op_t; /* Encoder operations */ #define XO_OP_UNKNOWN 0 -#define XO_OP_CREATE 1 +#define XO_OP_CREATE 1 /* Called when the handle is init'd */ #define XO_OP_OPEN_CONTAINER 2 #define XO_OP_CLOSE_CONTAINER 3 #define XO_OP_OPEN_LIST 4 #define XO_OP_CLOSE_LIST 5 #define XO_OP_OPEN_LEAF_LIST 6 #define XO_OP_CLOSE_LEAF_LIST 7 -#define XO_OP_STRING 8 /* Quoted UTF-8 string */ -#define XO_OP_CONTENT 9 /* Other content */ -#define XO_OP_DESTROY 10 /* Clean up function */ +#define XO_OP_OPEN_INSTANCE 8 +#define XO_OP_CLOSE_INSTANCE 9 +#define XO_OP_STRING 10 /* Quoted UTF-8 string */ +#define XO_OP_CONTENT 11 /* Other content */ +#define XO_OP_FLUSH 12 /* Clean up function */ +#define XO_OP_FINISH 13 /* Clean up function */ +#define XO_OP_DESTROY 14 /* Clean up function */ +#define XO_OP_ATTR 15 /* Attribute name/value */ +#define XO_OP_VERSION 16 /* Version string */ #define XO_ENCODER_HANDLER_ARGS \ xo_handle_t *xop __attribute__ ((__unused__)), \ @@ -65,7 +71,9 @@ typedef int (*xo_encoder_init_func_t)(XO_ENCODER_INIT_ARGS); * should return zero for success. */ #define XO_ENCODER_INIT_NAME_TOKEN xo_encoder_library_init -#define XO_ENCODER_INIT_NAME "" ## XO_ENCODER_INIT_NAME_TOKEN +#define XO_STRINGIFY(_x) #_x +#define XO_STRINGIFY2(_x) XO_STRINGIFY(_x) +#define XO_ENCODER_INIT_NAME XO_STRINGIFY2(XO_ENCODER_INIT_NAME_TOKEN) extern int XO_ENCODER_INIT_NAME_TOKEN (XO_ENCODER_INIT_ARGS); void @@ -102,4 +110,7 @@ xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op, void xo_encoders_clean (void); +const char * +xo_encoder_op_name (xo_encoder_op_t op); + #endif /* XO_ENCODER_H */ From ba4cea8f9eb52553f4f3e006572a031f654be619 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:52:15 -0400 Subject: [PATCH 348/514] Add XO_STYLE_ENCODER to xo_format_content --- libxo/libxo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libxo/libxo.c b/libxo/libxo.c index 45337333..30a4a3ee 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -4239,6 +4239,12 @@ xo_format_content (xo_handle_t *xop, const char *class_name, flags | XFF_NO_OUTPUT); } break; + + case XO_STYLE_ENCODER: + if (len == 0) + xo_do_format_field(xop, NULL, fmt, flen, + flags | XFF_NO_OUTPUT); + break; } } From 2d24171a087c189806ae81a5f0f1a8170c6aef01 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:52:34 -0400 Subject: [PATCH 349/514] Add encoder=test test cases --- tests/core/Makefile.am | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/core/Makefile.am b/tests/core/Makefile.am index 7e117e9c..0131a6f5 100644 --- a/tests/core/Makefile.am +++ b/tests/core/Makefile.am @@ -76,13 +76,18 @@ valgrind: #TEST_TRACE = set -x ; -TEST_ONE = \ - LIBXO_OPTIONS=:W$$fmt \ +TEST_JIG = \ ${CHECKER} ./$$base.test ${TEST_OPTS} \ > out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \ ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \ ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O} +TEST_ONE = \ + LIBXO_OPTIONS=:W$$fmt ${TEST_JIG} + +TEST_TWO = \ + LIBXO_OPTIONS=warn,encoder=test ${TEST_JIG} + TEST_FORMATS = T XP JP HP X J H HIPx test tests: ${bin_PROGRAMS} @@ -93,6 +98,11 @@ test tests: ${bin_PROGRAMS} echo "... $$test ... $$fmt ..."; \ ${TEST_ONE}; \ true; \ + done) ; \ + (for fmt in E; do \ + echo "... $$test ... $$fmt ..."; \ + ${TEST_TWO}; \ + true; \ done) \ done) @@ -102,7 +112,7 @@ one: accept: -@(for test in ${TEST_CASES} ; do \ base=`${BASENAME} $$test .c` ; \ - (for fmt in ${TEST_FORMATS}; do \ + (for fmt in ${TEST_FORMATS} E; do \ echo "... $$test ... $$fmt ..."; \ ${CP} out/$$base.$$fmt.out ${srcdir}/saved/$$base.$$fmt.out ; \ ${CP} out/$$base.$$fmt.err ${srcdir}/saved/$$base.$$fmt.err ; \ From 51df40cb8590616c37278183c6d0693b9395bf2c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:11 -0400 Subject: [PATCH 350/514] Add encoder=test test cases --- tests/core/saved/test_01.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_01.E.err diff --git a/tests/core/saved/test_01.E.err b/tests/core/saved/test_01.E.err new file mode 100644 index 00000000..e69de29b From a21ed8fadc55b2996a4a1ce75610e1e47b635757 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:13 -0400 Subject: [PATCH 351/514] Add encoder=test test cases --- tests/core/saved/test_01.E.out | 119 +++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tests/core/saved/test_01.E.out diff --git a/tests/core/saved/test_01.E.out b/tests/core/saved/test_01.E.out new file mode 100644 index 00000000..36e149cd --- /dev/null +++ b/tests/core/saved/test_01.E.out @@ -0,0 +1,119 @@ +op create: [] [] +op open_container: [top] [] +op string: [host] [my-box] +op string: [domain] [example.com] +op attr: [test] [value] +op open_container: [data] [] +op open_list: [item] [] +op attr: [test2] [value2] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [GRO-000-415] +op string: [name] [gum] +op content: [sold] [1412] +op content: [in-stock] [54] +op content: [on-order] [10] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [HRD-000-212] +op string: [name] [rope] +op content: [sold] [85] +op content: [in-stock] [4] +op content: [on-order] [2] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [HRD-000-517] +op string: [name] [ladder] +op content: [sold] [0] +op content: [in-stock] [2] +op content: [on-order] [1] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [HRD-000-632] +op string: [name] [bolt] +op content: [sold] [4123] +op content: [in-stock] [144] +op content: [on-order] [42] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [GRO-000-2331] +op string: [name] [water] +op content: [sold] [17] +op content: [in-stock] [14] +op content: [on-order] [2] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [data] [] +op open_container: [data] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [sku] [GRO-000-415] +op string: [name] [gum] +op content: [sold] [1412.0] +op content: [in-stock] [54] +op content: [on-order] [10] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [HRD-000-212] +op string: [name] [rope] +op content: [sold] [85.0] +op content: [in-stock] [4] +op content: [on-order] [2] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [HRD-000-517] +op string: [name] [ladder] +op content: [sold] [0] +op content: [in-stock] [2] +op content: [on-order] [1] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [HRD-000-632] +op string: [name] [bolt] +op content: [sold] [4123.0] +op content: [in-stock] [144] +op content: [on-order] [42] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [GRO-000-2331] +op string: [name] [water] +op content: [sold] [17.0] +op content: [in-stock] [14] +op content: [on-order] [2] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [data] [] +op open_container: [data] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [sku] [GRO-000-533] +op string: [name] [fish] +op content: [sold] [1321.0] +op content: [in-stock] [45] +op content: [on-order] [1] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [data] [] +op open_container: [data] [] +op open_list: [item] [] +op attr: [test4] [value4] +op string: [item] [gum] +op attr: [test4] [value4] +op string: [item] [rope] +op attr: [test4] [value4] +op string: [item] [ladder] +op attr: [test4] [value4] +op string: [item] [bolt] +op attr: [test4] [value4] +op string: [item] [water] +op close_list: [item] [] +op close_container: [data] [] +op content: [cost] [425] +op content: [cost] [455] +op close_container: [top] [] +op finish: [] [] +op flush: [] [] From 724fdf0f86520d9ac3debb150a5fc00c08b907da Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:14 -0400 Subject: [PATCH 352/514] Add encoder=test test cases --- tests/core/saved/test_02.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_02.E.err diff --git a/tests/core/saved/test_02.E.err b/tests/core/saved/test_02.E.err new file mode 100644 index 00000000..e69de29b From d9f349a76c826276273e1f14b88385a99a53f7fa Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:14 -0400 Subject: [PATCH 353/514] Add encoder=test test cases --- tests/core/saved/test_02.E.out | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/core/saved/test_02.E.out diff --git a/tests/core/saved/test_02.E.out b/tests/core/saved/test_02.E.out new file mode 100644 index 00000000..9e1ec96b --- /dev/null +++ b/tests/core/saved/test_02.E.out @@ -0,0 +1,68 @@ +op create: [] [] +op open_container: [top] [] +op open_container: [data] [] +op string: [what] [braces] +op string: [length] [abcdef] +op content: [fd] [-1] +op string: [error] [Bad file descriptor] +op string: [test] [good] +op content: [fd] [-1] +op string: [error] [Bad fi] +op string: [test] [good] +op content: [lines] [20] +op content: [words] [30] +op content: [characters] [40] +op open_leaf_list: [bytes] [] +op content: [bytes] [0] +op content: [bytes] [1] +op content: [bytes] [2] +op content: [bytes] [3] +op content: [bytes] [4] +op close_leaf_list: [bytes] [] +op content: [mbuf-current] [10] +op content: [mbuf-cache] [20] +op content: [mbuf-total] [30] +op content: [distance] [50] +op string: [location] [Boston] +op content: [memory] [64] +op content: [total] [640] +op content: [memory] [64] +op content: [total] [640] +op content: [ten] [10] +op content: [eleven] [11] +op content: [unknown] [1010] +op content: [unknown] [1010] +op content: [min] [15] +op content: [cur] [20] +op content: [max] [30] +op content: [min] [15] +op content: [cur] [20] +op content: [max] [125] +op content: [min] [15] +op content: [cur] [20] +op content: [max] [125] +op content: [min] [15] +op content: [cur] [20] +op content: [max] [125] +op content: [val1] [21] +op content: [val2] [58368] +op content: [val3] [100663296] +op content: [val4] [44470272] +op content: [val5] [1342172800] +op open_list: [flag] [] +op string: [flag] [one] +op string: [flag] [two] +op string: [flag] [three] +op close_list: [flag] [] +op content: [works] [null] +op content: [empty-tag] [true] +op string: [t1] [1000] +op string: [t2] [test5000] +op string: [t3] [ten-longx] +op string: [t4] [xtest] +op content: [count] [10] +op content: [test] [4] +op close_container: [data] [] +op close_container: [top] [] +op finish: [] [] +op flush: [] [] From d55856982533d6d8a884adf17369ae9a69e0dd5d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:15 -0400 Subject: [PATCH 354/514] Add encoder=test test cases --- tests/core/saved/test_03.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_03.E.err diff --git a/tests/core/saved/test_03.E.err b/tests/core/saved/test_03.E.err new file mode 100644 index 00000000..e69de29b From 1c03c1e87c0902b45a2a0b29b4500158ea17efc4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:16 -0400 Subject: [PATCH 355/514] Add encoder=test test cases --- tests/core/saved/test_03.E.out | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/core/saved/test_03.E.out diff --git a/tests/core/saved/test_03.E.out b/tests/core/saved/test_03.E.out new file mode 100644 index 00000000..39657834 --- /dev/null +++ b/tests/core/saved/test_03.E.out @@ -0,0 +1,22 @@ +op create: [] [] +op open_container: [employees] [] +op open_list: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Terry] +op string: [last-name] [Jones] +op content: [department] [660] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Leslie] +op string: [last-name] [Patterson] +op content: [department] [341] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Ashley] +op string: [last-name] [Smith] +op content: [department] [1440] +op close_instance: [employee] [] +op close_list: [employee] [] +op close_container: [employees] [] +op finish: [] [] +op flush: [] [] From 5e232399cd20b22be18dd4d04cdd5cac6eee18bc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:17 -0400 Subject: [PATCH 356/514] Add encoder=test test cases --- tests/core/saved/test_04.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_04.E.err diff --git a/tests/core/saved/test_04.E.err b/tests/core/saved/test_04.E.err new file mode 100644 index 00000000..e69de29b From 36016aa79a42c9aea3ff76c62d1c501c52483fc5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:17 -0400 Subject: [PATCH 357/514] Add encoder=test test cases --- tests/core/saved/test_04.E.out | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/core/saved/test_04.E.out diff --git a/tests/core/saved/test_04.E.out b/tests/core/saved/test_04.E.out new file mode 100644 index 00000000..39657834 --- /dev/null +++ b/tests/core/saved/test_04.E.out @@ -0,0 +1,22 @@ +op create: [] [] +op open_container: [employees] [] +op open_list: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Terry] +op string: [last-name] [Jones] +op content: [department] [660] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Leslie] +op string: [last-name] [Patterson] +op content: [department] [341] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Ashley] +op string: [last-name] [Smith] +op content: [department] [1440] +op close_instance: [employee] [] +op close_list: [employee] [] +op close_container: [employees] [] +op finish: [] [] +op flush: [] [] From f7ff8250383562440e3f743dbe6c2f6ebea2df5a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:18 -0400 Subject: [PATCH 358/514] Add encoder=test test cases --- tests/core/saved/test_05.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_05.E.err diff --git a/tests/core/saved/test_05.E.err b/tests/core/saved/test_05.E.err new file mode 100644 index 00000000..e69de29b From 9d8b1879ee897d5b3b111820fe2461750fa073b5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:19 -0400 Subject: [PATCH 359/514] Add encoder=test test cases --- tests/core/saved/test_05.E.out | 86 ++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/core/saved/test_05.E.out diff --git a/tests/core/saved/test_05.E.out b/tests/core/saved/test_05.E.out new file mode 100644 index 00000000..7fc3a0ca --- /dev/null +++ b/tests/core/saved/test_05.E.out @@ -0,0 +1,86 @@ +op create: [] [] +op open_container: [employees] [] +op open_leaf_list: [wc] [] +op string: [wc] [෴ - 0xdf4 - 1] +op string: [wc] [ණ - 0xdab - 1] +op string: [wc] [් - 0xdca - 1] +op string: [wc] [ණ - 0xdab - 1] +op string: [wc] [្ - 0x17d2 - 1] +op string: [wc] [෴ - 0xdf4 - 1] +op close_leaf_list: [wc] [] +op string: [v1] [γιγνώσκειν] +op string: [v2] [ὦ ἄνδρες ᾿Αθηναῖοι] +op string: [v1] [ახლავე გაიაროთ რეგისტრაცია] +op string: [v2] [Unicode-ის მეათე საერთაშორისო] +op content: [width] [55] +op string: [sinhala] [෴ණ්ණ෴] +op content: [width] [5] +op string: [sinhala] [෴] +op content: [width] [1] +op string: [sinhala] [෴ණ්ණ෴෴ණ්ණ෴] +op content: [width] [10] +op string: [not-sinhala] [123456] +op string: [tag] [ර්ඝ] +op content: [width] [3] +op open_list: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Jim] +op string: [nic-name] ["რეგტ"] +op string: [last-name] [გთხოვთ ახ] +op content: [department] [431] +op content: [percent-time] [90] +op attr: [full-time] [honest & for true] +op string: [benefits] [full] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Terry] +op string: [nic-name] [" Date: Tue, 4 Aug 2015 17:53:20 -0400 Subject: [PATCH 360/514] Add encoder=test test cases --- tests/core/saved/test_06.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_06.E.err diff --git a/tests/core/saved/test_06.E.err b/tests/core/saved/test_06.E.err new file mode 100644 index 00000000..e69de29b From ecea84d3ed3867addf4be7a03e10cafeac80f7f4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:20 -0400 Subject: [PATCH 361/514] Add encoder=test test cases --- tests/core/saved/test_06.E.out | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/core/saved/test_06.E.out diff --git a/tests/core/saved/test_06.E.out b/tests/core/saved/test_06.E.out new file mode 100644 index 00000000..39657834 --- /dev/null +++ b/tests/core/saved/test_06.E.out @@ -0,0 +1,22 @@ +op create: [] [] +op open_container: [employees] [] +op open_list: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Terry] +op string: [last-name] [Jones] +op content: [department] [660] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Leslie] +op string: [last-name] [Patterson] +op content: [department] [341] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Ashley] +op string: [last-name] [Smith] +op content: [department] [1440] +op close_instance: [employee] [] +op close_list: [employee] [] +op close_container: [employees] [] +op finish: [] [] +op flush: [] [] From 80ecbd62dfbba168c61ccee0a10aff59593f6232 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:21 -0400 Subject: [PATCH 362/514] Add encoder=test test cases --- tests/core/saved/test_07.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_07.E.err diff --git a/tests/core/saved/test_07.E.err b/tests/core/saved/test_07.E.err new file mode 100644 index 00000000..e69de29b From af9cae3280780b0d882ee3455c02995a11f44024 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:22 -0400 Subject: [PATCH 363/514] Add encoder=test test cases --- tests/core/saved/test_07.E.out | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 tests/core/saved/test_07.E.out diff --git a/tests/core/saved/test_07.E.out b/tests/core/saved/test_07.E.out new file mode 100644 index 00000000..45e4b693 --- /dev/null +++ b/tests/core/saved/test_07.E.out @@ -0,0 +1,76 @@ +op create: [] [] +op open_container: [employees] [] +op open_list: [test] [] +op open_instance: [test] [] +op string: [filename] [(null)] +op close_instance: [test] [] +op close_list: [test] [] +op string: [v1] [γιγνώσκειν] +op string: [v2] [ὦ ἄνδρες ᾿Αθηναῖοι] +op content: [columns] [28] +op content: [columns] [2] +op string: [v1] [ახლავე გაიაროთ რეგისტრაცია] +op string: [v2] [Unicode-ის მეათე საერთაშორისო] +op content: [columns] [55] +op content: [columns] [0] +op open_list: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Jim] +op string: [nic-name] ["რეგტ"] +op string: [last-name] [გთხოვთ ახ] +op content: [department] [431] +op content: [percent-time] [90] +op content: [columns] [23] +op attr: [full-time] [honest & for true] +op string: [benefits] [full] +op close_instance: [employee] [] +op open_instance: [employee] [] +op string: [first-name] [Terry] +op string: [nic-name] [" Date: Tue, 4 Aug 2015 17:53:23 -0400 Subject: [PATCH 364/514] Add encoder=test test cases --- tests/core/saved/test_08.E.err | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/core/saved/test_08.E.err diff --git a/tests/core/saved/test_08.E.err b/tests/core/saved/test_08.E.err new file mode 100644 index 00000000..445bfb71 --- /dev/null +++ b/tests/core/saved/test_08.E.err @@ -0,0 +1,18 @@ +test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm2'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'top' From 5d263796789dbe3bac218bef2b575ad090ba6399 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:23 -0400 Subject: [PATCH 365/514] Add encoder=test test cases --- tests/core/saved/test_08.E.out | 186 +++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 tests/core/saved/test_08.E.out diff --git a/tests/core/saved/test_08.E.out b/tests/core/saved/test_08.E.out new file mode 100644 index 00000000..c0fdb6b1 --- /dev/null +++ b/tests/core/saved/test_08.E.out @@ -0,0 +1,186 @@ +op create: [] [] +op open_container: [top] [] +op open_container: [data] [] +op open_container: [contents] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [name] [gum] +op content: [count] [1412] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [rope] +op content: [count] [85] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [ladder] +op content: [count] [0] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [bolt] +op content: [count] [4123] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [water] +op content: [count] [17] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [contents] [] +op close_container: [data] [] +op open_container: [data] [] +op open_container: [contents] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [name] [gum] +op content: [count] [1412] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [rope] +op content: [count] [85] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [ladder] +op content: [count] [0] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [bolt] +op content: [count] [4123] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [water] +op content: [count] [17] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [contents] [] +op close_container: [data] [] +op open_container: [data] [] +op open_container: [contents] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [name] [gum] +op content: [count] [1412] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [rope] +op content: [count] [85] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [ladder] +op content: [count] [0] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [bolt] +op content: [count] [4123] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [water] +op content: [count] [17] +op string: [test] [one] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [contents] [] +op close_container: [data] [] +op open_container: [data] [] +op open_container: [contents] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [name] [gum] +op content: [count] [1412] +op open_list: [sub] [] +op open_instance: [sub] [] +op content: [name] [0] +op content: [next] [1] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [1] +op content: [next] [2] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [2] +op content: [next] [3] +op close_instance: [sub] [] +op close_list: [sub] [] +op content: [last] [3] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [rope] +op content: [count] [85] +op open_list: [sub] [] +op open_instance: [sub] [] +op content: [name] [0] +op content: [next] [1] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [1] +op content: [next] [2] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [2] +op content: [next] [3] +op close_instance: [sub] [] +op close_list: [sub] [] +op content: [last] [3] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [ladder] +op content: [count] [0] +op open_list: [sub] [] +op open_instance: [sub] [] +op content: [name] [0] +op content: [next] [1] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [1] +op content: [next] [2] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [2] +op content: [next] [3] +op close_instance: [sub] [] +op close_list: [sub] [] +op content: [last] [3] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [bolt] +op content: [count] [4123] +op open_list: [sub] [] +op open_instance: [sub] [] +op content: [name] [0] +op content: [next] [1] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [1] +op content: [next] [2] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [2] +op content: [next] [3] +op close_instance: [sub] [] +op close_list: [sub] [] +op content: [last] [3] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [name] [water] +op content: [count] [17] +op open_list: [sub] [] +op open_instance: [sub] [] +op content: [name] [0] +op content: [next] [1] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [1] +op content: [next] [2] +op close_instance: [sub] [] +op open_instance: [sub] [] +op content: [name] [2] +op content: [next] [3] +op close_instance: [sub] [] +op close_list: [sub] [] +op content: [last] [3] +op string: [test] [one] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [contents] [] +op close_container: [data] [] +op close_container: [top] [] +op finish: [] [] +op flush: [] [] From d71c685ea041cff844b306a60522a38bb9ba5835 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:24 -0400 Subject: [PATCH 366/514] Add encoder=test test cases --- tests/core/saved/test_09.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_09.E.err diff --git a/tests/core/saved/test_09.E.err b/tests/core/saved/test_09.E.err new file mode 100644 index 00000000..e69de29b From 97a2008eb93d29dbc012ba12121633035fc77345 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:25 -0400 Subject: [PATCH 367/514] Add encoder=test test cases --- tests/core/saved/test_09.E.out | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/core/saved/test_09.E.out diff --git a/tests/core/saved/test_09.E.out b/tests/core/saved/test_09.E.out new file mode 100644 index 00000000..bb808d5e --- /dev/null +++ b/tests/core/saved/test_09.E.out @@ -0,0 +1,40 @@ +op create: [] [] +op open_container: [top] [] +op open_container: [data] [] +op open_container: [contents] [] +op open_leaf_list: [name] [] +op string: [name] [gum] +op string: [name] [rope] +op string: [name] [ladder] +op string: [name] [bolt] +op string: [name] [water] +op close_leaf_list: [name] [] +op close_container: [contents] [] +op open_container: [contents] [] +op open_leaf_list: [item] [] +op string: [item] [gum] +op string: [item] [rope] +op string: [item] [ladder] +op string: [item] [bolt] +op string: [item] [water] +op close_leaf_list: [item] [] +op close_container: [contents] [] +op open_container: [contents] [] +op open_list: [item] [] +op string: [item] [gum] +op string: [item] [rope] +op string: [item] [ladder] +op string: [item] [bolt] +op string: [item] [water] +op close_list: [item] [] +op string: [total] [six] +op string: [one] [one] +op open_leaf_list: [two] [] +op string: [two] [two] +op close_leaf_list: [two] [] +op string: [three] [three] +op close_container: [contents] [] +op close_container: [data] [] +op close_container: [top] [] +op finish: [] [] +op flush: [] [] From 0adccce468e8f861d8e87d37825d5c58098511f9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:26 -0400 Subject: [PATCH 368/514] Add encoder=test test cases --- tests/core/saved/test_10.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.E.err diff --git a/tests/core/saved/test_10.E.err b/tests/core/saved/test_10.E.err new file mode 100644 index 00000000..e69de29b From ed48871efc8d88460df6bfec358af5a689d863b4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:26 -0400 Subject: [PATCH 369/514] Add encoder=test test cases --- tests/core/saved/test_10.E.out | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tests/core/saved/test_10.E.out diff --git a/tests/core/saved/test_10.E.out b/tests/core/saved/test_10.E.out new file mode 100644 index 00000000..4f21cda4 --- /dev/null +++ b/tests/core/saved/test_10.E.out @@ -0,0 +1,126 @@ +op create: [] [] +op version: [] [3.1.4] +op open_container: [top] [] +op attr: [test] [value] +op open_container: [data] [] +op open_list: [item] [] +op attr: [test2] [value2] +op close_list: [item] [] +op string: [data] [bold] +op string: [data] [bold-ul] +op string: [data] [triple] +op string: [data] [inv-ul] +op string: [data] [underline] +op string: [data] [plain] +op open_list: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [GRO-000-415] +op string: [name] [gum] +op content: [sold] [1412] +op content: [in-stock] [54] +op content: [on-order] [10] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [HRD-000-212] +op string: [name] [rope] +op content: [sold] [85] +op content: [in-stock] [4] +op content: [on-order] [2] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [HRD-000-517] +op string: [name] [ladder] +op content: [sold] [0] +op content: [in-stock] [2] +op content: [on-order] [1] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [HRD-000-632] +op string: [name] [bolt] +op content: [sold] [4123] +op content: [in-stock] [144] +op content: [on-order] [42] +op close_instance: [item] [] +op open_instance: [item] [] +op attr: [test3] [value3] +op string: [sku] [GRO-000-2331] +op string: [name] [water] +op content: [sold] [17] +op content: [in-stock] [14] +op content: [on-order] [2] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [data] [] +op open_container: [data] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [sku] [GRO-000-415] +op string: [name] [gum] +op content: [sold] [1412.0] +op content: [in-stock] [54] +op content: [on-order] [10] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [HRD-000-212] +op string: [name] [rope] +op content: [sold] [85.0] +op content: [in-stock] [4] +op content: [on-order] [2] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [HRD-000-517] +op string: [name] [ladder] +op content: [sold] [0] +op content: [in-stock] [2] +op content: [on-order] [1] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [HRD-000-632] +op string: [name] [bolt] +op content: [sold] [4123.0] +op content: [in-stock] [144] +op content: [on-order] [42] +op close_instance: [item] [] +op open_instance: [item] [] +op string: [sku] [GRO-000-2331] +op string: [name] [water] +op content: [sold] [17.0] +op content: [in-stock] [14] +op content: [on-order] [2] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [data] [] +op open_container: [data] [] +op open_list: [item] [] +op open_instance: [item] [] +op string: [sku] [GRO-000-533] +op string: [name] [fish] +op content: [sold] [1321.0] +op content: [in-stock] [45] +op content: [on-order] [1] +op close_instance: [item] [] +op close_list: [item] [] +op close_container: [data] [] +op open_container: [data] [] +op open_list: [item] [] +op attr: [test4] [value4] +op string: [item] [gum] +op attr: [test4] [value4] +op string: [item] [rope] +op attr: [test4] [value4] +op string: [item] [ladder] +op attr: [test4] [value4] +op string: [item] [bolt] +op attr: [test4] [value4] +op string: [item] [water] +op close_list: [item] [] +op close_container: [data] [] +op content: [cost] [425] +op content: [cost] [455] +op close_container: [top] [] +op finish: [] [] +op flush: [] [] From 39323c6055886537675333b0add616dcb156ffc1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:27 -0400 Subject: [PATCH 370/514] Add encoder=test test cases --- tests/core/saved/test_11.E.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_11.E.err diff --git a/tests/core/saved/test_11.E.err b/tests/core/saved/test_11.E.err new file mode 100644 index 00000000..e69de29b From e4c0ea7a7885450fe9543c9254fffaed262b7489 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:28 -0400 Subject: [PATCH 371/514] Add encoder=test test cases --- tests/core/saved/test_11.E.out | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/core/saved/test_11.E.out diff --git a/tests/core/saved/test_11.E.out b/tests/core/saved/test_11.E.out new file mode 100644 index 00000000..9fd70fa5 --- /dev/null +++ b/tests/core/saved/test_11.E.out @@ -0,0 +1,26 @@ +op create: [] [] +op version: [] [3.1.4] +op open_container: [top] [] +op create: [] [] +{{<14>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 animal-status [animal-status@42 animal="snake" state="loose"] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +op create: [] [] +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 animal-consumed [animal-consumed@42 animal="snake" pet="hamster"] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +op create: [] [] +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 animal-talk [animal-talk@42 count="1" animal="owl" quote="\"e=m\\c[2\]\""] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + +op create: [] [] +{{<165>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 ID47 [ID47@32473 iut="3" event-source="application" event-id="1011"] An application 1011 log entry}} +{{test-program: }} +{{An application 1011 log entry}} + +op close_container: [top] [] +op finish: [] [] +op flush: [] [] From d9c08f496cfa55129deda2635b2836b0fdd0cd6b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:55 -0400 Subject: [PATCH 372/514] initial version --- encoder/test/Makefile.am | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 encoder/test/Makefile.am diff --git a/encoder/test/Makefile.am b/encoder/test/Makefile.am new file mode 100644 index 00000000..1a883faf --- /dev/null +++ b/encoder/test/Makefile.am @@ -0,0 +1,51 @@ +# +# $Id$ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +if HAVE_GCC +GCC_WARNINGS = yes +endif +include ${top_srcdir}/warnings.mk + +enc_testincdir = ${includedir}/libxo + +AM_CFLAGS = \ + -I${top_srcdir}/libxo \ + -I${top_builddir}/libxo \ + ${WARNINGS} + +LIBNAME = libenc_test +pkglib_LTLIBRARIES = libenc_test.la +LIBS = \ + -L${top_builddir}/libxo -lxo + +LDADD = ${top_builddir}/libxo/libxo.la + +libenc_test_la_SOURCES = \ + enc_test.c + +pkglibdir = ${XO_EXTDIR} + +UGLY_NAME = test.enc + +install-exec-hook: + @DLNAME=`sh -c '. ./libenc_test.la ; echo $$dlname'` ; \ + if [ x"$$DLNAME" = x ]; \ + then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \ + if [ "$(build_os)" = "cygwin" ]; \ + then DLNAME="../bin/$$DLNAME"; fi ; \ + echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \ + mkdir -p ${DESTDIR}${XO_EXTDIR} ; \ + cd ${DESTDIR}${XO_EXTDIR} \ + && chmod +w . \ + && rm -f ${UGLY_NAME} \ + && ${LN_S} $$DLNAME ${UGLY_NAME} From 039f2765643da913d982172625979daee0c0f548 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 4 Aug 2015 17:53:56 -0400 Subject: [PATCH 373/514] initial version --- encoder/test/enc_test.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 encoder/test/enc_test.c diff --git a/encoder/test/enc_test.c b/encoder/test/enc_test.c new file mode 100644 index 00000000..500bd147 --- /dev/null +++ b/encoder/test/enc_test.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +#include "xo.h" +#include "xo_encoder.h" + +static int +test_handler (XO_ENCODER_HANDLER_ARGS) +{ + printf("op %s: [%s] [%s]\n", xo_encoder_op_name(op), + name ?: "", value ?: ""); + + return 0; +} + +int +xo_encoder_library_init (XO_ENCODER_INIT_ARGS) +{ + arg->xei_handler = test_handler; + + return 0; +} From f5aea66c5390bd6f2bd939985386e12b7cb4b912 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:13:21 -0400 Subject: [PATCH 374/514] rename xo*.h to xo_*.h for consistency --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 88b483dc..8d70b6cc 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ configure .DS_Store xoconfig.h.in +xo_config.h.in .gdbinit .gdbinit.local From beba3a34c462603b0dd02379e9ea4edb3a43ecff Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:13:30 -0400 Subject: [PATCH 375/514] rename xo*.h to xo_*.h for consistency --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index a030616f..56a7e804 100644 --- a/configure.ac +++ b/configure.ac @@ -379,15 +379,15 @@ AC_SUBST(LIBXO_VERSION) AC_SUBST(LIBXO_VERSION_NUMBER) AC_SUBST(LIBXO_VERSION_EXTRA) -AC_CONFIG_HEADERS([libxo/xoconfig.h]) +AC_CONFIG_HEADERS([libxo/xo_config.h]) AC_CONFIG_FILES([ Makefile libxo-config xohtml/xohtml.sh libxo/Makefile - libxo/xoversion.h + libxo/xo_version.h encoder/Makefile - encoder/cbr/Makefile + encoder/cbor/Makefile encoder/test/Makefile xo/Makefile xolint/Makefile From 704f4f774c43bc86805ede5f9a9852580dfd5749 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:13:38 -0400 Subject: [PATCH 376/514] s/cbr/cbor/ --- encoder/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/encoder/Makefile.am b/encoder/Makefile.am index fe846be5..10d19de7 100644 --- a/encoder/Makefile.am +++ b/encoder/Makefile.am @@ -6,4 +6,4 @@ # using the SOFTWARE, you agree to be bound by the terms of that # LICENSE. -SUBDIRS = cbr test +SUBDIRS = cbor test From 72a806b8057e9a41f895e1f4beb53dfa010e4551 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:13:43 -0400 Subject: [PATCH 377/514] s/cbr/cbor/ --- encoder/cbr/Makefile.am | 51 ----------------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 encoder/cbr/Makefile.am diff --git a/encoder/cbr/Makefile.am b/encoder/cbr/Makefile.am deleted file mode 100644 index b6bd185b..00000000 --- a/encoder/cbr/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -# -# $Id$ -# -# Copyright 2015, Juniper Networks, Inc. -# All rights reserved. -# This SOFTWARE is licensed under the LICENSE provided in the -# ../Copyright file. By downloading, installing, copying, or otherwise -# using the SOFTWARE, you agree to be bound by the terms of that -# LICENSE. - -if LIBXO_WARNINGS_HIGH -LIBXO_WARNINGS = HIGH -endif -if HAVE_GCC -GCC_WARNINGS = yes -endif -include ${top_srcdir}/warnings.mk - -enc_cbrincdir = ${includedir}/libxo - -AM_CFLAGS = \ - -I${top_srcdir}/libxo \ - -I${top_builddir}/libxo \ - ${WARNINGS} - -LIBNAME = libenc_cbr -pkglib_LTLIBRARIES = libenc_cbr.la -LIBS = \ - -L${top_builddir}/libxo -lxo - -LDADD = ${top_builddir}/libxo/libxo.la - -libenc_cbr_la_SOURCES = \ - enc_cbr.c - -pkglibdir = ${XO_EXTDIR} - -UGLY_NAME = cbr.enc - -install-exec-hook: - @DLNAME=`sh -c '. ./libenc_cbr.la ; echo $$dlname'` ; \ - if [ x"$$DLNAME" = x ]; \ - then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \ - if [ "$(build_os)" = "cygwin" ]; \ - then DLNAME="../bin/$$DLNAME"; fi ; \ - echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \ - mkdir -p ${DESTDIR}${XO_EXTDIR} ; \ - cd ${DESTDIR}${XO_EXTDIR} \ - && chmod +w . \ - && rm -f ${UGLY_NAME} \ - && ${LN_S} $$DLNAME ${UGLY_NAME} From 86d1f944e692b3530a207b28f5aa86ebd3d7dc22 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:13:46 -0400 Subject: [PATCH 378/514] s/cbr/cbor/ --- encoder/cbr/enc_cbr.c | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 encoder/cbr/enc_cbr.c diff --git a/encoder/cbr/enc_cbr.c b/encoder/cbr/enc_cbr.c deleted file mode 100644 index 28bdcb71..00000000 --- a/encoder/cbr/enc_cbr.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015, Juniper Networks, Inc. - * All rights reserved. - * This SOFTWARE is licensed under the LICENSE provided in the - * ../Copyright file. By downloading, installing, copying, or otherwise - * using the SOFTWARE, you agree to be bound by the terms of that - * LICENSE. - * Phil Shafer, August 2015 - */ - -#include "xo.h" -#include "xo_encoder.h" - -static int -cbr_handler (XO_ENCODER_HANDLER_ARGS) -{ - return 0; -} - -int -xo_encoder_library_init (XO_ENCODER_INIT_ARGS) -{ - arg->xei_handler = cbr_handler; - - return 0; -} From d316dceff87c621590bd18bd7cf124aeee291ab7 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:14:02 -0400 Subject: [PATCH 379/514] add xo_encoder.h and xo_buf.h --- libxo/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index ec8309cc..27017b90 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -30,7 +30,11 @@ LIBS = \ ${GETTEXT_LIBS} libxoinc_HEADERS = \ - xo.h + xo.h \ + xo_encoder.h + +noinst_HEADERS = \ + xo_buf.h libxo_la_SOURCES = \ libxo.c \ From 19ccccc22e1ed4a2e20cf3763d365d85a89ae0ac Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:14:25 -0400 Subject: [PATCH 380/514] pull xo_buf* code into xo_buf.h --- libxo/libxo.c | 129 ++------------------------------------------------ 1 file changed, 3 insertions(+), 126 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 30a4a3ee..ae1d9466 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -24,10 +24,11 @@ #include #include -#include "xoconfig.h" +#include "xo_config.h" #include "xo.h" #include "xo_encoder.h" -#include "xoversion.h" +#include "xo_buf.h" +#include "xo_version.h" #ifdef HAVE_STDIO_EXT_H #include @@ -76,22 +77,11 @@ const char xo_version_extra[] = LIBXO_VERSION_EXTRA; #endif /* UNUSED */ #define XO_INDENT_BY 2 /* Amount to indent when pretty printing */ -#define XO_BUFSIZ (8*1024) /* Initial buffer size */ #define XO_DEPTH 512 /* Default stack depth */ #define XO_MAX_ANCHOR_WIDTH (8*1024) /* Anything wider is just sillyb */ #define XO_FAILURE_NAME "failure" -/* - * xo_buffer_t: a memory buffer that can be grown as needed. We - * use them for building format strings and output data. - */ -typedef struct xo_buffer_s { - char *xb_bufp; /* Buffer memory */ - char *xb_curp; /* Current insertion point */ - unsigned xb_size; /* Size of buffer */ -} xo_buffer_t; - /* Flags for the stack frame */ typedef unsigned xo_xsf_flags_t; /* XSF_* flags */ #define XSF_NOT_FIRST (1<<0) /* Not the first element */ @@ -480,63 +470,6 @@ xo_flush_file (void *opaque) return fflush(fp); } -/* - * Initialize the contents of an xo_buffer_t. - */ -static void -xo_buf_init (xo_buffer_t *xbp) -{ - xbp->xb_size = XO_BUFSIZ; - xbp->xb_bufp = xo_realloc(NULL, xbp->xb_size); - xbp->xb_curp = xbp->xb_bufp; -} - -/* - * Reset the buffer to empty - */ -static void -xo_buf_reset (xo_buffer_t *xbp) -{ - xbp->xb_curp = xbp->xb_bufp; -} - -/* - * See if the buffer to empty - */ -static int -xo_buf_is_empty (xo_buffer_t *xbp) -{ - return (xbp->xb_curp == xbp->xb_bufp); -} - -/* - * Return the current offset - */ -static unsigned -xo_buf_offset (xo_buffer_t *xbp) -{ - return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0; -} - -static char * -xo_buf_data (xo_buffer_t *xbp, unsigned offset) -{ - if (xbp == NULL) - return NULL; - return xbp->xb_bufp + offset; -} - -/* - * Initialize the contents of an xo_buffer_t. - */ -static void -xo_buf_cleanup (xo_buffer_t *xbp) -{ - if (xbp->xb_bufp) - xo_free(xbp->xb_bufp); - bzero(xbp, sizeof(*xbp)); -} - /* * Use a rotating stock of buffers to make a printable string */ @@ -707,34 +640,6 @@ xo_default_init (void) xo_default_inited = 1; } -/* - * Does the buffer have room for the given number of bytes of data? - * If not, realloc the buffer to make room. If that fails, we - * return 0 to tell the caller they are in trouble. - */ -static int -xo_buf_has_room (xo_buffer_t *xbp, int len) -{ - if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) { - int sz = xbp->xb_size + XO_BUFSIZ; - char *bp = xo_realloc(xbp->xb_bufp, sz); - if (bp == NULL) { - /* - * XXX If we wanted to put a stick XOF_ENOMEM on xop, - * this would be the place to do it. But we'd need - * to churn the code to pass xop in here.... - */ - return 0; - } - - xbp->xb_curp = bp + (xbp->xb_curp - xbp->xb_bufp); - xbp->xb_bufp = bp; - xbp->xb_size = sz; - } - - return 1; -} - /* * Cheap convenience function to return either the argument, or * the internal handle, after it has been initialized. The usage @@ -933,34 +838,6 @@ xo_escape_sdparams (xo_buffer_t *xbp, int len, xo_xff_flags_t flags UNUSED) return len + delta; } -/* - * Append the given string to the given buffer - */ -static void -xo_buf_append (xo_buffer_t *xbp, const char *str, int len) -{ - if (!xo_buf_has_room(xbp, len)) - return; - - memcpy(xbp->xb_curp, str, len); - xbp->xb_curp += len; -} - -/* - * Append the given NUL-terminated string to the given buffer - */ -static void -xo_buf_append_str (xo_buffer_t *xbp, const char *str) -{ - int len = strlen(str); - - if (!xo_buf_has_room(xbp, len)) - return; - - memcpy(xbp->xb_curp, str, len); - xbp->xb_curp += len; -} - static void xo_buf_escape (xo_handle_t *xop, xo_buffer_t *xbp, const char *str, int len, xo_xff_flags_t flags) From 82ba2d5ddf5af6c7f779de460696aa2f9a608517 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:14:29 -0400 Subject: [PATCH 381/514] pull xo_buf* code into xo_buf.h --- libxo/xo_buf.h | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 libxo/xo_buf.h diff --git a/libxo/xo_buf.h b/libxo/xo_buf.h new file mode 100644 index 00000000..349e9ade --- /dev/null +++ b/libxo/xo_buf.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +/* + * This file is an _internal_ part of the libxo plumbing, not suitable + * for external use. It is not considered part of the libxo API and + * will not be a stable part of that API. Mine, not your's, dude... + * The real hope is that something like this will become a standard part + * of libc and I can kill this off. + */ + +#ifndef XO_BUF_H +#define XO_BUF_H + +#define XO_BUFSIZ (8*1024) /* Initial buffer size */ + +/* + * xo_buffer_t: a memory buffer that can be grown as needed. We + * use them for building format strings and output data. + */ +typedef struct xo_buffer_s { + char *xb_bufp; /* Buffer memory */ + char *xb_curp; /* Current insertion point */ + unsigned xb_size; /* Size of buffer */ +} xo_buffer_t; + +/* + * Initialize the contents of an xo_buffer_t. + */ +static inline void +xo_buf_init (xo_buffer_t *xbp) +{ + xbp->xb_size = XO_BUFSIZ; + xbp->xb_bufp = xo_realloc(NULL, xbp->xb_size); + xbp->xb_curp = xbp->xb_bufp; +} + +/* + * Reset the buffer to empty + */ +static inline void +xo_buf_reset (xo_buffer_t *xbp) +{ + xbp->xb_curp = xbp->xb_bufp; +} + +/* + * Return the number of bytes left in the buffer + */ +static inline int +xo_buf_left (xo_buffer_t *xbp) +{ + return xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); +} + +/* + * See if the buffer to empty + */ +static inline int +xo_buf_is_empty (xo_buffer_t *xbp) +{ + return (xbp->xb_curp == xbp->xb_bufp); +} + +/* + * Return the current offset + */ +static inline unsigned +xo_buf_offset (xo_buffer_t *xbp) +{ + return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0; +} + +static inline char * +xo_buf_data (xo_buffer_t *xbp, unsigned offset) +{ + if (xbp == NULL) + return NULL; + return xbp->xb_bufp + offset; +} + +static inline char * +xo_buf_cur (xo_buffer_t *xbp) +{ + if (xbp == NULL) + return NULL; + return xbp->xb_curp; +} + +/* + * Initialize the contents of an xo_buffer_t. + */ +static inline void +xo_buf_cleanup (xo_buffer_t *xbp) +{ + if (xbp->xb_bufp) + xo_free(xbp->xb_bufp); + bzero(xbp, sizeof(*xbp)); +} + +/* + * Does the buffer have room for the given number of bytes of data? + * If not, realloc the buffer to make room. If that fails, we + * return 0 to tell the caller they are in trouble. + */ +static inline int +xo_buf_has_room (xo_buffer_t *xbp, int len) +{ + if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) { + int sz = xbp->xb_size + XO_BUFSIZ; + char *bp = xo_realloc(xbp->xb_bufp, sz); + if (bp == NULL) + return 0; + + xbp->xb_curp = bp + (xbp->xb_curp - xbp->xb_bufp); + xbp->xb_bufp = bp; + xbp->xb_size = sz; + } + + return 1; +} + +/* + * Append the given string to the given buffer + */ +static inline void +xo_buf_append (xo_buffer_t *xbp, const char *str, int len) +{ + if (!xo_buf_has_room(xbp, len)) + return; + + memcpy(xbp->xb_curp, str, len); + xbp->xb_curp += len; +} + +/* + * Append the given NUL-terminated string to the given buffer + */ +static inline void +xo_buf_append_str (xo_buffer_t *xbp, const char *str) +{ + int len = strlen(str); + + if (!xo_buf_has_room(xbp, len)) + return; + + memcpy(xbp->xb_curp, str, len); + xbp->xb_curp += len; +} + +#endif /* XO_BUF_H */ From 3f02253e06318918ae230d3df0ef257a428353ea Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:14:41 -0400 Subject: [PATCH 382/514] rename xoconfig.h xo_config.h --- libxo/xo_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_encoder.c b/libxo/xo_encoder.c index 399cdc70..52fedb13 100644 --- a/libxo/xo_encoder.c +++ b/libxo/xo_encoder.c @@ -22,7 +22,7 @@ #include #include -#include "xoconfig.h" +#include "xo_config.h" #include "xo.h" #include "xo_encoder.h" From 84c5a4b0dd781b58696cdabbeac7ef23117755db Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:14:50 -0400 Subject: [PATCH 383/514] use xo_buf.h --- libxo/xo_syslog.c | 55 ++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/libxo/xo_syslog.c b/libxo/xo_syslog.c index 9e60c069..b5d93dac 100644 --- a/libxo/xo_syslog.c +++ b/libxo/xo_syslog.c @@ -59,7 +59,10 @@ #include #include +#include "xo_config.h" #include "xo.h" +#include "xo_encoder.h" /* For xo_realloc */ +#include "xo_buf.h" /* * SYSLOG (RFC 5424) requires an enterprise identifier. This turns @@ -137,16 +140,6 @@ enum { CONNPRIV, }; -/* - * We can't see the real xo_buffer_t (for now), so we cons up a compatible - * version of it. - */ -typedef struct xo_sbuffer_s { - char *xb_basep; /* start of buffer */ - char *xb_curp; /* start of buffer */ - int xb_size; -} xo_sbuffer_t; - static xo_syslog_open_t xo_syslog_open; static xo_syslog_send_t xo_syslog_send; static xo_syslog_close_t xo_syslog_close; @@ -165,12 +158,6 @@ xo_set_syslog_enterprise_id (unsigned short eid) "%u", eid); } -static int -xo_sleft (xo_sbuffer_t *xbp) -{ - return xbp->xb_size - (xbp->xb_curp - xbp->xb_basep); -} - /* * Handle the work of transmitting the syslog message */ @@ -463,9 +450,9 @@ xo_snprintf (char *out, size_t outsize, const char *fmt, ...) static int xo_syslog_handle_write (void *opaque, const char *data) { - xo_sbuffer_t *xbp = opaque; + xo_buffer_t *xbp = opaque; int len = strlen(data); - int left = xo_sleft(xbp); + int left = xo_buf_left(xbp); if (len > left - 1) len = left - 1; @@ -502,7 +489,7 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) char *tp = NULL, *ep = NULL; unsigned start_of_msg = 0; char *v0_hdr = NULL; - xo_sbuffer_t xb; + xo_buffer_t xb; static pid_t my_pid; unsigned log_offset; @@ -530,7 +517,7 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) pri |= xo_logfacility; /* Create the primary stdio hook */ - xb.xb_basep = tbuf; + xb.xb_bufp = tbuf; xb.xb_curp = tbuf; xb.xb_size = sizeof(tbuf); @@ -578,16 +565,16 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) tp += xo_snprintf(tp, ep - tp, ": "); } - log_offset = xb.xb_curp - xb.xb_basep; + log_offset = xb.xb_curp - xb.xb_bufp; /* Add PRI, PRIVAL, and VERSION */ - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "<%d>1 ", pri); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "<%d>1 ", pri); /* Add TIMESTAMP with milliseconds and TZOFFSET */ - xb.xb_curp += strftime(xb.xb_curp, xo_sleft(&xb), "%FT%T", &tm); - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), + xb.xb_curp += strftime(xb.xb_curp, xo_buf_left(&xb), "%FT%T", &tm); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), ".%03.3u", tv.tv_usec / 1000); - xb.xb_curp += strftime(xb.xb_curp, xo_sleft(&xb), "%z ", &tm); + xb.xb_curp += strftime(xb.xb_curp, xo_buf_left(&xb), "%z ", &tm); /* * Add HOSTNAME; we rely on gethostname and don't fluff with @@ -600,15 +587,15 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) else (void) gethostname(hostname, sizeof(hostname)); - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s ", + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%s ", hostname[0] ? hostname : "-"); /* Add APP-NAME */ - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s ", + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%s ", xo_logtag ?: "-"); /* Add PROCID */ - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%d ", my_pid); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%d ", my_pid); /* * Add MSGID. The user should provide us with a name, which we @@ -650,7 +637,7 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) } } - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "%s [%s%s%s ", + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%s [%s%s%s ", name, name, at_sign, eid); /* @@ -672,18 +659,18 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) xb.xb_curp -= 1; /* Close the structured data (SD-ELEMENT) */ - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), "] "); + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "] "); /* * Since our MSG is known to be UTF-8, we MUST prefix it with * that most-annoying-of-all-UTF-8 features, the BOM (0xEF.BB.BF). */ - xb.xb_curp += xo_snprintf(xb.xb_curp, xo_sleft(&xb), + xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%c%c%c", 0xEF, 0xBB, 0xBF); /* Save the start of the message */ if (xo_logstat & LOG_PERROR) - start_of_msg = xb.xb_curp - xb.xb_basep; + start_of_msg = xb.xb_curp - xb.xb_bufp; xo_set_style(xop, XO_STYLE_TEXT); xo_set_flags(xop, XOF_UTF8); @@ -697,9 +684,9 @@ xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) *--xb.xb_curp = '\0'; if (xo_get_flags(xop) & XOF_LOG_SYSLOG) - fprintf(stderr, "xo: syslog: %s\n", xb.xb_basep + log_offset); + fprintf(stderr, "xo: syslog: %s\n", xb.xb_bufp + log_offset); - xo_send_syslog(xb.xb_basep, v0_hdr, xb.xb_basep + start_of_msg); + xo_send_syslog(xb.xb_bufp, v0_hdr, xb.xb_bufp + start_of_msg); xo_destroy(xop); From 4a11f46136dcabe63fb4e37cf18db73a6e1cfd80 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:03 -0400 Subject: [PATCH 384/514] rename xo*.h to xo_*.h --- libxo/xoversion.h.in | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 libxo/xoversion.h.in diff --git a/libxo/xoversion.h.in b/libxo/xoversion.h.in deleted file mode 100644 index 777e83e3..00000000 --- a/libxo/xoversion.h.in +++ /dev/null @@ -1,38 +0,0 @@ -/* - * $Id$ - * - * Copyright (c) 2014, Juniper Networks, Inc. - * All rights reserved. - * This SOFTWARE is licensed under the LICENSE provided in the - * ../Copyright file. By downloading, installing, copying, or otherwise - * using the SOFTWARE, you agree to be bound by the terms of that - * LICENSE. - * - * xoversion.h -- compile time constants for libxo - * NOTE: This file is generated from xoversion.h.in. - */ - -#ifndef LIBXO_XOVERSION_H -#define LIBXO_XOVERSION_H - -/** - * The version string - */ -#define LIBXO_VERSION "@PACKAGE_VERSION@" - -/** - * The version number - */ -#define LIBXO_VERSION_NUMBER @LIBXO_VERSION_NUMBER@ - -/** - * The version number as a string - */ -#define LIBXO_VERSION_STRING "@LIBXO_VERSION_NUMBER@" - -/** - * The version number extra info as a string - */ -#define LIBXO_VERSION_EXTRA "@LIBXO_VERSION_EXTRA@" - -#endif /* LIBXO_XOVERSION_H */ From 34dd2bbc4b2669d7ed31f1a5d067dc86e5d31f1e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:12 -0400 Subject: [PATCH 385/514] update test cases --- tests/core/saved/test_01.E.out | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_01.E.out b/tests/core/saved/test_01.E.out index 36e149cd..296a34ef 100644 --- a/tests/core/saved/test_01.E.out +++ b/tests/core/saved/test_01.E.out @@ -48,7 +48,7 @@ op content: [on-order] [2] op close_instance: [item] [] op close_list: [item] [] op close_container: [data] [] -op open_container: [data] [] +op open_container: [data2] [] op open_list: [item] [] op open_instance: [item] [] op string: [sku] [GRO-000-415] @@ -86,8 +86,8 @@ op content: [in-stock] [14] op content: [on-order] [2] op close_instance: [item] [] op close_list: [item] [] -op close_container: [data] [] -op open_container: [data] [] +op close_container: [data2] [] +op open_container: [data3] [] op open_list: [item] [] op open_instance: [item] [] op string: [sku] [GRO-000-533] @@ -97,8 +97,8 @@ op content: [in-stock] [45] op content: [on-order] [1] op close_instance: [item] [] op close_list: [item] [] -op close_container: [data] [] -op open_container: [data] [] +op close_container: [data3] [] +op open_container: [data4] [] op open_list: [item] [] op attr: [test4] [value4] op string: [item] [gum] @@ -111,7 +111,7 @@ op string: [item] [bolt] op attr: [test4] [value4] op string: [item] [water] op close_list: [item] [] -op close_container: [data] [] +op close_container: [data4] [] op content: [cost] [425] op content: [cost] [455] op close_container: [top] [] From 4e53864f2be59e6aa477df5bd293d0a7dfca57b9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:13 -0400 Subject: [PATCH 386/514] update test cases --- tests/core/saved/test_01.HIPx.out | 70 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/tests/core/saved/test_01.HIPx.out b/tests/core/saved/test_01.HIPx.out index 04a8c4e7..2b8e2969 100644 --- a/tests/core/saved/test_01.HIPx.out +++ b/tests/core/saved/test_01.HIPx.out @@ -54,224 +54,224 @@
Item
'
-
gum
+
gum
':
Total sold
:
-
1412.0
+
1412.0
In stock
:
-
54
+
54
On order
:
-
10
+
10
SKU
:
-
GRO-000-415
+
GRO-000-415
Item
'
-
rope
+
rope
':
Total sold
:
-
85.0
+
85.0
In stock
:
-
4
+
4
On order
:
-
2
+
2
SKU
:
-
HRD-000-212
+
HRD-000-212
Item
'
-
ladder
+
ladder
':
Total sold
:
-
0
+
0
In stock
:
-
2
+
2
On order
:
-
1
+
1
SKU
:
-
HRD-000-517
+
HRD-000-517
Item
'
-
bolt
+
bolt
':
Total sold
:
-
4123.0
+
4123.0
In stock
:
-
144
+
144
On order
:
-
42
+
42
SKU
:
-
HRD-000-632
+
HRD-000-632
Item
'
-
water
+
water
':
Total sold
:
-
17.0
+
17.0
In stock
:
-
14
+
14
On order
:
-
2
+
2
SKU
:
-
GRO-000-2331
+
GRO-000-2331
Item
'
-
fish
+
fish
':
Total sold
:
-
1321.0
+
1321.0
In stock
:
-
45
+
45
On order
:
-
1
+
1
SKU
:
-
GRO-000-533
+
GRO-000-533
Item
:
-
gum
+
gum
Item
:
-
rope
+
rope
Item
:
-
ladder
+
ladder
Item
:
-
bolt
+
bolt
Item
:
-
water
+
water
X
From 205d6a9edb9cd28ae937901695f36e7098d7b27a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:14 -0400 Subject: [PATCH 387/514] update test cases --- tests/core/saved/test_01.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_01.J.out b/tests/core/saved/test_01.J.out index 43837d2c..69e3faa6 100644 --- a/tests/core/saved/test_01.J.out +++ b/tests/core/saved/test_01.J.out @@ -1,2 +1,2 @@ -{"top": {"host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455} +{"top": {"host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455} } From f9d34901f51678d2b43e5dbedb60814a9f0ef8a2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:16 -0400 Subject: [PATCH 388/514] update test cases --- tests/core/saved/test_01.JP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_01.JP.out b/tests/core/saved/test_01.JP.out index 6258f861..e65897fe 100644 --- a/tests/core/saved/test_01.JP.out +++ b/tests/core/saved/test_01.JP.out @@ -41,7 +41,7 @@ } ] }, - "data": { + "data2": { "item": [ { "sku": "GRO-000-415", @@ -80,7 +80,7 @@ } ] }, - "data": { + "data3": { "item": [ { "sku": "GRO-000-533", @@ -91,7 +91,7 @@ } ] }, - "data": { + "data4": { "item": [ "gum", "rope", From 2b1f79c2c52011c9fca5b9fcc114b0896acb35fe Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:16 -0400 Subject: [PATCH 389/514] update test cases --- tests/core/saved/test_01.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_01.X.out b/tests/core/saved/test_01.X.out index 4791f406..46f501e2 100644 --- a/tests/core/saved/test_01.X.out +++ b/tests/core/saved/test_01.X.out @@ -1 +1 @@ -my-boxexample.comGRO-000-415gum14125410HRD-000-212rope8542HRD-000-517ladder021HRD-000-632bolt412314442GRO-000-2331water17142GRO-000-415gum1412.05410HRD-000-212rope85.042HRD-000-517ladder021HRD-000-632bolt4123.014442GRO-000-2331water17.0142GRO-000-533fish1321.0451gumropeladderboltwater425455 \ No newline at end of file +my-boxexample.comGRO-000-415gum14125410HRD-000-212rope8542HRD-000-517ladder021HRD-000-632bolt412314442GRO-000-2331water17142GRO-000-415gum1412.05410HRD-000-212rope85.042HRD-000-517ladder021HRD-000-632bolt4123.014442GRO-000-2331water17.0142GRO-000-533fish1321.0451gumropeladderboltwater425455 \ No newline at end of file From d985501ab3efd9ba099cacec7f32531c7e1eb804 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:19 -0400 Subject: [PATCH 390/514] update test cases --- tests/core/saved/test_01.XP.out | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_01.XP.out b/tests/core/saved/test_01.XP.out index 8e4f5c4e..c7f4bfe8 100644 --- a/tests/core/saved/test_01.XP.out +++ b/tests/core/saved/test_01.XP.out @@ -38,7 +38,7 @@ 2 - + GRO-000-415 gum @@ -74,8 +74,8 @@ 14 2 - - + + GRO-000-533 fish @@ -83,14 +83,14 @@ 45 1 - - + + gum rope ladder bolt water - + 425 455 From 2a95946c359989b577cc32e0161344c788dc9094 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:20 -0400 Subject: [PATCH 391/514] update test cases --- tests/core/saved/test_08.E.err | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.E.err b/tests/core/saved/test_08.E.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.E.err +++ b/tests/core/saved/test_08.E.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From c90eed9ba628b7724a567060cc882013961fadf8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:21 -0400 Subject: [PATCH 392/514] update test cases --- tests/core/saved/test_08.E.out | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_08.E.out b/tests/core/saved/test_08.E.out index c0fdb6b1..c00f4b81 100644 --- a/tests/core/saved/test_08.E.out +++ b/tests/core/saved/test_08.E.out @@ -26,7 +26,7 @@ op close_instance: [item] [] op close_list: [item] [] op close_container: [contents] [] op close_container: [data] [] -op open_container: [data] [] +op open_container: [data2] [] op open_container: [contents] [] op open_list: [item] [] op open_instance: [item] [] @@ -51,8 +51,8 @@ op content: [count] [17] op close_instance: [item] [] op close_list: [item] [] op close_container: [contents] [] -op close_container: [data] [] -op open_container: [data] [] +op close_container: [data2] [] +op open_container: [data3] [] op open_container: [contents] [] op open_list: [item] [] op open_instance: [item] [] @@ -78,8 +78,8 @@ op string: [test] [one] op close_instance: [item] [] op close_list: [item] [] op close_container: [contents] [] -op close_container: [data] [] -op open_container: [data] [] +op close_container: [data3] [] +op open_container: [data4] [] op open_container: [contents] [] op open_list: [item] [] op open_instance: [item] [] @@ -180,7 +180,7 @@ op string: [test] [one] op close_instance: [item] [] op close_list: [item] [] op close_container: [contents] [] -op close_container: [data] [] +op close_container: [data4] [] op close_container: [top] [] op finish: [] [] op flush: [] [] From 206c984ef4a6fa1ba9877a0a8fbc41f84a54aa57 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:22 -0400 Subject: [PATCH 393/514] update test cases --- tests/core/saved/test_08.H.err | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.H.err b/tests/core/saved/test_08.H.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.H.err +++ b/tests/core/saved/test_08.H.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From c97dc80236935d2c9d92af04cbcd40ac14663bc2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:23 -0400 Subject: [PATCH 394/514] update test cases --- tests/core/saved/test_08.HIPx.err | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.HIPx.err b/tests/core/saved/test_08.HIPx.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.HIPx.err +++ b/tests/core/saved/test_08.HIPx.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From c84d36efe7ef58cdca77dfae6ef0df0447dd51c3 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:25 -0400 Subject: [PATCH 395/514] update test cases --- tests/core/saved/test_08.HIPx.out | 134 +++++++++++++++--------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/tests/core/saved/test_08.HIPx.out b/tests/core/saved/test_08.HIPx.out index 87bfbed3..2263347c 100644 --- a/tests/core/saved/test_08.HIPx.out +++ b/tests/core/saved/test_08.HIPx.out @@ -31,24 +31,24 @@
Count
-
gum
-
1412
+
gum
+
1412
-
rope
-
85
+
rope
+
85
-
ladder
-
0
+
ladder
+
0
-
bolt
-
4123
+
bolt
+
4123
-
water
-
17
+
water
+
17
@@ -59,27 +59,27 @@
Count
-
gum
-
1412
+
gum
+
1412
-
rope
-
85
+
rope
+
85
-
ladder
-
0
+
ladder
+
0
-
bolt
-
4123
+
bolt
+
4123
-
water
-
17
+
water
+
17
-
one
+
one
@@ -88,177 +88,177 @@
Count
-
gum
-
1412
+
gum
+
1412
Name
:
-
0
+
0
+ 1 =
-
1
+
1
Name
:
-
1
+
1
+ 1 =
-
2
+
2
Name
:
-
2
+
2
+ 1 =
-
3
+
3
Last
:
-
3
+
3
-
rope
-
85
+
rope
+
85
Name
:
-
0
+
0
+ 1 =
-
1
+
1
Name
:
-
1
+
1
+ 1 =
-
2
+
2
Name
:
-
2
+
2
+ 1 =
-
3
+
3
Last
:
-
3
+
3
-
ladder
-
0
+
ladder
+
0
Name
:
-
0
+
0
+ 1 =
-
1
+
1
Name
:
-
1
+
1
+ 1 =
-
2
+
2
Name
:
-
2
+
2
+ 1 =
-
3
+
3
Last
:
-
3
+
3
-
bolt
-
4123
+
bolt
+
4123
Name
:
-
0
+
0
+ 1 =
-
1
+
1
Name
:
-
1
+
1
+ 1 =
-
2
+
2
Name
:
-
2
+
2
+ 1 =
-
3
+
3
Last
:
-
3
+
3
-
water
-
17
+
water
+
17
Name
:
-
0
+
0
+ 1 =
-
1
+
1
Name
:
-
1
+
1
+ 1 =
-
2
+
2
Name
:
-
2
+
2
+ 1 =
-
3
+
3
Last
:
-
3
+
3
-
one
+
one
From 7a9730c0e4b89411227de47adb4245e579f7826e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:26 -0400 Subject: [PATCH 396/514] update test cases --- tests/core/saved/test_08.HP.err | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.HP.err b/tests/core/saved/test_08.HP.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.HP.err +++ b/tests/core/saved/test_08.HP.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From 83633d0ffacee92d1d56595cce929e6c87669366 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:27 -0400 Subject: [PATCH 397/514] update test cases --- tests/core/saved/test_08.J.err | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.J.err b/tests/core/saved/test_08.J.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.J.err +++ b/tests/core/saved/test_08.J.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From 8324b349591845bcd151e225be5bdcbc377d036c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:28 -0400 Subject: [PATCH 398/514] update test cases --- tests/core/saved/test_08.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_08.J.out b/tests/core/saved/test_08.J.out index cbce0910..9d897552 100644 --- a/tests/core/saved/test_08.J.out +++ b/tests/core/saved/test_08.J.out @@ -1,2 +1,2 @@ -{"top": {"data": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17,"test":"one"}]}}, "data": {"contents": {"item": [{"name":"gum","count":1412, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"rope","count":85, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"ladder","count":0, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"bolt","count":4123, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"water","count":17, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3,"test":"one"}]}}} +{"top": {"data": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data2": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data3": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17,"test":"one"}]}}, "data4": {"contents": {"item": [{"name":"gum","count":1412, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"rope","count":85, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"ladder","count":0, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"bolt","count":4123, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"water","count":17, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3,"test":"one"}]}}} } From d66ba05044c175b05560f5bd72e7378eaceac37b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:29 -0400 Subject: [PATCH 399/514] update test cases --- tests/core/saved/test_08.JP.err | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.JP.err b/tests/core/saved/test_08.JP.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.JP.err +++ b/tests/core/saved/test_08.JP.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From 02a391ee6c35ee9b34517144db3da3980aadd836 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:30 -0400 Subject: [PATCH 400/514] update test cases --- tests/core/saved/test_08.JP.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/saved/test_08.JP.out b/tests/core/saved/test_08.JP.out index 932d6a12..46f3de5f 100644 --- a/tests/core/saved/test_08.JP.out +++ b/tests/core/saved/test_08.JP.out @@ -26,7 +26,7 @@ ] } }, - "data": { + "data2": { "contents": { "item": [ { @@ -52,7 +52,7 @@ ] } }, - "data": { + "data3": { "contents": { "item": [ { @@ -79,7 +79,7 @@ ] } }, - "data": { + "data4": { "contents": { "item": [ { From bd86b050ab9755e58909105bf14f6452bcd3535e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:31 -0400 Subject: [PATCH 401/514] update test cases --- tests/core/saved/test_08.T.err | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.T.err b/tests/core/saved/test_08.T.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.T.err +++ b/tests/core/saved/test_08.T.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From c9ca5c221acedb5d948051319fb03018a43d7808 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:32 -0400 Subject: [PATCH 402/514] update test cases --- tests/core/saved/test_08.X.err | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.X.err b/tests/core/saved/test_08.X.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.X.err +++ b/tests/core/saved/test_08.X.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From f02d132cd1ae6bbfd205aee557f0e8eb9167f569 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:33 -0400 Subject: [PATCH 403/514] update test cases --- tests/core/saved/test_08.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_08.X.out b/tests/core/saved/test_08.X.out index 5eb72b20..b8ee3921 100644 --- a/tests/core/saved/test_08.X.out +++ b/tests/core/saved/test_08.X.out @@ -1 +1 @@ -gum1412rope85ladder0bolt4123water17gum1412rope85ladder0bolt4123water17gum1412rope85ladder0bolt4123water17onegum14120112233rope850112233ladder00112233bolt41230112233water170112233one \ No newline at end of file +gum1412rope85ladder0bolt4123water17gum1412rope85ladder0bolt4123water17gum1412rope85ladder0bolt4123water17onegum14120112233rope850112233ladder00112233bolt41230112233water170112233one \ No newline at end of file From e838a8ece520896271e21a56fe7f54075ec9002c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:34 -0400 Subject: [PATCH 404/514] update test cases --- tests/core/saved/test_08.XP.err | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/core/saved/test_08.XP.err b/tests/core/saved/test_08.XP.err index 445bfb71..011858cd 100644 --- a/tests/core/saved/test_08.XP.err +++ b/tests/core/saved/test_08.XP.err @@ -1,18 +1,18 @@ -test: close (xo_close_container) fails at marker 'm1'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm2'; not found 'data' -test: close (xo_close_container) fails at marker 'm1'; not found 'data' +test: close (xo_close_container) fails at marker 'm1'; not found 'data3' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm2'; not found 'data4' +test: close (xo_close_container) fails at marker 'm1'; not found 'data4' test: close (xo_close_container) fails at marker 'm1'; not found 'top' From 339474a717740749ce70713ef7edd7a5ab971dac Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:35 -0400 Subject: [PATCH 405/514] update test cases --- tests/core/saved/test_08.XP.out | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_08.XP.out b/tests/core/saved/test_08.XP.out index 99520c07..1d9b70f8 100644 --- a/tests/core/saved/test_08.XP.out +++ b/tests/core/saved/test_08.XP.out @@ -23,7 +23,7 @@ - + gum @@ -46,8 +46,8 @@ 17 - - + + gum @@ -71,8 +71,8 @@ one - - + + gum @@ -161,5 +161,5 @@ one - + From 3e571e3ec6c9ab3f41cb6c7e9687a5212ff36d1a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:36 -0400 Subject: [PATCH 406/514] update test cases --- tests/core/test_01.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core/test_01.c b/tests/core/test_01.c index 86b0ba1f..6987229e 100644 --- a/tests/core/test_01.c +++ b/tests/core/test_01.c @@ -109,7 +109,7 @@ main (int argc, char **argv) xo_emit("\n\n"); - xo_open_container("data"); + xo_open_container("data2"); xo_open_list("item"); for (ip = list; ip->i_title; ip++) { @@ -128,9 +128,9 @@ main (int argc, char **argv) } xo_close_list("item"); - xo_close_container("data"); + xo_close_container("data2"); - xo_open_container("data"); + xo_open_container("data3"); xo_open_list("item"); for (ip = list2; ip->i_title; ip++) { @@ -149,9 +149,9 @@ main (int argc, char **argv) } xo_close_list("item"); - xo_close_container("data"); + xo_close_container("data3"); - xo_open_container("data"); + xo_open_container("data4"); xo_open_list("item"); for (ip = list; ip->i_title; ip++) { @@ -160,7 +160,7 @@ main (int argc, char **argv) } xo_close_list("item"); - xo_close_container("data"); + xo_close_container("data4"); xo_emit("X{P:}X", "epic fail"); xo_emit("X{T:}X", "epic fail"); From a17fb734d0fb4ad6d847ef1c1b323da1b0375ade Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:37 -0400 Subject: [PATCH 407/514] update test cases --- tests/core/test_08.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/core/test_08.c b/tests/core/test_08.c index eb3776dc..7e19ebeb 100644 --- a/tests/core/test_08.c +++ b/tests/core/test_08.c @@ -85,7 +85,7 @@ main (int argc, char **argv) xo_emit("\n\n"); - xo_open_container("data"); + xo_open_container("data2"); xo_open_container("contents"); xo_emit("{T:Item/%-10s}{T:Count/%12s}\n"); @@ -97,11 +97,11 @@ main (int argc, char **argv) ip->i_title, ip->i_count); } - xo_close_container("data"); + xo_close_container("data2"); xo_emit("\n\n"); - xo_open_container("data"); + xo_open_container("data3"); xo_open_marker("m1"); xo_open_container("contents"); @@ -114,15 +114,15 @@ main (int argc, char **argv) ip->i_title, ip->i_count); } - xo_close_container("data"); /* Should be a noop */ + xo_close_container("data3"); /* Should be a noop */ xo_emit("{:test}", "one"); xo_close_marker("m1"); - xo_close_container("data"); /* Should be a noop */ + xo_close_container("data3"); /* Should be a noop */ xo_emit("\n\n"); - xo_open_container("data"); + xo_open_container("data4"); xo_open_marker("m1"); xo_open_container("contents"); @@ -138,13 +138,13 @@ main (int argc, char **argv) for (i = 0; i < 3; i++) { xo_open_instance("sub"); xo_emit("{Lwc:/Name}{:name/%d} + 1 = {:next/%d}\n", i, i + 1); - xo_close_container("data"); + xo_close_container("data4"); } xo_close_marker("m2"); xo_emit("{Lwc:/Last}{:last/%d}\n", i); } - xo_close_container("data"); /* Should be a noop */ + xo_close_container("data4"); /* Should be a noop */ xo_emit("{:test}", "one"); xo_emit("\n\n"); From 58ddc520f657e50b09f9fc564ecea5faf42d4245 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:50 -0400 Subject: [PATCH 408/514] rename xo*.h to xo_*.h for conssitency --- xo/xo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xo/xo.c b/xo/xo.c index e113c7fc..303899e6 100644 --- a/xo/xo.c +++ b/xo/xo.c @@ -13,9 +13,9 @@ #include #include -#include "xoconfig.h" +#include "xo_config.h" #include "xo.h" -#include "xoversion.h" +#include "xo_version.h" #include /* Include after xo.h for testing */ From 6fa4680423fea639ec0a2a6c69138739da139ff6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:15:51 -0400 Subject: [PATCH 409/514] rename xo*.h to xo_*.h for conssitency --- xopo/xopo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xopo/xopo.c b/xopo/xopo.c index 37a94c09..581637f2 100644 --- a/xopo/xopo.c +++ b/xopo/xopo.c @@ -16,9 +16,9 @@ #include #include -#include "xoconfig.h" +#include "xo_config.h" #include "xo.h" -#include "xoversion.h" +#include "xo_version.h" #include /* Include after xo.h for testing */ From 3bfbbd0883f02447b6751bb127fd7a6ac0d5902a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:16:23 -0400 Subject: [PATCH 410/514] rename cbr to cbor --- encoder/cbor/Makefile.am | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 encoder/cbor/Makefile.am diff --git a/encoder/cbor/Makefile.am b/encoder/cbor/Makefile.am new file mode 100644 index 00000000..d086c148 --- /dev/null +++ b/encoder/cbor/Makefile.am @@ -0,0 +1,51 @@ +# +# $Id$ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +if HAVE_GCC +GCC_WARNINGS = yes +endif +include ${top_srcdir}/warnings.mk + +enc_cborincdir = ${includedir}/libxo + +AM_CFLAGS = \ + -I${top_srcdir}/libxo \ + -I${top_builddir}/libxo \ + ${WARNINGS} + +LIBNAME = libenc_cbor +pkglib_LTLIBRARIES = libenc_cbor.la +LIBS = \ + -L${top_builddir}/libxo -lxo + +LDADD = ${top_builddir}/libxo/libxo.la + +libenc_cbor_la_SOURCES = \ + enc_cbor.c + +pkglibdir = ${XO_EXTDIR} + +UGLY_NAME = cbor.enc + +install-exec-hook: + @DLNAME=`sh -c '. ./libenc_cbor.la ; echo $$dlname'` ; \ + if [ x"$$DLNAME" = x ]; \ + then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \ + if [ "$(build_os)" = "cygwin" ]; \ + then DLNAME="../bin/$$DLNAME"; fi ; \ + echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \ + mkdir -p ${DESTDIR}${XO_EXTDIR} ; \ + cd ${DESTDIR}${XO_EXTDIR} \ + && chmod +w . \ + && rm -f ${UGLY_NAME} \ + && ${LN_S} $$DLNAME ${UGLY_NAME} From f87bee26297675d69fd484062425b4d570a6a876 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:16:26 -0400 Subject: [PATCH 411/514] rename cbr to cbor --- encoder/cbor/enc_cbor.c | 305 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 encoder/cbor/enc_cbor.c diff --git a/encoder/cbor/enc_cbor.c b/encoder/cbor/enc_cbor.c new file mode 100644 index 00000000..95ca5f39 --- /dev/null +++ b/encoder/cbor/enc_cbor.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +/* + * CBOR (RFC 7049) mades a suitable test case for libxo's external + * encoder API. It's simple, streaming, well documented, and an + * IETF standard. Yes, I know being an IETF standard is no where + * near as valuable a claim, especially in the post-BEEP era, but + * it's a hope that this code won't be a complete waste. + */ + +#include +#include +#include +#include +#include + +#include "xo.h" +#include "xo_encoder.h" +#include "xo_buf.h" + +/* + * memdump(): dump memory contents in hex/ascii +0 1 2 3 4 5 6 7 +0123456789012345678901234567890123456789012345678901234567890123456789012345 +XX XX XX XX XX XX XX XX - XX XX XX XX XX XX XX XX abcdefghijklmnop + */ +static void +cbor_memdump (FILE *fp, const char *title, const char *data, + size_t len, const char *tag, int indent) +{ + enum { MAX_PER_LINE = 16 }; + char buf[ 80 ]; + char text[ 80 ]; + char *bp, *tp; + size_t i; +#if 0 + static const int ends[ MAX_PER_LINE ] = { 2, 5, 8, 11, 15, 18, 21, 24, + 29, 32, 35, 38, 42, 45, 48, 51 }; +#endif + + if (fp == NULL) + fp = stdout; + if (tag == NULL) + tag = ""; + + fprintf(fp, "%*s[%s] @ %p (%lx/%lu)\n", indent + 1, tag, + title, data, (unsigned long) len, (unsigned long) len); + + while (len > 0) { + bp = buf; + tp = text; + + for (i = 0; i < MAX_PER_LINE && i < len; i++) { + if (i && (i % 4) == 0) *bp++ = ' '; + if (i == 8) { + *bp++ = '-'; + *bp++ = ' '; + } + sprintf(bp, "%02x ", (unsigned char) *data); + bp += strlen(bp); + *tp++ = (isprint((int) *data) && *data >= ' ') ? *data : '.'; + data += 1; + } + + *tp = 0; + *bp = 0; + fprintf(fp, "%*s%-54s%s\n", indent + 1, tag, buf, text); + len -= i; + } +} + +/* + * CBOR breaks the first byte into two pieces, the major type in the + * top 3 bits and the minor value in the low 5 bits. The value can be + * a small value (0 .. 23), an 8-bit value (24), a 16-bit value (25), + * a 32-bit value (26), or a 64-bit value (27). A value of 31 + * represents an unknown length, which we'll use extensively for + * streaming our content. + */ +#define CBOR_MAJOR_MASK 0xE0 +#define CBOR_MINOR_MASK 0x1F +#define CBOR_MAJOR_SHIFT 5 + +#define CBOR_MAJOR(_x) ((_x) & CBOR_MAJOR_MASK) +#define CBOR_MAJOR_VAL(_x) ((_x) << CBOR_MAJOR_SHIFT) +#define CBOR_MINOR_VAL(_x) ((_x) & CBOR_MINOR_MASK) + +/* Major type codes */ +#define CBOR_UNSIGNED CBOR_MAJOR_VAL(0) /* 0x00 */ +#define CBOR_NEGATIVE CBOR_MAJOR_VAL(1) /* 0x20 */ +#define CBOR_BYTES CBOR_MAJOR_VAL(2) /* 0x40 */ +#define CBOR_STRING CBOR_MAJOR_VAL(3) /* 0x60 */ +#define CBOR_ARRAY CBOR_MAJOR_VAL(4) /* 0x80 */ +#define CBOR_MAP CBOR_MAJOR_VAL(5) /* 0xa0 */ +#define CBOR_SEMANTIC CBOR_MAJOR_VAL(6) /* 0xc0 */ +#define CBOR_SPECIAL CBOR_MAJOR_VAL(7) /* 0xe0 */ + +#define CBOR_BREAK 0xFF +#define CBOR_INDEF 0x1F + +#define CBOR_LEN8 0x18 /* 24 - 8-bit value */ +#define CBOR_LEN16 0x19 /* 25 - 16-bit value */ +#define CBOR_LEN32 0x1a /* 26 - 32-bit value */ +#define CBOR_LEN64 0x1b /* 27 - 64-bit value */ +#define CBOR_LEN128 0x1c /* 28 - 128-bit value */ + +typedef struct cbor_private_s { + xo_buffer_t c_data; /* Our data buffer */ + unsigned c_indent; /* Indent level */ + unsigned c_open_leaf_list; /* Open leaf list construct? */ +} cbor_private_t; + +static void +cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor) +{ + char *bp = xbp->xb_curp; + int i, m; + + if (minor > (1UL<<32)) { + *bp++ |= CBOR_LEN64; + m = 64; + + } else if (minor > (1<<16)) { + *bp++ |= CBOR_LEN32; + m = 32; + + } else if (minor > (1<<8)) { + *bp++ |= CBOR_LEN16; + m = 16; + + } else if (minor > 24) { + *bp++ |= CBOR_LEN8; + m = 8; + } else { + *bp++ |= minor & CBOR_MINOR_MASK; + m = 0; + } + + if (m) { + for (i = m - 8; i >= 0; i -= 8) + *bp++ = minor >> i; + } + + xbp->xb_curp = bp; +} + +static void +cbor_append (xo_handle_t *xop, cbor_private_t *cbr, xo_buffer_t *xbp, + unsigned major, unsigned minor, const char *data) +{ + if (!xo_buf_has_room(xbp, minor + 2)) + return; + + unsigned offset = xo_buf_offset(xbp); + + *xbp->xb_curp = major; + cbor_encode_uint(xbp, minor); + if (data) + xo_buf_append(xbp, data, minor); + + if (xo_get_flags(xop) & XOF_PRETTY) + cbor_memdump(stdout, "append", xo_buf_data(xbp, offset), + xbp->xb_curp - xbp->xb_bufp - offset, "", + cbr->c_indent * 2); +} + +static int +cbor_create (xo_handle_t *xop) +{ + cbor_private_t *cbor = xo_realloc(NULL, sizeof(*cbor)); + if (cbor == NULL) + return -1; + + bzero(cbor, sizeof(*cbor)); + xo_buf_init(&cbor->c_data); + + xo_set_private(xop, cbor); + + cbor_append(xop, cbor, &cbor->c_data, CBOR_MAP | CBOR_INDEF, 0, NULL); + + return 0; +} + +static int +cbor_handler (XO_ENCODER_HANDLER_ARGS) +{ + int rc = 0; + cbor_private_t *cbor = private; + xo_buffer_t *xbp = cbor ? &cbor->c_data : NULL; + + if (xo_get_flags(xop) & XOF_PRETTY) { + printf("%*sop %s: [%s] [%s]\n", cbor ? cbor->c_indent * 2 + 4 : 0, "", + xo_encoder_op_name(op), name ?: "", value ?: ""); + fflush(stdout); + } + + /* If we don't have private data, we're sunk */ + if (cbor == NULL && op != XO_OP_CREATE) + return -1; + + switch (op) { + case XO_OP_CREATE: /* Called when the handle is init'd */ + rc = cbor_create(xop); + break; + + case XO_OP_OPEN_CONTAINER: + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_MAP | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + break; + + case XO_OP_CLOSE_CONTAINER: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_OPEN_LIST: + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_ARRAY | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + break; + + case XO_OP_CLOSE_LIST: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_OPEN_LEAF_LIST: + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_ARRAY | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + cbor->c_open_leaf_list = 1; + break; + + case XO_OP_CLOSE_LEAF_LIST: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + cbor->c_open_leaf_list = 0; + break; + + case XO_OP_OPEN_INSTANCE: + cbor_append(xop, cbor, xbp, CBOR_MAP | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + break; + + case XO_OP_CLOSE_INSTANCE: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_STRING: /* Quoted UTF-8 string */ + if (!cbor->c_open_leaf_list) + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value); + break; + + case XO_OP_CONTENT: /* Other content */ + if (!cbor->c_open_leaf_list) + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value); + break; + + case XO_OP_FLUSH: /* Clean up function */ + if (xo_get_flags(xop) & XOF_PRETTY) + cbor_memdump(stdout, "cbor", + xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp, + ">", 0); + else + write(1, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp); + break; + + case XO_OP_FINISH: /* Clean up function */ + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_DESTROY: /* Clean up function */ + break; + + case XO_OP_ATTR: /* Attribute name/value */ + break; + + case XO_OP_VERSION: /* Version string */ + break; + + } + + return rc; +} + +int +xo_encoder_library_init (XO_ENCODER_INIT_ARGS) +{ + arg->xei_handler = cbor_handler; + + return 0; +} From 068bf44a8a432b9340d8fc6faae3ed20c59f9f5f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:16:35 -0400 Subject: [PATCH 412/514] rename xo*.h to xo_*.h --- libxo/xo_version.h.in | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 libxo/xo_version.h.in diff --git a/libxo/xo_version.h.in b/libxo/xo_version.h.in new file mode 100644 index 00000000..777e83e3 --- /dev/null +++ b/libxo/xo_version.h.in @@ -0,0 +1,38 @@ +/* + * $Id$ + * + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * + * xoversion.h -- compile time constants for libxo + * NOTE: This file is generated from xoversion.h.in. + */ + +#ifndef LIBXO_XOVERSION_H +#define LIBXO_XOVERSION_H + +/** + * The version string + */ +#define LIBXO_VERSION "@PACKAGE_VERSION@" + +/** + * The version number + */ +#define LIBXO_VERSION_NUMBER @LIBXO_VERSION_NUMBER@ + +/** + * The version number as a string + */ +#define LIBXO_VERSION_STRING "@LIBXO_VERSION_NUMBER@" + +/** + * The version number extra info as a string + */ +#define LIBXO_VERSION_EXTRA "@LIBXO_VERSION_EXTRA@" + +#endif /* LIBXO_XOVERSION_H */ From 8be206bc24d5ce60dea91d71b01804cc9fac5956 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 12:27:14 -0400 Subject: [PATCH 413/514] fix comment --- encoder/cbor/enc_cbor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/encoder/cbor/enc_cbor.c b/encoder/cbor/enc_cbor.c index 95ca5f39..1069b5aa 100644 --- a/encoder/cbor/enc_cbor.c +++ b/encoder/cbor/enc_cbor.c @@ -11,9 +11,7 @@ /* * CBOR (RFC 7049) mades a suitable test case for libxo's external * encoder API. It's simple, streaming, well documented, and an - * IETF standard. Yes, I know being an IETF standard is no where - * near as valuable a claim, especially in the post-BEEP era, but - * it's a hope that this code won't be a complete waste. + * IETF standard. */ #include From b4b8b72f748c264e9d9a206a5873ef1bef5c0638 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:10:46 -0400 Subject: [PATCH 414/514] doc fix --- doc/libxo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index 1e66fcdb..7e6a08ff 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -1065,8 +1065,8 @@ number of columns to emit. xo_emit uses the precision as the former, and adds a third value for specifying the maximum number of columns. In this example, the name field is printed with a minimum of 3 columns -and a maximum of 6. Up to ten bytes are in used in filling those -columns. +and a maximum of 6. Up to ten bytes of data at the location given by +'name' are in used in filling those columns. xo_emit("{:name/%3.10.6s}", name); From 2414703292cee856313cd8f0915fa0a47ecf3641 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:11:04 -0400 Subject: [PATCH 415/514] add content types (type, false, null, numbers) --- encoder/cbor/enc_cbor.c | 78 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/encoder/cbor/enc_cbor.c b/encoder/cbor/enc_cbor.c index 1069b5aa..23e458cc 100644 --- a/encoder/cbor/enc_cbor.c +++ b/encoder/cbor/enc_cbor.c @@ -12,6 +12,9 @@ * CBOR (RFC 7049) mades a suitable test case for libxo's external * encoder API. It's simple, streaming, well documented, and an * IETF standard. + * + * This encoder uses the "pretty" flag for diagnostics, which isn't + * really kosher, but it's example code. */ #include @@ -19,6 +22,8 @@ #include #include #include +#include +#include #include "xo.h" #include "xo_encoder.h" @@ -101,9 +106,17 @@ cbor_memdump (FILE *fp, const char *title, const char *data, #define CBOR_SEMANTIC CBOR_MAJOR_VAL(6) /* 0xc0 */ #define CBOR_SPECIAL CBOR_MAJOR_VAL(7) /* 0xe0 */ +#define CBOR_ULIMIT 24 /* Largest unsigned value */ +#define CBOR_NLIMIT 23 /* Largest negative value */ + #define CBOR_BREAK 0xFF #define CBOR_INDEF 0x1F +#define CBOR_FALSE 0xF4 +#define CBOR_TRUE 0xF5 +#define CBOR_NULL 0xF6 +#define CBOR_UNDEF 0xF7 + #define CBOR_LEN8 0x18 /* 24 - 8-bit value */ #define CBOR_LEN16 0x19 /* 25 - 16-bit value */ #define CBOR_LEN32 0x1a /* 26 - 32-bit value */ @@ -117,7 +130,7 @@ typedef struct cbor_private_s { } cbor_private_t; static void -cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor) +cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor, unsigned limit) { char *bp = xbp->xb_curp; int i, m; @@ -134,7 +147,7 @@ cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor) *bp++ |= CBOR_LEN16; m = 16; - } else if (minor > 24) { + } else if (minor > limit) { *bp++ |= CBOR_LEN8; m = 8; } else { @@ -151,7 +164,7 @@ cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor) } static void -cbor_append (xo_handle_t *xop, cbor_private_t *cbr, xo_buffer_t *xbp, +cbor_append (xo_handle_t *xop, cbor_private_t *cbor, xo_buffer_t *xbp, unsigned major, unsigned minor, const char *data) { if (!xo_buf_has_room(xbp, minor + 2)) @@ -160,14 +173,14 @@ cbor_append (xo_handle_t *xop, cbor_private_t *cbr, xo_buffer_t *xbp, unsigned offset = xo_buf_offset(xbp); *xbp->xb_curp = major; - cbor_encode_uint(xbp, minor); + cbor_encode_uint(xbp, minor, CBOR_ULIMIT); if (data) xo_buf_append(xbp, data, minor); if (xo_get_flags(xop) & XOF_PRETTY) cbor_memdump(stdout, "append", xo_buf_data(xbp, offset), xbp->xb_curp - xbp->xb_bufp - offset, "", - cbr->c_indent * 2); + cbor->c_indent * 2); } static int @@ -187,6 +200,46 @@ cbor_create (xo_handle_t *xop) return 0; } +static int +cbor_content (xo_handle_t *xop, cbor_private_t *cbor, xo_buffer_t *xbp, + const char *value) +{ + int rc = 0; + + unsigned offset = xo_buf_offset(xbp); + + if (value == NULL || *value == '\0' || strcmp(value, "true") == 0) + cbor_append(xop, cbor, &cbor->c_data, CBOR_TRUE, 0, NULL); + else if (strcmp(value, "false") == 0) + cbor_append(xop, cbor, &cbor->c_data, CBOR_FALSE, 0, NULL); + else { + int negative = 0; + if (*value == '-') { + value += 1; + negative = 1; + } + + char *ep; + unsigned long long ival; + ival = strtoull(value, &ep, 0); + if (ival == ULLONG_MAX) /* Sometimes a string is just a string */ + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value); + else { + *xbp->xb_curp = negative ? CBOR_NEGATIVE : CBOR_UNSIGNED; + if (negative) + ival -= 1; /* Don't waste a negative zero */ + cbor_encode_uint(xbp, ival, negative ? CBOR_NLIMIT : CBOR_ULIMIT); + } + } + + if (xo_get_flags(xop) & XOF_PRETTY) + cbor_memdump(stdout, "content", xo_buf_data(xbp, offset), + xbp->xb_curp - xbp->xb_bufp - offset, "", + cbor->c_indent * 2); + + return rc; +} + static int cbor_handler (XO_ENCODER_HANDLER_ARGS) { @@ -263,7 +316,13 @@ cbor_handler (XO_ENCODER_HANDLER_ARGS) case XO_OP_CONTENT: /* Other content */ if (!cbor->c_open_leaf_list) cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); - cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value); + + /* + * It's content, not string, so we need to look at the + * string and build some content. Turns out we only + * care about true, false, null, and numbers. + */ + cbor_content(xop, cbor, xbp, value); break; case XO_OP_FLUSH: /* Clean up function */ @@ -271,8 +330,11 @@ cbor_handler (XO_ENCODER_HANDLER_ARGS) cbor_memdump(stdout, "cbor", xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp, ">", 0); - else - write(1, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp); + else { + rc = write(1, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp); + if (rc > 0) + rc = 0; + } break; case XO_OP_FINISH: /* Clean up function */ From 5a8d7088020ab698265a28a258b82981b675fcf9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:32:49 -0400 Subject: [PATCH 416/514] Incorporate Markus Kuhn's wcwidth() (as xo_wcwidth) --- configure.ac | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/configure.ac b/configure.ac index 56a7e804..2438f79a 100644 --- a/configure.ac +++ b/configure.ac @@ -277,6 +277,16 @@ AC_ARG_ENABLE([text-only], AC_MSG_RESULT([$LIBXO_TEXT_ONLY]) AM_CONDITIONAL([LIBXO_TEXT_ONLY], [test "$LIBXO_TEXT_ONLY" != "no"]) +AC_MSG_CHECKING([whether to build with local wcwidth implementation]) +AC_ARG_ENABLE([wcwidth], + [ --disable-wcwidth Disable local wcwidth implementation], + [LIBXO_WCWIDTH=$enableval], + [LIBXO_WCWIDTH=yes]) +AC_MSG_RESULT([$LIBXO_WCWIDTH]) +if test "${LIBXO_WCWIDTH}" != "no"; then + AC_DEFINE([LIBXO_WCWIDTH], [1], [Enable local wcwidth implementation]) +fi + AC_CHECK_LIB([m], [lrint]) AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"]) @@ -429,4 +439,5 @@ AC_MSG_NOTICE([summary of build options: gettext: ${HAVE_GETTEXT:-no} (${GETTEXT_PREFIX}) isthreaded: ${HAVE_ISTHREADED:-no} thread-local: ${THREAD_LOCAL:-no} + local wcwidth: ${LIBXO_WCWIDTH:-no} ]) From fb0bd1067836fe18407a26c0c32e1e27bf323d67 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:32:51 -0400 Subject: [PATCH 417/514] Incorporate Markus Kuhn's wcwidth() (as xo_wcwidth) --- libxo/libxo.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index ae1d9466..f6c83044 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -30,6 +30,12 @@ #include "xo_buf.h" #include "xo_version.h" +#ifdef LIBXO_WCWIDTH +#include "xo_wcwidth.h" +#else /* LIBXO_WCWIDTH */ +#define xo_wcwidth(_x) wcwidth(_x) +#endif /* LIBXO_WCWIDTH */ + #ifdef HAVE_STDIO_EXT_H #include #endif /* HAVE_STDIO_EXT_H */ @@ -1157,7 +1163,7 @@ xo_buf_append_locale_from_utf8 (xo_handle_t *xop, xo_buffer_t *xbp, xbp->xb_curp += len; } - return wcwidth(wc); + return xo_wcwidth(wc); } static void @@ -2310,7 +2316,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, * in wide characters, since we lack a mbswidth() function. If * it doesn't fit */ - width = wcwidth(wc); + width = xo_wcwidth(wc); if (width < 0) width = iswcntrl(wc) ? 0 : 1; @@ -2604,7 +2610,7 @@ xo_count_utf8_cols (const char *str, int len) * Find the width-in-columns of this character, which must be done * in wide characters, since we lack a mbswidth() function. */ - int width = wcwidth(wc); + int width = xo_wcwidth(wc); if (width < 0) width = iswcntrl(wc) ? 0 : 1; From 8a92c05981f4e499c899a7daf00bfbe2fb09a957 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:32:52 -0400 Subject: [PATCH 418/514] Incorporate Markus Kuhn's wcwidth() (as xo_wcwidth) --- tests/core/test_05.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index 9136dc03..c83e81dc 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -14,6 +14,13 @@ #include #include "xo.h" +#include "xo_config.h" + +#ifdef LIBXO_WCWIDTH +#include "xo_wcwidth.h" +#else /* LIBXO_WCWIDTH */ +#define xo_wcwidth(_x) wcwidth(_x) +#endif /* LIBXO_WCWIDTH */ xo_info_t info[] = { { "employee", "object", "Employee data" }, @@ -58,7 +65,7 @@ main (int argc, char **argv) wchar_t wc[] = { L'෴', L'ණ', L'්', L'ණ', L'\u17D2', L'෴', 0 }; for (i = 0; wc[i]; i++) xo_emit("Wide char: {lq:wc/%lc - %#lx - %d}\n", - wc[i], (unsigned long) wc[i], wcwidth(wc[i])); + wc[i], (unsigned long) wc[i], xo_wcwidth(wc[i])); xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); From 3704e399e151cc78a10b6cb28b4dc071a75d3854 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:32:56 -0400 Subject: [PATCH 419/514] Incorporate Markus Kuhn's wcwidth() (as xo_wcwidth) --- libxo/xo_wcwidth.h | 310 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 libxo/xo_wcwidth.h diff --git a/libxo/xo_wcwidth.h b/libxo/xo_wcwidth.h new file mode 100644 index 00000000..22d33c2b --- /dev/null +++ b/libxo/xo_wcwidth.h @@ -0,0 +1,310 @@ +/* + * This is an implementation of wcwidth() and wcswidth() (defined in + * IEEE Std 1002.1-2001) for Unicode. + * + * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html + * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html + * + * In fixed-width output devices, Latin characters all occupy a single + * "cell" position of equal width, whereas ideographic CJK characters + * occupy two such cells. Interoperability between terminal-line + * applications and (teletype-style) character terminals using the + * UTF-8 encoding requires agreement on which character should advance + * the cursor by how many cell positions. No established formal + * standards exist at present on which Unicode character shall occupy + * how many cell positions on character terminals. These routines are + * a first attempt of defining such behavior based on simple rules + * applied to data provided by the Unicode Consortium. + * + * For some graphical characters, the Unicode standard explicitly + * defines a character-cell width via the definition of the East Asian + * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. + * In all these cases, there is no ambiguity about which width a + * terminal shall use. For characters in the East Asian Ambiguous (A) + * class, the width choice depends purely on a preference of backward + * compatibility with either historic CJK or Western practice. + * Choosing single-width for these characters is easy to justify as + * the appropriate long-term solution, as the CJK practice of + * displaying these characters as double-width comes from historic + * implementation simplicity (8-bit encoded characters were displayed + * single-width and 16-bit ones double-width, even for Greek, + * Cyrillic, etc.) and not any typographic considerations. + * + * Much less clear is the choice of width for the Not East Asian + * (Neutral) class. Existing practice does not dictate a width for any + * of these characters. It would nevertheless make sense + * typographically to allocate two character cells to characters such + * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be + * represented adequately with a single-width glyph. The following + * routines at present merely assign a single-cell width to all + * neutral characters, in the interest of simplicity. This is not + * entirely satisfactory and should be reconsidered before + * establishing a formal standard in this area. At the moment, the + * decision which Not East Asian (Neutral) characters should be + * represented by double-width glyphs cannot yet be answered by + * applying a simple rule from the Unicode database content. Setting + * up a proper standard for the behavior of UTF-8 character terminals + * will require a careful analysis not only of each Unicode character, + * but also of each presentation form, something the author of these + * routines has avoided to do so far. + * + * http://www.unicode.org/unicode/reports/tr11/ + * + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + * + * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + */ + +#include + +struct interval { + int first; + int last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following two functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - SOFT HYPHEN (U+00AD) has a column width of 1. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * Full-width (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +static int xo_wcwidth(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ + static const struct interval combining[] = { + { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, + { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, + { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, + { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, + { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, + { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, + { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, + { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, + { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, + { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, + { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, + { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, + { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, + { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, + { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, + { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, + { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, + { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, + { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, + { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, + { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, + { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, + { 0xE0100, 0xE01EF } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); +} + +#if UNUSED_CODE +static int xo_wcswidth(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + + +/* + * The following functions are the same as mk_wcwidth() and + * mk_wcswidth(), except that spacing characters in the East Asian + * Ambiguous (A) category as defined in Unicode Technical Report #11 + * have a column width of 2. This variant might be useful for users of + * CJK legacy encodings who want to migrate to UCS without changing + * the traditional terminal character-width behaviour. It is not + * otherwise recommended for general use. + */ +int mk_wcwidth_cjk(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ + static const struct interval ambiguous[] = { + { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, + { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, + { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, + { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, + { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, + { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, + { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, + { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, + { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, + { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, + { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, + { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, + { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, + { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, + { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, + { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, + { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, + { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 }, + { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, + { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 }, + { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, + { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, + { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, + { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 }, + { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, + { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, + { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, + { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 }, + { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 }, + { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, + { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, + { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B }, + { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, + { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, + { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E }, + { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 }, + { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, + { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F }, + { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, + { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, + { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B }, + { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, + { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, + { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, + { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, + { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, + { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 }, + { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, + { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, + { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, + { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF }, + { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } + }; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, + sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return mk_wcwidth(ucs); +} + + +int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} +#endif /* UNUSED_CODE */ From 619c244bc1e7bd2618227880dee9becf7bd5156f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 16:35:35 -0400 Subject: [PATCH 420/514] add xo_wcwidth.h; move xo_humanize.h to noinst_HEADERS --- libxo/Makefile.am | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index 27017b90..645dcd6d 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -34,7 +34,9 @@ libxoinc_HEADERS = \ xo_encoder.h noinst_HEADERS = \ - xo_buf.h + xo_buf.h \ + xo_humanize.h \ + xo_wcwidth.h libxo_la_SOURCES = \ libxo.c \ @@ -65,8 +67,7 @@ man_MANS = \ xo_set_writer.3 EXTRA_DIST = \ - ${man_MANS} \ - xo_humanize.h + ${man_MANS} call-graph: ${RM} libxo.o From 92a33ea1b30cff24eaace6f4eb247c3e5b87908b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:01 -0400 Subject: [PATCH 421/514] Add docs for encoders --- doc/libxo.txt | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/doc/libxo.txt b/doc/libxo.txt index 7e6a08ff..9d793adb 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -2158,6 +2158,127 @@ messages should register their own EID and use that value in their software to ensure that messages can be uniquely identified by the combination of EID + message name. +** Creating Custom Encoders + +The number of encoding schemes in current use is staggering, with new +and distinct schemes appearing daily. While libxo provide XML, JSON, +HMTL, and text natively, there are requirements for other encodings. + +Rather than bake support for all possible encoders into libxo, the API +allows them to be defined externally. libxo can then interfaces with +these encoding modules using a simplistic API. libxo processes all +functions calls, handles state transitions, performs all formatting, +and then passes the results as operations to a customized encoding +function, which implements specific encoding logic as required. This +means your encoder doesn't need to detect errors with unbalanced +open/close operations but can rely on libxo to pass correct data. + +By making a simple API, libxo internals are not exposed, insulating the +encoder and the library from future or internal changes. + +The three elements of the API are: +- loading +- initialization +- operations + +The following sections provide details about these topics. + +libxo source contain an encoder for Concise Binary Object +Representation, aka CBOR (RFC 7049) which can be used as used as an +example for the API. + +*** Loading Encoders + +Encoders can be registered statically or discovered dynamically. +Applications can choose to call the xo_encoder_register() +function to explicitly register encoders, but more typically they are +built as shared libraries, placed in the libxo/extensions directory, +and loaded based on name. libxo looks for a file with the name of the encoder +and an extension of ".enc". This can be a file or a symlink to the +shared library file that supports the encoder. + + % ls -1 lib/libxo/extensions/*.enc + lib/libxo/extensions/cbor.enc + lib/libxo/extensions/test.enc + +*** Encoder Initialization + +Each encoder must export a symbol used to access the library, which +must have the following signature: + + int xo_encoder_library_init (XO_ENCODER_INIT_ARGS); + +XO_ENCODER_INIT_ARGS is a macro defined in xo_encoder.h that defines +an argument called "arg", a pointer of the type +xo_encoder_init_args_t. This structure contains two fields: + +- xei_version is the version number of the API as implemented within +libxo. This version is currently as 1 using XO_ENCODER_VERSION. This +number can be checked to ensure compatibility. The working assumption +is that all versions should be backward compatible, but each side may +need to accurately know the version supported by the other side. +xo_encoder_library_init can optionally check this value, and must then +set it to the version number used by the encoder, allowing libxo to +detect version differences and react accordingly. For example, if +version 2 adds new operations, then libxo will know that an encoding +library that set xei_version to 1 cannot be expected to handle those +new operations. + +- xei_handler must be set to a pointer to a function of type +xo_encoder_func_t, as defined in xo_encoder.h. This function +takes a set of parameters: +-- xop is a pointer to the opaque xo_handle_t structure +-- op is an integer representing the current operation +-- name is a string whose meaning differs by operation +-- value is a string whose meaning differs by operation +-- private is an opaque structure provided by the encoder + +Additional arguments may be added in the future, so handler functions +should use the XO_ENCODER_HANDLER_ARGS macro. An appropriate +"extern" declaration is provided to help catch errors. + +Once the encoder initialization function has completed processing, it +should return zero to indicate that no error has occurred. A non-zero +return code will cause the handle initialization to fail. + +*** Operations + +The encoder API defines a set of operations representing the +processing model of libxo. Content is formatted within libxo, and +callbacks are made to the encoder's handler function when data is +ready to be processed. + +|-----------------------+---------------------------------------| +| Operation | Meaning (Base function) | +|-----------------------+---------------------------------------| +| XO_OP_CREATE | Called when the handle is created | +| XO_OP_OPEN_CONTAINER | Container opened (xo_open_container) | +| XO_OP_CLOSE_CONTAINER | Container closed (xo_close_container) | +| XO_OP_OPEN_LIST | List opened (xo_open_list) | +| XO_OP_CLOSE_LIST | List closed (xo_close_list) | +| XO_OP_OPEN_LEAF_LIST | Leaf list opened (xo_open_leaf_list) | +| XO_OP_CLOSE_LEAF_LIST | Leaf list closed (xo_close_leaf_list) | +| XO_OP_OPEN_INSTANCE | Instance opened (xo_open_instance) | +| XO_OP_CLOSE_INSTANCE | Instance closed (xo_close_instance) | +| XO_OP_STRING | Field with Quoted UTF-8 string | +| XO_OP_CONTENT | Field with content | +| XO_OP_FINISH | Finish any pending output | +| XO_OP_FLUSH | Flush any buffered output | +| XO_OP_DESTROY | Clean up resources | +| XO_OP_ATTRIBUTE | An attribute name/value pair | +| XO_OP_VERSION | A version string | +|-----------------------+---------------------------------------| + +For all the open and close operations, the name parameter holds the +name of the construct. For string, content, and attribute operations, +the name parameter is the name of the field and the value parameter is +the value. "string" are differentiated from "content" to allow differing +treatment of true, false, null, and numbers from real strings, though +content values are formatted as strings before the handler is called. +For version operations, the value parameter contains the version. + +All strings are encoded in UTF-8. + * The "xo" Utility The "xo" utility allows command line access to the functionality of From 8709f40302b9f5b747c2d879c2fd4174c32bb47b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:14 -0400 Subject: [PATCH 422/514] nits --- encoder/cbor/enc_cbor.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/encoder/cbor/enc_cbor.c b/encoder/cbor/enc_cbor.c index 23e458cc..513063fb 100644 --- a/encoder/cbor/enc_cbor.c +++ b/encoder/cbor/enc_cbor.c @@ -325,6 +325,11 @@ cbor_handler (XO_ENCODER_HANDLER_ARGS) cbor_content(xop, cbor, xbp, value); break; + case XO_OP_FINISH: /* Clean up function */ + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + case XO_OP_FLUSH: /* Clean up function */ if (xo_get_flags(xop) & XOF_PRETTY) cbor_memdump(stdout, "cbor", @@ -337,15 +342,10 @@ cbor_handler (XO_ENCODER_HANDLER_ARGS) } break; - case XO_OP_FINISH: /* Clean up function */ - cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); - cbor->c_indent -= 1; - break; - case XO_OP_DESTROY: /* Clean up function */ break; - case XO_OP_ATTR: /* Attribute name/value */ + case XO_OP_ATTRIBUTE: /* Attribute name/value */ break; case XO_OP_VERSION: /* Version string */ From c418d3da9138bf8bf5aba57470d3749030f4e4d2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:26 -0400 Subject: [PATCH 423/514] init func sets version number --- encoder/test/enc_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/encoder/test/enc_test.c b/encoder/test/enc_test.c index 500bd147..ec49499c 100644 --- a/encoder/test/enc_test.c +++ b/encoder/test/enc_test.c @@ -23,6 +23,7 @@ test_handler (XO_ENCODER_HANDLER_ARGS) int xo_encoder_library_init (XO_ENCODER_INIT_ARGS) { + arg->xei_version = XO_ENCODER_VERSION; arg->xei_handler = test_handler; return 0; From 38ba3a700527cdbf66ba6d0976838dddefec95cc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:40 -0400 Subject: [PATCH 424/514] s/XO_OP_ATTR/XO_OP_ATTRIBUTE/ --- libxo/libxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index f6c83044..970728ba 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -5984,7 +5984,7 @@ xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap) if (rc >= 0) { xbp->xb_curp += rc; *xbp->xb_curp = '\0'; - rc = xo_encoder_handle(xop, XO_OP_ATTR, + rc = xo_encoder_handle(xop, XO_OP_ATTRIBUTE, xo_buf_data(xbp, name_offset), xo_buf_data(xbp, value_offset)); } From 2f33ed17702da1b3f43b0637c37d5fd39426dcef Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:48 -0400 Subject: [PATCH 425/514] reorder flush/finish --- libxo/xo_encoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxo/xo_encoder.c b/libxo/xo_encoder.c index 52fedb13..68b59ec3 100644 --- a/libxo/xo_encoder.c +++ b/libxo/xo_encoder.c @@ -357,8 +357,8 @@ xo_encoder_op_name (xo_encoder_op_t op) /* 9 */ "close_instance", /* 10 */ "string", /* 11 */ "content", - /* 12 */ "flush", - /* 13 */ "finish", + /* 12 */ "finish", + /* 13 */ "flush", /* 14 */ "destroy", /* 15 */ "attr", /* 16 */ "version", From 17b0bdea9c22f5067c8ff9bda2ebea5dc2db5e82 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:50 -0400 Subject: [PATCH 426/514] reorder flush/finish --- libxo/xo_encoder.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libxo/xo_encoder.h b/libxo/xo_encoder.h index c44a244a..f73552b1 100644 --- a/libxo/xo_encoder.h +++ b/libxo/xo_encoder.h @@ -26,7 +26,7 @@ extern xo_free_func_t xo_free; typedef unsigned xo_encoder_op_t; -/* Encoder operations */ +/* Encoder operations; names are in xo_encoder.c:xo_encoder_op_name() */ #define XO_OP_UNKNOWN 0 #define XO_OP_CREATE 1 /* Called when the handle is init'd */ #define XO_OP_OPEN_CONTAINER 2 @@ -39,10 +39,10 @@ typedef unsigned xo_encoder_op_t; #define XO_OP_CLOSE_INSTANCE 9 #define XO_OP_STRING 10 /* Quoted UTF-8 string */ #define XO_OP_CONTENT 11 /* Other content */ -#define XO_OP_FLUSH 12 /* Clean up function */ -#define XO_OP_FINISH 13 /* Clean up function */ +#define XO_OP_FINISH 12 /* Finish any pending output */ +#define XO_OP_FLUSH 13 /* Flush any buffered output */ #define XO_OP_DESTROY 14 /* Clean up function */ -#define XO_OP_ATTR 15 /* Attribute name/value */ +#define XO_OP_ATTRIBUTE 15 /* Attribute name/value */ #define XO_OP_VERSION 16 /* Version string */ #define XO_ENCODER_HANDLER_ARGS \ From 4702e148a2db1b044c18144f921a8ad78c23e417 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:20:59 -0400 Subject: [PATCH 427/514] update test cases --- tests/core/saved/test_05.E.out | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core/saved/test_05.E.out b/tests/core/saved/test_05.E.out index 7fc3a0ca..4078f6c8 100644 --- a/tests/core/saved/test_05.E.out +++ b/tests/core/saved/test_05.E.out @@ -3,9 +3,9 @@ op open_container: [employees] [] op open_leaf_list: [wc] [] op string: [wc] [෴ - 0xdf4 - 1] op string: [wc] [ණ - 0xdab - 1] -op string: [wc] [් - 0xdca - 1] +op string: [wc] [් - 0xdca - 0] op string: [wc] [ණ - 0xdab - 1] -op string: [wc] [្ - 0x17d2 - 1] +op string: [wc] [្ - 0x17d2 - 0] op string: [wc] [෴ - 0xdf4 - 1] op close_leaf_list: [wc] [] op string: [v1] [γιγνώσκειν] @@ -14,14 +14,14 @@ op string: [v1] [ახლავე გაიაროთ რეგისტრ op string: [v2] [Unicode-ის მეათე საერთაშორისო] op content: [width] [55] op string: [sinhala] [෴ණ්ණ෴] -op content: [width] [5] +op content: [width] [4] op string: [sinhala] [෴] op content: [width] [1] op string: [sinhala] [෴ණ්ණ෴෴ණ්ණ෴] -op content: [width] [10] +op content: [width] [8] op string: [not-sinhala] [123456] op string: [tag] [ර්ඝ] -op content: [width] [3] +op content: [width] [2] op open_list: [employee] [] op open_instance: [employee] [] op string: [first-name] [Jim] From b8062e8c0cf7e0f1205240b2750f5803b018d038 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:21:00 -0400 Subject: [PATCH 428/514] update test cases --- tests/core/saved/test_05.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.H.out b/tests/core/saved/test_05.H.out index 021f78a2..b7bf05bf 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 1
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 1
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
7
[
]
Width
:
3
[
෴ණ්ණ
]
Width
:
6
[
1234
]
[
ර්ඝ
]
Width
:
5
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
110
20
\ No newline at end of file +
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file From eafa03a2bd250ac4a1c1be6d5720bd99d7d6741c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:21:00 -0400 Subject: [PATCH 429/514] update test cases --- tests/core/saved/test_05.HIPx.out | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index 9326b203..f383650c 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -8,7 +8,7 @@
Wide char:
-
් - 0xdca - 1
+
් - 0xdca - 0
Wide char:
@@ -16,7 +16,7 @@
Wide char:
-
្ - 0x17d2 - 1
+
្ - 0x17d2 - 0
Wide char:
@@ -49,7 +49,7 @@
Width
:
-
7
+
6
[
@@ -64,7 +64,7 @@
[
-
෴ණ්ණ
+
෴ණ්ණ෴
]
@@ -87,7 +87,7 @@
Width
:
-
5
+
4
First Name
@@ -159,8 +159,8 @@
(
"Mick"
)
-
-
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
+
+
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
From 79f901ee091ad2c3b0bf3c57a4fac569de8090e0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:21:02 -0400 Subject: [PATCH 430/514] update test cases --- tests/core/saved/test_05.HP.out | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index a6244aa7..dc40409e 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -8,7 +8,7 @@
Wide char:
-
් - 0xdca - 1
+
් - 0xdca - 0
Wide char:
@@ -16,7 +16,7 @@
Wide char:
-
្ - 0x17d2 - 1
+
្ - 0x17d2 - 0
Wide char:
@@ -49,7 +49,7 @@
Width
:
-
7
+
6
[
@@ -64,7 +64,7 @@
[
-
෴ණ්ණ
+
෴ණ්ණ෴
]
@@ -87,7 +87,7 @@
Width
:
-
5
+
4
First Name
@@ -159,8 +159,8 @@
(
"Mick"
)
-
-
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
+
+
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
From 0c01c3fe09dcd4850904af2d8513a595af2a6d92 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:21:03 -0400 Subject: [PATCH 431/514] update test cases --- tests/core/saved/test_05.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.J.out b/tests/core/saved/test_05.J.out index aec598c8..62f0026e 100644 --- a/tests/core/saved/test_05.J.out +++ b/tests/core/saved/test_05.J.out @@ -1,2 +1,2 @@ -{"employees": {"wc": ["෴ - 0xdf4 - 1","ණ - 0xdab - 1","් - 0xdca - 1","ණ - 0xdab - 1","្ - 0x17d2 - 1","෴ - 0xdf4 - 1"],"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":5,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":10,"not-sinhala":"123456","tag":"ර්ඝ","width":3, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Wed, 5 Aug 2015 22:21:04 -0400 Subject: [PATCH 432/514] update test cases --- tests/core/saved/test_05.JP.out | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index a1a14182..518c492e 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -3,9 +3,9 @@ "wc": [ "෴ - 0xdf4 - 1", "ණ - 0xdab - 1", - "් - 0xdca - 1", + "් - 0xdca - 0", "ණ - 0xdab - 1", - "្ - 0x17d2 - 1", + "្ - 0x17d2 - 0", "෴ - 0xdf4 - 1" ], "v1": "γιγνώσκειν", @@ -14,14 +14,14 @@ "v2": "Unicode-ის მეათე საერთაშორისო", "width": 55, "sinhala": "෴ණ්ණ෴", - "width": 5, + "width": 4, "sinhala": "෴", "width": 1, "sinhala": "෴ණ්ණ෴෴ණ්ණ෴", - "width": 10, + "width": 8, "not-sinhala": "123456", "tag": "ර්ඝ", - "width": 3, + "width": 2, "employee": [ { "first-name": "Jim", From d13735fda6d94909c3eace7f94b05d54b1dc939a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:21:05 -0400 Subject: [PATCH 433/514] update test cases --- tests/core/saved/test_05.T.out | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index faafc287..53c996bd 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -1,21 +1,21 @@ Wide char: ෴ - 0xdf4 - 1 Wide char: ණ - 0xdab - 1 -Wide char: ් - 0xdca - 1 +Wide char: ් - 0xdca - 0 Wide char: ණ - 0xdab - 1 -Wide char: ្ - 0x17d2 - 1 +Wide char: ្ - 0x17d2 - 0 Wide char: ෴ - 0xdf4 - 1 Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო Width: 63 [෴ණ්ණ෴] -Width: 7 +Width: 6 [෴] Width: 3 -[෴ණ්ණ] +[෴ණ්ණ෴] Width: 6 [1234] [ර්ඝ] -Width: 5 +Width: 4 First Name Last Name Department Time (%) Jim ("რეგტ") გთხოვთ ახ 431 90 Terry (" Date: Wed, 5 Aug 2015 22:21:06 -0400 Subject: [PATCH 434/514] update test cases --- tests/core/saved/test_05.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.X.out b/tests/core/saved/test_05.X.out index 76a68288..ebcd10e4 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 1ණ - 0xdab - 1្ - 0x17d2 - 1෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴51෴ණ්ණ෴෴ණ්ණ෴10123456ර්ඝ3Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file +෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From 461643fead44a736721245af961e855e4608767c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 5 Aug 2015 22:21:07 -0400 Subject: [PATCH 435/514] update test cases --- tests/core/saved/test_05.XP.out | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index de5e4dd7..1b9e5592 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -1,9 +1,9 @@ ෴ - 0xdf4 - 1 ණ - 0xdab - 1 - ් - 0xdca - 1 + ් - 0xdca - 0 ණ - 0xdab - 1 - ្ - 0x17d2 - 1 + ្ - 0x17d2 - 0 ෴ - 0xdf4 - 1 γιγνώσκειν ὦ ἄνδρες ᾿Αθηναῖοι @@ -11,14 +11,14 @@ Unicode-ის მეათე საერთაშორისო 55 ෴ණ්ණ෴ - 5 + 4 1 ෴ණ්ණ෴෴ණ්ණ෴ - 10 + 8 123456 ර්ඝ - 3 + 2 Jim "რეგტ" From c2d7c9913d1d754b4bfa1d88c1dc61e2a020fb26 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 00:25:46 -0400 Subject: [PATCH 436/514] Try hex wchar_t values --- tests/core/test_05.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index c83e81dc..2d8e8f30 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -62,7 +62,7 @@ main (int argc, char **argv) xo_open_container("employees"); - wchar_t wc[] = { L'෴', L'ණ', L'්', L'ණ', L'\u17D2', L'෴', 0 }; + wchar_t wc[] = { L'෴', L'ණ', L'්', L'ණ', 0x17D2, L'෴', 0 }; for (i = 0; wc[i]; i++) xo_emit("Wide char: {lq:wc/%lc - %#lx - %d}\n", wc[i], (unsigned long) wc[i], xo_wcwidth(wc[i])); From 02a9bce4e0948aa37c2164a1da1d9058e43fa93e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:00:35 -0400 Subject: [PATCH 437/514] Nuke iswprint() test; many fancy unicode characters are marking !print but they are --- libxo/libxo.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 970728ba..1fc37791 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -2307,10 +2307,6 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, len = 0; } - /* We only print printable characters */ - if (!iswprint((wint_t) wc)) - continue; - /* * Find the width-in-columns of this character, which must be done * in wide characters, since we lack a mbswidth() function. If From 9b4483633a84f19b6d22657de222236f4f7a0eac Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:00:44 -0400 Subject: [PATCH 438/514] rename bisearch --- libxo/xo_wcwidth.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libxo/xo_wcwidth.h b/libxo/xo_wcwidth.h index 22d33c2b..773307f3 100644 --- a/libxo/xo_wcwidth.h +++ b/libxo/xo_wcwidth.h @@ -67,7 +67,9 @@ struct interval { }; /* auxiliary function for binary search in interval table */ -static int bisearch(wchar_t ucs, const struct interval *table, int max) { +static int +xo_bisearch (wchar_t ucs, const struct interval *table, int max) +{ int min = 0; int mid; @@ -119,7 +121,8 @@ static int bisearch(wchar_t ucs, const struct interval *table, int max) { * in ISO 10646. */ -static int xo_wcwidth(wchar_t ucs) +static int +xo_wcwidth (wchar_t ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ @@ -181,7 +184,7 @@ static int xo_wcwidth(wchar_t ucs) return -1; /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, + if (xo_bisearch(ucs, combining, sizeof(combining) / sizeof(struct interval) - 1)) return 0; @@ -287,7 +290,7 @@ int mk_wcwidth_cjk(wchar_t ucs) }; /* binary search in table of non-spacing characters */ - if (bisearch(ucs, ambiguous, + if (xo_bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; From 220cd6b7545d7da251f727dc8d8ce63f0ab88cdf Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:02 -0400 Subject: [PATCH 439/514] update test cases --- tests/core/saved/test_02.H.out | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.H.out b/tests/core/saved/test_02.H.out index 657712b9..f1387a64 100644 --- a/tests/core/saved/test_02.H.out +++ b/tests/core/saved/test_02.H.out @@ -1 +1,7 @@ -
We are
{emit}
{ting}
some
braces
abcdef
abcdef: Bad file descriptor
improper use of profanity; ten yard penalty; first down
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! <>!,"!<>
\ No newline at end of file +
We are
{emit}
{ting}
some
braces
abcdef +
abcdef: Bad file descriptor +
improper use of profanity; ten yard penalty; first down +
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! <>!,"!<> +
\ No newline at end of file From 8df9c8a09858c61f553e305e55bab40f3d51109e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:03 -0400 Subject: [PATCH 440/514] update test cases --- tests/core/saved/test_02.HIPx.out | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_02.HIPx.out b/tests/core/saved/test_02.HIPx.out index 9c3ebc33..7af26b39 100644 --- a/tests/core/saved/test_02.HIPx.out +++ b/tests/core/saved/test_02.HIPx.out @@ -6,13 +6,16 @@
braces
-
abcdef
+
abcdef +
-
abcdef: Bad file descriptor
+
abcdef: Bad file descriptor +
-
improper use of profanity; ten yard penalty; first down
+
improper use of profanity; ten yard penalty; first down +
length
@@ -35,7 +38,8 @@
good
-
improper use of profanity; ten yard penalty; first down
+
improper use of profanity; ten yard penalty; first down +
@@ -212,8 +216,10 @@
tries
-
improper use of profanity; ten yard penalty; first down
+
improper use of profanity; ten yard penalty; first down +
-
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
+
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +
From 7d5c934f027e4b4d13f1f81f87ab7dbadfd76c65 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:03 -0400 Subject: [PATCH 441/514] update test cases --- tests/core/saved/test_02.HP.out | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/core/saved/test_02.HP.out b/tests/core/saved/test_02.HP.out index a2576cba..f7c9d9b4 100644 --- a/tests/core/saved/test_02.HP.out +++ b/tests/core/saved/test_02.HP.out @@ -6,13 +6,16 @@
braces
-
abcdef
+
abcdef +
-
abcdef: Bad file descriptor
+
abcdef: Bad file descriptor +
-
improper use of profanity; ten yard penalty; first down
+
improper use of profanity; ten yard penalty; first down +
length
@@ -35,7 +38,8 @@
good
-
improper use of profanity; ten yard penalty; first down
+
improper use of profanity; ten yard penalty; first down +
@@ -212,8 +216,10 @@
tries
-
improper use of profanity; ten yard penalty; first down
+
improper use of profanity; ten yard penalty; first down +
-
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
+
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +
From 729a9c7c02be4ced026675a510c7b2826d233181 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:04 -0400 Subject: [PATCH 442/514] 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 22719d87..5578389a 100644 --- a/tests/core/saved/test_02.J.out +++ b/tests/core/saved/test_02.J.out @@ -1,2 +1,2 @@ -{"top": {"data": {"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":30,"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! <>!,\"!<>"}}} +{"top": {"data": {"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":30,"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"}}} } From e41fc763a100051ea17d75f434b1f546dbb722bd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:06 -0400 Subject: [PATCH 443/514] update test cases --- tests/core/saved/test_02.JP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out index 5c3adf73..fd910aa6 100644 --- a/tests/core/saved/test_02.JP.out +++ b/tests/core/saved/test_02.JP.out @@ -75,7 +75,7 @@ "count": 10, "test": 4, "error": { - "message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>" + "message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n" } } } From 9a2127bab7611981cfc39e5155594105378dc68a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:07 -0400 Subject: [PATCH 444/514] update test cases --- tests/core/saved/test_02.X.out | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.X.out b/tests/core/saved/test_02.X.out index ebb7b644..30421ea5 100644 --- a/tests/core/saved/test_02.X.out +++ b/tests/core/saved/test_02.X.out @@ -3,4 +3,5 @@ improper use of profanity; ten yard penalty; first down abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down 2030400123410203050Boston64640646401011101010101520301520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-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! <>!,"!<> \ No newline at end of file +Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> + \ No newline at end of file From eae7b6422b95e353d2f238bf872d60dae9e17f79 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:08 -0400 Subject: [PATCH 445/514] update test cases --- tests/core/saved/test_02.XP.out | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.XP.out b/tests/core/saved/test_02.XP.out index b38c8353..e70e6ef7 100644 --- a/tests/core/saved/test_02.XP.out +++ b/tests/core/saved/test_02.XP.out @@ -80,7 +80,8 @@ improper use of profanity; ten yard penalty; first down - Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> + Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> + From 8ae40ef110c44992765d50da32484cf502a2e4a2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:09 -0400 Subject: [PATCH 446/514] update test cases --- tests/core/saved/test_05.E.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.E.out b/tests/core/saved/test_05.E.out index 4078f6c8..57de2ea5 100644 --- a/tests/core/saved/test_05.E.out +++ b/tests/core/saved/test_05.E.out @@ -20,7 +20,7 @@ op content: [width] [1] op string: [sinhala] [෴ණ්ණ෴෴ණ්ණ෴] op content: [width] [8] op string: [not-sinhala] [123456] -op string: [tag] [ර්ඝ] +op string: [tag] [ර්‍ඝ] op content: [width] [2] op open_list: [employee] [] op open_instance: [employee] [] From 4e6b01d8b7698f413ad93ac5a11d812b6860c68c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:10 -0400 Subject: [PATCH 447/514] update test cases --- tests/core/saved/test_05.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.H.out b/tests/core/saved/test_05.H.out index b7bf05bf..bb44ab77 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file +
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්‍ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file From 0202033be18486417553b38390e69c1e3b99059a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:11 -0400 Subject: [PATCH 448/514] update test cases --- tests/core/saved/test_05.HIPx.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index f383650c..79031780 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -80,7 +80,7 @@
[
-
ර්ඝ
+
ර්‍ඝ
]
From 68668e07749e0cebb65748602e3ca44233cfc993 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:12 -0400 Subject: [PATCH 449/514] update test cases --- tests/core/saved/test_05.HP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index dc40409e..831db5be 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -80,7 +80,7 @@
[
-
ර්ඝ
+
ර්‍ඝ
]
From 08780a190a735bd29ab1e5ffee541ecc5ba588c0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:13 -0400 Subject: [PATCH 450/514] update test cases --- tests/core/saved/test_05.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.J.out b/tests/core/saved/test_05.J.out index 62f0026e..7aa99b5d 100644 --- a/tests/core/saved/test_05.J.out +++ b/tests/core/saved/test_05.J.out @@ -1,2 +1,2 @@ -{"employees": {"wc": ["෴ - 0xdf4 - 1","ණ - 0xdab - 1","් - 0xdca - 0","ණ - 0xdab - 1","្ - 0x17d2 - 0","෴ - 0xdf4 - 1"],"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":4,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":8,"not-sinhala":"123456","tag":"ර්ඝ","width":2, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Thu, 6 Aug 2015 16:01:14 -0400 Subject: [PATCH 451/514] update test cases --- tests/core/saved/test_05.JP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index 518c492e..28e6e1e7 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -20,7 +20,7 @@ "sinhala": "෴ණ්ණ෴෴ණ්ණ෴", "width": 8, "not-sinhala": "123456", - "tag": "ර්ඝ", + "tag": "ර්‍ඝ", "width": 2, "employee": [ { From dd82df326aa7fdeea16eee26fb3d6843d374cc88 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:16 -0400 Subject: [PATCH 452/514] update test cases --- tests/core/saved/test_05.T.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index 53c996bd..da835118 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -14,7 +14,7 @@ Width: 3 [෴ණ්ණ෴] Width: 6 [1234] -[ර්ඝ] +[ර්‍ඝ] Width: 4 First Name Last Name Department Time (%) Jim ("რეგტ") გთხოვთ ახ 431 90 From f135c4cd316fade98301a43cdf3b7352671a1b0f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:17 -0400 Subject: [PATCH 453/514] update test cases --- tests/core/saved/test_05.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.X.out b/tests/core/saved/test_05.X.out index ebcd10e4..50ded780 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file +෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්‍ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From 5e2efeb68b4fd4b8197e1b3792088007998ff187 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 6 Aug 2015 16:01:18 -0400 Subject: [PATCH 454/514] update test cases --- tests/core/saved/test_05.XP.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index 1b9e5592..1ff1432f 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -17,7 +17,7 @@ ෴ණ්ණ෴෴ණ්ණ෴ 8 123456 - ර්ඝ + ර්‍ඝ 2 Jim From 3deab14eef24225923d3ed286bb14b9ead778f9c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 7 Aug 2015 12:59:09 -0400 Subject: [PATCH 455/514] remove xo_version.h --- configure.ac | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2438f79a..84032e0e 100644 --- a/configure.ac +++ b/configure.ac @@ -389,13 +389,21 @@ AC_SUBST(LIBXO_VERSION) AC_SUBST(LIBXO_VERSION_NUMBER) AC_SUBST(LIBXO_VERSION_EXTRA) +AC_DEFINE_UNQUOTED(LIBXO_VERSION, ["$LIBXO_VERSION"], + [Version number as dotted value]) +AC_DEFINE_UNQUOTED(LIBXO_VERSION_NUMBER, [$LIBXO_VERSION_NUMBER], + [Version number as a number]) +AC_DEFINE_UNQUOTED(LIBXO_VERSION_STRING, ["$LIBXO_VERSION_NUMBER"], + [Version number as string]) +AC_DEFINE_UNQUOTED(LIBXO_VERSION_EXTRA, ["$LIBXO_VERSION_EXTRA"], + [Version number extra information]) + AC_CONFIG_HEADERS([libxo/xo_config.h]) AC_CONFIG_FILES([ Makefile libxo-config xohtml/xohtml.sh libxo/Makefile - libxo/xo_version.h encoder/Makefile encoder/cbor/Makefile encoder/test/Makefile From cbe9003265dabadabdad0e1df942a384a100d0fd Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 7 Aug 2015 12:59:11 -0400 Subject: [PATCH 456/514] remove xo_version.h --- libxo/libxo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 1fc37791..49ad0a07 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -28,7 +28,6 @@ #include "xo.h" #include "xo_encoder.h" #include "xo_buf.h" -#include "xo_version.h" #ifdef LIBXO_WCWIDTH #include "xo_wcwidth.h" From 62dda824a70c45e401c4ec70d7f516ca1273bb48 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 7 Aug 2015 12:59:13 -0400 Subject: [PATCH 457/514] remove xo_version.h --- libxo/xo_version.h.in | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 libxo/xo_version.h.in diff --git a/libxo/xo_version.h.in b/libxo/xo_version.h.in deleted file mode 100644 index 777e83e3..00000000 --- a/libxo/xo_version.h.in +++ /dev/null @@ -1,38 +0,0 @@ -/* - * $Id$ - * - * Copyright (c) 2014, Juniper Networks, Inc. - * All rights reserved. - * This SOFTWARE is licensed under the LICENSE provided in the - * ../Copyright file. By downloading, installing, copying, or otherwise - * using the SOFTWARE, you agree to be bound by the terms of that - * LICENSE. - * - * xoversion.h -- compile time constants for libxo - * NOTE: This file is generated from xoversion.h.in. - */ - -#ifndef LIBXO_XOVERSION_H -#define LIBXO_XOVERSION_H - -/** - * The version string - */ -#define LIBXO_VERSION "@PACKAGE_VERSION@" - -/** - * The version number - */ -#define LIBXO_VERSION_NUMBER @LIBXO_VERSION_NUMBER@ - -/** - * The version number as a string - */ -#define LIBXO_VERSION_STRING "@LIBXO_VERSION_NUMBER@" - -/** - * The version number extra info as a string - */ -#define LIBXO_VERSION_EXTRA "@LIBXO_VERSION_EXTRA@" - -#endif /* LIBXO_XOVERSION_H */ From 02726d368ee3314ca8f942aa07dd05d895e23dd6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 7 Aug 2015 12:59:14 -0400 Subject: [PATCH 458/514] remove xo_version.h --- xo/xo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xo/xo.c b/xo/xo.c index 303899e6..ce758afb 100644 --- a/xo/xo.c +++ b/xo/xo.c @@ -15,7 +15,6 @@ #include "xo_config.h" #include "xo.h" -#include "xo_version.h" #include /* Include after xo.h for testing */ From 4009763b50248bf60867df776c681684ab50c45b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 7 Aug 2015 12:59:15 -0400 Subject: [PATCH 459/514] remove xo_version.h --- xopo/xopo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xopo/xopo.c b/xopo/xopo.c index 581637f2..991b7579 100644 --- a/xopo/xopo.c +++ b/xopo/xopo.c @@ -18,7 +18,6 @@ #include "xo_config.h" #include "xo.h" -#include "xo_version.h" #include /* Include after xo.h for testing */ From aff4bb8ab7c7c1306d5811531cf1ce307c5b54bf Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:16 -0400 Subject: [PATCH 460/514] update test cases --- tests/core/saved/test_05.E.out | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/core/saved/test_05.E.out b/tests/core/saved/test_05.E.out index 57de2ea5..8253a6a1 100644 --- a/tests/core/saved/test_05.E.out +++ b/tests/core/saved/test_05.E.out @@ -1,4 +1,9 @@ op create: [] [] +op open_container: [indian-languages] [] +op string: [gurmukhi] [ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।] +op string: [shahmukhi] [لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔] +op string: [tranliteration] [lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.] +op close_container: [indian-languages] [] op open_container: [employees] [] op open_leaf_list: [wc] [] op string: [wc] [෴ - 0xdf4 - 1] From dfe45616c0f7fd9aabe31e7f92dd5bd7b35daf74 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:19 -0400 Subject: [PATCH 461/514] update test cases --- tests/core/saved/test_05.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.H.out b/tests/core/saved/test_05.H.out index bb44ab77..82e4ebec 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්‍ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file +
Sample text
This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.
Gurmukhi:
ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।
Shahmukhi:
لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔
Transliteration
:
lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්‍ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file From fc29d8ddc82ed312d3850d8888275e4bd812ff4f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:21 -0400 Subject: [PATCH 462/514] update test cases --- tests/core/saved/test_05.HIPx.out | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index 79031780..1b5be677 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -1,3 +1,28 @@ +
+
Sample text
+
+
+
This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.
+
+
+
Gurmukhi:
+
+
+
ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।
+
+
+
Shahmukhi:
+
+
+
لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔
+
+
+
Transliteration
+
:
+
+
+
lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.
+
Wide char:
෴ - 0xdf4 - 1
From 6da643deb01977843430fb44afb263b4fbc1e674 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:22 -0400 Subject: [PATCH 463/514] update test cases --- tests/core/saved/test_05.HP.out | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index 831db5be..f5143af2 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -1,3 +1,28 @@ +
+
Sample text
+
+
+
This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.
+
+
+
Gurmukhi:
+
+
+
ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।
+
+
+
Shahmukhi:
+
+
+
لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔
+
+
+
Transliteration
+
:
+
+
+
lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.
+
Wide char:
෴ - 0xdf4 - 1
From 32196521b418c3792566784f79df1b16a14d916b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:32 -0400 Subject: [PATCH 464/514] update test cases --- tests/core/saved/test_05.J.out | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.J.out b/tests/core/saved/test_05.J.out index 7aa99b5d..2d347091 100644 --- a/tests/core/saved/test_05.J.out +++ b/tests/core/saved/test_05.J.out @@ -1,2 +1,3 @@ -{"employees": {"wc": ["෴ - 0xdf4 - 1","ණ - 0xdab - 1","් - 0xdca - 0","ණ - 0xdab - 1","្ - 0x17d2 - 0","෴ - 0xdf4 - 1"],"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":4,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":8,"not-sinhala":"123456","tag":"ර්‍ඝ","width":2, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Sat, 8 Aug 2015 00:13:34 -0400 Subject: [PATCH 465/514] update test cases --- tests/core/saved/test_05.JP.out | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index 28e6e1e7..ef5bbbe4 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -1,4 +1,10 @@ { + "indian-languages": { + "gurmukhi": "ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।", + "shahmukhi": "لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔", + "tranliteration": "lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē." + } +, "employees": { "wc": [ "෴ - 0xdf4 - 1", From 49fdeacad1f280604c4ee352c08f74d98cf42ff6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:36 -0400 Subject: [PATCH 466/514] update test cases --- tests/core/saved/test_05.T.out | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index da835118..22fc3e81 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -1,3 +1,11 @@ +Sample text +This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script. +Gurmukhi: +ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ । +Shahmukhi: +لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔ +Transliteration: +lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē. Wide char: ෴ - 0xdf4 - 1 Wide char: ණ - 0xdab - 1 Wide char: ් - 0xdca - 0 From f62a88d220b03dc336c01e1a4c88030f561997b0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:37 -0400 Subject: [PATCH 467/514] update test cases --- tests/core/saved/test_05.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.X.out b/tests/core/saved/test_05.X.out index 50ded780..c3f6808d 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්‍ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file +ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්‍ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From 7b1d0e8dd0967bb7a90acdda0ec4ed0ad2b1cfda Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:39 -0400 Subject: [PATCH 468/514] update test cases --- tests/core/saved/test_05.XP.out | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index 1ff1432f..8695644d 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -1,3 +1,8 @@ + + ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ । + لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔ + lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē. + ෴ - 0xdf4 - 1 ණ - 0xdab - 1 From a82f0ac07d0389a18c693f4b16e22ba0b7f151bb Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 8 Aug 2015 00:13:42 -0400 Subject: [PATCH 469/514] update test cases --- tests/core/test_05.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index 2d8e8f30..78e18b2c 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -60,6 +60,27 @@ main (int argc, char **argv) xo_set_info(NULL, info, info_count); xo_set_flags(NULL, XOF_COLUMNS); + xo_open_container("indian-languages"); + + xo_emit("{T:Sample text}\n"); + xo_emit("This sample text was taken from the Punjabi Wikipedia " + "article on Lahore and transliterated into the Latin script.\n"); + + xo_emit("{T:Gurmukhi:}\n"); + xo_emit("{:gurmukhi}\n", + "ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।"); + + + xo_emit("{T:Shahmukhi:}\n"); + xo_emit("{:shahmukhi}\n", + "لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔"); + + xo_emit("{T:Transliteration}:\n"); + xo_emit("{:tranliteration}\n", + "lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē."); + + xo_close_container("indian-languages"); + xo_open_container("employees"); wchar_t wc[] = { L'෴', L'ණ', L'්', L'ණ', 0x17D2, L'෴', 0 }; From 8e0e0b5719397dc500d042e46398fdd64ed336ce Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 12 Aug 2015 20:39:15 -0400 Subject: [PATCH 470/514] add comments; fix xo_depth_check's return code --- libxo/libxo.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 49ad0a07..7fc8b974 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -29,6 +29,28 @@ #include "xo_encoder.h" #include "xo_buf.h" +/* + * We ask wcwidth() to do an impossible job, really. It's supposed to + * need to tell us the number of columns consumed to display a unicode + * character. It returns that number without any sort of context, but + * we know they are characters whose glyph differs based on placement + * (end of word, middle of word, etc) and many that affect characters + * previously emitted. Without content, it can't hope to tell us. + * But it's the only standard tool we've got, so we use it. We would + * use wcswidth() but it typically just loops thru adding the results + * of wcwidth() calls in an entirely unhelpful way. + * + * Even then, there are many poor implementations (macosx), so we have + * to carry our own. We could have configure.ac test this (with + * something like 'assert(wcwidth(0x200d) == 0)'), but it would have + * to run a binary, which breaks cross-compilation. Hmm... I could + * run this test at init time and make a warning for our dear user. + * + * Anyhow, it remains a best-effort sort of thing. And it's all made + * more hopeless because we assume the terminal doing the rendering is + * playing by the same rules we are. If it display 0x200d as a square + * box or a funky question mark, the output will be hosed. + */ #ifdef LIBXO_WCWIDTH #include "xo_wcwidth.h" #else /* LIBXO_WCWIDTH */ @@ -39,6 +61,10 @@ #include #endif /* HAVE_STDIO_EXT_H */ +/* + * humanize_number is a great function, unless you don't have it. So + * we carry one in our pocket. + */ #ifdef HAVE_HUMANIZE_NUMBER #include #define xo_humanize_number humanize_number @@ -82,7 +108,7 @@ const char xo_version_extra[] = LIBXO_VERSION_EXTRA; #endif /* UNUSED */ #define XO_INDENT_BY 2 /* Amount to indent when pretty printing */ -#define XO_DEPTH 512 /* Default stack depth */ +#define XO_DEPTH 128 /* Default stack depth */ #define XO_MAX_ANCHOR_WIDTH (8*1024) /* Anything wider is just sillyb */ #define XO_FAILURE_NAME "failure" @@ -189,7 +215,7 @@ typedef struct xo_stack_s { #define XO_EFF_UNDERLINE (1<<3) #define XO_EFF_INVERSE (1<<4) -#define XO_EFF_CLEAR_BITS XO_EFF_RESET +#define XO_EFF_CLEAR_BITS XO_EFF_RESET /* Reset gets reset, surprisingly */ typedef uint8_t xo_effect_t; typedef uint8_t xo_color_t; @@ -331,7 +357,6 @@ typedef unsigned long xo_xff_flags_t; * that is C string handling. The simplicity and completenesss are * sunk in ways we haven't even begun to understand. */ - #define XF_WIDTH_MIN 0 /* Minimal width */ #define XF_WIDTH_SIZE 1 /* Maximum number of bytes to examine */ #define XF_WIDTH_MAX 2 /* Maximum width */ @@ -484,13 +509,13 @@ xo_flush_file (void *opaque) static const char * xo_printable (const char *str) { - static char bufset[XO_NUMBUFS][XO_SMBUFSZ]; - static int bufnum = 0; + static THREAD_LOCAL(char) bufset[XO_NUMBUFS][XO_SMBUFSZ]; + static THREAD_LOCAL(int) bufnum = 0; if (str == NULL) return ""; - if (++bufnum == XO_NUMBUFS) /* Not thread safe */ + if (++bufnum == XO_NUMBUFS) bufnum = 0; char *res = bufset[bufnum], *cp, *ep; @@ -519,11 +544,12 @@ xo_depth_check (xo_handle_t *xop, int depth) xo_stack_t *xsp; if (depth >= xop->xo_stack_size) { - depth += 16; + depth += XO_DEPTH; /* Extra room */ + xsp = xo_realloc(xop->xo_stack, sizeof(xop->xo_stack[0]) * depth); if (xsp == NULL) { xo_failure(xop, "xo_depth_check: out of memory (%d)", depth); - return 0; + return -1; } int count = depth - xop->xo_stack_size; From 24ab93334b78ef70d5d25e6bfcaf0b3d5a16a70e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:00:54 -0400 Subject: [PATCH 471/514] Add "add.man" --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 84032e0e..66dc7ba9 100644 --- a/configure.ac +++ b/configure.ac @@ -404,6 +404,7 @@ AC_CONFIG_FILES([ libxo-config xohtml/xohtml.sh libxo/Makefile + libxo/add.man encoder/Makefile encoder/cbor/Makefile encoder/test/Makefile From df6cbb924ce899483ba338f0f9a1cc8a10b50d63 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:01:19 -0400 Subject: [PATCH 472/514] add install-data-hook for add.man; add xo_set_syslog_enterprise_id.3 and xo_syslog.3 --- libxo/Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index 645dcd6d..1d1b169f 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -63,6 +63,8 @@ man_MANS = \ xo_set_info.3 \ xo_set_options.3 \ xo_set_style.3 \ + xo_set_syslog_enterprise_id.3 \ + xo_syslog.3 \ xo_set_version.3 \ xo_set_writer.3 @@ -73,3 +75,7 @@ call-graph: ${RM} libxo.o ${MAKE} CC="clang -Xclang -analyze -Xclang \ -analyzer-checker=debug.ViewCallGraph" libxo.o + +install-data-hook: + for file in ${man_MANS}; do \ + cat add.man >> ${DESTDIR}${man3dir}/$$file ; done From 33aa57add0e70580f526ce33d44b0af18ed9f4e8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:01:43 -0400 Subject: [PATCH 473/514] Nuke add.man content --- libxo/libxo.3 | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/libxo/libxo.3 b/libxo/libxo.3 index cf5ccadc..4e2488cd 100644 --- a/libxo/libxo.3 +++ b/libxo/libxo.3 @@ -290,24 +290,6 @@ Instructs .Nm to use an alternative set of low-level output functions. .El -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo 1 , .Xr xolint 1 , @@ -329,10 +311,3 @@ https://github.com/Juniper/libxo/releases .Xr xo_set_style 3 , .Xr xo_set_writer 3 , .Xr xo_format 5 -.Sh HISTORY -The -.Nm -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer From 85f9759d489bfaf264db4974bbb6eb29e019d390 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:02:45 -0400 Subject: [PATCH 474/514] add comments; refactor xo_err_* function to nuke check_warn flag --- libxo/libxo.c | 92 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 15 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 7fc8b974..1dd862c3 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -6,6 +6,24 @@ * using the SOFTWARE, you agree to be bound by the terms of that * LICENSE. * Phil Shafer, July 2014 + * + * This is the implementation of libxo, the formatting library that + * generates multiple styles of output from a single code path. + * Command line utilities can have their normal text output while + * automation tools can see XML or JSON output, and web tools can use + * HTML output that encodes the text output annotated with additional + * information. Specialized encoders can be built that allow custom + * encoding including binary ones like CBOR, thrift, protobufs, etc. + * + * Full documentation is available in ./doc/libxo.txt or online at: + * http://juniper.github.io/libxo/libxo-manual.html + * + * For first time readers, the core bits of code to start looking at are: + * - xo_do_emit() -- the central function of the library + * - xo_do_format_field() -- handles formatting a single field + * - xo_transiton() -- the state machine that keeps things sane + * and of course the "xo_handle_t" data structure, which carries all + * configuration and state. */ #include @@ -47,7 +65,7 @@ * run this test at init time and make a warning for our dear user. * * Anyhow, it remains a best-effort sort of thing. And it's all made - * more hopeless because we assume the terminal doing the rendering is + * more hopeless because we assume the display code doing the rendering is * playing by the same rules we are. If it display 0x200d as a square * box or a funky question mark, the output will be hosed. */ @@ -1732,6 +1750,9 @@ xo_name_to_style (const char *name) return -1; } +/* + * Indicate if the style is an "encoding" one as opposed to a "display" one. + */ static int xo_style_is_encoding (xo_handle_t *xop) { @@ -7131,6 +7152,10 @@ xo_close_marker (const char *name) return xo_close_marker_h(NULL, name); } +/* + * Record custom output functions into the xo handle, allowing + * integration with a variety of output frameworks. + */ void xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func, xo_close_func_t close_func, xo_flush_func_t flush_func) @@ -7221,6 +7246,10 @@ xo_finish (void) return xo_finish_h(NULL); } +/* + * xo_finish_atexit is suitable for atexit() calls, to force clear up + * and finalizing output. + */ void xo_finish_atexit (void) { @@ -7308,6 +7337,12 @@ xo_error (const char *fmt, ...) va_end(vap); } +/* + * Parse any libxo-specific options from the command line, removing them + * so the main() argument parsing won't see them. We return the new value + * for argc or -1 for error. If an error occurred, the program should + * exit. A suitable error message has already been displayed. + */ int xo_parse_args (int argc, char **argv) { @@ -7367,6 +7402,10 @@ xo_parse_args (int argc, char **argv) return save; } +/* + * Debugging function that dumps the current stack of open libxo constructs, + * suitable for calling from the debugger. + */ void xo_dump_stack (xo_handle_t *xop) { @@ -7385,6 +7424,9 @@ xo_dump_stack (xo_handle_t *xop) } } +/* + * Record the program name used for error messages + */ void xo_set_program (const char *name) { @@ -7422,6 +7464,10 @@ xo_set_version_h (xo_handle_t *xop, const char *version UNUSED) } } +/* + * Set the version number for the API content being carried thru + * the xo handle. + */ void xo_set_version (const char *version) { @@ -7433,13 +7479,11 @@ xo_set_version (const char *version) * standard error. If the XOF_WARN_XML flag is set, then we generate * XMLified content on standard output. */ -static void -xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code, int check_warn, - const char *fmt, va_list vap) +void +xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code, + const char *fmt, va_list vap) { xop = xo_default(xop); - if (check_warn && !XOF_ISSET(xop, XOF_WARN)) - return; if (fmt == NULL) return; @@ -7493,7 +7537,7 @@ xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) va_list vap; va_start(vap, fmt); - xo_emit_warn_hcv(xop, 1, code, 0, fmt, vap); + xo_emit_warn_hcv(xop, 1, code, fmt, vap); va_end(vap); } @@ -7503,7 +7547,7 @@ xo_emit_warn_c (int code, const char *fmt, ...) va_list vap; va_start(vap, fmt); - xo_emit_warn_hcv(NULL, 1, code, 0, fmt, vap); + xo_emit_warn_hcv(NULL, 1, code, fmt, vap); va_end(vap); } @@ -7514,7 +7558,7 @@ xo_emit_warn (const char *fmt, ...) va_list vap; va_start(vap, fmt); - xo_emit_warn_hcv(NULL, 1, code, 0, fmt, vap); + xo_emit_warn_hcv(NULL, 1, code, fmt, vap); va_end(vap); } @@ -7524,20 +7568,26 @@ xo_emit_warnx (const char *fmt, ...) va_list vap; va_start(vap, fmt); - xo_emit_warn_hcv(NULL, 1, -1, 0, fmt, vap); + xo_emit_warn_hcv(NULL, 1, -1, fmt, vap); va_end(vap); } +void +xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) +{ + xo_emit_warn_hcv(NULL, 0, code, fmt, vap); + xo_finish(); + exit(eval); +} + void xo_emit_err (int eval, const char *fmt, ...) { int code = errno; va_list vap; - va_start(vap, fmt); - xo_emit_warn_hcv(NULL, 0, code, 0, fmt, vap); + xo_emit_err_v(0, code, fmt, vap); va_end(vap); - xo_finish(); exit(eval); } @@ -7547,7 +7597,7 @@ xo_emit_errx (int eval, const char *fmt, ...) va_list vap; va_start(vap, fmt); - xo_emit_warn_hcv(NULL, 0, -1, 0, fmt, vap); + xo_emit_err_v(0, -1, fmt, vap); va_end(vap); xo_finish(); exit(eval); @@ -7559,12 +7609,15 @@ xo_emit_errc (int eval, int code, const char *fmt, ...) va_list vap; va_start(vap, fmt); - xo_emit_warn_hcv(NULL, 0, code, 0, fmt, vap); + xo_emit_warn_hcv(NULL, 0, code, fmt, vap); va_end(vap); xo_finish(); exit(eval); } +/* + * Get the opaque private pointer for an xo handle + */ void * xo_get_private (xo_handle_t *xop) { @@ -7572,6 +7625,9 @@ xo_get_private (xo_handle_t *xop) return xop->xo_private; } +/* + * Set the opaque private pointer for an xo handle. + */ void xo_set_private (xo_handle_t *xop, void *opaque) { @@ -7579,6 +7635,9 @@ xo_set_private (xo_handle_t *xop, void *opaque) xop->xo_private = opaque; } +/* + * Get the encoder function + */ xo_encoder_func_t xo_get_encoder (xo_handle_t *xop) { @@ -7586,6 +7645,9 @@ xo_get_encoder (xo_handle_t *xop) return xop->xo_encoder; } +/* + * Record an encoder callback function in an xo handle. + */ void xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t encoder) { From 0a3dbe303531137486d475e2b4de0585c0f7ee8c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:03:14 -0400 Subject: [PATCH 475/514] Make PRINTFLIKE versions of all printf-like functions. --- libxo/xo.h | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 8 deletions(-) diff --git a/libxo/xo.h b/libxo/xo.h index 596a3682..88bcce29 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -12,6 +12,9 @@ * libxo provides a means of generating text, XML, JSON, and HTML output * using a single set of function calls, maximizing the value of output * while minimizing the cost/impact on the code. + * + * Full documentation is available in ./doc/libxo.txt or online at: + * http://juniper.github.io/libxo/libxo-manual.html */ #ifndef INCLUDE_XO_H @@ -20,6 +23,8 @@ #include #include #include +#include +#include #ifdef __dead2 #define NORETURN __dead2 @@ -100,6 +105,8 @@ typedef struct xo_info_s { const char *xi_help; /* Description of field */ } xo_info_t; +#define XO_INFO_NULL NULL, NULL, NULL /* Use '{ XO_INFO_NULL }' to end lists */ + struct xo_handle_s; /* Opaque structure forward */ typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */ @@ -173,6 +180,35 @@ xo_emit_h (xo_handle_t *xop, const char *fmt, ...); int xo_emit (const char *fmt, ...); +PRINTFLIKE(2, 0) +static inline int +xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap) +{ + return xo_emit_hv(xop, fmt, vap); +} + +PRINTFLIKE(2, 3) +static inline int +xo_emit_hp (xo_handle_t *xop, const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + int rc = xo_emit_hv(xop, fmt, vap); + va_end(vap); + return rc; +} + +PRINTFLIKE(1, 2) +static inline int +xo_emit_p (const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + int rc = xo_emit_hv(NULL, fmt, vap); + va_end(vap); + return rc; +} + int xo_open_container_h (xo_handle_t *xop, const char *name); @@ -315,7 +351,7 @@ void xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4); void -xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap); +xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0); void xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4); @@ -329,6 +365,10 @@ xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2); void xo_message (const char *fmt, ...) PRINTFLIKE(1, 2); +void +xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code, + const char *fmt, va_list vap); + void xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...); @@ -342,13 +382,100 @@ void xo_emit_warnx (const char *fmt, ...); void -xo_emit_err (int eval, const char *fmt, ...); - -void -xo_emit_errx (int eval, const char *fmt, ...); - -void -xo_emit_errc (int eval, int code, const char *fmt, ...); +xo_emit_err (int eval, const char *fmt, ...) NORETURN; + +void +xo_emit_errx (int eval, const char *fmt, ...) NORETURN; + +void +xo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN; + +PRINTFLIKE(4, 0) +static inline void +xo_emit_warn_hcvp (xo_handle_t *xop, int as_warning, int code, + const char *fmt, va_list vap) +{ + xo_emit_warn_hcv(xop, as_warning, code, fmt, vap); +} + +PRINTFLIKE(3, 4) +static inline void +xo_emit_warn_hcp (xo_handle_t *xop, int code, const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(xop, 1, code, fmt, vap); + va_end(vap); +} + +PRINTFLIKE(2, 3) +static inline void +xo_emit_warn_cp (int code, const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 1, code, fmt, vap); + va_end(vap); +} + +PRINTFLIKE(1, 2) +static inline void +xo_emit_warn_p (const char *fmt, ...) +{ + int code = errno; + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 1, code, fmt, vap); + va_end(vap); +} + +PRINTFLIKE(1, 2) +static inline void +xo_emit_warnx_p (const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 1, -1, fmt, vap); + va_end(vap); +} + +NORETURN PRINTFLIKE(2, 3) +static inline void +xo_emit_err_p (int eval, const char *fmt, ...) +{ + int code = errno; + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 0, code, fmt, vap); + va_end(vap); + + exit(eval); +} + +PRINTFLIKE(2, 3) +static inline void +xo_emit_errx_p (int eval, const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 0, -1, fmt, vap); + va_end(vap); + exit(eval); +} + +PRINTFLIKE(3, 4) +static inline void +xo_emit_errc_p (int eval, int code, const char *fmt, ...) +{ + va_list vap; + va_start(vap, fmt); + xo_emit_warn_hcv(NULL, 0, code, fmt, vap); + va_end(vap); + exit(eval); +} + +void +xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0); void xo_no_setlocale (void); From d647c004dcddda6ff9bea87ff2a1ec3d71f2eff5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:03:35 -0400 Subject: [PATCH 476/514] nuke add.man content --- libxo/xo_attr.3 | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/libxo/xo_attr.3 b/libxo/xo_attr.3 index 7ac092ca..c71377fd 100644 --- a/libxo/xo_attr.3 +++ b/libxo/xo_attr.3 @@ -55,27 +55,6 @@ parameter as passed to Since attributes are only emitted in XML, their use should be limited to meta-data and additional or redundant representations of data already emitted in other form. -.Sh ADDITIONAL DOCUMENTATION -.Pp -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -libxo lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of libxo is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Fa libxo -library was added in FreeBSD 11.0. -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From f64ac2791cf191bf3a92dbf2700495bd4a8cdbb4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:03:48 -0400 Subject: [PATCH 477/514] nuke add.man content --- libxo/xo_create.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_create.3 b/libxo/xo_create.3 index 6abed671..bfbadc4e 100644 --- a/libxo/xo_create.3 +++ b/libxo/xo_create.3 @@ -61,31 +61,7 @@ with a .Dv NULL handle will release any resources associated with the default handle. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo_emit 3 , -.Xr xo_set_options 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_set_options 3 , +.Xr libxo 3 From a83bd4f8cc12266bf73580517ecbec76f2e28b53 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:03:55 -0400 Subject: [PATCH 478/514] nuke add.man content --- libxo/xo_emit.3 | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/libxo/xo_emit.3 b/libxo/xo_emit.3 index c92af96b..8ff3c619 100644 --- a/libxo/xo_emit.3 +++ b/libxo/xo_emit.3 @@ -43,30 +43,8 @@ uses an explicit handle. accepts a .Fa va_list for additional flexibility. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of libxo is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo_open_container 3 , .Xr xo_open_list 3 , -.Xr xo_format 5 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_format 5 , +.Xr libxo 3 From 6e48a1ebd39a1718088c24c40f51158fa543ac9f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:00 -0400 Subject: [PATCH 479/514] nuke add.man content --- libxo/xo_emit_err.3 | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/libxo/xo_emit_err.3 b/libxo/xo_emit_err.3 index c16f1ccb..bb1ca640 100644 --- a/libxo/xo_emit_err.3 +++ b/libxo/xo_emit_err.3 @@ -65,32 +65,8 @@ parameter. if (open(filename, O_RDONLY) < 0) xo_err(1, "cannot open file '%s'", filename); .Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo_emit 3 , -.Xr xo_format 5 , and -.Xr xo_err 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_format 5 , +.Xr xo_err 3 , +.Xr libxo 3 From 42d510333493fcdbc564fb6ca0b274a6a5b5766b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:02 -0400 Subject: [PATCH 480/514] nuke add.man content --- libxo/xo_err.3 | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/libxo/xo_err.3 b/libxo/xo_err.3 index dc37edea..532899ab 100644 --- a/libxo/xo_err.3 +++ b/libxo/xo_err.3 @@ -48,7 +48,7 @@ The argument is one compatible with .Xr printf 3 rather than -.Xf xo_emit 3 +.Xr xo_emit 3 to aid in simple conversion. This means these functions make unstructured data. To generate structured data, @@ -68,31 +68,7 @@ parameter. if (open(filename, O_RDONLY) < 0) xo_err(1, "cannot open file '%s'", filename); .Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 and -.Xr xo_emit_err 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr xo_emit_err 3 , +.Xr libxo 3 From 745e085efba7097815e98ec20a21a8f4a9795776 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:07 -0400 Subject: [PATCH 481/514] nuke add.man content --- libxo/xo_error.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_error.3 b/libxo/xo_error.3 index 9e17589b..e5c99e9d 100644 --- a/libxo/xo_error.3 +++ b/libxo/xo_error.3 @@ -35,31 +35,7 @@ one can replace calls with .Fn xo_error calls. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr printf 3 , -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 5b0b2a60a86981628a6bb27da8ef9b5f84c5fda3 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:08 -0400 Subject: [PATCH 482/514] nuke add.man content --- libxo/xo_finish.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_finish.3 b/libxo/xo_finish.3 index 56668730..221b1c17 100644 --- a/libxo/xo_finish.3 +++ b/libxo/xo_finish.3 @@ -34,30 +34,6 @@ Calling this function is .Em vital to the proper operation of libxo, especially for the non-TEXT output styles. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 42feb26f51240a016787cfda8f03d2c00104b5c5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:10 -0400 Subject: [PATCH 483/514] nuke add.man content --- libxo/xo_flush.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_flush.3 b/libxo/xo_flush.3 index 4a8a96e8..e43bae00 100644 --- a/libxo/xo_flush.3 +++ b/libxo/xo_flush.3 @@ -30,30 +30,6 @@ caller may wish to flush any data buffered within the library. The .Fn xo_flush function is used for this. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 58b663eb626c828ff1acf398b52dad04fce62a80 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:13 -0400 Subject: [PATCH 484/514] nuke add.man content --- libxo/xo_format.5 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index 23550ca1..689c370b 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -945,31 +945,7 @@ If there is no difference, use only one of the field names. If there is a difference, change the names to make that difference more obvious. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xolint 1 , -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 64c5a82fb1ba50f5f55666e3996b8eed4687a0a3 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:15 -0400 Subject: [PATCH 485/514] nuke add.man content --- libxo/xo_message.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_message.3 b/libxo/xo_message.3 index 915e6871..36f01488 100644 --- a/libxo/xo_message.3 +++ b/libxo/xo_message.3 @@ -63,30 +63,6 @@ as opened by .Xr xo_create 3 and .Nm xo_message_hcv accepts a va_list parameter of arguments. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 8e81f3edbb37c8dfbd59c602c0edd096b35e329c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:16 -0400 Subject: [PATCH 486/514] nuke add.man content --- libxo/xo_no_setlocale.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_no_setlocale.3 b/libxo/xo_no_setlocale.3 index 8e9bb8f0..f91abc00 100644 --- a/libxo/xo_no_setlocale.3 +++ b/libxo/xo_no_setlocale.3 @@ -35,33 +35,9 @@ The caller may wish to avoid this behavior, and can do so by calling the .Fn xo_no_setlocale function. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo_emit 3 , .Xr xo_open_container 3 , .Xr xo_open_list 3 , -.Xr xo_format 5 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_format 5 , +.Xr libxo 3 From c3b5c69f26d80d68fe90c2d61e28504df4ef43e1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:19 -0400 Subject: [PATCH 487/514] nuke add.man content --- libxo/xo_open_container.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_open_container.3 b/libxo/xo_open_container.3 index abbc50f2..9e48fbee 100644 --- a/libxo/xo_open_container.3 +++ b/libxo/xo_open_container.3 @@ -183,30 +183,6 @@ to track open containers, lists, and instances. A warning is generated when the name given to the close function and the name recorded do not match. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 22c39df2aabd64f1e44a5906d844837b1bad3d13 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:21 -0400 Subject: [PATCH 488/514] nuke add.man content --- libxo/xo_open_list.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_open_list.3 b/libxo/xo_open_list.3 index 341a84d5..054ea752 100644 --- a/libxo/xo_open_list.3 +++ b/libxo/xo_open_list.3 @@ -153,30 +153,6 @@ are rendered as multiple leaf elements. hammer nail .Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From e6b4ef183e89b754d47de467636308fa2042fb6c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:23 -0400 Subject: [PATCH 489/514] nuke add.man content --- libxo/xo_open_marker.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_open_marker.3 b/libxo/xo_open_marker.3 index df4a9c5e..e7356ba6 100644 --- a/libxo/xo_open_marker.3 +++ b/libxo/xo_open_marker.3 @@ -100,30 +100,6 @@ properly. xo_close_marker("fish-guts"); } .Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From de537c97dfad36c42337754547d65afd45cbd628 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:25 -0400 Subject: [PATCH 490/514] nuke add.man content --- libxo/xo_parse_args.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_parse_args.3 b/libxo/xo_parse_args.3 index e39e88c9..80dceca9 100644 --- a/libxo/xo_parse_args.3 +++ b/libxo/xo_parse_args.3 @@ -143,30 +143,6 @@ Note that the value is not copied, so the memory passed to .Fn xo_parse_args ) must be maintained by the caller. .Pp -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 3b6efec8b4eba42ca3c09de30613e79d6ac60ff9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:28 -0400 Subject: [PATCH 491/514] nuke add.man content --- libxo/xo_set_allocator.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_set_allocator.3 b/libxo/xo_set_allocator.3 index 4cacecc0..c20a0f52 100644 --- a/libxo/xo_set_allocator.3 +++ b/libxo/xo_set_allocator.3 @@ -49,30 +49,6 @@ By default, the standard and .Xr free 3 functions are used. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From ea587524c995d4c697e019ccf2de3b8a32df915d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:29 -0400 Subject: [PATCH 492/514] nuke add.man content --- libxo/xo_set_flags.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_set_flags.3 b/libxo/xo_set_flags.3 index afcac54c..52997c5e 100644 --- a/libxo/xo_set_flags.3 +++ b/libxo/xo_set_flags.3 @@ -134,30 +134,6 @@ The .Fn xo_clear_flags function turns off the given flags in a specific handle. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From beb0588494c2917d74d0e60f566334695bb10ae4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:34 -0400 Subject: [PATCH 493/514] nuke add.man content --- libxo/xo_set_info.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_set_info.3 b/libxo/xo_set_info.3 index 90c7fd93..8ea06570 100644 --- a/libxo/xo_set_info.3 +++ b/libxo/xo_set_info.3 @@ -97,30 +97,6 @@ and "data-help" attributes:
GRO-000-533
.Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 850517107cdd694fbb0dd22ef1650ec616dacd9a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:40 -0400 Subject: [PATCH 494/514] nuke add.man content --- libxo/xo_set_options.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_set_options.3 b/libxo/xo_set_options.3 index 85761c9a..5b7c8eda 100644 --- a/libxo/xo_set_options.3 +++ b/libxo/xo_set_options.3 @@ -26,30 +26,6 @@ function accepts a comma-separated list of styles and flags and enables them for a specific handle. The options are identical to those listed in .Xr xo_parse_args 3 . -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 67941dfaf19d9b3238d2890443aefb40222ce357 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:41 -0400 Subject: [PATCH 495/514] nuke add.man content --- libxo/xo_set_style.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_set_style.3 b/libxo/xo_set_style.3 index d408e6c6..8e34033a 100644 --- a/libxo/xo_set_style.3 +++ b/libxo/xo_set_style.3 @@ -48,30 +48,6 @@ The name can be any of the styles: "text", "xml", "json", or "html". EXAMPLE: xo_set_style_name(NULL, "html"); .Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 861765a05d781bc62c12e31132151a6337b8bc9b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:43 -0400 Subject: [PATCH 496/514] nuke add.man content --- libxo/xo_set_version.3 | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/libxo/xo_set_version.3 b/libxo/xo_set_version.3 index 45b82ee6..5f9394d5 100644 --- a/libxo/xo_set_version.3 +++ b/libxo/xo_set_version.3 @@ -29,31 +29,6 @@ part of the data for encoding styles (XML and JSON). This version number is suitable for tracking changes in the content, allowing a user of the data to discern which version of the data model is in use. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo_emit 3 , .Xr libxo 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer From 5bae49968b1709ad5a9a84c7f0d41764847bbb6d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:44 -0400 Subject: [PATCH 497/514] nuke add.man content --- libxo/xo_set_writer.3 | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/libxo/xo_set_writer.3 b/libxo/xo_set_writer.3 index 5bf735c2..2f93bd94 100644 --- a/libxo/xo_set_writer.3 +++ b/libxo/xo_set_writer.3 @@ -51,30 +51,6 @@ The .Fa flush_func function should flush any pending data associated with the opaque pointer. -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of -.Nm libxo -is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO -.Xr xo_emit 3 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_emit 3 , +.Xr libxo 3 From 1edcd566614b33cd5afb68277ac5e5d3dbe98aca Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:04:53 -0400 Subject: [PATCH 498/514] nuke add.man content --- libxo/xo_syslog.3 | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/libxo/xo_syslog.3 b/libxo/xo_syslog.3 index fa8410f5..db92d369 100644 --- a/libxo/xo_syslog.3 +++ b/libxo/xo_syslog.3 @@ -72,31 +72,8 @@ function names. "{e:iut/%u}An {:event-source} {:event-id/%u} log entry", iut, source, id); .Ed -.Sh ADDITIONAL DOCUMENTATION -Complete documentation can be found on github: -.Bd -literal -offset indent -http://juniper.github.io/libxo/libxo-manual.html -.Ed -.Pp -.Nm libxo -lives on github as: -.Bd -literal -offset indent -https://github.com/Juniper/libxo -.Ed -.Pp -The latest release of libxo is available at: -.Bd -literal -offset indent -https://github.com/Juniper/libxo/releases -.Ed .Sh SEE ALSO .Xr xo_syslog 3 , .Xr xo_set_syslog_enterprise_id 3 , -.Xr xo_set_syslog_handler 3 , and -.Xr xo_format 5 -.Sh HISTORY -The -.Nm libxo -library was added in -.Fx 11.0 . -.Sh AUTHOR -Phil Shafer +.Xr xo_format 5 , +.Xr libxo 3 From 3eba9a79812d02d5e65d6c08771cb67914de4f59 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:05:08 -0400 Subject: [PATCH 499/514] use XO_INFO_NULL to end arrays --- tests/core/test_01.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/core/test_01.c b/tests/core/test_01.c index 6987229e..f7fe61ec 100644 --- a/tests/core/test_01.c +++ b/tests/core/test_01.c @@ -46,9 +46,8 @@ main (int argc, char **argv) { "on-order", "number", "Number of items on order" }, { "sku", "string", "Stock Keeping Unit" }, { "sold", "number", "Number of items sold" }, - { NULL, NULL, NULL }, + { XO_INFO_NULL }, }; - int info_count = (sizeof(info) / sizeof(info[0])) - 1; argc = xo_parse_args(argc, argv); if (argc < 0) @@ -75,7 +74,7 @@ main (int argc, char **argv) } } - xo_set_info(NULL, info, info_count); + xo_set_info(NULL, info, -1); xo_set_flags(NULL, XOF_KEYS); xo_open_container_h(NULL, "top"); From 0aecd0c1c6e74035d744f60a4a65aa2dae386d28 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:05:26 -0400 Subject: [PATCH 500/514] Add 0x34f/0x20dd test case --- tests/core/test_05.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index 78e18b2c..07de037e 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -88,6 +88,12 @@ main (int argc, char **argv) xo_emit("Wide char: {lq:wc/%lc - %#lx - %d}\n", wc[i], (unsigned long) wc[i], xo_wcwidth(wc[i])); + wchar_t msg[] = { L'1', 0x034f, L'2', 0x20dd, 0 }; + for (i = 0; msg[i]; i++) + xo_emit("Wide char: {lq:wc/%lc - %#lx - %d}\n", + msg[i], (unsigned long) msg[i], xo_wcwidth((int) msg[i])); + xo_emit("Cool: [{:fancy/%ls}]\n", msg); + xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); From d1ffc554c033bac19692d3a84450dd8356c2066f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:05:33 -0400 Subject: [PATCH 501/514] Initial version --- libxo/add.man.in | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 libxo/add.man.in diff --git a/libxo/add.man.in b/libxo/add.man.in new file mode 100644 index 00000000..4eae2656 --- /dev/null +++ b/libxo/add.man.in @@ -0,0 +1,29 @@ +.Sh ADDITIONAL DOCUMENTATION +.Fx +uses +.Nm libxo +version @LIBXO_VERSION@. +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/@LIBXO_VERSION@/libxo\-manual.html +.Ed +.Pp +.Nm libxo +lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of +.Nm libxo +is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh HISTORY +The +.Nm libxo +library was added in +.Fx 11.0 . +.Sh AUTHOR +Phil Shafer From f430dd5edcd98cb89d7df4ae646bb3e9232f7016 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 13:05:37 -0400 Subject: [PATCH 502/514] Initial version --- libxo/xo_set_syslog_enterprise_id.3 | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 libxo/xo_set_syslog_enterprise_id.3 diff --git a/libxo/xo_set_syslog_enterprise_id.3 b/libxo/xo_set_syslog_enterprise_id.3 new file mode 100644 index 00000000..da2eed73 --- /dev/null +++ b/libxo/xo_set_syslog_enterprise_id.3 @@ -0,0 +1,36 @@ +.\" # +.\" # Copyright (c) 2015, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2015 +.\" +.Dd July 20, 2015 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_set_syslog_enterprise_id +.Nd Set the enterprise identifier for syslog content +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_set_syslog_enterprise_id "unsigned short eid" +.Ft void +.Sh DESCRIPTION +The +.Fn xo_set_syslog_enterprise_id +function records an enterprise identifier used for subsequent +.Xr xo_syslog 3 +calls. +Enterprise IDs are +defined by IANA, the Internet Assigned Numbers Authority: +.Bd -literal -offset indent +https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers +.Ed +.Sh SEE ALSO +.Xr xo_syslog 3 , +.Xr libxo 3 From 57c1fb2b83bbe58e6ba12490c93396f576e54835 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:17 -0400 Subject: [PATCH 503/514] add _p functions --- doc/libxo.txt | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/doc/libxo.txt b/doc/libxo.txt index 9d793adb..924dd937 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -1117,6 +1117,52 @@ default to "%s". For padding and labels, the content string is considered the content, unless a format is given. +*** Argument Validation @printf-like@ + +Many compilers and tool chains support validation of printf-like +arguments. When the format string fails to match the argument list, +a warning is generated. This is a valuable feature and while the +formatting strings for libxo differ considerably from printf, many of +these checks can still provide build-time protection against bugs. + +libxo provide variants of functions that provide this ability, if the +"--enable-printflike" option is passed to the "configure" script. +These functions use the "_p" suffix, like "xo_emit_p()", +xo_emit_hp()", etc. + +The following are features of libxo formatting strings that are +incompatible with printf-like testing: + +- implicit formats, where "{:tag}" has an implicit "%s"; +- the "max" parameter for strings, where "{:tag/%4.10.6s}" means up to +ten bytes of data can be inspected to fill a minimum of 4 columns and +a maximum of 6; +- percent signs in strings, where "{:filled}%" makes a single, +trailing percent sign; +- the "l" and "h" modifiers for strings, where "{:tag/%hs}" means +locale-based string and "{:tag/%ls}" means a wide character string; +- distinct encoding formats, where "{:tag/#%s/%s}" means the display +styles (text and HTML) will use "#%s" where other styles use "%s"; + +If none of these features are in use by your code, then using the "_p" +variants might be wise. + +|------------------+------------------------| +| Function | printf-like Equivalent | +|------------------+------------------------| +| xo_emit_hv | xo_emit_hvp | +| xo_emit_h | xo_emit_hp | +| xo_emit | xo_emit_p | +| xo_emit_warn_hcv | xo_emit_warn_hcvp | +| xo_emit_warn_hc | xo_emit_warn_hcp | +| xo_emit_warn_c | xo_emit_warn_cp | +| xo_emit_warn | xo_emit_warn_p | +| xo_emit_warnx_ | xo_emit_warnx_p | +| xo_emit_err | xo_emit_err_p | +| xo_emit_errx | xo_emit_errx_p | +| xo_emit_errc | xo_emit_errc_p | +|------------------+------------------------| + *** Example In this example, the value for the number of items in stock is emitted: From e97df3ed7d341f9a43fe6be3231142c30b66d92c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:24 -0400 Subject: [PATCH 504/514] update test cases --- tests/core/saved/test_05.E.out | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/core/saved/test_05.E.out b/tests/core/saved/test_05.E.out index 8253a6a1..0ca15f4f 100644 --- a/tests/core/saved/test_05.E.out +++ b/tests/core/saved/test_05.E.out @@ -12,7 +12,12 @@ op string: [wc] [් - 0xdca - 0] op string: [wc] [ණ - 0xdab - 1] op string: [wc] [្ - 0x17d2 - 0] op string: [wc] [෴ - 0xdf4 - 1] +op string: [wc] [1 - 0x31 - 1] +op string: [wc] [͏ - 0x34f - 0] +op string: [wc] [2 - 0x32 - 1] +op string: [wc] [⃝ - 0x20dd - 0] op close_leaf_list: [wc] [] +op string: [fancy] [1͏2⃝] op string: [v1] [γιγνώσκειν] op string: [v2] [ὦ ἄνδρες ᾿Αθηναῖοι] op string: [v1] [ახლავე გაიაროთ რეგისტრაცია] From 27e34bd29af4d441e60fd845b35a2daf93f6be11 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:25 -0400 Subject: [PATCH 505/514] update test cases --- tests/core/saved/test_05.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.H.out b/tests/core/saved/test_05.H.out index 82e4ebec..e8fd6d11 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Sample text
This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.
Gurmukhi:
ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।
Shahmukhi:
لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔
Transliteration
:
lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්‍ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file +
Sample text
This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.
Gurmukhi:
ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।
Shahmukhi:
لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔
Transliteration
:
lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.
Wide char:
෴ - 0xdf4 - 1
Wide char:
ණ - 0xdab - 1
Wide char:
් - 0xdca - 0
Wide char:
ණ - 0xdab - 1
Wide char:
្ - 0x17d2 - 0
Wide char:
෴ - 0xdf4 - 1
Wide char:
1 - 0x31 - 1
Wide char:
͏ - 0x34f - 0
Wide char:
2 - 0x32 - 1
Wide char:
⃝ - 0x20dd - 0
Cool: [
1͏2⃝
]
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
6
[
]
Width
:
3
[
෴ණ්ණ෴
]
Width
:
6
[
1234
]
[
ර්‍ඝ
]
Width
:
4
First Name
Last Name
Department
Time (%)
Jim
(
"რეგტ"
)
გთხოვთ ახ
431
90
Terry
(
"<one"
)
Οὐχὶ ταὐτὰ παρ
660
90
Leslie
(
"Les"
)
Patterson
341
60
Ashley
(
"Ash"
)
Meter & Smith
1440
40
0123456789
(
"0123456789"
)
01234567890123
1440
40
ახლა
(
"გაიარო"
)
საერთაშორისო
123
90
෴ණ්ණ෴෴ණ්ණ෴
(
"Mick"
)
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴
110
20
\ No newline at end of file From ee333697e5a4e39feae17ca26e57984f9a3393ba Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:26 -0400 Subject: [PATCH 506/514] update test cases --- tests/core/saved/test_05.HIPx.out | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index 1b5be677..4389b85a 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -47,6 +47,27 @@
Wide char:
෴ - 0xdf4 - 1
+
+
Wide char:
+
1 - 0x31 - 1
+
+
+
Wide char:
+
͏ - 0x34f - 0
+
+
+
Wide char:
+
2 - 0x32 - 1
+
+
+
Wide char:
+
⃝ - 0x20dd - 0
+
+
+
Cool: [
+
1͏2⃝
+
]
+
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
From 5a839c34e990450afcb5575f89dc47625a515e1e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:28 -0400 Subject: [PATCH 507/514] update test cases --- tests/core/saved/test_05.HP.out | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index f5143af2..e3fcdda0 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -47,6 +47,27 @@
Wide char:
෴ - 0xdf4 - 1
+
+
Wide char:
+
1 - 0x31 - 1
+
+
+
Wide char:
+
͏ - 0x34f - 0
+
+
+
Wide char:
+
2 - 0x32 - 1
+
+
+
Wide char:
+
⃝ - 0x20dd - 0
+
+
+
Cool: [
+
1͏2⃝
+
]
+
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
From cff3c33b0af99d784f588c46ca67101a1778f81c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:29 -0400 Subject: [PATCH 508/514] update test cases --- tests/core/saved/test_05.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.J.out b/tests/core/saved/test_05.J.out index 2d347091..3525c432 100644 --- a/tests/core/saved/test_05.J.out +++ b/tests/core/saved/test_05.J.out @@ -1,3 +1,3 @@ {"indian-languages": {"gurmukhi":"ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।","shahmukhi":"لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔","tranliteration":"lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē."} -, "employees": {"wc": ["෴ - 0xdf4 - 1","ණ - 0xdab - 1","් - 0xdca - 0","ණ - 0xdab - 1","្ - 0x17d2 - 0","෴ - 0xdf4 - 1"],"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":4,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":8,"not-sinhala":"123456","tag":"ර්‍ඝ","width":2, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Fri, 21 Aug 2015 14:21:34 -0400 Subject: [PATCH 509/514] update test cases --- tests/core/saved/test_05.JP.out | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index ef5bbbe4..e027034e 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -12,8 +12,13 @@ "් - 0xdca - 0", "ණ - 0xdab - 1", "្ - 0x17d2 - 0", - "෴ - 0xdf4 - 1" + "෴ - 0xdf4 - 1", + "1 - 0x31 - 1", + "͏ - 0x34f - 0", + "2 - 0x32 - 1", + "⃝ - 0x20dd - 0" ], + "fancy": "1͏2⃝", "v1": "γιγνώσκειν", "v2": "ὦ ἄνδρες ᾿Αθηναῖοι", "v1": "ახლავე გაიაროთ რეგისტრაცია", From 9808185b0ac0667351858a3c665b70b43d8f0ac0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:35 -0400 Subject: [PATCH 510/514] update test cases --- tests/core/saved/test_05.T.out | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index 22fc3e81..397a64ee 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -12,6 +12,11 @@ Wide char: ් - 0xdca - 0 Wide char: ණ - 0xdab - 1 Wide char: ្ - 0x17d2 - 0 Wide char: ෴ - 0xdf4 - 1 +Wide char: 1 - 0x31 - 1 +Wide char: ͏ - 0x34f - 0 +Wide char: 2 - 0x32 - 1 +Wide char: ⃝ - 0x20dd - 0 +Cool: [1͏2⃝] Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო Width: 63 From d49e6de45f65f4b59f01c24e8af842fa79821233 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:37 -0400 Subject: [PATCH 511/514] update test cases --- tests/core/saved/test_05.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_05.X.out b/tests/core/saved/test_05.X.out index c3f6808d..2a40010f 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 1γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්‍ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file +ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.෴ - 0xdf4 - 1ණ - 0xdab - 1් - 0xdca - 0ණ - 0xdab - 1្ - 0x17d2 - 0෴ - 0xdf4 - 11 - 0x31 - 1͏ - 0x34f - 02 - 0x32 - 1⃝ - 0x20dd - 01͏2⃝γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴41෴ණ්ණ෴෴ණ්ණ෴8123456ර්‍ඝ2Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From 89d07d085f5d8da8b1b088101bb6c0dab6bc243b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:21:43 -0400 Subject: [PATCH 512/514] update test cases --- tests/core/saved/test_05.XP.out | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index 8695644d..cf48b5b9 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -10,6 +10,11 @@ ණ - 0xdab - 1 ្ - 0x17d2 - 0 ෴ - 0xdf4 - 1 + 1 - 0x31 - 1 + ͏ - 0x34f - 0 + 2 - 0x32 - 1 + ⃝ - 0x20dd - 0 + 1͏2⃝ γιγνώσκειν ὦ ἄνδρες ᾿Αθηναῖοι ახლავე გაიაროთ რეგისტრაცია From 54c2c008388f45017f43f9860a2911d1ef8e2681 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:40:48 -0400 Subject: [PATCH 513/514] filename should be last in the example --- doc/libxo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index 924dd937..1e7acc79 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -43,10 +43,10 @@ can then be generated in various style, using the "--libxo" option: % wc --libxo xml,pretty,warn /etc/motd - /etc/motd 25 165 1140 + /etc/motd % wc --libxo json,pretty,warn /etc/motd @@ -54,10 +54,10 @@ can then be generated in various style, using the "--libxo" option: "wc": { "file": [ { - "filename": "/etc/motd", "lines": 25, "words": 165, - "characters": 1140 + "characters": 1140, + "filename": "/etc/motd" } ] } From a556a966b0d4326bfede5d616bf0674898c522c9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 21 Aug 2015 14:40:58 -0400 Subject: [PATCH 514/514] add example and return code sections --- libxo/xo_emit.3 | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/libxo/xo_emit.3 b/libxo/xo_emit.3 index 8ff3c619..155ea75d 100644 --- a/libxo/xo_emit.3 +++ b/libxo/xo_emit.3 @@ -43,6 +43,60 @@ uses an explicit handle. accepts a .Fa va_list for additional flexibility. +.Sh EXAMPLES +In this example, a set of four values is emitted using the following +source code: +.Bd -literal -offset indent + xo_emit(" {:lines/%7ju} {:words/%7ju} " + "{:characters/%7ju} {d:filename/%s}\n", + linect, wordct, charct, file); +.Ed +Output can then be generated in various style, using +the "--libxo" option: +.Bd -literal -offset indent + % wc /etc/motd + 25 165 1140 /etc/motd + % wc --libxo xml,pretty,warn /etc/motd + + + 25 + 165 + 1140 + /etc/motd + + + % wc --libxo json,pretty,warn /etc/motd + { + "wc": { + "file": [ + { + "lines": 25, + "words": 165, + "characters": 1140, + "filename": "/etc/motd" + } + ] + } + } + % wc --libxo html,pretty,warn /etc/motd +
+
+
25
+
+
165
+
+
1140
+
+
/etc/motd
+
+.Ed +.Sh RETURN CODE +.Nm +returns a negative value on error. If the +.Nm XOF_COLUMNS +flag has been turned on for the specific handle using +.Xr xo_set_flags 3 , +then the number of display columns consumed by the output will be returned. .Sh SEE ALSO .Xr xo_open_container 3 , .Xr xo_open_list 3 ,