From 820abac6b15233ab8ed77223fdb984aa76f22584 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 15 Dec 2014 19:12:12 +0100 Subject: [PATCH 01/90] xo_error.3: mdoc cleanup. --- libxo/xo_error.3 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libxo/xo_error.3 b/libxo/xo_error.3 index da917859..01431cb0 100644 --- a/libxo/xo_error.3 +++ b/libxo/xo_error.3 @@ -28,12 +28,13 @@ The argument is a string containing printf-style formatting instructions that describe the remaining arguments. .Pp -When converting an application to libxo, one can replace +When converting an application to +.Nm libxo , +one can replace .Em "fprintf(stderr,...)" calls with .Fn xo_error calls. -.Pp .Sh ADDITIONAL DOCUMENTATION Complete documentation can be found on github: .Bd -literal -offset indent @@ -53,7 +54,7 @@ is available at: https://github.com/Juniper/libxo/releases .Ed .Sh SEE ALSO -.Xr printf 3 +.Xr printf 3 , .Xr xo_emit 3 .Sh HISTORY The From d2b3e47fd9cd1b52caa5ee584d4ae5cbc1bf5088 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 10:25:02 -0500 Subject: [PATCH 02/90] Add --enable-text-only flag --- configure.ac | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure.ac b/configure.ac index b2553b89..084186f8 100644 --- a/configure.ac +++ b/configure.ac @@ -133,6 +133,14 @@ AC_ARG_ENABLE([debug], AC_MSG_RESULT([$LIBXO_DEBUG]) AM_CONDITIONAL([LIBXO_DEBUG], [test "$LIBXO_DEBUG" != "no"]) +AC_MSG_CHECKING([whether to build with text-only rendering]) +AC_ARG_ENABLE([text-only], + [ --enable-text-only Turn on text-only rendering], + [LIBXO_TEXT_ONLY=yes; AC_DEFINE([LIBXO_TEXT_ONLY], [1], [Enable text-only rendering])], + [LIBXO_TEXT_ONLY=no]) +AC_MSG_RESULT([$LIBXO_TEXT_ONLY]) +AM_CONDITIONAL([LIBXO_TEXT_ONLY], [test "$LIBXO_TEXT_ONLY" != "no"]) + AC_CHECK_LIB([m], [lrint]) AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"]) @@ -262,4 +270,5 @@ AC_MSG_NOTICE([summary of build options: debug: ${LIBXO_DEBUG:-no} printf-like: ${HAVE_PRINTFLIKE:-no} libxo-options: ${LIBXO_OPTS:-no} + text-only: ${LIBXO_TEXT_ONLY:-no} ]) From 25203d7ca80e3cf281966e7794baab56c4f3ad1c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 10:25:28 -0500 Subject: [PATCH 03/90] turn xop->xo_style references into accessor xo_style() to enable text-only rendering --- libxo/libxo.c | 88 ++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index e9d05ce0..b2cd995b 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -276,6 +276,16 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, static void xo_anchor_clear (xo_handle_t *xop); +static inline unsigned short +xo_style (xo_handle_t *xop UNUSED) +{ +#ifdef LIBXO_TEXT_ONLY + return XO_STYLE_TEXT; +#else /* LIBXO_TEXT_ONLY */ + return xop->xo_style; +#endif /* LIBXO_TEXT_ONLY */ +} + /* * Callback to write data to a FILE pointer */ @@ -656,7 +666,7 @@ xo_buf_escape (xo_handle_t *xop, xo_buffer_t *xbp, memcpy(xbp->xb_curp, str, len); - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: case XO_STYLE_HTML: len = xo_escape_xml(xbp, len, (flags & XFF_ATTR)); @@ -1219,7 +1229,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) int need_nl = (fmt[strlen(fmt) - 1] != '\n'); - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: xbp = &xop->xo_data; if (xop->xo_flags & XOF_PRETTY) @@ -1457,7 +1467,7 @@ xo_style_t xo_get_style (xo_handle_t *xop) { xop = xo_default(xop); - return xop->xo_style; + return xo_style(xop); } static int @@ -1801,7 +1811,7 @@ xo_line_ensure_open (xo_handle_t *xop, xo_xff_flags_t flags UNUSED) if (xop->xo_flags & XOF_DIV_OPEN) return; - if (xop->xo_style != XO_STYLE_HTML) + if (xo_style(xop) != XO_STYLE_HTML) return; xop->xo_flags |= XOF_DIV_OPEN; @@ -1819,7 +1829,7 @@ xo_line_close (xo_handle_t *xop) { static char div_close[] = ""; - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_HTML: if (!(xop->xo_flags & XOF_DIV_OPEN)) xo_line_ensure_open(xop, 0); @@ -1976,7 +1986,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, if (width < 0) width = iswcntrl(wc) ? 0 : 1; - if (xop->xo_style == XO_STYLE_TEXT || xop->xo_style == XO_STYLE_HTML) { + if (xo_style(xop) == XO_STYLE_TEXT || xo_style(xop) == XO_STYLE_HTML) { if (max > 0 && cols + width > max) break; } @@ -1985,7 +1995,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, case XF_ENC_UTF8: /* Output in UTF-8 needs to be escaped, based on the style */ - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: case XO_STYLE_HTML: if (wc == '<') @@ -2071,7 +2081,7 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, wchar_t *wcp = NULL; int len, cols = 0, rc = 0; int off = xbp->xb_curp - xbp->xb_bufp, off2; - int need_enc = (xop->xo_style == XO_STYLE_TEXT) + int need_enc = (xo_style(xop) == XO_STYLE_TEXT) ? XF_ENC_LOCALE : XF_ENC_UTF8; if (xo_check_conversion(xop, xfp->xf_enc, need_enc)) @@ -2185,7 +2195,7 @@ static void xo_data_append_content (xo_handle_t *xop, const char *str, int len) { int cols; - int need_enc = (xop->xo_style == XO_STYLE_TEXT) + int need_enc = (xo_style(xop) == XO_STYLE_TEXT) ? XF_ENC_LOCALE : XF_ENC_UTF8; cols = xo_format_string_direct(xop, &xop->xo_data, XFF_UNESCAPE, @@ -2246,9 +2256,9 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, xo_format_t xf; const char *cp, *ep, *sp, *xp = NULL; int rc, cols; - int style = (flags & XFF_XML) ? XO_STYLE_XML : xop->xo_style; + int style = (flags & XFF_XML) ? XO_STYLE_XML : xo_style(xop); unsigned make_output = !(flags & XFF_NO_OUTPUT); - int need_enc = (xop->xo_style == XO_STYLE_TEXT) + int need_enc = (xo_style(xop) == XO_STYLE_TEXT) ? XF_ENC_LOCALE : XF_ENC_UTF8; if (xbp == NULL) @@ -2310,11 +2320,11 @@ 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 - && xop->xo_style != XO_STYLE_JSON) + && xo_style(xop) != XO_STYLE_JSON) xf.xf_skip = 1; } else if (xop->xo_flags & XFF_DISPLAY_ONLY) { if (style != XO_STYLE_TEXT - && xop->xo_style != XO_STYLE_HTML) + && xo_style(xop) != XO_STYLE_HTML) xf.xf_skip = 1; } @@ -2420,8 +2430,8 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, rc = xo_format_string(xop, xbp, flags, &xf); if ((flags & XFF_TRIM_WS) - && (xop->xo_style == XO_STYLE_XML - || xop->xo_style == XO_STYLE_JSON)) + && (xo_style(xop) == XO_STYLE_XML + || xo_style(xop) == XO_STYLE_JSON)) rc = xo_trim_ws(xbp, rc); } else { @@ -2753,7 +2763,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, static void xo_format_text (xo_handle_t *xop, const char *str, int len) { - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_TEXT: xo_buf_append_locale(xop, &xop->xo_data, str, len); break; @@ -2776,7 +2786,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, flen = 2; } - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: case XO_STYLE_JSON: /* @@ -2794,7 +2804,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, int rc; int need_enc = XF_ENC_LOCALE; - if (xop->xo_style == XO_STYLE_HTML) { + if (xo_style(xop) == XO_STYLE_HTML) { need_enc = XF_ENC_UTF8; xo_line_ensure_open(xop, 0); if (xop->xo_flags & XOF_PRETTY) @@ -2862,7 +2872,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, } /* If we're styling HTML, then we need to escape it */ - if (xop->xo_style == XO_STYLE_HTML) { + if (xo_style(xop) == XO_STYLE_HTML) { rc = xo_escape_xml(xbp, rc, 0); } @@ -2870,7 +2880,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, xbp->xb_curp += rc; move_along: - if (xop->xo_style == XO_STYLE_HTML) { + if (xo_style(xop) == XO_STYLE_HTML) { xo_data_append(xop, div_close, sizeof(div_close) - 1); if (xop->xo_flags & XOF_PRETTY) xo_data_append(xop, "\n", 1); @@ -2978,7 +2988,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, } } - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_TEXT: if (flags & XFF_ENCODE_ONLY) flags |= XFF_NO_OUTPUT; @@ -3142,7 +3152,7 @@ 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) { - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_TEXT: if (len) { xo_data_append_content(xop, str, len); @@ -3211,9 +3221,9 @@ xo_format_units (xo_handle_t *xop, const char *str, int len, int start = xop->xo_units_offset; int stop = xbp->xb_curp - xbp->xb_bufp; - if (xop->xo_style == XO_STYLE_XML) + if (xo_style(xop) == XO_STYLE_XML) xo_buf_append(xbp, units_start_xml, sizeof(units_start_xml) - 1); - else if (xop->xo_style == XO_STYLE_HTML) + else if (xo_style(xop) == XO_STYLE_HTML) xo_buf_append(xbp, units_start_html, sizeof(units_start_html) - 1); else return; @@ -3295,7 +3305,7 @@ static void xo_anchor_start (xo_handle_t *xop, const char *str, int len, const char *fmt, int flen) { - if (xop->xo_style != XO_STYLE_TEXT && xop->xo_style != XO_STYLE_HTML) + if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML) return; if (xop->xo_flags & XOF_ANCHOR) @@ -3317,7 +3327,7 @@ static void xo_anchor_stop (xo_handle_t *xop, const char *str, int len, const char *fmt, int flen) { - if (xop->xo_style != XO_STYLE_TEXT && xop->xo_style != XO_STYLE_HTML) + if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML) return; if (!(xop->xo_flags & XOF_ANCHOR)) { @@ -3726,7 +3736,7 @@ 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 (xop->xo_style != XO_STYLE_XML) + if (xo_style(xop) != XO_STYLE_XML) return 0; int nlen = strlen(name); @@ -3798,7 +3808,7 @@ static void xo_depth_change (xo_handle_t *xop, const char *name, int delta, int indent, xo_state_t state, xo_xsf_flags_t flags) { - if (xop->xo_style == XO_STYLE_HTML || xop->xo_style == XO_STYLE_TEXT) + if (xo_style(xop) == XO_STYLE_HTML || xo_style(xop) == XO_STYLE_TEXT) indent = 0; if (xop->xo_flags & XOF_DTRT) @@ -3898,7 +3908,7 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) flags |= xop->xo_flags; /* Pick up handle flags */ - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: rc = xo_printf(xop, "%*s<%s", xo_indent(xop), "", name); @@ -3992,7 +4002,7 @@ xo_do_close_container (xo_handle_t *xop, const char *name) } } - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: xo_depth_change(xop, name, -1, -1, XSS_CLOSE_CONTAINER, 0); rc = xo_printf(xop, "%*s%s", xo_indent(xop), "", name, ppn); @@ -4048,7 +4058,7 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) xop = xo_default(xop); - if (xop->xo_style == XO_STYLE_JSON) { + if (xo_style(xop) == XO_STYLE_JSON) { const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; const char *pre_nl = ""; @@ -4133,7 +4143,7 @@ xo_do_close_list (xo_handle_t *xop, const char *name) } } - if (xop->xo_style == XO_STYLE_JSON) { + if (xo_style(xop) == XO_STYLE_JSON) { if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; @@ -4182,7 +4192,7 @@ xo_do_open_leaf_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) xop = xo_default(xop); - if (xop->xo_style == XO_STYLE_JSON) { + if (xo_style(xop) == XO_STYLE_JSON) { const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; const char *pre_nl = ""; @@ -4238,7 +4248,7 @@ xo_do_close_leaf_list (xo_handle_t *xop, const char *name) } } - if (xop->xo_style == XO_STYLE_JSON) { + if (xo_style(xop) == XO_STYLE_JSON) { if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; @@ -4271,7 +4281,7 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) name = XO_FAILURE_NAME; } - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: rc = xo_printf(xop, "%*s<%s", xo_indent(xop), "", name); @@ -4357,7 +4367,7 @@ xo_do_close_instance (xo_handle_t *xop, const char *name) } } - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_XML: xo_depth_change(xop, name, -1, -1, XSS_CLOSE_INSTANCE, 0); rc = xo_printf(xop, "%*s%s", xo_indent(xop), "", name, ppn); @@ -4836,7 +4846,7 @@ xo_flush_h (xo_handle_t *xop) xop = xo_default(xop); - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_HTML: if (xop->xo_flags & XOF_DIV_OPEN) { xop->xo_flags &= ~XOF_DIV_OPEN; @@ -4871,7 +4881,7 @@ xo_finish_h (xo_handle_t *xop) if (!(xop->xo_flags & XOF_NO_CLOSE)) xo_do_close_all(xop, xop->xo_stack); - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_JSON: if (!(xop->xo_flags & XOF_NO_TOP)) { if (xop->xo_flags & XOF_TOP_EMITTED) @@ -4913,7 +4923,7 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) fmt = newfmt; } - switch (xop->xo_style) { + switch (xo_style(xop)) { case XO_STYLE_TEXT: vfprintf(stderr, fmt, vap); break; From 5b8af3193261cffa2902be54912ac65ee8acc49c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 10:25:47 -0500 Subject: [PATCH 04/90] Add --enable-text-only flag --- libxo/xoconfig.h.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libxo/xoconfig.h.in b/libxo/xoconfig.h.in index 467f5644..f981ad74 100644 --- a/libxo/xoconfig.h.in +++ b/libxo/xoconfig.h.in @@ -149,6 +149,9 @@ /* Enable debugging */ #undef LIBXO_DEBUG +/* Enable text-only rendering */ +#undef LIBXO_TEXT_ONLY + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR From 248970e5d539b67a05dc7126e275ca048025121e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 19:34:19 -0500 Subject: [PATCH 05/90] new man page --- libxo/xo_open_marker.3 | 118 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 libxo/xo_open_marker.3 diff --git a/libxo/xo_open_marker.3 b/libxo/xo_open_marker.3 new file mode 100644 index 00000000..73bd4456 --- /dev/null +++ b/libxo/xo_open_marker.3 @@ -0,0 +1,118 @@ +.\" # +.\" # 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, January 2015 +.\" +.Dd January 22, 2015 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_open_marker +.Nd prevent and allow closing of open constructs +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Sh NAME +.Nm xo_open_marker +.Nm xo_open_marker_h +.Nm xo_close_marker +.Nm xo_close_marker_h +.Nd open and close markers +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.Ft int +.Fn xo_open_marker "const char *name" +.Ft int +.Fn xo_open_marker_h "xo_handle_t *handle" "const char *name" +.Ft int +.Fn xo_close_marker "const char *name" +.Ft int +.Fn xo_close_marker_h "xo_handle_t *handle" "const char *name" +.Sh DESCRIPTION +.Nm libxo +represents hierarchy using two consstructs: +.Dq markers +and +.Dq lists . +A marker can be used to affect how open constructs are closed, either +by preventing their (implicit or explicit) closure or by forcing their +closure. +A marker is used to "freeze" any open constructs. Calls to +.Fn xo_close_* +functions that would normally close them will be ignored, effectively +blocking their closure. +However when +.Fn xo_close_marker +is called, any containers, lists, or leaf-lists open since the +matching +.Fn xo_open_marker +call will be close and the marker discarded. +The marker has no value and is not emitted in any form. +.Pp +To open a marker, call +.Fn xo_open_marker +or +.Fn xo_open_marker_h . +The former uses the default handle and +the latter accepts a specific handle. +.Pp +To close a level, use the +.Fn xo_close_marker +or +.Fn xo_close_marker_h +functions. +.Pp +Each open call must have a matching close call. +.Bd -literal -offset indent -compact + Example: + + xo_open_container("top"); + xo_open_marker("outer"); + xo_open_container("system"); + xo_emit("{:host-name/%s%s%s", hostname, + domainname ? "." : "", domainname ?: ""); + xo_close_container("top"); /* [1] */ + xo_close_marker("outer"); /* [2] */ + xo_close_container("top"); +.Ed +The +.Fn xo_close_container +call on line [1] will be ignored, since the open marker "outer" +will prevent close of any open constructs that precede it. +The +.Fn xo_close_marker +call on line [2] will close the "system" container, since it was +opened after the "outer" marker. +.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 139d69b6cb1dc864592546451475fbeefb51904e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 19:41:56 -0500 Subject: [PATCH 06/90] add xo_open_marker --- libxo/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index 3303e94e..a89f96c8 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -38,6 +38,7 @@ man_MANS = \ xo_no_setlocale.3 \ xo_open_container.3 \ xo_open_list.3 \ + xo_open_marker.3 \ xo_parse_args.3 \ xo_set_allocator.3 \ xo_set_flags.3 \ From b89cb3c18d0cca8fcbf4f53d8b5cd8fb88c64ed8 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 19:42:08 -0500 Subject: [PATCH 07/90] s/must/should/ s/to/two --- libxo/xo_open_container.3 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libxo/xo_open_container.3 b/libxo/xo_open_container.3 index 285f5a68..b327d33f 100644 --- a/libxo/xo_open_container.3 +++ b/libxo/xo_open_container.3 @@ -11,8 +11,8 @@ .Dt LIBXO 3 .Os .Sh NAME -.Nm xo_emit -.Nd emit formatted output based on format string and arguments +.Nm xo_open_container +.Nd open (and close) container constructs .Sh LIBRARY .Lb libxo .Sh SYNOPSIS @@ -48,7 +48,7 @@ .Fn xo_close_container_d "void" .Sh DESCRIPTION .Nm libxo -represents to types of hierarchy: +represents two types of hierarchy: .Dq containers and .Dq lists . @@ -72,7 +72,7 @@ or .Fn xo_close_container_h functions. .Pp -Each open call must have a matching close call. +Each open call should have a matching close call. If the .Dv XOF_WARN flag is set and the name given does not match the name of From 729fb1b609b04369e5def36c8ef494a0870fab03 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 22 Jan 2015 19:42:17 -0500 Subject: [PATCH 08/90] churn docs --- libxo/xo_open_marker.3 | 44 ++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/libxo/xo_open_marker.3 b/libxo/xo_open_marker.3 index 73bd4456..d7a858c8 100644 --- a/libxo/xo_open_marker.3 +++ b/libxo/xo_open_marker.3 @@ -36,14 +36,18 @@ .Fn xo_close_marker_h "xo_handle_t *handle" "const char *name" .Sh DESCRIPTION .Nm libxo -represents hierarchy using two consstructs: -.Dq markers +represents hierarchy using two constructs: +.Dq containers and .Dq lists . A marker can be used to affect how open constructs are closed, either by preventing their (implicit or explicit) closure or by forcing their closure. -A marker is used to "freeze" any open constructs. Calls to +While a marker is open, no other open constructs can be closed. +When a marker is closed, all constructs open since the marker was opened +will be closed. +A marker is used to "freeze" any open constructs. +Calls to .Fn xo_close_* functions that would normally close them will be ignored, effectively blocking their closure. @@ -53,6 +57,8 @@ is called, any containers, lists, or leaf-lists open since the matching .Fn xo_open_marker call will be close and the marker discarded. +Markers use names which are not user-visible, allowing the caller to +choose appropriate internal names. The marker has no value and is not emitted in any form. .Pp To open a marker, call @@ -62,13 +68,22 @@ or The former uses the default handle and the latter accepts a specific handle. .Pp -To close a level, use the +To close a marker, use the .Fn xo_close_marker or .Fn xo_close_marker_h functions. .Pp Each open call must have a matching close call. +.Pp +In this example, the +.Fn xo_close_container +call on line [1] will be ignored, since the open marker "outer" +will prevent close of any open constructs that precede it. +The +.Fn xo_close_marker +call on line [2] will close the "system" container, since it was +opened after the "outer" marker. .Bd -literal -offset indent -compact Example: @@ -81,14 +96,19 @@ Each open call must have a matching close call. xo_close_marker("outer"); /* [2] */ xo_close_container("top"); .Ed -The -.Fn xo_close_container -call on line [1] will be ignored, since the open marker "outer" -will prevent close of any open constructs that precede it. -The -.Fn xo_close_marker -call on line [2] will close the "system" container, since it was -opened after the "outer" marker. +.Pp +In this example, the code whiffles through a list of fish, calling a +function to emit details about each fish. The marker "fish-guts" is +used to ensure that any constructs opened by the function are closed +properly. +.Bd -literal -offset indent + for (i = 0; fish[i]; i++) { + xo_open_instance("fish"); + xo_open_marker("fish-guts"); + dump_fish_details(i); + xo_close_marker("fish-guts"); + } +.Ed .Sh ADDITIONAL DOCUMENTATION Complete documentation can be found on github: .Bd -literal -offset indent From ad2618e10c7dc65b2b63f26a16e509cb98e545f3 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Feb 2015 16:10:20 -0500 Subject: [PATCH 09/90] Fix for issue #24; ship man pages --- libxo/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index a89f96c8..e2a7243b 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -47,4 +47,5 @@ man_MANS = \ xo_set_style.3 \ xo_set_writer.3 -EXTRA_DIST = +EXTRA_DIST = ${man_MANS} + From 87173db83582c4f34256b0fa7d2ee798cf6ccf27 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Feb 2015 16:11:17 -0500 Subject: [PATCH 10/90] Add some Sinhalese test cases; don't really work, but one day when I understand i18n more, this will help. --- tests/core/test_05.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/core/test_05.c b/tests/core/test_05.c index 61241b82..a883a888 100644 --- a/tests/core/test_05.c +++ b/tests/core/test_05.c @@ -39,23 +39,38 @@ main (int argc, char **argv) { "Ashley", "Ash", "Meter & Smith", 1440, 40 }, { "0123456789", "0123456789", "012345678901234567890", 1440, 40 }, { "ახლა", "გაიარო", "საერთაშორისო", 123, 90 }, + { "෴ණ්ණ෴෴ණ්ණ෴", "Mick", + "෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴", 110, 20 }, { NULL, NULL } }, *ep = employees; + int rc; argc = xo_parse_args(argc, argv); if (argc < 0) return 1; xo_set_info(NULL, info, info_count); + xo_set_flags(NULL, XOF_COLUMNS); xo_open_container("employees"); xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); - xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n", + rc = xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n", "ახლავე გაიაროთ რეგისტრაცია", "Unicode-ის მეათე საერთაშორისო"); + xo_emit("{Twc:Width}{:width/%d}\n", rc); + + /* Okay, Sinhala is uber cool ... */ + rc = xo_emit("[{:sinhala}]\n", "෴ණ්ණ෴"); + xo_emit("{Twc:Width}{:width/%d}\n", rc); + rc = xo_emit("[{:sinhala}]\n", "෴"); + xo_emit("{Twc:Width}{:width/%d}\n", rc); + rc = xo_emit("[{:sinhala/%-4..4s/%s}]\n", "෴ණ්ණ෴෴ණ්ණ෴"); + xo_emit("[{:not-sinhala/%-4..4s/%s}]\n", "123456"); + rc = xo_emit("[{:tag/%s}]\n", "ර්‍ඝ"); + xo_emit("{Twc:Width}{:width/%d}\n", rc); xo_open_list("employee"); From e5b100115ed49f2e82dcec13f59396ab3d8235e7 Mon Sep 17 00:00:00 2001 From: olevole Date: Mon, 2 Mar 2015 18:13:55 +0300 Subject: [PATCH 11/90] man xo(1): escaping for \n characters --- xo/xo.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xo/xo.1 b/xo/xo.1 index 12fc9594..9dcae85f 100644 --- a/xo/xo.1 +++ b/xo/xo.1 @@ -74,7 +74,7 @@ utility accepts a format string suitable for .Xr xo_emit 3 and a set of zero or more arguments used to supply data for that string. .Bd -literal -offset indent - xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6 + xo "The {k:name} weighs {:weight/%d} pounds.\\n" fish 6 TEXT: The fish weighs 6 pounds. From 4b6929802382f2a9b5736e6c521e9fd6784fc1a2 Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Sat, 7 Mar 2015 15:29:07 -0500 Subject: [PATCH 12/90] Update xo_format.5 fix incorrect example output, JSON output will contain the value 65, not 6 --- libxo/xo_format.5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index b021b98f..57c9da5b 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -74,7 +74,7 @@ function as an unsigned integer. .Ed .Pp This single line of code can generate text ("In stock: 65\\n"), XML -("65"), JSON ('"in-stock": 6'), or HTML (too +("65"), JSON ('"in-stock": 65'), or HTML (too lengthy to be listed here). .Ss Modifier Roles Modifiers are optional, and indicate the role and formatting of the From 1e97fb6128eef1553a343202794bd0f473efbb61 Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Sat, 7 Mar 2015 15:36:50 -0500 Subject: [PATCH 13/90] encoding modify documentation is incorrect the encoding modify text is wrong, is copy/pasted from the display modifier, and actually does the opposite of what it says, --- libxo/xo_format.5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index b021b98f..2cfaf501 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -269,8 +269,8 @@ the display output styles, TEXT and HTML. The display modifier is the opposite of the encoding modifier, and they are often used to give to distinct views of the underlying data. .Ss The Encoding Modifier ({e:}) -The display modifier indicated the field should only be generated for -the display output styles, TEXT and HTML. +The encoding modifier indicated the field should only be generated for +the encoding output styles, such as JSON and XML. .Bd -literal -offset indent EXAMPLE: xo_emit("{Lcw:Name}{:name} {e:id/%d}\\n", "phil", 1); From 56087df2e93e42d86940ee769199c2f225a786ee Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 17 Mar 2015 16:50:34 -0400 Subject: [PATCH 14/90] add uninstall hook for xolint --- xolint/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xolint/Makefile.am b/xolint/Makefile.am index a847e72c..ec5c36d8 100644 --- a/xolint/Makefile.am +++ b/xolint/Makefile.am @@ -12,3 +12,6 @@ EXTRA_DIST = xolint.1 xolint.pl install-exec-hook: install ${srcdir}/xolint.pl ${DESTDIR}${bindir}/xolint + +uninstall-hook: + rm -f ${DESTDIR}${bindir}/xolint From f07ba5f5b2062551f3b7f535f2c9304da51c2cb1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Tue, 17 Mar 2015 17:25:16 -0400 Subject: [PATCH 15/90] flag xo_err{,x,c} with __dead2/NORETURN --- libxo/xo.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libxo/xo.h b/libxo/xo.h index 82b965a2..a715b996 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -17,6 +17,14 @@ #ifndef INCLUDE_XO_H #define INCLUDE_XO_H +#include + +#ifdef __dead2 +#define NORETURN __dead2 +#else +#define NORETURN +#endif /* __dead2 */ + /** Formatting types */ typedef unsigned xo_style_t; #define XO_STYLE_TEXT 0 /** Generate text output */ @@ -272,13 +280,13 @@ void xo_warnx (const char *fmt, ...); void -xo_err (int eval, const char *fmt, ...); +xo_err (int eval, const char *fmt, ...) NORETURN; void -xo_errx (int eval, const char *fmt, ...); +xo_errx (int eval, const char *fmt, ...) NORETURN; void -xo_errc (int eval, int code, const char *fmt, ...); +xo_errc (int eval, int code, const char *fmt, ...) NORETURN; void xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap); From 598345c96e340b53443ae7a57260fd4c75aa4bc5 Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Thu, 19 Mar 2015 02:26:49 -0400 Subject: [PATCH 16/90] Fix pretty printing of leaf nodes in a list --- libxo/libxo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index e9d05ce0..ce2badaa 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -3103,7 +3103,9 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, } if (flags & XFF_LEAF_LIST) { - if (first && pretty) + if (!first && pretty) + xo_data_append(xop, "\n", 1); + if (pretty) xo_buf_indent(xop, -1); } else { if (pretty) @@ -3122,10 +3124,10 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen, xbp->xb_bufp[off] = '_'; } xo_data_append(xop, "\":", 2); + if (pretty) + xo_data_append(xop, " ", 1); } - if (pretty) - xo_data_append(xop, " ", 1); if (quote) xo_data_append(xop, "\"", 1); From 8a079833ea7d58dbd22de053f5b586cab6069101 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:21 -0400 Subject: [PATCH 17/90] Add doc for leaf flag --- libxo/xo_format.5 | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index 77210fa8..92fa4498 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -230,6 +230,7 @@ content emitted for some output styles: .It d "display " "Only emit field for display styles (text/HTML)" .It e "encoding " "Only emit for encoding styles (XML/JSON)" .It k "key " "Field is a key, suitable for XPath predicates" +.It l "leaf " "Field is a leaf-list, a list of leaf values" .It n "no-quotes " "Do not quote the field when using JSON style" .It q "quotes " "Quote the field when using JSON style" .It w "white space " "A blank ("" "") is appended after the label" From feaa83e4fcf9014dcfb27eecf0849193afb5ca3a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:25 -0400 Subject: [PATCH 18/90] update tests --- 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 b75d7288..136b9560 100644 --- a/tests/core/saved/test_05.H.out +++ b/tests/core/saved/test_05.H.out @@ -1 +1 @@ -
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
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
\ No newline at end of file +
Οὐχὶ ταὐτὰ παρίσταταί μοι
γιγνώσκειν
,
ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ
ახლავე გაიაროთ რეგისტრაცია
Unicode-ის მეათე საერთაშორისო
Width
:
63
[
෴ණ්ණ෴
]
Width
:
7
[
]
Width
:
3
[
෴ණ්ණ
]
[
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 b23372efa895f18ac8139b58fad2ccea7c3d0099 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:26 -0400 Subject: [PATCH 19/90] update tests --- tests/core/saved/test_05.HIPx.out | 59 +++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/core/saved/test_05.HIPx.out b/tests/core/saved/test_05.HIPx.out index 2054de13..105f8482 100644 --- a/tests/core/saved/test_05.HIPx.out +++ b/tests/core/saved/test_05.HIPx.out @@ -10,6 +10,55 @@
Unicode-ის მეათე საერთაშორისო
+
+
Width
+
:
+
+
63
+
+
+
[
+
෴ණ්ණ෴
+
]
+
+
+
Width
+
:
+
+
7
+
+
+
[
+
+
]
+
+
+
Width
+
:
+
+
3
+
+
+
[
+
෴ණ්ණ
+
]
+
+
+
[
+
1234
+
]
+
+
+
[
+
ර්‍ඝ
+
]
+
+
+
Width
+
:
+
+
5
+
First Name
Last Name
@@ -75,3 +124,13 @@
123
90
+
+
෴ණ්ණ෴෴ණ්ණ෴
+
(
+
"Mick"
+
)
+
+
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
+
110
+
20
+
From d8af0d0f794e54d9d24fd9383e10a0b586a190f6 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:27 -0400 Subject: [PATCH 20/90] update tests --- tests/core/saved/test_05.HP.out | 59 +++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/core/saved/test_05.HP.out b/tests/core/saved/test_05.HP.out index 1c34b950..e66cf2b5 100644 --- a/tests/core/saved/test_05.HP.out +++ b/tests/core/saved/test_05.HP.out @@ -10,6 +10,55 @@
Unicode-ის მეათე საერთაშორისო
+
+
Width
+
:
+
+
63
+
+
+
[
+
෴ණ්ණ෴
+
]
+
+
+
Width
+
:
+
+
7
+
+
+
[
+
+
]
+
+
+
Width
+
:
+
+
3
+
+
+
[
+
෴ණ්ණ
+
]
+
+
+
[
+
1234
+
]
+
+
+
[
+
ර්‍ඝ
+
]
+
+
+
Width
+
:
+
+
5
+
First Name
Last Name
@@ -75,3 +124,13 @@
123
90
+
+
෴ණ්ණ෴෴ණ්ණ෴
+
(
+
"Mick"
+
)
+
+
෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ
+
110
+
20
+
From 61b6619c9264152e27dc0e2508b5b8d2e7ff6596 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:28 -0400 Subject: [PATCH 21/90] update tests --- 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 51554895..25d13ea0 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-ის მეათე საერთაშორისო", "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\" Date: Thu, 19 Mar 2015 17:08:28 -0400 Subject: [PATCH 22/90] update tests --- tests/core/saved/test_05.JP.out | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/core/saved/test_05.JP.out b/tests/core/saved/test_05.JP.out index 7d77d70c..c3219172 100644 --- a/tests/core/saved/test_05.JP.out +++ b/tests/core/saved/test_05.JP.out @@ -4,6 +4,15 @@ "v2": "ὦ ἄνδρες ᾿Αθηναῖοι", "v1": "ახლავე გაიაროთ რეგისტრაცია", "v2": "Unicode-ის მეათე საერთაშორისო", + "width": 55, + "sinhala": "෴ණ්ණ෴", + "width": 5, + "sinhala": "෴", + "width": 1, + "sinhala": "෴ණ්ණ෴෴ණ්ණ෴", + "not-sinhala": "123456", + "tag": "ර්‍ඝ", + "width": 3, "employee": [ { "first-name": "Jim", @@ -50,6 +59,13 @@ "department": 123, "percent-time": 90, "benefits": "full" + }, + { + "first-name": "෴ණ්ණ෴෴ණ්ණ෴", + "nic-name": "\"Mick\"", + "last-name": "෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴", + "department": 110, + "percent-time": 20 } ] } From 27f4ada66cb86efa62cc30ce2ec56b7042907dd0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:29 -0400 Subject: [PATCH 23/90] update tests --- tests/core/saved/test_05.T.out | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/core/saved/test_05.T.out b/tests/core/saved/test_05.T.out index c709f6cb..db713a6b 100644 --- a/tests/core/saved/test_05.T.out +++ b/tests/core/saved/test_05.T.out @@ -1,5 +1,14 @@ Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო +Width: 63 +[෴ණ්ණ෴] +Width: 7 +[෴] +Width: 3 +[෴ණ්ණ] +[1234] +[ර්‍ඝ] +Width: 5 First Name Last Name Department Time (%) Jim ("რეგტ") გთხოვთ ახ 431 90 Terry (" Date: Thu, 19 Mar 2015 17:08:30 -0400 Subject: [PATCH 24/90] update tests --- 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 85ecbbcf..7cd29260 100644 --- a/tests/core/saved/test_05.X.out +++ b/tests/core/saved/test_05.X.out @@ -1 +1 @@ -γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისოJim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full \ No newline at end of file +γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοιახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო55෴ණ්ණ෴51෴ණ්ණ෴෴ණ්ණ෴123456ර්‍ඝ3Jim"რეგტ"გთხოვთ ახ43190fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones66090fullLeslie"Les"Patterson34160fullAshley"Ash"Meter & Smith1440400123456789"0123456789"012345678901234567890144040ახლა"გაიარო"საერთაშორისო12390full෴ණ්ණ෴෴ණ්ණ෴"Mick"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴11020 \ No newline at end of file From 85fc03e6736895e98d51b56c5e566fe6d3ddd969 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:08:31 -0400 Subject: [PATCH 25/90] update tests --- tests/core/saved/test_05.XP.out | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/core/saved/test_05.XP.out b/tests/core/saved/test_05.XP.out index 55507eb4..6ef573f3 100644 --- a/tests/core/saved/test_05.XP.out +++ b/tests/core/saved/test_05.XP.out @@ -3,6 +3,15 @@ ὦ ἄνδρες ᾿Αθηναῖοι ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო + 55 + ෴ණ්ණ෴ + 5 + + 1 + ෴ණ්ණ෴෴ණ්ණ෴ + 123456 + ර්‍ඝ + 3 Jim "რეგტ" @@ -49,4 +58,11 @@ 90 full + + ෴ණ්ණ෴෴ණ්ණ෴ + "Mick" + ෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴ + 110 + 20 + From 20e8675e8582a8de4a214b6c228dc669b906423b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:09:42 -0400 Subject: [PATCH 26/90] update tests --- tests/core/saved/test_01.JP.out | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_01.JP.out b/tests/core/saved/test_01.JP.out index e1fd2318..47900652 100644 --- a/tests/core/saved/test_01.JP.out +++ b/tests/core/saved/test_01.JP.out @@ -91,7 +91,11 @@ }, "data": { "item": [ - "gum", "rope", "ladder", "bolt", "water" + "gum", + "rope", + "ladder", + "bolt", + "water" ] }, "cost": 425, From ec2ec69c97b32f310b84c1c5cc1a781c2d0a2347 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:09:43 -0400 Subject: [PATCH 27/90] update tests --- tests/core/saved/test_02.JP.out | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/saved/test_02.JP.out b/tests/core/saved/test_02.JP.out index 21b168bd..ade2dc22 100644 --- a/tests/core/saved/test_02.JP.out +++ b/tests/core/saved/test_02.JP.out @@ -26,7 +26,9 @@ "cur": 20, "max": 125, "flag": [ - "one", "two", "three" + "one", + "two", + "three" ], "empty-tag": true, "t1": "1000", From de14d5f1b3c9273d54300d9d9ba15c83fa544398 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Thu, 19 Mar 2015 17:09:44 -0400 Subject: [PATCH 28/90] update tests --- tests/core/saved/test_09.JP.out | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/core/saved/test_09.JP.out b/tests/core/saved/test_09.JP.out index 8340b275..48e20c14 100644 --- a/tests/core/saved/test_09.JP.out +++ b/tests/core/saved/test_09.JP.out @@ -3,22 +3,34 @@ "data": { "contents": { "name": [ - "gum", "rope", "ladder", "bolt", "water" + "gum", + "rope", + "ladder", + "bolt", + "water" ] }, "contents": { "item": [ - "gum", "rope", "ladder", "bolt", "water" + "gum", + "rope", + "ladder", + "bolt", + "water" ] }, "contents": { "item": [ - "gum", "rope", "ladder", "bolt", "water" + "gum", + "rope", + "ladder", + "bolt", + "water" ], "total": "six", "one": "one", "two": [ - "two" + "two" ], "three": "three" } From d66b6106c2ddc0be1fee96bcd6e4e70341275307 Mon Sep 17 00:00:00 2001 From: Alexey Shamrin Date: Sun, 5 Apr 2015 01:39:58 +0300 Subject: [PATCH 29/90] doc: fix html output example (forgotten quotes) --- doc/libxo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index 31aec533..2b396b47 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -228,17 +228,17 @@ data, including data type, description, and an XPath location.
36
-
./src
+
./src
40
-
./bin
+
./bin
90
-
./
+
./
** Format Strings @format-strings@ From cd619580176367d2b4a5c259e25ef1b55912feb2 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Fri, 17 Apr 2015 13:24:08 -0400 Subject: [PATCH 30/90] missing quote --- doc/libxo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index 2b396b47..227b1ea6 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -134,7 +134,7 @@ A single libxo function call in source code is all that's required: my-box example.com JSON: - "host": my-box", + "host": "my-box", "domain": "example.com" For brevity, the HTML output is emitted. From ce76e8f60dcf18c59dd2f8a95c178f63602df39b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:15 -0400 Subject: [PATCH 31/90] checkpoint color work; still needs html support --- doc/libxo.txt | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/doc/libxo.txt b/doc/libxo.txt index 227b1ea6..a85e78d9 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -285,6 +285,7 @@ content. The roles are listed below; only one role is permitted: |---+--------------+-------------------------------------------------| | M | Name | Description | |---+--------------+-------------------------------------------------| +| C | color/effect | Field has color and effect controls | | D | decoration | Field is non-text (e.g., colon, comma) | | E | error | Field is an error message | | L | label | Field is text that prefixes a value | @@ -298,6 +299,57 @@ content. The roles are listed below; only one role is permitted: | ] | stop anchor | End a section of anchored variable-width text | |---+--------------+-------------------------------------------------| +**** The Color Role ({C:}) + +Colors and effects control how text values are displayed; they are +used for display styles (TEXT and HTML). The color content can be +either static, when placed directly within the field descriptor, or a +printf-style format descriptor can be used, if preceded by a slash ("/"): + + EXAMPLES: + xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost); + xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n", + fg_color, bg_color, cost); + +The content should be a comma-separated list of zero or more colors or +display effects. These colors and effects remain in affect until +modified by other "C" roles. If the content is empty, the "reset" +action is performed. + +|---------------+-------------------------------------------------| +| Name | Description | +|---------------+-------------------------------------------------| +| bg-XXXXX | Change background color | +| bold | Start bold text effect | +| fg-XXXXX | Change foreground color | +| inverse | Start inverse (aka reverse) text effect | +| no-bold | Stop bold text effect | +| no-inverse | Stop inverse (aka reverse) text effect | +| no-underline | Stop underline text effect | +| normal | Reset effects (only) | +| reset | Reset colors and effects (restore defaults) | +| underline | Start underline text effect | +|---------------+-------------------------------------------------| + +The following color names are supported: + +|---------------| +| Name | +|---------------| +| black | +| blue | +| cyan | +| default | +| green | +| magenta | +| red | +| white | +| yellow | +|---------------| + +Color names are prefixed with either "fg-" or "bg-" to change the +foreground and background colors, respectively. + **** The Decoration Role ({D:}) Decorations are typically punctuation marks such as colons, From 38eece3c02097ab5f4c6afbb08ce7ebafe73be56 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:18 -0400 Subject: [PATCH 32/90] checkpoint color work; still needs html support --- libxo/libxo.c | 401 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 394 insertions(+), 7 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 9226e8c0..bd1256e9 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -121,6 +121,54 @@ typedef struct xo_stack_s { char *xs_keys; /* XPath predicate for any key fields */ } xo_stack_t; +/* "colors" refers to fancy ansi codes */ +#define XO_COL_BLACK 0 +#define XO_COL_RED 1 +#define XO_COL_GREEN 2 +#define XO_COL_YELLOW 3 +#define XO_COL_BLUE 4 +#define XO_COL_MAGENTA 5 +#define XO_COL_CYAN 6 +#define XO_COL_WHITE 7 +#define XO_COL_DEFAULT 8 + +#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 + * director who adds "Would you like us to burst into show tunes?" on + * the list of questions asking while making funeral arrangements. + * It's formalizing wrongness in the wrong way. And we're just too + * civilized to do that. Hhhmph! + */ +#define XO_EFF_RESET (1<<0) +#define XO_EFF_NORMAL (1<<1) +#define XO_EFF_FOREGROUND (1<<2) /* "Special" effects bit: fg color */ +#define XO_EFF_BACKGROUND (1<<3) /* "Special" effects bit: bg color */ +#define XO_EFF_BOLD (1<<4) +#define XO_EFF_UNDERLINE (1<<5) +#define XO_EFF_INVERSE (1<<6) + +#define XO_EFF_CLEAR_BITS \ + (XO_EFF_RESET | XO_EFF_NORMAL | XO_EFF_FOREGROUND | XO_EFF_BACKGROUND) + +typedef uint8_t xo_effect_t; +typedef uint8_t xo_color_t; +typedef struct xo_colors_s { + xo_effect_t xoc_eff_on; /* Bits to turn on */ + xo_effect_t xoc_eff_off; /* Bits to turn off */ + xo_color_t xoc_col_fg; /* Foreground color */ + xo_color_t xoc_col_bg; /* Background color */ +} xo_colors_t; + /* * xo_handle_t: this is the principle data structure for libxo. * It's used as a store for state, options, and content. @@ -136,7 +184,6 @@ struct xo_handle_s { xo_formatter_t xo_formatter; /* Custom formating function */ xo_checkpointer_t xo_checkpointer; /* Custom formating support function */ void *xo_opaque; /* Opaque data for write function */ - FILE *xo_fp; /* XXX File pointer */ xo_buffer_t xo_data; /* Output data */ xo_buffer_t xo_fmt; /* Work area for building format strings */ xo_buffer_t xo_attrs; /* Work area for building XML attributes */ @@ -154,6 +201,9 @@ struct xo_handle_s { int xo_anchor_min_width; /* Desired width of anchored text */ unsigned xo_units_offset; /* Start of units insertion point */ unsigned xo_columns; /* Columns emitted during this xo_emit call */ + uint8_t xo_color_map_fg[XO_NUM_COLORS]; /* Foreground color mappings */ + uint8_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */ + xo_colors_t xo_colors; /* Current color and effect values */ }; /* Flags for formatting functions */ @@ -161,7 +211,7 @@ typedef unsigned long xo_xff_flags_t; #define XFF_COLON (1<<0) /* Append a ":" */ #define XFF_COMMA (1<<1) /* Append a "," iff there's more output */ #define XFF_WS (1<<2) /* Append a blank */ -#define XFF_ENCODE_ONLY (1<<3) /* Only emit for encoding formats (xml and json) */ +#define XFF_ENCODE_ONLY (1<<3) /* Only emit for encoding formats (xml, json) */ #define XFF_QUOTE (1<<4) /* Force quotes */ #define XFF_NOQUOTE (1<<5) /* Force no quotes */ @@ -276,6 +326,14 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, static void xo_anchor_clear (xo_handle_t *xop); +/* + * xo_style is used to retrieve the current style. When we're built + * for "text only" mode, we use this function to drive the removal + * of most of the code in libxo. We return a constant and the compiler + * happily removes the non-text code that is not longer executed. This + * trims our code nicely without needing to trampel perfectly readable + * code with ifdefs. + */ static inline unsigned short xo_style (xo_handle_t *xop UNUSED) { @@ -373,8 +431,8 @@ xo_no_setlocale (void) /* * We need to decide if stdout is line buffered (_IOLBF). Lacking a * standard way to decide this (e.g. getlinebuf()), we have configure - * look to find __flbf, which glibc supported. If not, we'll rely - * on isatty, with the assumption that terminals are the only thing + * look to find __flbf, which glibc supported. If not, we'll rely on + * isatty, with the assumption that terminals are the only thing * that's line buffered. We _could_ test for "steam._flags & _IOLBF", * which is all __flbf does, but that's even tackier. Like a * bedazzled Elvis outfit on an ugly lap dog sort of tacky. Not @@ -408,6 +466,13 @@ xo_init_handle (xo_handle_t *xop) if (xo_is_line_buffered(stdout)) xop->xo_flags |= XOF_FLUSH_LINE; + /* + * We only want to do color output on terminals, but we only want + * to do this if the user has asked for color. + */ + if ((xop->xo_flags & XOF_COLOR_ALLOWED) && isatty(1)) + xop->xo_flags |= XOF_COLOR; + /* * We need to initialize the locale, which isn't really pretty. * Libraries should depend on their caller to set up the @@ -507,7 +572,7 @@ xo_default (xo_handle_t *xop) /* * Return the number of spaces we should be indenting. If - * we are pretty-printing, theis is indent * indent_by. + * we are pretty-printing, this is indent * indent_by. */ static int xo_indent (xo_handle_t *xop) @@ -1502,6 +1567,8 @@ xo_name_to_flag (const char *name) return XOF_INFO; if (strcmp(name, "warn-xml") == 0) return XOF_WARN_XML; + if (strcmp(name, "color") == 0) + return XOF_COLOR_ALLOWED; if (strcmp(name, "columns") == 0) return XOF_COLUMNS; if (strcmp(name, "dtrt") == 0) @@ -1557,6 +1624,11 @@ xo_set_options (xo_handle_t *xop, const char *input) xop = xo_default(xop); +#ifdef LIBXO_COLOR_ON_BY_DEFAULT + /* If the installer used --enable-color-on-by-default, then we allow it */ + xop->xo_flags |= XOF_COLOR_ALLOWED; +#endif /* LIBXO_COLOR_ON_BY_DEFAULT */ + /* * We support a simpler, old-school style of giving option * also, using a single character for each option. It's @@ -1567,6 +1639,10 @@ xo_set_options (xo_handle_t *xop, const char *input) for (input++ ; *input; input++) { switch (*input) { + case 'c': + xop->xo_flags |= XOF_COLOR_ALLOWED; + break; + case 'f': xop->xo_flags |= XOF_FLUSH; break; @@ -1644,6 +1720,11 @@ xo_set_options (xo_handle_t *xop, const char *input) if (vp) *vp++ = '\0'; + if (strcmp("colors", cp) == 0) { + /* XXX Look for colors=red-blue+green-yellow */ + continue; + } + new_style = xo_name_to_style(cp); if (new_style >= 0) { if (style >= 0) @@ -1655,7 +1736,9 @@ xo_set_options (xo_handle_t *xop, const char *input) if (new_flag != 0) xop->xo_flags |= new_flag; else { - if (strcmp(cp, "indent") == 0) { + if (strcmp(cp, "no-color") == 0) { + xop->xo_flags &= ~XOF_COLOR_ALLOWED; + } else if (strcmp(cp, "indent") == 0) { xop->xo_indent_by = atoi(vp); } else { xo_warnx("unknown option: '%s'", cp); @@ -3207,6 +3290,307 @@ xo_format_content (xo_handle_t *xop, const char *class_name, } } +static const char *xo_color_names[] = { + "black", /* XO_COL_BLACK */ + "red", /* XO_CLOR_RED */ + "green", /* XO_COL_GREEN */ + "yellow", /* XO_COL_YELLOW */ + "blue", /* XO_COL_BLUE */ + "magenta", /* XO_COL_MAGENTA */ + "cyan", /* XO_COL_CYAN */ + "white", /* XO_COL_WHITE */ + "custom-color", /* nonsense; space savere */ + "default", /* XO_COL_DEFAULT */ + NULL +}; + +static int +xo_color_find (const char *str) +{ + int i; + + for (i = 0; xo_color_names[i]; i++) { + if (strcmp(xo_color_names[i], str) == 0) + return i; + } + + return -1; +} + +static const char *xo_effect_names[] = { + "reset", /* XO_EFF_RESET */ + "normal", /* XO_EFF_NORMAL */ + "fg-", /* XO_EFF_FOREGROUND */ + "bg-", /* XO_EFF_BACKGROUND */ + "bold", /* XO_EFF_BOLD */ + "underline", /* XO_EFF_UNDERLINE */ + "inverse", /* XO_EFF_INVERSE */ + NULL +}; + +static const char *xo_effect_on_codes[] = { + "0", /* XO_EFF_RESET */ + "0", /* XO_EFF_NORMAL */ + "3", /* 30-37 */ /* XO_EFF_FOREGROUND */ + "4", /* 40-47 */ /* XO_EFF_BACKGROUND */ + "1", /* XO_EFF_BOLD */ + "4", /* XO_EFF_UNDERLINE */ + "7", /* XO_EFF_INVERSE */ + NULL +}; + +#if 0 +static const char *xo_effect_off_codes[] = { + "0", /* XO_EFF_RESET */ + "0", /* XO_EFF_NORMAL */ + "39", /* XO_EFF_FOREGROUND */ + "49", /* XO_EFF_BACKGROUND */ + "21", /* XO_EFF_BOLD */ + "24", /* XO_EFF_UNDERLINE */ + "27", /* XO_EFF_INVERSE */ + NULL +}; +#endif + +static int +xo_effect_find (const char *str) +{ + int i; + + for (i = 0; xo_effect_names[i]; i++) { + if (strcmp(xo_effect_names[i], str) == 0) + return i; + } + + return -1; +} + +static void +xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp UNUSED, char *str) +{ +#ifdef LIBXO_TEXT_ONLY + return; +#endif /* LIBXO_TEXT_ONLY */ + + char *cp, *ep, *np; + int len = strlen(str); + int rc; + + /* + * Possible tokens: colors, bg-colors, effects, no-effects, "reset". + */ + for (cp = str, ep = cp + len - 1; cp && cp < ep; cp = np) { + np = strchr(cp, ','); + if (np) + *np++ = '\0'; + + if (cp[0] == 'f' && cp[1] == 'g' && cp[2] == '-') { + rc = xo_color_find(cp + 3); + if (rc < 0) + goto unknown; + xocp->xoc_col_fg = rc; + xocp->xoc_eff_on |= XO_EFF_FOREGROUND; + + } else if (cp[0] == 'b' && cp[1] == 'g' && cp[2] == '-') { + rc = xo_color_find(cp + 3); + if (rc < 0) + goto unknown; + xocp->xoc_col_bg = rc; + xocp->xoc_eff_on |= XO_EFF_BACKGROUND; + + } else if (cp[0] == 'n' && cp[1] == 'o' && cp[2] == '-') { + rc = xo_effect_find(cp + 3); + if (rc < 0) + goto unknown; + xocp->xoc_eff_off |= 1 << rc; + + } else { + rc = xo_effect_find(cp); + if (rc < 0) + goto unknown; + xocp->xoc_eff_on |= 1 << rc; + + switch (1 << rc) { + case XO_EFF_RESET: + xocp->xoc_col_fg = xocp->xoc_col_bg = 0; + xocp->xoc_eff_on = xocp->xoc_eff_off = 0; + break; + + case XO_EFF_NORMAL: + xocp->xoc_eff_on &= ~(XO_EFF_BOLD | XO_EFF_UNDERLINE + | XO_EFF_INVERSE); + break; + } + } + continue; + + unknown: + if (xop->xo_flags & XOF_WARN) + xo_failure(xop, "color/effect string detected: '%s'", cp); + } +} + +static inline int +xo_colors_isset (xo_colors_t *xocp) +{ +#ifdef LIBXO_TEXT_ONLY + return 0; +#else /* LIBXO_TEXT_ONLY */ + return ((xocp->xoc_eff_on || xocp->xoc_eff_off + || xocp->xoc_col_fg || xocp->xoc_col_bg) ? 1 : 0); +#endif /* LIBXO_TEXT_ONLY */ +} + +static void +xo_colors_emit_text (xo_handle_t *xop UNUSED, xo_colors_t *xocp) +{ + char buf[BUFSIZ]; + char *cp = buf, *ep = buf + sizeof(buf); + unsigned i, bit; + + /* + * Start the buffer with an escape. We don't want to add the '[' + * now, since we let xo_effect_text_add unconditionally add the ';'. + * We'll replace the first ';' with a '[' when we're done. + */ + *cp++ = 0x1b; /* Escape */ + + /* + * Terminals were designed back in the age before "certainty" was + * invented, when standards were more what you'd call "guidelines" + * than actual rules. Anyway we can't depend on them to operate + * correctly. So when display attributes are changed, we punt, + * reseting them all and turning back on the ones we want to keep. + * Longer, but should be completely reliable. Savvy? + */ + if (xocp->xoc_eff_off) { + xo_effect_t val = xocp->xoc_eff_off; + val &= ~(XO_EFF_BACKGROUND | XO_EFF_FOREGROUND); /* Should not occur */ + val = ~val & xocp->xoc_eff_on; /* Only turn off what was on*/ + val |= XO_EFF_RESET; /* Add the reset */ + xocp->xoc_eff_on = val; + xocp->xoc_eff_off = 0; + xop->xo_colors.xoc_eff_on = 0; /* Reset previous settings */ + } + + for (i = 0, bit = 1; xo_effect_names[i]; i++, bit <<= 1) { + if (!(xocp->xoc_eff_on & bit)) + continue; + + if (xop->xo_colors.xoc_eff_on & bit) { + if (bit == XO_EFF_FOREGROUND + && xocp->xoc_col_fg == xop->xo_colors.xoc_col_fg) + continue; + else if (bit == XO_EFF_BACKGROUND + && xocp->xoc_col_bg == xop->xo_colors.xoc_col_bg) + continue; + else + continue; + } + + cp += snprintf(cp, ep - cp, ";%s", xo_effect_on_codes[i]); + if (cp >= ep) + return; /* Should not occur */ + + if (bit == XO_EFF_FOREGROUND) + *cp++ = '0' + xocp->xoc_col_fg; + else if (bit == XO_EFF_BACKGROUND) + *cp++ = '0' + xocp->xoc_col_bg; + } + + if ((xocp->xoc_eff_on & XO_EFF_FOREGROUND) + && (xocp->xoc_col_fg == XO_COL_DEFAULT)) { + xocp->xoc_eff_on &= ~XO_EFF_FOREGROUND; + xocp->xoc_col_fg = 0; + } + + if ((xocp->xoc_eff_on & XO_EFF_BACKGROUND) + && (xocp->xoc_col_bg == XO_COL_DEFAULT)) { + xocp->xoc_eff_on &= ~XO_EFF_BACKGROUND; + xocp->xoc_col_bg = 0; + } + + if (cp - buf != 1 && cp < ep - 3) { + buf[1] = '['; /* Overwrite leading ';' */ + *cp++ = 'm'; + *cp = '\0'; + xo_buf_append(&xop->xo_data, buf, cp - buf); + } +} + +static void +xo_colors_emit_html (xo_handle_t *xop UNUSED, xo_colors_t *xocp UNUSED) +{ +} + +static void +xo_format_colors (xo_handle_t *xop, const char *str, int len, + const char *fmt, int flen) +{ + 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)) + return; + + xo_buf_init(&xb); + + if (len) + xo_buf_append(&xb, str, len); + else if (flen == 0) + xo_format_data(xop, &xb, fmt, flen, 0); + else + xo_buf_append(&xb, "reset", 6); /* Default if empty */ + + switch (xo_style(xop)) { + case XO_STYLE_TEXT: + case XO_STYLE_HTML: + xo_buf_append(&xb, "", 1); + + xo_colors_t xoc = xop->xo_colors; + + xo_colors_parse(xop, &xoc, xb.xb_bufp); + if (xo_colors_isset(&xoc)) { + if (xo_style(xop) == XO_STYLE_TEXT) { + /* + * Text mode means emitting the colors as ANSI character + * codes. This will allow people who like colors to have + * colors. The issue is, of course conflicting with the + * user's perfectly reasonable color scheme. Which leads + * to the hell of LSCOLORS, where even app need to have + * customization hooks for adjusting colors. Instead we + * provide a simpler-but-still-annoying answer where one + * can map colors to other colors. + */ + xo_colors_emit_text(xop, &xoc); + } else { + /* + * HTML output is wrapped in divs, so the color information + * must appear in every div until cleared. Most pathetic. + * Mostly unavoidable. + */ + xo_colors_emit_html(xop, &xoc); + } + + xoc.xoc_eff_off = 0; + xoc.xoc_eff_on &= ~XO_EFF_CLEAR_BITS; + xop->xo_colors = xoc; + } + break; + + case XO_STYLE_XML: + case XO_STYLE_JSON: + /* + * Nothing to do; we did all that work just to clear the stack of + * formatting arguments. + */ + break; + } + + xo_buf_cleanup(&xb); +} + static void xo_format_units (xo_handle_t *xop, const char *str, int len, const char *fmt, int flen) @@ -3496,6 +3880,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) } switch (*sp) { + case 'C': case 'D': case 'E': case 'L': @@ -3641,7 +4026,9 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) flen = 2; } - if (ftype == 'D') + if (ftype == 'C') + xo_format_colors(xop, content, clen, format, flen); + else if (ftype == 'D') xo_format_content(xop, "decoration", NULL, 1, content, clen, format, flen); else if (ftype == 'E') From 0b67be3cdb3bdafa8fffc7cffea05eb4638c7f7c Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:20 -0400 Subject: [PATCH 33/90] checkpoint color work; still needs html support --- libxo/xo.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libxo/xo.h b/libxo/xo.h index a715b996..ca9dfbc3 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -66,6 +66,8 @@ typedef unsigned long long xo_xof_flags_t; #define XOF_FLUSH_LINE XOF_BIT(23) /** Flush after each newline */ #define XOF_NO_CLOSE XOF_BIT(24) /** xo_finish won't close open elements */ +#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */ +#define XOF_COLOR XOF_BIT(26) /** Enable color and effects */ /* * The xo_info_t structure provides a mapping between names and From d3f553db31c06eb3121d490376196f9601e9e3b4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:22 -0400 Subject: [PATCH 34/90] checkpoint color work; still needs html support --- libxo/xo_format.5 | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index 92fa4498..09865da1 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -96,6 +96,55 @@ The roles are listed below; only one role is permitted: .It \&] "stop anchor " "End a section of anchored variable-width text" .El .Pp +.Ss The Color Role ({C:}) +Colors and effects control how text values are displayed; they are +used for display styles (TEXT and HTML). +The color content can be +either static, when placed directly within the field descriptor, or a +printf-style format descriptor can be used, if preceded by a slash ("/"): +.Bd -literal -offset indent + EXAMPLES: + xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost); + xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n", + fg_color, bg_color, cost); +.Ed +.Pp +The content should be a comma-separated list of zero or more colors or +display effects. +These colors and effects remain in affect until modified by other "C" +roles. +If the content is empty, the "reset" action is performed. +.Pp +.Bl -column "Name12345678901" +.It Sy "Name Description" +.It "bg-XXXXX " "Change background color" +.It "bold " "Start bold text effect" +.It "fg-XXXXX " "Change foreground color" +.It "inverse " "Start inverse (aka reverse) text effect" +.It "no-bold " "Stop bold text effect" +.It "no-inverse " "Stop inverse (aka reverse) text effect" +.It "no-underline " "Stop underline text effect" +.It "normal " "Reset effects (only)" +.It "reset " "Reset colors and effects (restore defaults)" +.It "underline " "Start underline text effect" +.El +.Pp +The following color names are supported: +.Bl -column M "Name" +.It Sy "Name" +.It "black" +.It "blue" +.It "cyan" +.It "default" +.It "green" +.It "magenta" +.It "red" +.It "white" +.It "yellow" +.El +.Pp +Color names are prefixed with either "fg-" or "bg-" to change the +foreground and background colors, respectively. .Ss The Decoration Role ({D:}) Decorations are typically punctuation marks such as colons, semi-colons, and commas used to decorate the text and make it simpler From 013cde69381ccd2248d049adc7f330085b62f565 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:25 -0400 Subject: [PATCH 35/90] checkpoint color work; still needs html support --- 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 f145d183..92f5f364 100644 --- a/tests/core/Makefile.am +++ b/tests/core/Makefile.am @@ -20,7 +20,8 @@ test_05.c \ test_06.c \ test_07.c \ test_08.c \ -test_09.c +test_09.c \ +test_10.c test_01_test_SOURCES = test_01.c test_02_test_SOURCES = test_02.c @@ -31,6 +32,7 @@ test_06_test_SOURCES = test_06.c 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_CASES := $(shell cd ${srcdir} ; echo *.c ) From 2fe86438c8609a5ff35658c027f89de9fec953ed Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:39 -0400 Subject: [PATCH 36/90] new test case --- tests/core/saved/test_10.H.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.H.err diff --git a/tests/core/saved/test_10.H.err b/tests/core/saved/test_10.H.err new file mode 100644 index 00000000..e69de29b From 60e9802149a9c49789bc452461b79a5ecba4d3d4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:40 -0400 Subject: [PATCH 37/90] new test case --- tests/core/saved/test_10.H.out | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/core/saved/test_10.H.out diff --git a/tests/core/saved/test_10.H.out b/tests/core/saved/test_10.H.out new file mode 100644 index 00000000..8f5b0158 --- /dev/null +++ b/tests/core/saved/test_10.H.out @@ -0,0 +1 @@ +
blue
green
red
yellow
default
Item
Total Sold
In Stock
On Order
SKU
gum
1412
54
10
GRO-000-415
rope
85
4
2
HRD-000-212
ladder
0
2
1
HRD-000-517
bolt
4123
144
42
HRD-000-632
water
17
14
2
GRO-000-2331
Item
'
gum
':
Total sold
:
1412.0
In stock
:
54
On order
:
10
SKU
:
GRO-000-415
Item
'
rope
':
Total sold
:
85.0
In stock
:
4
On order
:
2
SKU
:
HRD-000-212
Item
'
ladder
':
Total sold
:
0
In stock
:
2
On order
:
1
SKU
:
HRD-000-517
Item
'
bolt
':
Total sold
:
4123.0
In stock
:
144
On order
:
42
SKU
:
HRD-000-632
Item
'
water
':
Total sold
:
17.0
In stock
:
14
On order
:
2
SKU
:
GRO-000-2331
Item
'
fish
':
Total sold
:
1321.0
In stock
:
45
On order
:
1
SKU
:
GRO-000-533
Item
:
gum
Item
:
rope
Item
:
ladder
Item
:
bolt
Item
:
water
X
X
X
X
X
X
X
X
X
X
Cost
:
425
X
X
Cost
:
455
\ No newline at end of file From cfc413b69ce149945a461fe70008db9b73c32085 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:41 -0400 Subject: [PATCH 38/90] new test case --- tests/core/saved/test_10.HIPx.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.HIPx.err diff --git a/tests/core/saved/test_10.HIPx.err b/tests/core/saved/test_10.HIPx.err new file mode 100644 index 00000000..e69de29b From bec21a81cfbaa1528fe440235738b224b4d2e562 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:42 -0400 Subject: [PATCH 39/90] new test case --- tests/core/saved/test_10.HIPx.out | 303 ++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 tests/core/saved/test_10.HIPx.out diff --git a/tests/core/saved/test_10.HIPx.out b/tests/core/saved/test_10.HIPx.out new file mode 100644 index 00000000..28105260 --- /dev/null +++ b/tests/core/saved/test_10.HIPx.out @@ -0,0 +1,303 @@ +
+
blue
+
green
+
red
+
yellow
+
default
+
+
+
Item
+
Total Sold
+
In Stock
+
On Order
+
SKU
+
+
+
gum
+
1412
+
54
+
10
+
GRO-000-415
+
+
+
rope
+
85
+
4
+
2
+
HRD-000-212
+
+
+
ladder
+
0
+
2
+
1
+
HRD-000-517
+
+
+
bolt
+
4123
+
144
+
42
+
HRD-000-632
+
+
+
water
+
17
+
14
+
2
+
GRO-000-2331
+
+
+
+
+
+
+
Item
+
'
+
gum
+
':
+
+
+
+
Total sold
+
:
+
1412.0
+
+
+
+
In stock
+
:
+
+
54
+
+
+
+
On order
+
:
+
+
10
+
+
+
+
SKU
+
:
+
GRO-000-415
+
+
+
Item
+
'
+
rope
+
':
+
+
+
+
Total sold
+
:
+
85.0
+
+
+
+
In stock
+
:
+
+
4
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
HRD-000-212
+
+
+
Item
+
'
+
ladder
+
':
+
+
+
+
Total sold
+
:
+
0
+
+
+
+
In stock
+
:
+
+
2
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
HRD-000-517
+
+
+
Item
+
'
+
bolt
+
':
+
+
+
+
Total sold
+
:
+
4123.0
+
+
+
+
In stock
+
:
+
+
144
+
+
+
+
On order
+
:
+
+
42
+
+
+
+
SKU
+
:
+
HRD-000-632
+
+
+
Item
+
'
+
water
+
':
+
+
+
+
Total sold
+
:
+
17.0
+
+
+
+
In stock
+
:
+
+
14
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
GRO-000-2331
+
+
+
Item
+
'
+
fish
+
':
+
+
+
+
Total sold
+
:
+
1321.0
+
+
+
+
In stock
+
:
+
+
45
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
GRO-000-533
+
+
+
Item
+
:
+
+
gum
+
+
+
Item
+
:
+
+
rope
+
+
+
Item
+
:
+
+
ladder
+
+
+
Item
+
:
+
+
bolt
+
+
+
Item
+
:
+
+
water
+
+
+
X
+
X
+
X
+
X
+
X
+
X
+
X
+
X
+
+
+
X
+
+
X
+
Cost
+
:
+
+
425
+
+
+
X
+
+
X
+
Cost
+
:
+
+
455
+
From f3ba6ff94cb4de96dad6ab1fba7ba839402fd0f0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:42 -0400 Subject: [PATCH 40/90] new test case --- tests/core/saved/test_10.HP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.HP.err diff --git a/tests/core/saved/test_10.HP.err b/tests/core/saved/test_10.HP.err new file mode 100644 index 00000000..e69de29b From 887f1e99cf01684073b8742cd149b5f4cec93b32 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:43 -0400 Subject: [PATCH 41/90] new test case --- tests/core/saved/test_10.HP.out | 303 ++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 tests/core/saved/test_10.HP.out diff --git a/tests/core/saved/test_10.HP.out b/tests/core/saved/test_10.HP.out new file mode 100644 index 00000000..7df28fe9 --- /dev/null +++ b/tests/core/saved/test_10.HP.out @@ -0,0 +1,303 @@ +
+
blue
+
green
+
red
+
yellow
+
default
+
+
+
Item
+
Total Sold
+
In Stock
+
On Order
+
SKU
+
+
+
gum
+
1412
+
54
+
10
+
GRO-000-415
+
+
+
rope
+
85
+
4
+
2
+
HRD-000-212
+
+
+
ladder
+
0
+
2
+
1
+
HRD-000-517
+
+
+
bolt
+
4123
+
144
+
42
+
HRD-000-632
+
+
+
water
+
17
+
14
+
2
+
GRO-000-2331
+
+
+
+
+
+
+
Item
+
'
+
gum
+
':
+
+
+
+
Total sold
+
:
+
1412.0
+
+
+
+
In stock
+
:
+
+
54
+
+
+
+
On order
+
:
+
+
10
+
+
+
+
SKU
+
:
+
GRO-000-415
+
+
+
Item
+
'
+
rope
+
':
+
+
+
+
Total sold
+
:
+
85.0
+
+
+
+
In stock
+
:
+
+
4
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
HRD-000-212
+
+
+
Item
+
'
+
ladder
+
':
+
+
+
+
Total sold
+
:
+
0
+
+
+
+
In stock
+
:
+
+
2
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
HRD-000-517
+
+
+
Item
+
'
+
bolt
+
':
+
+
+
+
Total sold
+
:
+
4123.0
+
+
+
+
In stock
+
:
+
+
144
+
+
+
+
On order
+
:
+
+
42
+
+
+
+
SKU
+
:
+
HRD-000-632
+
+
+
Item
+
'
+
water
+
':
+
+
+
+
Total sold
+
:
+
17.0
+
+
+
+
In stock
+
:
+
+
14
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
GRO-000-2331
+
+
+
Item
+
'
+
fish
+
':
+
+
+
+
Total sold
+
:
+
1321.0
+
+
+
+
In stock
+
:
+
+
45
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
GRO-000-533
+
+
+
Item
+
:
+
+
gum
+
+
+
Item
+
:
+
+
rope
+
+
+
Item
+
:
+
+
ladder
+
+
+
Item
+
:
+
+
bolt
+
+
+
Item
+
:
+
+
water
+
+
+
X
+
X
+
X
+
X
+
X
+
X
+
X
+
X
+
+
+
X
+
+
X
+
Cost
+
:
+
+
425
+
+
+
X
+
+
X
+
Cost
+
:
+
+
455
+
From f5f3dd32ec75e3447702b79c3bcb96474903e6cc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:43 -0400 Subject: [PATCH 42/90] new test case --- tests/core/saved/test_10.J.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.J.err diff --git a/tests/core/saved/test_10.J.err b/tests/core/saved/test_10.J.err new file mode 100644 index 00000000..e69de29b From 5ef9314ef92739d87419b0b8aa64f22e298cfb10 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:44 -0400 Subject: [PATCH 43/90] new test case --- tests/core/saved/test_10.J.out | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/core/saved/test_10.J.out diff --git a/tests/core/saved/test_10.J.out b/tests/core/saved/test_10.J.out new file mode 100644 index 00000000..6fcdbd41 --- /dev/null +++ b/tests/core/saved/test_10.J.out @@ -0,0 +1,2 @@ +{"top": {"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} +} From 94d2b58b3952c7f1845aa758e6873994b367f0cf Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:45 -0400 Subject: [PATCH 44/90] new test case --- tests/core/saved/test_10.JP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.JP.err diff --git a/tests/core/saved/test_10.JP.err b/tests/core/saved/test_10.JP.err new file mode 100644 index 00000000..e69de29b From 859a731bded1e5ddd7e45c677fe0020ca9f3f352 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:45 -0400 Subject: [PATCH 45/90] new test case --- tests/core/saved/test_10.JP.out | 104 ++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 tests/core/saved/test_10.JP.out diff --git a/tests/core/saved/test_10.JP.out b/tests/core/saved/test_10.JP.out new file mode 100644 index 00000000..47900652 --- /dev/null +++ b/tests/core/saved/test_10.JP.out @@ -0,0 +1,104 @@ +{ + "top": { + "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 + } +} From 7361db0bc2b2130a3aa75bca2bd347702640734d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:46 -0400 Subject: [PATCH 46/90] new test case --- tests/core/saved/test_10.T.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.T.err diff --git a/tests/core/saved/test_10.T.err b/tests/core/saved/test_10.T.err new file mode 100644 index 00000000..e69de29b From 38b13779bd8c0ec60cc08517839057f569d5897a Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:46 -0400 Subject: [PATCH 47/90] new test case --- tests/core/saved/test_10.T.out | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/core/saved/test_10.T.out diff --git a/tests/core/saved/test_10.T.out b/tests/core/saved/test_10.T.out new file mode 100644 index 00000000..b6bb4015 --- /dev/null +++ b/tests/core/saved/test_10.T.out @@ -0,0 +1,47 @@ +bluegreenredyellowdefault +Item  Total Sold In Stock On Order SKU +gum 1412 54 10 GRO-000-415 +rope 85 4 2 HRD-000-212 +ladder 0 2 1 HRD-000-517 +bolt 4123 144 42 HRD-000-632 +water 17 14 2 GRO-000-2331 + + +Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 +Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 +Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 +Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 +Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 +Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 +Item: gum +Item: rope +Item: ladder +Item: bolt +Item: water +XXXXXXXX +X XCost: 425 +X XCost: 455 From 757b5fa47664f9cc2d68a8021435be9d558179cc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:47 -0400 Subject: [PATCH 48/90] new test case --- tests/core/saved/test_10.X.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.X.err diff --git a/tests/core/saved/test_10.X.err b/tests/core/saved/test_10.X.err new file mode 100644 index 00000000..e69de29b From beb744802842f21132f9415c5963bf26ed9517a7 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:48 -0400 Subject: [PATCH 49/90] new test case --- tests/core/saved/test_10.X.out | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/core/saved/test_10.X.out diff --git a/tests/core/saved/test_10.X.out b/tests/core/saved/test_10.X.out new file mode 100644 index 00000000..ce271926 --- /dev/null +++ b/tests/core/saved/test_10.X.out @@ -0,0 +1 @@ +GRO-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 c831bcbb7a67a9fbd31cc495801c17c7ae363287 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:48 -0400 Subject: [PATCH 50/90] new test case --- tests/core/saved/test_10.XP.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.XP.err diff --git a/tests/core/saved/test_10.XP.err b/tests/core/saved/test_10.XP.err new file mode 100644 index 00000000..e69de29b From 4837215696c9b7345fe5f883290e8ea9b4c3cce0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:49 -0400 Subject: [PATCH 51/90] new test case --- tests/core/saved/test_10.XP.out | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tests/core/saved/test_10.XP.out diff --git a/tests/core/saved/test_10.XP.out b/tests/core/saved/test_10.XP.out new file mode 100644 index 00000000..e5ea3e08 --- /dev/null +++ b/tests/core/saved/test_10.XP.out @@ -0,0 +1,94 @@ + + + + GRO-000-415 + gum + 1412 + 54 + 10 + + + HRD-000-212 + rope + 85 + 4 + 2 + + + HRD-000-517 + ladder + 0 + 2 + 1 + + + HRD-000-632 + bolt + 4123 + 144 + 42 + + + GRO-000-2331 + water + 17 + 14 + 2 + + + + + GRO-000-415 + gum + 1412.0 + 54 + 10 + + + HRD-000-212 + rope + 85.0 + 4 + 2 + + + HRD-000-517 + ladder + 0 + 2 + 1 + + + HRD-000-632 + bolt + 4123.0 + 144 + 42 + + + GRO-000-2331 + water + 17.0 + 14 + 2 + + + + + GRO-000-533 + fish + 1321.0 + 45 + 1 + + + + gum + rope + ladder + bolt + water + + 425 + 455 + From 4e91714a97bd0c4995a133514bc54c5d31e0acc1 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:49 -0400 Subject: [PATCH 52/90] new test case --- tests/core/saved/test_10.err | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/core/saved/test_10.err diff --git a/tests/core/saved/test_10.err b/tests/core/saved/test_10.err new file mode 100644 index 00000000..e69de29b From 78c58176322245789d514c81f0bf5f859d42cfaa Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:50 -0400 Subject: [PATCH 53/90] new test case --- tests/core/saved/test_10.out | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/core/saved/test_10.out diff --git a/tests/core/saved/test_10.out b/tests/core/saved/test_10.out new file mode 100644 index 00000000..c2ad7a00 --- /dev/null +++ b/tests/core/saved/test_10.out @@ -0,0 +1,38 @@ +Item Total Sold In Stock On Order SKU +gum 1412 54 10 GRO-000-415 +rope 85 4 2 HRD-000-212 +ladder 0 2 1 HRD-000-517 +bolt 4123 144 42 HRD-000-632 +water 17 14 2 GRO-000-2331 + + +Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 +Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 +Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 +Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 +Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 +Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 From 850dc2e3d78b146c93e4d0d622074440e52cf768 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:52:51 -0400 Subject: [PATCH 54/90] new test case --- tests/core/test_10.c | 193 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tests/core/test_10.c diff --git a/tests/core/test_10.c b/tests/core/test_10.c new file mode 100644 index 00000000..f012eb78 --- /dev/null +++ b/tests/core/test_10.c @@ -0,0 +1,193 @@ +/* + * 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 "xo.h" + +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", 1412, 54, 10, base_grocery, 415 }, + { "rope", 85, 4, 2, base_hardware, 212 }, + { "ladder", 0, 2, 1, base_hardware, 517 }, + { "bolt", 4123, 144, 42, base_hardware, 632 }, + { "water", 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) + return 1; + + for (argc = 1; argv[argc]; argc++) { + if (strcmp(argv[argc], "xml") == 0) + xo_set_style(NULL, XO_STYLE_XML); + else if (strcmp(argv[argc], "json") == 0) + xo_set_style(NULL, XO_STYLE_JSON); + else if (strcmp(argv[argc], "text") == 0) + xo_set_style(NULL, XO_STYLE_TEXT); + else if (strcmp(argv[argc], "html") == 0) + xo_set_style(NULL, XO_STYLE_HTML); + else if (strcmp(argv[argc], "pretty") == 0) + xo_set_flags(NULL, XOF_PRETTY); + else if (strcmp(argv[argc], "xpath") == 0) + xo_set_flags(NULL, XOF_XPATH); + else if (strcmp(argv[argc], "info") == 0) + xo_set_flags(NULL, XOF_INFO); + else if (strcmp(argv[argc], "error") == 0) { + close(-1); + xo_err(1, "error detected"); + } + } + + xo_set_info(NULL, info, info_count); + xo_set_flags(NULL, XOF_KEYS); + + /* Normally one would use "XOF_COLOR_ALLOWED", but we want to force it */ + xo_set_flags(NULL, XOF_COLOR); + + xo_open_container_h(NULL, "top"); + + xo_attr("test", "value"); + xo_open_container("data"); + xo_open_list("item"); + xo_attr("test2", "value2"); + + static const char *colors[] = + { "blue", "green", "red", "yellow", "default", NULL }; + + int i; + for (i = 0; colors[i]; i++) { + if (i > 0) + xo_emit("{C:/bg-%s}", colors[i-1]); + xo_emit("{C:/fg-%s}{T:/%s}", colors[i], colors[i]); + } + xo_emit("{C:reset}\n"); + + xo_emit("{T:Item/%-10s}{C:bold,underline}{T:Total Sold/%12s}{C:no-bold}" + "{T:In Stock/%12s}{C:/%s}" + "{T:On Order/%12s}{C:normal}{T:SKU/%5s}\n", "inverse"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + xo_attr("test3", "value3"); + + xo_emit("{keq:sku/%s-%u/%s-000-%u}" + "{k:name/%-10s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}" + "{:on-order/%12u/%u}{qkd:sku/%5s-000-%u/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num, + 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_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); + 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}: {qkd: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("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); + 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}: {qkd: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 = list; ip->i_title; ip++) { + xo_attr("test4", "value4"); + xo_emit("{Lwc:Item}{l:item}\n", ip->i_title); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_emit("X{P:}X", "epic fail"); + xo_emit("X{T:}X", "epic fail"); + xo_emit("X{N:}X", "epic fail"); + xo_emit("X{L:}X\n", "epic fail"); + + xo_emit("X{P: }X{Lwc:Cost}{:cost/%u}\n", 425); + xo_emit("X{P:/%30s}X{Lwc:Cost}{:cost/%u}\n", "", 455); + + xo_close_container_h(NULL, "top"); + + xo_finish(); + + return 0; +} From 175c02b1895a4f8ed16b4a69148fc2ffa8362b19 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:53:08 -0400 Subject: [PATCH 55/90] checkpoint color work --- libxo/xo_format.5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index 09865da1..bcd0ef29 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -116,7 +116,7 @@ roles. If the content is empty, the "reset" action is performed. .Pp .Bl -column "Name12345678901" -.It Sy "Name Description" +.It Sy "Name q Description" .It "bg-XXXXX " "Change background color" .It "bold " "Start bold text effect" .It "fg-XXXXX " "Change foreground color" From 007f4035a7db8d61de74b794baaa422722c72f3e Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Wed, 22 Apr 2015 02:54:44 -0400 Subject: [PATCH 56/90] xo_colors_emit_html needs help --- libxo/libxo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/libxo.c b/libxo/libxo.c index bd1256e9..4466855c 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -3521,6 +3521,7 @@ xo_colors_emit_text (xo_handle_t *xop UNUSED, xo_colors_t *xocp) static void xo_colors_emit_html (xo_handle_t *xop UNUSED, xo_colors_t *xocp UNUSED) { + /* Shockingly underimplemented */ } static void From 7ba4dc2b5a0064de2c5e4d23472e877c0b29bc60 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 01:38:47 -0400 Subject: [PATCH 57/90] add xohtml --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 4ff2aad8..1abfd5e7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,7 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libxo xo xolint tests doc +SUBDIRS = libxo xo xolint xohtml tests doc bin_SCRIPTS=libxo-config dist_doc_DATA = Copyright From dc327419845db68b63f53d7961973900e01077e4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 01:38:49 -0400 Subject: [PATCH 58/90] add xohtml --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 084186f8..2678eb9b 100644 --- a/configure.ac +++ b/configure.ac @@ -241,6 +241,7 @@ AC_CONFIG_FILES([ libxo/xoversion.h xo/Makefile xolint/Makefile + xohtml/Makefile packaging/libxo.pc doc/Makefile tests/Makefile From 79187a73a50a9fdd00d302946b0960592daed466 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 01:38:58 -0400 Subject: [PATCH 59/90] add color for html --- libxo/libxo.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 136 insertions(+), 7 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 4466855c..3024cc91 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -204,6 +204,7 @@ struct xo_handle_s { uint8_t xo_color_map_fg[XO_NUM_COLORS]; /* Foreground color mappings */ uint8_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */ xo_colors_t xo_colors; /* Current color and effect values */ + xo_buffer_t xo_color_buf; /* HTML: buffer of colors and effects */ }; /* Flags for formatting functions */ @@ -388,6 +389,24 @@ xo_buf_init (xo_buffer_t *xbp) 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; +} + +/* + * Reset the buffer to empty + */ +static int +xo_buf_is_empty (xo_buffer_t *xbp) +{ + return (xbp->xb_curp == xbp->xb_bufp); +} + /* * Initialize the contents of an xo_buffer_t. */ @@ -1506,6 +1525,7 @@ xo_destroy (xo_handle_t *xop_arg) xo_buf_cleanup(&xop->xo_fmt); xo_buf_cleanup(&xop->xo_predicate); xo_buf_cleanup(&xop->xo_attrs); + xo_buf_cleanup(&xop->xo_color_buf); if (xop_arg == NULL) { bzero(&xo_default_handle, sizeof(xo_default_handle)); @@ -2659,6 +2679,20 @@ xo_fix_encoding (xo_handle_t *xop UNUSED, char *encoding) return cp; } +static void +xo_color_append_html (xo_handle_t *xop) +{ + /* + * If the color buffer has content, we add it now. It's already + * prebuilt and ready, since we want to add it to every
. + */ + if (!xo_buf_is_empty(&xop->xo_color_buf)) { + xo_buffer_t *xbp = &xop->xo_color_buf; + + xo_data_append(xop, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp); + } +} + static void xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, const char *name, int nlen, @@ -2756,6 +2790,16 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, xo_data_append(xop, div_start, sizeof(div_start) - 1); xo_data_append(xop, class, strlen(class)); + /* + * If the color buffer has content, we add it now. It's already + * prebuilt and ready, since we want to add it to every
. + */ + if (!xo_buf_is_empty(&xop->xo_color_buf)) { + xo_buffer_t *xbp = &xop->xo_color_buf; + + xo_data_append(xop, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp); + } + if (name) { xo_data_append(xop, div_tag, sizeof(div_tag) - 1); xo_data_escape(xop, name, nlen); @@ -2861,7 +2905,8 @@ static void xo_format_title (xo_handle_t *xop, const char *str, int len, const char *fmt, int flen) { - static char div_open[] = "
"; + static char div_open[] = "
"; static char div_close[] = "
"; if (flen == 0) { @@ -2893,6 +2938,8 @@ xo_format_title (xo_handle_t *xop, const char *str, int len, if (xop->xo_flags & XOF_PRETTY) xo_buf_indent(xop, xop->xo_indent_by); xo_buf_append(&xop->xo_data, div_open, sizeof(div_open) - 1); + xo_color_append_html(xop); + xo_buf_append(&xop->xo_data, div_middle, sizeof(div_middle) - 1); } start = xbp->xb_curp - xbp->xb_bufp; /* Reset start */ @@ -3413,7 +3460,8 @@ xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp UNUSED, char *str) switch (1 << rc) { case XO_EFF_RESET: xocp->xoc_col_fg = xocp->xoc_col_bg = 0; - xocp->xoc_eff_on = xocp->xoc_eff_off = 0; + xocp->xoc_eff_off = 0; + xocp->xoc_eff_on &= XO_EFF_RESET; break; case XO_EFF_NORMAL: @@ -3516,12 +3564,95 @@ xo_colors_emit_text (xo_handle_t *xop UNUSED, xo_colors_t *xocp) *cp = '\0'; xo_buf_append(&xop->xo_data, buf, cp - buf); } + + xocp->xoc_eff_off = 0; + xocp->xoc_eff_on &= ~XO_EFF_CLEAR_BITS; } static void -xo_colors_emit_html (xo_handle_t *xop UNUSED, xo_colors_t *xocp UNUSED) +xo_colors_emit_html (xo_handle_t *xop, xo_colors_t *xocp) { - /* Shockingly underimplemented */ + /* + * HTML colors are mostly trivial: fill in xo_color_buf with + * a set of class tags representing the colors and effects. + */ + if (xocp->xoc_eff_off) { + xo_effect_t val = xocp->xoc_eff_off; + val &= ~(XO_EFF_BACKGROUND | XO_EFF_FOREGROUND); /* Should not occur */ + val = ~val & xocp->xoc_eff_on; /* Only turn off what was on*/ + xocp->xoc_eff_on = val; + xocp->xoc_eff_off = 0; + } + + if (xocp->xoc_eff_on & XO_EFF_RESET) { + xocp->xoc_col_fg = xocp->xoc_col_bg = 0; + xocp->xoc_eff_on = xocp->xoc_eff_off = 0; + } + + if (xocp->xoc_eff_on & XO_EFF_NORMAL) { + xocp->xoc_eff_on &= (XO_EFF_FOREGROUND | XO_EFF_BACKGROUND); + xocp->xoc_eff_off = 0; + } + + if ((xocp->xoc_eff_on & XO_EFF_FOREGROUND) + && (xocp->xoc_col_fg == XO_COL_DEFAULT)) { + xocp->xoc_eff_on &= ~XO_EFF_FOREGROUND; + xocp->xoc_col_fg = 0; + } + + if ((xocp->xoc_eff_on & XO_EFF_BACKGROUND) + && (xocp->xoc_col_bg == XO_COL_DEFAULT)) { + xocp->xoc_eff_on &= ~XO_EFF_BACKGROUND; + xocp->xoc_col_bg = 0; + } + + /* If nothing changed, then do nothing */ + if (xop->xo_colors.xoc_eff_on == xocp->xoc_eff_on + && xop->xo_colors.xoc_col_fg == xocp->xoc_col_fg + && xop->xo_colors.xoc_col_bg == xocp->xoc_col_bg) + return; + + unsigned i, bit; + xo_buffer_t *xbp = &xop->xo_color_buf; + const char *value; + const char *name; + int inverse = (xocp->xoc_eff_on & XO_EFF_INVERSE) ? 1 : 0; + + xo_buf_reset(xbp); /* We rebuild content after each change */ + + for (i = 0, bit = 1; xo_effect_names[i]; i++, bit <<= 1) { + if (!(xocp->xoc_eff_on & bit)) + continue; + + /* No "inverse" in CSS, so we do this by hand */ + if (bit == XO_EFF_INVERSE) + continue; + + xo_buf_append(xbp, " ", 1); + + if (bit == XO_EFF_FOREGROUND) { + name = "color-fg-"; + value = xo_color_names[inverse ? xocp->xoc_col_bg + : xocp->xoc_col_fg]; + } else if (bit == XO_EFF_BACKGROUND) { + name = "color-bg-"; + value = xo_color_names[inverse ? xocp->xoc_col_fg + : xocp->xoc_col_bg]; + } else { + name = "effect-"; + value = xo_effect_names[i]; + } + + xo_buf_append(xbp, name, strlen(name)); + xo_buf_append(xbp, value, strlen(value)); + } + + if (inverse) { + if (!(xocp->xoc_eff_on & XO_EFF_FOREGROUND)) + xo_buf_append(xbp, " color-bg-inverse", 17); + if (!(xocp->xoc_eff_on & XO_EFF_BACKGROUND)) + xo_buf_append(xbp, " color-fg-inverse", 17); + } } static void @@ -3539,7 +3670,7 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, if (len) xo_buf_append(&xb, str, len); - else if (flen == 0) + else if (flen) xo_format_data(xop, &xb, fmt, flen, 0); else xo_buf_append(&xb, "reset", 6); /* Default if empty */ @@ -3574,8 +3705,6 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, xo_colors_emit_html(xop, &xoc); } - xoc.xoc_eff_off = 0; - xoc.xoc_eff_on &= ~XO_EFF_CLEAR_BITS; xop->xo_colors = xoc; } break; From 83ddab23c4ffb504338daa927efab606fe60aa3d Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 01:39:04 -0400 Subject: [PATCH 60/90] add color for html --- xohtml/xohtml.css | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/xohtml/xohtml.css b/xohtml/xohtml.css index 655bf122..fc9ea066 100644 --- a/xohtml/xohtml.css +++ b/xohtml/xohtml.css @@ -1014,3 +1014,27 @@ div.xpath { position: relative; top: 1px; } + +div.color-fg-black { color: black; } +div.color-fg-red { color: red; } +div.color-fg-green { color: green; } +div.color-fg-yellow { color: yellow; } +div.color-fg-blue { color: blue; } +div.color-fg-magenta { color: magenta; } +div.color-fg-cyan { color: cyan; } +div.color-fg-white { color: white; } + +div.color-bg-black { background-color: black; } +div.color-bg-red { background-color: red; } +div.color-bg-green { background-color: green; } +div.color-bg-yellow { background-color: yellow; } +div.color-bg-blue { background-color: blue; } +div.color-bg-magenta { background-color: magenta; } +div.color-bg-cyan { background-color: cyan; } +div.color-bg-white { background-color: white; } + +div.color-fg-inverse { color: white; } +div.color-bg-inverse { background-color: black; } + +div.effect-bold { font-weight:bold; } +div.effect-underline { text-decoration: underline; } From 655c456e2c6884b7497ae054f732bff6c9ed3313 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 01:39:11 -0400 Subject: [PATCH 61/90] initial version --- xohtml/Makefile.am | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 xohtml/Makefile.am diff --git a/xohtml/Makefile.am b/xohtml/Makefile.am new file mode 100644 index 00000000..763518d9 --- /dev/null +++ b/xohtml/Makefile.am @@ -0,0 +1,37 @@ +# +# 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. + +man_MANS = xohtml.1 + +EXTERNAL_FILES = \ + external/jquery.js \ + external/jquery.qtip.css \ + external/jquery.qtip.js + +INTERNAL_FILES = \ + xohtml.js \ + xohtml.css + +EXTRA_DIST = \ + xohtml.1 \ + xohtml.sh.in \ + ${INTERNAL_FILES} \ + ${EXTERNAL_FILES} + +install-exec-hook: + install xohtml.sh ${DESTDIR}${bindir}/xohtml + mkdir -p ${DESTDIR}${XO_SHAREDIR}/external + for file in ${INTERNAL_FILES}; do \ + install ${srcdir}/$$file ${DESTDIR}${XO_SHAREDIR} ; done + for file in ${EXTERNAL_FILES}; do \ + install ${srcdir}/$$file ${DESTDIR}${XO_SHAREDIR}/external ; done + +uninstall-hook: + for file in ${INTERNAL_FILES} ${EXTERNAL_FILES}; do \ + rm ${DESTDIR}${XO_SHAREDIR}/$$file ; done + rmdir ${DESTDIR}${XO_SHAREDIR}/external From dff688a0425cb8d49cb6ac12b1661064761a1a87 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 01:39:15 -0400 Subject: [PATCH 62/90] initial version --- xohtml/xohtml.1 | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 xohtml/xohtml.1 diff --git a/xohtml/xohtml.1 b/xohtml/xohtml.1 new file mode 100644 index 00000000..d99c7ab9 --- /dev/null +++ b/xohtml/xohtml.1 @@ -0,0 +1,2 @@ +." Need some docs + From e40c340ebe144fdc609df05e9cb027e5b417c840 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 13:07:45 -0400 Subject: [PATCH 63/90] redo colors to make it less stateful, more reliable/sane --- libxo/libxo.c | 290 +++++++++++++++++++++++--------------------------- 1 file changed, 132 insertions(+), 158 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 3024cc91..a7c5a6b2 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -122,15 +122,15 @@ typedef struct xo_stack_s { } xo_stack_t; /* "colors" refers to fancy ansi codes */ -#define XO_COL_BLACK 0 -#define XO_COL_RED 1 -#define XO_COL_GREEN 2 -#define XO_COL_YELLOW 3 -#define XO_COL_BLUE 4 -#define XO_COL_MAGENTA 5 -#define XO_COL_CYAN 6 -#define XO_COL_WHITE 7 -#define XO_COL_DEFAULT 8 +#define XO_COL_DEFAULT 0 +#define XO_COL_BLACK 1 +#define XO_COL_RED 2 +#define XO_COL_GREEN 3 +#define XO_COL_YELLOW 4 +#define XO_COL_BLUE 5 +#define XO_COL_MAGENTA 6 +#define XO_COL_CYAN 7 +#define XO_COL_WHITE 8 #define XO_NUM_COLORS 9 @@ -151,20 +151,16 @@ typedef struct xo_stack_s { */ #define XO_EFF_RESET (1<<0) #define XO_EFF_NORMAL (1<<1) -#define XO_EFF_FOREGROUND (1<<2) /* "Special" effects bit: fg color */ -#define XO_EFF_BACKGROUND (1<<3) /* "Special" effects bit: bg color */ -#define XO_EFF_BOLD (1<<4) -#define XO_EFF_UNDERLINE (1<<5) -#define XO_EFF_INVERSE (1<<6) +#define XO_EFF_BOLD (1<<2) +#define XO_EFF_UNDERLINE (1<<3) +#define XO_EFF_INVERSE (1<<4) -#define XO_EFF_CLEAR_BITS \ - (XO_EFF_RESET | XO_EFF_NORMAL | XO_EFF_FOREGROUND | XO_EFF_BACKGROUND) +#define XO_EFF_CLEAR_BITS XO_EFF_RESET typedef uint8_t xo_effect_t; typedef uint8_t xo_color_t; typedef struct xo_colors_s { - xo_effect_t xoc_eff_on; /* Bits to turn on */ - xo_effect_t xoc_eff_off; /* Bits to turn off */ + xo_effect_t xoc_effects; /* Current effect set */ xo_color_t xoc_col_fg; /* Foreground color */ xo_color_t xoc_col_bg; /* Background color */ } xo_colors_t; @@ -741,6 +737,21 @@ xo_buf_append (xo_buffer_t *xbp, const char *str, int 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) @@ -3338,6 +3349,7 @@ xo_format_content (xo_handle_t *xop, const char *class_name, } static const char *xo_color_names[] = { + "default", /* XO_COL_DEFAULT */ "black", /* XO_COL_BLACK */ "red", /* XO_CLOR_RED */ "green", /* XO_COL_GREEN */ @@ -3346,8 +3358,6 @@ static const char *xo_color_names[] = { "magenta", /* XO_COL_MAGENTA */ "cyan", /* XO_COL_CYAN */ "white", /* XO_COL_WHITE */ - "custom-color", /* nonsense; space savere */ - "default", /* XO_COL_DEFAULT */ NULL }; @@ -3367,8 +3377,6 @@ xo_color_find (const char *str) static const char *xo_effect_names[] = { "reset", /* XO_EFF_RESET */ "normal", /* XO_EFF_NORMAL */ - "fg-", /* XO_EFF_FOREGROUND */ - "bg-", /* XO_EFF_BACKGROUND */ "bold", /* XO_EFF_BOLD */ "underline", /* XO_EFF_UNDERLINE */ "inverse", /* XO_EFF_INVERSE */ @@ -3378,8 +3386,6 @@ static const char *xo_effect_names[] = { static const char *xo_effect_on_codes[] = { "0", /* XO_EFF_RESET */ "0", /* XO_EFF_NORMAL */ - "3", /* 30-37 */ /* XO_EFF_FOREGROUND */ - "4", /* 40-47 */ /* XO_EFF_BACKGROUND */ "1", /* XO_EFF_BOLD */ "4", /* XO_EFF_UNDERLINE */ "7", /* XO_EFF_INVERSE */ @@ -3387,17 +3393,24 @@ static const char *xo_effect_on_codes[] = { }; #if 0 +/* + * See comment below re: joy of terminal standards. These can + * be use by just adding: + * if (newp->xoc_effects & bit) + * code = xo_effect_on_codes[i]; + * + else + * + code = xo_effect_off_codes[i]; + * in xo_color_handle_text. + */ static const char *xo_effect_off_codes[] = { "0", /* XO_EFF_RESET */ "0", /* XO_EFF_NORMAL */ - "39", /* XO_EFF_FOREGROUND */ - "49", /* XO_EFF_BACKGROUND */ "21", /* XO_EFF_BOLD */ "24", /* XO_EFF_UNDERLINE */ "27", /* XO_EFF_INVERSE */ NULL }; -#endif +#endif /* 0 */ static int xo_effect_find (const char *str) @@ -3413,7 +3426,7 @@ xo_effect_find (const char *str) } static void -xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp UNUSED, char *str) +xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp, char *str) { #ifdef LIBXO_TEXT_ONLY return; @@ -3435,38 +3448,37 @@ xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp UNUSED, char *str) rc = xo_color_find(cp + 3); if (rc < 0) goto unknown; + xocp->xoc_col_fg = rc; - xocp->xoc_eff_on |= XO_EFF_FOREGROUND; } else if (cp[0] == 'b' && cp[1] == 'g' && cp[2] == '-') { rc = xo_color_find(cp + 3); if (rc < 0) goto unknown; xocp->xoc_col_bg = rc; - xocp->xoc_eff_on |= XO_EFF_BACKGROUND; } else if (cp[0] == 'n' && cp[1] == 'o' && cp[2] == '-') { rc = xo_effect_find(cp + 3); if (rc < 0) goto unknown; - xocp->xoc_eff_off |= 1 << rc; + xocp->xoc_effects &= ~(1 << rc); } else { rc = xo_effect_find(cp); if (rc < 0) goto unknown; - xocp->xoc_eff_on |= 1 << rc; + xocp->xoc_effects |= 1 << rc; switch (1 << rc) { case XO_EFF_RESET: xocp->xoc_col_fg = xocp->xoc_col_bg = 0; - xocp->xoc_eff_off = 0; - xocp->xoc_eff_on &= XO_EFF_RESET; + /* Note: not "|=" since we want to wipe out the old value */ + xocp->xoc_effects = XO_EFF_RESET; break; case XO_EFF_NORMAL: - xocp->xoc_eff_on &= ~(XO_EFF_BOLD | XO_EFF_UNDERLINE - | XO_EFF_INVERSE); + xocp->xoc_effects &= ~(XO_EFF_BOLD | XO_EFF_UNDERLINE + | XO_EFF_INVERSE | XO_EFF_NORMAL); break; } } @@ -3474,27 +3486,28 @@ xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp UNUSED, char *str) unknown: if (xop->xo_flags & XOF_WARN) - xo_failure(xop, "color/effect string detected: '%s'", cp); + xo_failure(xop, "unknown color/effect string detected: '%s'", cp); } } static inline int -xo_colors_isset (xo_colors_t *xocp) +xo_colors_enabled (xo_handle_t *xop UNUSED) { #ifdef LIBXO_TEXT_ONLY return 0; #else /* LIBXO_TEXT_ONLY */ - return ((xocp->xoc_eff_on || xocp->xoc_eff_off - || xocp->xoc_col_fg || xocp->xoc_col_bg) ? 1 : 0); + return ((xop->xo_flags & XOF_COLOR) ? 1 : 0); #endif /* LIBXO_TEXT_ONLY */ } static void -xo_colors_emit_text (xo_handle_t *xop UNUSED, xo_colors_t *xocp) +xo_colors_handle_text (xo_handle_t *xop UNUSED, xo_colors_t *newp) { char buf[BUFSIZ]; char *cp = buf, *ep = buf + sizeof(buf); unsigned i, bit; + xo_colors_t *oldp = &xop->xo_colors; + const char *code; /* * Start the buffer with an escape. We don't want to add the '[' @@ -3511,51 +3524,39 @@ xo_colors_emit_text (xo_handle_t *xop UNUSED, xo_colors_t *xocp) * reseting them all and turning back on the ones we want to keep. * Longer, but should be completely reliable. Savvy? */ - if (xocp->xoc_eff_off) { - xo_effect_t val = xocp->xoc_eff_off; - val &= ~(XO_EFF_BACKGROUND | XO_EFF_FOREGROUND); /* Should not occur */ - val = ~val & xocp->xoc_eff_on; /* Only turn off what was on*/ - val |= XO_EFF_RESET; /* Add the reset */ - xocp->xoc_eff_on = val; - xocp->xoc_eff_off = 0; - xop->xo_colors.xoc_eff_on = 0; /* Reset previous settings */ + if (oldp->xoc_effects != (newp->xoc_effects & oldp->xoc_effects)) { + newp->xoc_effects |= XO_EFF_RESET; + oldp->xoc_effects = 0; } for (i = 0, bit = 1; xo_effect_names[i]; i++, bit <<= 1) { - if (!(xocp->xoc_eff_on & bit)) + if ((newp->xoc_effects & bit) == (oldp->xoc_effects & bit)) continue; - if (xop->xo_colors.xoc_eff_on & bit) { - if (bit == XO_EFF_FOREGROUND - && xocp->xoc_col_fg == xop->xo_colors.xoc_col_fg) - continue; - else if (bit == XO_EFF_BACKGROUND - && xocp->xoc_col_bg == xop->xo_colors.xoc_col_bg) - continue; - else - continue; - } + if (newp->xoc_effects & bit) + code = xo_effect_on_codes[i]; - cp += snprintf(cp, ep - cp, ";%s", xo_effect_on_codes[i]); + cp += snprintf(cp, ep - cp, ";%s", code); if (cp >= ep) return; /* Should not occur */ - if (bit == XO_EFF_FOREGROUND) - *cp++ = '0' + xocp->xoc_col_fg; - else if (bit == XO_EFF_BACKGROUND) - *cp++ = '0' + xocp->xoc_col_bg; + if (bit == XO_EFF_RESET) { + /* Mark up the old value so we can detect current values as new */ + oldp->xoc_effects = 0; + oldp->xoc_col_fg = oldp->xoc_col_bg = XO_COL_DEFAULT; + } } - if ((xocp->xoc_eff_on & XO_EFF_FOREGROUND) - && (xocp->xoc_col_fg == XO_COL_DEFAULT)) { - xocp->xoc_eff_on &= ~XO_EFF_FOREGROUND; - xocp->xoc_col_fg = 0; + if (newp->xoc_col_fg != oldp->xoc_col_fg) { + cp += snprintf(cp, ep - cp, ";3%u", + (newp->xoc_col_fg != XO_COL_DEFAULT) + ? newp->xoc_col_fg - 1 : 9); } - if ((xocp->xoc_eff_on & XO_EFF_BACKGROUND) - && (xocp->xoc_col_bg == XO_COL_DEFAULT)) { - xocp->xoc_eff_on &= ~XO_EFF_BACKGROUND; - xocp->xoc_col_bg = 0; + if (newp->xoc_col_bg != oldp->xoc_col_bg) { + cp += snprintf(cp, ep - cp, ";4%u", + (newp->xoc_col_bg != XO_COL_DEFAULT) + ? newp->xoc_col_bg - 1 : 9); } if (cp - buf != 1 && cp < ep - 3) { @@ -3564,94 +3565,64 @@ xo_colors_emit_text (xo_handle_t *xop UNUSED, xo_colors_t *xocp) *cp = '\0'; xo_buf_append(&xop->xo_data, buf, cp - buf); } - - xocp->xoc_eff_off = 0; - xocp->xoc_eff_on &= ~XO_EFF_CLEAR_BITS; } static void -xo_colors_emit_html (xo_handle_t *xop, xo_colors_t *xocp) +xo_colors_handle_html (xo_handle_t *xop, xo_colors_t *newp) { + xo_colors_t *oldp = &xop->xo_colors; + /* * HTML colors are mostly trivial: fill in xo_color_buf with * a set of class tags representing the colors and effects. */ - if (xocp->xoc_eff_off) { - xo_effect_t val = xocp->xoc_eff_off; - val &= ~(XO_EFF_BACKGROUND | XO_EFF_FOREGROUND); /* Should not occur */ - val = ~val & xocp->xoc_eff_on; /* Only turn off what was on*/ - xocp->xoc_eff_on = val; - xocp->xoc_eff_off = 0; - } - - if (xocp->xoc_eff_on & XO_EFF_RESET) { - xocp->xoc_col_fg = xocp->xoc_col_bg = 0; - xocp->xoc_eff_on = xocp->xoc_eff_off = 0; - } - - if (xocp->xoc_eff_on & XO_EFF_NORMAL) { - xocp->xoc_eff_on &= (XO_EFF_FOREGROUND | XO_EFF_BACKGROUND); - xocp->xoc_eff_off = 0; - } - - if ((xocp->xoc_eff_on & XO_EFF_FOREGROUND) - && (xocp->xoc_col_fg == XO_COL_DEFAULT)) { - xocp->xoc_eff_on &= ~XO_EFF_FOREGROUND; - xocp->xoc_col_fg = 0; - } - - if ((xocp->xoc_eff_on & XO_EFF_BACKGROUND) - && (xocp->xoc_col_bg == XO_COL_DEFAULT)) { - xocp->xoc_eff_on &= ~XO_EFF_BACKGROUND; - xocp->xoc_col_bg = 0; - } /* If nothing changed, then do nothing */ - if (xop->xo_colors.xoc_eff_on == xocp->xoc_eff_on - && xop->xo_colors.xoc_col_fg == xocp->xoc_col_fg - && xop->xo_colors.xoc_col_bg == xocp->xoc_col_bg) + if (oldp->xoc_effects == newp->xoc_effects + && oldp->xoc_col_fg == newp->xoc_col_fg + && oldp->xoc_col_bg == newp->xoc_col_bg) return; unsigned i, bit; xo_buffer_t *xbp = &xop->xo_color_buf; - const char *value; - const char *name; - int inverse = (xocp->xoc_eff_on & XO_EFF_INVERSE) ? 1 : 0; xo_buf_reset(xbp); /* We rebuild content after each change */ for (i = 0, bit = 1; xo_effect_names[i]; i++, bit <<= 1) { - if (!(xocp->xoc_eff_on & bit)) + if (!(newp->xoc_effects & bit)) continue; - /* No "inverse" in CSS, so we do this by hand */ - if (bit == XO_EFF_INVERSE) - continue; + xo_buf_append_str(xbp, " effect-"); + xo_buf_append_str(xbp, xo_effect_names[i]); + } - xo_buf_append(xbp, " ", 1); + const char *fg = NULL; + const char *bg = NULL; - if (bit == XO_EFF_FOREGROUND) { - name = "color-fg-"; - value = xo_color_names[inverse ? xocp->xoc_col_bg - : xocp->xoc_col_fg]; - } else if (bit == XO_EFF_BACKGROUND) { - name = "color-bg-"; - value = xo_color_names[inverse ? xocp->xoc_col_fg - : xocp->xoc_col_bg]; - } else { - name = "effect-"; - value = xo_effect_names[i]; - } + if (newp->xoc_col_fg != XO_COL_DEFAULT) + fg = xo_color_names[newp->xoc_col_fg]; + if (newp->xoc_col_bg != XO_COL_DEFAULT) + bg = xo_color_names[newp->xoc_col_bg]; + + if (newp->xoc_effects & XO_EFF_INVERSE) { + const char *tmp = fg; + fg = bg; + bg = tmp; + if (fg == NULL) + fg = "inverse"; + if (bg == NULL) + bg = "inverse"; + + } - xo_buf_append(xbp, name, strlen(name)); - xo_buf_append(xbp, value, strlen(value)); + if (fg) { + xo_buf_append_str(xbp, " color-fg-"); + xo_buf_append_str(xbp, fg); } - if (inverse) { - if (!(xocp->xoc_eff_on & XO_EFF_FOREGROUND)) - xo_buf_append(xbp, " color-bg-inverse", 17); - if (!(xocp->xoc_eff_on & XO_EFF_BACKGROUND)) - xo_buf_append(xbp, " color-fg-inverse", 17); + if (bg) { + xo_buf_append_str(xbp, " color-bg-"); + xo_buf_append_str(xbp, bg); } } @@ -3675,15 +3646,15 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, else xo_buf_append(&xb, "reset", 6); /* Default if empty */ - switch (xo_style(xop)) { - case XO_STYLE_TEXT: - case XO_STYLE_HTML: - xo_buf_append(&xb, "", 1); + if (xo_colors_enabled(xop)) { + switch (xo_style(xop)) { + case XO_STYLE_TEXT: + case XO_STYLE_HTML: + xo_buf_append(&xb, "", 1); - xo_colors_t xoc = xop->xo_colors; + xo_colors_t xoc = xop->xo_colors; + xo_colors_parse(xop, &xoc, xb.xb_bufp); - xo_colors_parse(xop, &xoc, xb.xb_bufp); - if (xo_colors_isset(&xoc)) { if (xo_style(xop) == XO_STYLE_TEXT) { /* * Text mode means emitting the colors as ANSI character @@ -3695,27 +3666,30 @@ xo_format_colors (xo_handle_t *xop, const char *str, int len, * provide a simpler-but-still-annoying answer where one * can map colors to other colors. */ - xo_colors_emit_text(xop, &xoc); + xo_colors_handle_text(xop, &xoc); + xoc.xoc_effects &= ~XO_EFF_RESET; /* After handling it */ + } else { /* * HTML output is wrapped in divs, so the color information * must appear in every div until cleared. Most pathetic. - * Mostly unavoidable. + * Most unavoidable. */ - xo_colors_emit_html(xop, &xoc); + xoc.xoc_effects &= ~XO_EFF_RESET; /* Before handling effects */ + xo_colors_handle_html(xop, &xoc); } xop->xo_colors = xoc; - } - break; + break; - case XO_STYLE_XML: - case XO_STYLE_JSON: - /* - * Nothing to do; we did all that work just to clear the stack of - * formatting arguments. - */ - break; + case XO_STYLE_XML: + case XO_STYLE_JSON: + /* + * Nothing to do; we did all that work just to clear the stack of + * formatting arguments. + */ + break; + } } xo_buf_cleanup(&xb); @@ -4148,6 +4122,8 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) xo_anchor_start(xop, content, clen, format, flen); else if (ftype == ']') xo_anchor_stop(xop, content, clen, format, flen); + else if (ftype == 'C') + xo_format_colors(xop, content, clen, format, flen); else if (clen || format) { /* Need either content or format */ if (format == NULL) { @@ -4156,9 +4132,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt) flen = 2; } - if (ftype == 'C') - xo_format_colors(xop, content, clen, format, flen); - else if (ftype == 'D') + if (ftype == 'D') xo_format_content(xop, "decoration", NULL, 1, content, clen, format, flen); else if (ftype == 'E') From e053c5dff848ba65989f5498ad5e94aa8e5ab361 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 13:07:50 -0400 Subject: [PATCH 64/90] update tests --- tests/core/test_10.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/core/test_10.c b/tests/core/test_10.c index f012eb78..86c77972 100644 --- a/tests/core/test_10.c +++ b/tests/core/test_10.c @@ -105,15 +105,24 @@ main (int argc, char **argv) "{T:In Stock/%12s}{C:/%s}" "{T:On Order/%12s}{C:normal}{T:SKU/%5s}\n", "inverse"); +#if 0 + xo_finish(); + return 0; +#endif + for (ip = list; ip->i_title; ip++) { xo_open_instance("item"); xo_attr("test3", "value3"); xo_emit("{keq:sku/%s-%u/%s-000-%u}" - "{k:name/%-10s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}" - "{:on-order/%12u/%u}{qkd:sku/%5s-000-%u/%s-000-%u}\n", + "{k:name/%-10s/%s}{n:sold/%12u/%u}" + "{C:/%s}{:in-stock/%12u/%u}{C:normal}" + "{C:/fg-%s}{:on-order/%12u/%u}{C:/fg-default}" + "{qkd:sku/%5s-000-%u/%s-000-%u}\n", ip->i_sku_base, ip->i_sku_num, - ip->i_title, ip->i_sold, ip->i_instock, ip->i_onorder, + ip->i_title, ip->i_sold, + (ip->i_instock < 5) ? "inverse" : "normal", ip->i_instock, + (ip->i_onorder > 5) ? "yellow" : "default", ip->i_onorder, ip->i_sku_base, ip->i_sku_num); xo_close_instance("item"); @@ -134,7 +143,8 @@ main (int argc, char **argv) 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:In stock}{C:inverse}{:in-stock/%u}{C:}\n", + ip->i_instock); xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n", ip->i_sku_base, ip->i_sku_num); @@ -153,7 +163,8 @@ main (int argc, char **argv) xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); - xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + xo_emit("{P: }{C:bg-blue,fg-white}{L:Total sold}: " + "{n:sold/%u%s}{C:}\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); From 809f08da901809056199e2f0236fa739c9aff83b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 16:03:03 -0400 Subject: [PATCH 65/90] allow whitespace in color/effect values --- libxo/libxo.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index a7c5a6b2..3d6503ed 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -3432,7 +3432,7 @@ xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp, char *str) return; #endif /* LIBXO_TEXT_ONLY */ - char *cp, *ep, *np; + char *cp, *ep, *np, *xp; int len = strlen(str); int rc; @@ -3440,10 +3440,19 @@ xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp, char *str) * Possible tokens: colors, bg-colors, effects, no-effects, "reset". */ for (cp = str, ep = cp + len - 1; cp && cp < ep; cp = np) { + /* Trim leading whitespace */ + while (isspace((int) *cp)) + cp += 1; + np = strchr(cp, ','); if (np) *np++ = '\0'; + /* Trim trailing whitespace */ + xp = cp + strlen(cp) - 1; + while (isspace(*xp) && xp > cp) + *xp-- = '\0'; + if (cp[0] == 'f' && cp[1] == 'g' && cp[2] == '-') { rc = xo_color_find(cp + 3); if (rc < 0) From f94a8ca98228d1b5585ca39e3e8f02cd02b8a8a0 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 16:03:13 -0400 Subject: [PATCH 66/90] update tests --- tests/core/test_10.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/core/test_10.c b/tests/core/test_10.c index 86c77972..aaffab6e 100644 --- a/tests/core/test_10.c +++ b/tests/core/test_10.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "xo.h" @@ -101,6 +102,11 @@ main (int argc, char **argv) } xo_emit("{C:reset}\n"); + xo_emit("{C:bold}{:data} {C:underline}{:data} {C:inverse}{:data} " + "{C:no-bold}{:data} {C:no-inverse}{:data} " + "{C:no-underline}{:data}\n", + "bold", "bold-ul", "triple", "inv-ul", "underline", "plain"); + xo_emit("{T:Item/%-10s}{C:bold,underline}{T:Total Sold/%12s}{C:no-bold}" "{T:In Stock/%12s}{C:/%s}" "{T:On Order/%12s}{C:normal}{T:SKU/%5s}\n", "inverse"); @@ -163,7 +169,7 @@ main (int argc, char **argv) xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); - xo_emit("{P: }{C:bg-blue,fg-white}{L:Total sold}: " + xo_emit("{P: }{C:bg-blue , fg-white, bold }{L:Total sold}: " "{n:sold/%u%s}{C:}\n", ip->i_sold, ip->i_sold ? ".0" : ""); xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); From 67512ee6620b58d54d8b1f0edff945e0a27cff87 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 16:03:22 -0400 Subject: [PATCH 67/90] add checks for color/effect fields --- xolint/xolint.pl | 63 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/xolint/xolint.pl b/xolint/xolint.pl index 427edf7a..515f7faa 100644 --- a/xolint/xolint.pl +++ b/xolint/xolint.pl @@ -347,32 +347,32 @@ sub check_field { error("only one field role can be used (" . join(", ", @roles) . ")") if $#roles > 0; - # Field is a note, label, or title - if ($field[0] =~ /[DLNT]/) { + # Field is a color, note, label, or title + if ($field[0] =~ /[CDLNT]/) { - #@ Potential missing slash after N, L, or T with format + #@ Potential missing slash after C, D, N, L, or T with format #@ xo_emit("{T:%6.6s}\n", "Max"); #@ should be: #@ xo_emit("{T:/%6.6s}\n", "Max"); #@ The "%6.6s" will be a literal, not a field format. While #@ it's possibly valid, it's likely a missing "/". - info("potential missing slash after N, L, or T with format") + info("potential missing slash after C, D, N, L, or T with format") if $field[1] =~ /%/; #@ An encoding format cannot be given (roles: DNLT) #@ xo_emit("{T:Max//%s}", "Max"); - #@ Fields with the D, N, L, and T roles are not emitted in + #@ Fields with the C, D, N, L, and T roles are not emitted in #@ the 'encoding' style (JSON, XML), so an encoding format #@ would make no sense. error("encoding format cannot be given when content is present") if $field[3]; } - # Field is a decoration, label, or title - if ($field[0] =~ /DLN/) { - #@ Format cannot be given when content is present (roles: DLN) + # Field is a color, decoration, label, or title + if ($field[0] =~ /[CDLN]/) { + #@ Format cannot be given when content is present (roles: CDLN) #@ xo_emit("{N:Max/%6.6s}", "Max"); - #@ Fields with the D, L, or N roles can't have both + #@ Fields with the C, D, L, or N roles can't have both #@ static literal content ("{L:Label}") and a #@ format ("{L:/%s}"). #@ This error will also occur when the content has a backslash @@ -383,6 +383,49 @@ sub check_field { if $field[1] && $field[2]; } + # Field is a color/effect + if ($field[0] =~ /C/) { + if ($field[1]) { + my $val; + my @sub = split(/,/, $field[1]); + grep { s/^\s*//; s/\s*$//; } @sub; + + for $val (@sub) { + if ($val =~ /^(default,black,red,green,yellow,blue,magenta,cyan,white)$/) { + + #@ Field has color without fg- or bg- (role: C) + #@ xo_emit("{C:green}{:foo}{C:}", x); + #@ Should be: + #@ xo_emit("{C:fg-green}{:foo}{C:}", x); + #@ Colors must be prefixed by either "fg-" or "bg-". + error("Field has color without fg- or bg- (role: C)"); + + } elsif ($val =~ /^(fg|bg)-(default|black|red|green|yellow|blue|magenta|cyan|white)$/) { + # color + } elsif ($val =~ /^(bold|underline)$/) { + } elsif ($val =~ /^(no-)?(bold|underline|inverse)$/) { + # effect + + } elsif ($val =~ /^(reset|normal)$/) { + # effect also + } else { + #@ Field has invalid color or effect (role: C) + #@ xo_emit("{C:fg-purple,bold}{:foo}{C:gween}", x); + #@ Should be: + #@ xo_emit("{C:fg-red,bold}{:foo}{C:fg-green}", x); + #@ The list of colors and effects are limited. The + #@ set of colors includes default, black, red, green, + #@ yellow, blue, magenta, cyan, and white, which must + #@ be prefixed by either "fg-" or "bg-". Effects are + #@ limited to bold, no-bold, underline, no-underline, + #@ inverse, no-inverse, normal, and reset. Values must + #@ be separated by commas. + error("Field has invalid color or effect (role: C) ($val)"); + } + } + } + } + # A value field if (length($field[0]) == 0 || $field[0] =~ /V/) { @@ -456,7 +499,7 @@ sub check_field { #@ Should be: #@ xo_emit("{D:((}{:good}{D:))}", "yes"); #@ This is minor, but fields should use proper roles. Decoration - #@ fields are meant to hold puncuation and other characters used + #@ fields are meant to hold punctuation and other characters used #@ to decorate the content, typically to make it more readable #@ to human readers. warn("decoration field contains invalid character") From 31bb875e3b9a9f4173ae90157f31ef547483f735 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 16:45:45 -0400 Subject: [PATCH 68/90] add man page for xohtml --- xohtml/xohtml.1 | 125 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/xohtml/xohtml.1 b/xohtml/xohtml.1 index d99c7ab9..f826d485 100644 --- a/xohtml/xohtml.1 +++ b/xohtml/xohtml.1 @@ -1,2 +1,125 @@ -." Need some docs +.\" # +.\" # 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 2014 +.\" +.Dd December 4, 2014 +.Dt XOHTML 1 +.Os +.Sh NAME +.Nm xohtml +.Nd display libxo html output +.Xr xo_emit 3 +.Sh SYNOPSIS +.Nm xohtml +.Op Fl c +.Op Fl "b " +.Op Fl "c" " +.Op Fl "f" +.Op Ar command argument... +.Sh DESCRIPTION +.Nm +is a tool for preparing +.Xr libxo 3 +HTML output for display in a HTML5 browser. +.Nm +can operate in two modes. +If command is provided +either with the +.Fl c +option or as argument(s) to the +.Nm +command, that command is executed and the resulting output is processed. +If no command is given, the +standard input is used. +.Pp +.Nm +is typically used to wrap +.Nm libxo +output with sufficient HTML5 content to allow display in a web browser. +This includes parent HTML tags as well as +.Nm CSS +stylesheets and +.Nm Javascript +files. +.Pp +If the command is given directly on the command line, +.Nm +will add the "--libxo=html" option needed to generate HTML output +from +.Nm libxo "-enabled" +applications. See +.Xr libxo 3 +for details. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl "b " +.It Fl "-base " +Supplies a source path for the CSS and Javascript files referenced in +the output of +.Nm xohtml . +.It Fl "c " +.It Fl "-command " +Use the given command instead of one on the command line. +This command should be quoted if it consists of multiple tokens, and +should contain the "--libxo=html" option or equivalent, since the +command is used directly. +.It Fl "f " +.It Fl "-file " +Output is saved to the given file, rather than to the standard output +descriptor. +.El +.Pp +.Sh EXAMPLES +The following command line will run "du --libxo=html ~/src" and save +the output to /tmp/src.html: +.Bd -literal -offset indent + xohtml du ~/src > /tmp/src.html +.Ed +.Pp +The following command line will run "du --libxo=html,warn ~/src" and save +the output to /tmp/src.html: +.Bd -literal -offset indent + du --libxo=html,warn ~/src | xohtml -f /tmp/src.html +.Ed +.Pp +The following command line will run "du --libxo=html,warn ~/src" and save +the output to /tmp/src.html: +.Bd -literal -offset indent + xohtml -c "du --libxo=html,warn ~/src" -f /tmp/src.html +.Ed +.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 libxo 3 , +.Xr xo_emit 3 +.Sh HISTORY +The +.Nm libxo +library was added in +.Fx 11.0 . +.Sh AUTHOR +Phil Shafer From 271fa9e0b6eab693cbe9ce8dab65904d2a1c78f9 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 16:46:02 -0400 Subject: [PATCH 69/90] add ability to parse command line commands --- xohtml/xohtml.sh.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xohtml/xohtml.sh.in b/xohtml/xohtml.sh.in index cbd3066b..e86f868e 100644 --- a/xohtml/xohtml.sh.in +++ b/xohtml/xohtml.sh.in @@ -33,6 +33,9 @@ while [ -z "$DONE" -a ! -z "$1" ]; do ;; *) DONE=1; + XX=$1; + shift; + CMD="$XX --libxo=html $@" ;; esac done From cb628eaff9df22150e148a52a164212dfe84e84b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 16:46:10 -0400 Subject: [PATCH 70/90] fix release name --- xolint/xolint.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xolint/xolint.1 b/xolint/xolint.1 index fcf7bcde..16a59fc9 100644 --- a/xolint/xolint.1 +++ b/xolint/xolint.1 @@ -99,6 +99,6 @@ https://github.com/Juniper/libxo/releases The .Nm libxo library was added in -.Fx 10.1 . +.Fx 11.0 . .Sh AUTHOR Phil Shafer From c8dca3e46c5ade6e104d255ad3a93fd86c9a032f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 17:13:51 -0400 Subject: [PATCH 71/90] add xohtml and fix {C:} section --- doc/libxo.txt | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/libxo.txt b/doc/libxo.txt index a85e78d9..320c731f 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -306,13 +306,12 @@ used for display styles (TEXT and HTML). The color content can be either static, when placed directly within the field descriptor, or a printf-style format descriptor can be used, if preceded by a slash ("/"): - EXAMPLES: xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost); xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n", fg_color, bg_color, cost); The content should be a comma-separated list of zero or more colors or -display effects. These colors and effects remain in affect until +display effects. Colors and effects remain in effect until modified by other "C" roles. If the content is empty, the "reset" action is performed. @@ -1757,6 +1756,32 @@ The "-V" option does not report errors, but prints a complete list of all field names, sorted alphabetically. The output can help spot inconsistencies and spelling errors. +* xohtml + +xohtml is a tool for turning the output of libxo-enabled commands into +html files suitable for display in modern HTML web browsers. It can +be used to test and debug HTML output, as well as to make the user +ache to escape the world of 70s terminal devices. + +xohtml is given a command, either on the command line or via the "-c" +option. If not command is given, standard input is used. The +command's output is wrapped in HTML tags, with references to +supporting CSS and Javascript files, and written to standard output or +the file given in the "-f" option. The "-b" option can be used to +provide an alternative base path for the support files. + +|--------------+---------------------------------------------------| +| Option | Meaning | +|--------------+---------------------------------------------------| +| -b | Base path for finding css/javascript files | +| -c | Command to execute | +| -f | Output file name | +|--------------+---------------------------------------------------| + +The "-c" option takes a full command with arguments, including +any libxo options needed to generate html ("--libxo=html"). This +value must be quoted if it consists of multiple tokens. + * FAQs This section contains the set of questions that users typically ask, From fd5b0ae502b6495506846e2f0b50f0c5f0583285 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 17:14:00 -0400 Subject: [PATCH 72/90] add {C:} docs --- libxo/xo_format.5 | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libxo/xo_format.5 b/libxo/xo_format.5 index bcd0ef29..bce5dc5a 100644 --- a/libxo/xo_format.5 +++ b/libxo/xo_format.5 @@ -103,7 +103,6 @@ The color content can be either static, when placed directly within the field descriptor, or a printf-style format descriptor can be used, if preceded by a slash ("/"): .Bd -literal -offset indent - EXAMPLES: xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost); xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n", fg_color, bg_color, cost); @@ -111,15 +110,16 @@ printf-style format descriptor can be used, if preceded by a slash ("/"): .Pp The content should be a comma-separated list of zero or more colors or display effects. -These colors and effects remain in affect until modified by other "C" -roles. +.Pp +Colors and effects remain in effect until modified by other "C" roles. +.Pp If the content is empty, the "reset" action is performed. .Pp -.Bl -column "Name12345678901" -.It Sy "Name q Description" -.It "bg-XXXXX " "Change background color" +.Bl -column "no-underline" +.It Sy "Name Description" +.It "bg-xxxxx " "Change background color" .It "bold " "Start bold text effect" -.It "fg-XXXXX " "Change foreground color" +.It "fg-xxxxx " "Change foreground color" .It "inverse " "Start inverse (aka reverse) text effect" .It "no-bold " "Stop bold text effect" .It "no-inverse " "Stop inverse (aka reverse) text effect" @@ -130,17 +130,17 @@ If the content is empty, the "reset" action is performed. .El .Pp The following color names are supported: -.Bl -column M "Name" +.Bl -column "no-underline" .It Sy "Name" -.It "black" -.It "blue" -.It "cyan" -.It "default" -.It "green" -.It "magenta" -.It "red" -.It "white" -.It "yellow" +.It black +.It blue +.It cyan +.It default +.It green +.It magenta +.It red +.It white +.It yellow .El .Pp Color names are prefixed with either "fg-" or "bg-" to change the From bccfe361d1abf37a1f8befb1abcb233f074d9bce Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sat, 25 Apr 2015 17:14:06 -0400 Subject: [PATCH 73/90] fix docs --- xohtml/xohtml.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xohtml/xohtml.1 b/xohtml/xohtml.1 index f826d485..d520cb31 100644 --- a/xohtml/xohtml.1 +++ b/xohtml/xohtml.1 @@ -25,7 +25,7 @@ .Nm is a tool for preparing .Xr libxo 3 -HTML output for display in a HTML5 browser. +HTML output for display in modern HTML web browsers. .Nm can operate in two modes. If command is provided @@ -40,7 +40,7 @@ standard input is used. .Nm is typically used to wrap .Nm libxo -output with sufficient HTML5 content to allow display in a web browser. +output with sufficient HTML content to allow display in a web browser. This includes parent HTML tags as well as .Nm CSS stylesheets and From 9dec8f0b29f6ecdc0c80a1310f6944570dfb6bf4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:55:59 -0400 Subject: [PATCH 74/90] show oxtradoc dir --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 2678eb9b..7706b4c7 100644 --- a/configure.ac +++ b/configure.ac @@ -262,6 +262,7 @@ AC_MSG_NOTICE([summary of build options: bindir: ${XO_BINDIR} includedir: ${XO_INCLUDEDIR} share dir: ${XO_SHAREDIR} + oxtradoc dir: ${SLAX_OXTRADOCDIR} compiler: ${CC} (${HAVE_GCC:-no}) compiler flags: ${CFLAGS} From c0833176f682b1d66755f2dd644b2fc62b30fa48 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:56:08 -0400 Subject: [PATCH 75/90] add docs for xo_set_version --- doc/libxo.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/libxo.txt b/doc/libxo.txt index 320c731f..81a40b61 100644 --- a/doc/libxo.txt +++ b/doc/libxo.txt @@ -1455,9 +1455,21 @@ functions like xo_failure, xo_warn, xo_err, etc. The program name is initialized by xo_parse_args, but subsequent calls to xo_set_program can override this value. + xo_set_program(argv[0]); + Note that the value is not copied, so the memory passed to xo_set_program (and xo_parse_args) must be maintained by the caller. +*** xo_set_version + +The xo_set_version function records a version number to be emitted as +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. + + void xo_set_version (const char *version); + void xo_set_version_h (xo_handle_t *xop, const char *version); + *** Field Information (xo_info_t) @info@ HTML data can include additional information in attributes that From 85d38be9e512d9e38c9674a1933e4f2e3de69db5 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:56:10 -0400 Subject: [PATCH 76/90] add docs for xo_set_version --- libxo/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libxo/Makefile.am b/libxo/Makefile.am index e2a7243b..0047b632 100644 --- a/libxo/Makefile.am +++ b/libxo/Makefile.am @@ -45,6 +45,7 @@ man_MANS = \ xo_set_info.3 \ xo_set_options.3 \ xo_set_style.3 \ + xo_set_version.3 \ xo_set_writer.3 EXTRA_DIST = ${man_MANS} From 1f66642ec5f9a4ba42e04aa93c7902317cf54425 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:19 -0400 Subject: [PATCH 77/90] add xo_set_version; add warning for bad state transitions; fix xo_has_room bug; --- libxo/libxo.c | 83 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/libxo/libxo.c b/libxo/libxo.c index 3d6503ed..87599409 100644 --- a/libxo/libxo.c +++ b/libxo/libxo.c @@ -201,6 +201,7 @@ struct xo_handle_s { uint8_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */ 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 */ }; /* Flags for formatting functions */ @@ -816,7 +817,7 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap) else rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); - if (rc > xbp->xb_size) { + if (rc >= left) { if (!xo_buf_has_room(xbp, rc)) { va_end(va_local); return -1; @@ -826,7 +827,7 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap) * After we call vsnprintf(), the stage of vap is not defined. * We need to copy it before we pass. Then we have to do our * own logic below to move it along. This is because the - * implementation can have va_list be a point (bsd) or a + * implementation can have va_list be a pointer (bsd) or a * structure (macosx) or anything in between. */ @@ -835,7 +836,7 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap) left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); if (xop->xo_formatter) - xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local); + rc = xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local); else rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); } @@ -1538,6 +1539,9 @@ xo_destroy (xo_handle_t *xop_arg) xo_buf_cleanup(&xop->xo_attrs); xo_buf_cleanup(&xop->xo_color_buf); + if (xop->xo_version) + xo_free(xop->xo_version); + if (xop_arg == NULL) { bzero(&xo_default_handle, sizeof(xo_default_handle)); xo_default_inited = 0; @@ -4396,6 +4400,20 @@ xo_stack_flags (unsigned xflags) return 0; } +static void +xo_emit_top (xo_handle_t *xop, const char *ppn) +{ + xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn); + xop->xo_flags |= XOF_TOP_EMITTED; + + if (xop->xo_version) { + xo_printf(xop, "%*s\"__version\": \"%s\", %s", + xo_indent(xop), "", xop->xo_version, ppn); + xo_free(xop->xo_version); + xop->xo_version = NULL; + } +} + static int xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) { @@ -4427,12 +4445,9 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) case XO_STYLE_JSON: xo_stack_set_flags(xop); - if (!(xop->xo_flags & XOF_NO_TOP)) { - if (!(xop->xo_flags & XOF_TOP_EMITTED)) { - xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn); - xop->xo_flags |= XOF_TOP_EMITTED; - } - } + if (!(xop->xo_flags & XOF_NO_TOP) + && !(xop->xo_flags & XOF_TOP_EMITTED)) + xo_emit_top(xop, ppn); if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) pre_nl = (xop->xo_flags & XOF_PRETTY) ? ",\n" : ", "; @@ -4565,12 +4580,9 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) const char *pre_nl = ""; indent = 1; - if (!(xop->xo_flags & XOF_NO_TOP)) { - if (!(xop->xo_flags & XOF_TOP_EMITTED)) { - xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn); - xop->xo_flags |= XOF_TOP_EMITTED; - } - } + if (!(xop->xo_flags & XOF_NO_TOP) + && !(xop->xo_flags & XOF_TOP_EMITTED)) + xo_emit_top(xop, ppn); if (name == NULL) { xo_failure(xop, "NULL passed for list name"); @@ -5151,8 +5163,8 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name, rc = xo_do_open_instance(xop, flags, name); break; - case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_OPEN_INSTANCE): case XSS_TRANSITION(XSS_INIT, XSS_OPEN_INSTANCE): + case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_OPEN_INSTANCE): rc = xo_do_open_list(xop, flags, name); if (rc >= 0) goto open_instance; @@ -5185,6 +5197,8 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name, case XSS_TRANSITION(XSS_INIT, XSS_CLOSE_INSTANCE): /* This one makes no sense; ignore it */ + xo_failure(xop, "xo_close_instance ignored when called from " + "initial state ('%s')", name ?: "(unknown)"); break; case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_CLOSE_INSTANCE): @@ -5227,6 +5241,8 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name, case XSS_TRANSITION(XSS_INIT, XSS_CLOSE_LEAF_LIST): /* Makes no sense; ignore */ + xo_failure(xop, "xo_close_leaf_list ignored when called from " + "initial state ('%s')", name ?: "(unknown)"); break; case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_CLOSE_LEAF_LIST): @@ -5564,6 +5580,41 @@ xo_set_program (const char *name) xo_program = name; } +void +xo_set_version_h (xo_handle_t *xop, const char *version UNUSED) +{ + xop = xo_default(xop); + + if (version == NULL || strchr(version, '"') != NULL) + return; + + switch (xo_style(xop)) { + case XO_STYLE_XML: + /* For XML, we record this as an attribute for the first tag */ + xo_attr_h(xop, "__version", "%s", version); + 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); + } + break; + } +} + +void +xo_set_version (const char *version) +{ + xo_set_version_h(NULL, version); +} + #ifdef UNIT_TEST int main (int argc, char **argv) From 24f2446f7654a340994886aea59737c0da47a2b4 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:27 -0400 Subject: [PATCH 78/90] add xo_set_version --- libxo/xo.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/libxo/xo.h b/libxo/xo.h index ca9dfbc3..1ceee17c 100644 --- a/libxo/xo.h +++ b/libxo/xo.h @@ -9,7 +9,7 @@ */ /** - * libxo provides a means of generating text, XML, and JSON output + * 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. */ @@ -305,29 +305,81 @@ xo_message (const char *fmt, ...); void xo_no_setlocale (void); +/** + * @brief Lift libxo-specific arguments from a set of arguments + * + * libxo-enable programs typically use command line options to enable + * all the nifty-cool libxo features. xo_parse_args() makes this simple + * by pre-processing the command line arguments given to main(), handling + * and removing the libxo-specific ones, meaning anything starting with + * "--libxo". A full description of these arguments is in the base + * documentation. + * @param[in] argc Number of arguments (ala #main()) + * @param[in] argc Array of argument strings (ala #main()) + * @return New number of arguments, or -1 for failure. + */ int xo_parse_args (int argc, char **argv); -/* +/** * This is the "magic" number returned by libxo-supporting commands * when passed the equally magic "--libxo-check" option. If you - * return this, we can assume that since you know the magic handshake, - * you'll happily handle future --libxo options and not do something - * violent like reboot the box or create another hole in the ozone - * layer. + * return this, we can (unsafely) assume that since you know the magic + * handshake, you'll happily handle future --libxo options and not do + * something violent like reboot the box or create another hole in the + * ozone layer. */ #define XO_HAS_LIBXO 121 -/* - * externs for our version number strings +/** + * externs for libxo's version number strings */ -extern const char xo_version[]; -extern const char xo_version_extra[]; +extern const char xo_version[]; /** Base version triple string */ +extern const char xo_version_extra[]; /** Extra version magic content */ +/** + * @brief Dump the internal stack of a libxo handle. + * + * This diagnostic function is something I will ask you to call from + * your program when you write to tell me libxo has gone bat-stink + * crazy and has discarded your list or container or content. Output + * content will be what we lovingly call "developer entertainment". + * @param[in] xop A valid libxo handle, or NULL for the default handle + */ void xo_dump_stack (xo_handle_t *xop); +/** + * @brief Recode the name of the program, suitable for error output. + * + * libxo will record the given name for use while generating error + * messages. The contents are not copied, so the value must continue + * to point to a valid memory location. This allows the caller to change + * the value, but requires the caller to manage the memory. Typically + * this is called with argv[0] from main(). + * @param[in] name The name of the current application program + */ void xo_set_program (const char *name); +/** + * @brief Add a version string to the output, where possible. + * + * Adds a version number to the output, suitable for tracking + * changes in the content. This is only important for the "encoding" + * format styles (XML and JSON) and allows a user of the data to + * discern which version of the data model is in use. + * @param[in] version The version number, encoded as a string + */ +void +xo_set_version (const char *version); + +/** + * #xo_set_version with a handle. + * @param[in] xop A valid libxo handle, or NULL for the default handle + * @param[in] version The version number, encoded as a string + */ +void +xo_set_version_h (xo_handle_t *xop, const char *version); + #endif /* INCLUDE_XO_H */ From 20c366be2ca447a889e7cdcfb2a558e510faa1db Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:31 -0400 Subject: [PATCH 79/90] update test cases --- tests/core/saved/test_10.H.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_10.H.out b/tests/core/saved/test_10.H.out index 8f5b0158..d4ec07da 100644 --- a/tests/core/saved/test_10.H.out +++ b/tests/core/saved/test_10.H.out @@ -1 +1 @@ -
blue
green
red
yellow
default
Item
Total Sold
In Stock
On Order
SKU
gum
1412
54
10
GRO-000-415
rope
85
4
2
HRD-000-212
ladder
0
2
1
HRD-000-517
bolt
4123
144
42
HRD-000-632
water
17
14
2
GRO-000-2331
Item
'
gum
':
Total sold
:
1412.0
In stock
:
54
On order
:
10
SKU
:
GRO-000-415
Item
'
rope
':
Total sold
:
85.0
In stock
:
4
On order
:
2
SKU
:
HRD-000-212
Item
'
ladder
':
Total sold
:
0
In stock
:
2
On order
:
1
SKU
:
HRD-000-517
Item
'
bolt
':
Total sold
:
4123.0
In stock
:
144
On order
:
42
SKU
:
HRD-000-632
Item
'
water
':
Total sold
:
17.0
In stock
:
14
On order
:
2
SKU
:
GRO-000-2331
Item
'
fish
':
Total sold
:
1321.0
In stock
:
45
On order
:
1
SKU
:
GRO-000-533
Item
:
gum
Item
:
rope
Item
:
ladder
Item
:
bolt
Item
:
water
X
X
X
X
X
X
X
X
X
X
Cost
:
425
X
X
Cost
:
455
\ No newline at end of file +
blue
green
red
yellow
default
bold
bold-ul
triple
inv-ul
underline
plain
Item
Total Sold
In Stock
On Order
SKU
gum
1412
54
10
GRO-000-415
rope
85
4
2
HRD-000-212
ladder
0
2
1
HRD-000-517
bolt
4123
144
42
HRD-000-632
water
17
14
2
GRO-000-2331
Item
'
gum
':
Total sold
:
1412.0
In stock
:
54
On order
:
10
SKU
:
GRO-000-415
Item
'
rope
':
Total sold
:
85.0
In stock
:
4
On order
:
2
SKU
:
HRD-000-212
Item
'
ladder
':
Total sold
:
0
In stock
:
2
On order
:
1
SKU
:
HRD-000-517
Item
'
bolt
':
Total sold
:
4123.0
In stock
:
144
On order
:
42
SKU
:
HRD-000-632
Item
'
water
':
Total sold
:
17.0
In stock
:
14
On order
:
2
SKU
:
GRO-000-2331
Item
'
fish
':
Total sold
:
1321.0
In stock
:
45
On order
:
1
SKU
:
GRO-000-533
Item
:
gum
Item
:
rope
Item
:
ladder
Item
:
bolt
Item
:
water
X
X
X
X
X
X
X
X
X
X
Cost
:
425
X
X
Cost
:
455
\ No newline at end of file From 44b0c0c794e72dd3ce9492ce46f593b75230520f Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:33 -0400 Subject: [PATCH 80/90] update test cases --- tests/core/saved/test_10.HIPx.out | 53 +++++++++++++++++++------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/tests/core/saved/test_10.HIPx.out b/tests/core/saved/test_10.HIPx.out index 28105260..ef64173f 100644 --- a/tests/core/saved/test_10.HIPx.out +++ b/tests/core/saved/test_10.HIPx.out @@ -1,35 +1,48 @@
-
blue
-
green
-
red
-
yellow
-
default
+
blue
+
green
+
red
+
yellow
+
default
+
+
+
bold
+
+
bold-ul
+
+
triple
+
+
inv-ul
+
+
underline
+
+
plain
Item
-
Total Sold
-
In Stock
-
On Order
+
Total Sold
+
In Stock
+
On Order
SKU
gum
1412
54
-
10
+
10
GRO-000-415
rope
85
-
4
+
4
2
HRD-000-212
ladder
0
-
2
+
2
1
HRD-000-517
@@ -37,7 +50,7 @@
bolt
4123
144
-
42
+
42
HRD-000-632
@@ -68,7 +81,7 @@
In stock
:
-
54
+
54
@@ -100,7 +113,7 @@
In stock
:
-
4
+
4
@@ -132,7 +145,7 @@
In stock
:
-
2
+
2
@@ -164,7 +177,7 @@
In stock
:
-
144
+
144
@@ -196,7 +209,7 @@
In stock
:
-
14
+
14
@@ -219,9 +232,9 @@
-
Total sold
-
:
-
1321.0
+
Total sold
+
:
+
1321.0
From 0d7c72840d666be45c23738c758584970304f422 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:34 -0400 Subject: [PATCH 81/90] update test cases --- tests/core/saved/test_10.HP.out | 53 ++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/tests/core/saved/test_10.HP.out b/tests/core/saved/test_10.HP.out index 7df28fe9..abb1b018 100644 --- a/tests/core/saved/test_10.HP.out +++ b/tests/core/saved/test_10.HP.out @@ -1,35 +1,48 @@
-
blue
-
green
-
red
-
yellow
-
default
+
blue
+
green
+
red
+
yellow
+
default
+
+
+
bold
+
+
bold-ul
+
+
triple
+
+
inv-ul
+
+
underline
+
+
plain
Item
-
Total Sold
-
In Stock
-
On Order
+
Total Sold
+
In Stock
+
On Order
SKU
gum
1412
54
-
10
+
10
GRO-000-415
rope
85
-
4
+
4
2
HRD-000-212
ladder
0
-
2
+
2
1
HRD-000-517
@@ -37,7 +50,7 @@
bolt
4123
144
-
42
+
42
HRD-000-632
@@ -68,7 +81,7 @@
In stock
:
-
54
+
54
@@ -100,7 +113,7 @@
In stock
:
-
4
+
4
@@ -132,7 +145,7 @@
In stock
:
-
2
+
2
@@ -164,7 +177,7 @@
In stock
:
-
144
+
144
@@ -196,7 +209,7 @@
In stock
:
-
14
+
14
@@ -219,9 +232,9 @@
-
Total sold
-
:
-
1321.0
+
Total sold
+
:
+
1321.0
From dd8ddd7dd07a27a30c86aad83c6f8b129c1669bf Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:35 -0400 Subject: [PATCH 82/90] update test cases --- tests/core/saved/test_10.J.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_10.J.out b/tests/core/saved/test_10.J.out index 6fcdbd41..5091685f 100644 --- a/tests/core/saved/test_10.J.out +++ b/tests/core/saved/test_10.J.out @@ -1,2 +1,2 @@ -{"top": {"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} +{"__version": "3.1.4", "top": {"data": {"item": [],"data":"bold","data":"bold-ul","data":"triple","data":"inv-ul","data":"underline","data":"plain", "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} } From 1ffde01b42f1d856cad4e8bfccd4ee13164c1fcc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:37 -0400 Subject: [PATCH 83/90] update test cases --- tests/core/saved/test_10.JP.out | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/core/saved/test_10.JP.out b/tests/core/saved/test_10.JP.out index 47900652..0ca32699 100644 --- a/tests/core/saved/test_10.JP.out +++ b/tests/core/saved/test_10.JP.out @@ -1,6 +1,15 @@ { + "__version": "3.1.4", "top": { "data": { + "item": [ + ], + "data": "bold", + "data": "bold-ul", + "data": "triple", + "data": "inv-ul", + "data": "underline", + "data": "plain", "item": [ { "sku": "GRO-000-415", From 0e666533aa6f4fec475c8d419066a2e1fed45203 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:38 -0400 Subject: [PATCH 84/90] update test cases --- tests/core/saved/test_10.T.out | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/core/saved/test_10.T.out b/tests/core/saved/test_10.T.out index b6bb4015..21fa81bc 100644 --- a/tests/core/saved/test_10.T.out +++ b/tests/core/saved/test_10.T.out @@ -1,39 +1,40 @@ bluegreenredyellowdefault +bold bold-ul triple inv-ul underline plain Item  Total Sold In Stock On Order SKU -gum 1412 54 10 GRO-000-415 -rope 85 4 2 HRD-000-212 -ladder 0 2 1 HRD-000-517 -bolt 4123 144 42 HRD-000-632 +gum 1412 54 10 GRO-000-415 +rope 85 4 2 HRD-000-212 +ladder 0 2 1 HRD-000-517 +bolt 4123 144 42 HRD-000-632 water 17 14 2 GRO-000-2331 Item 'gum': Total sold: 1412.0 - In stock: 54 + In stock: 54 On order: 10 SKU: GRO-000-415 Item 'rope': Total sold: 85.0 - In stock: 4 + In stock: 4 On order: 2 SKU: HRD-000-212 Item 'ladder': Total sold: 0 - In stock: 2 + In stock: 2 On order: 1 SKU: HRD-000-517 Item 'bolt': Total sold: 4123.0 - In stock: 144 + In stock: 144 On order: 42 SKU: HRD-000-632 Item 'water': Total sold: 17.0 - In stock: 14 + In stock: 14 On order: 2 SKU: GRO-000-2331 Item 'fish': - Total sold: 1321.0 + Total sold: 1321.0 In stock: 45 On order: 1 SKU: GRO-000-533 From 61ff3d688bc70185f7eb2f5fbcef2928dcc4753b Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:39 -0400 Subject: [PATCH 85/90] update test cases --- tests/core/saved/test_10.X.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/saved/test_10.X.out b/tests/core/saved/test_10.X.out index ce271926..49c6dd88 100644 --- a/tests/core/saved/test_10.X.out +++ b/tests/core/saved/test_10.X.out @@ -1 +1 @@ -GRO-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 +boldbold-ultripleinv-ulunderlineplainGRO-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 57e79fc2930a933bcba70ec337accfe401e55144 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:40 -0400 Subject: [PATCH 86/90] update test cases --- tests/core/saved/test_10.XP.out | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/core/saved/test_10.XP.out b/tests/core/saved/test_10.XP.out index e5ea3e08..33c88d96 100644 --- a/tests/core/saved/test_10.XP.out +++ b/tests/core/saved/test_10.XP.out @@ -1,6 +1,12 @@ - + - + bold + bold-ul + triple + inv-ul + underline + plain + GRO-000-415 gum 1412 From 6cd9d256ce8078ac4e58f6ead3209eecd1fed936 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:57:52 -0400 Subject: [PATCH 87/90] add xo_set_version test --- tests/core/test_10.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/core/test_10.c b/tests/core/test_10.c index aaffab6e..223ec55d 100644 --- a/tests/core/test_10.c +++ b/tests/core/test_10.c @@ -84,6 +84,8 @@ main (int argc, char **argv) /* Normally one would use "XOF_COLOR_ALLOWED", but we want to force it */ xo_set_flags(NULL, XOF_COLOR); + xo_set_version("3.1.4"); + xo_open_container_h(NULL, "top"); xo_attr("test", "value"); From 787ffb992726be18c16a9e3b7de0bf667088a9fc Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:58:02 -0400 Subject: [PATCH 88/90] remove xohtml on uninstall --- xohtml/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/xohtml/Makefile.am b/xohtml/Makefile.am index 763518d9..f7b740e0 100644 --- a/xohtml/Makefile.am +++ b/xohtml/Makefile.am @@ -35,3 +35,4 @@ uninstall-hook: for file in ${INTERNAL_FILES} ${EXTERNAL_FILES}; do \ rm ${DESTDIR}${XO_SHAREDIR}/$$file ; done rmdir ${DESTDIR}${XO_SHAREDIR}/external + rm -f ${DESTDIR}${bindir}/xohtml \ No newline at end of file From 19c3ba3cceae86654dc353a62b45de32b6f11174 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:58:31 -0400 Subject: [PATCH 89/90] initial version --- libxo/xo_set_version.3 | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 libxo/xo_set_version.3 diff --git a/libxo/xo_set_version.3 b/libxo/xo_set_version.3 new file mode 100644 index 00000000..888aef5e --- /dev/null +++ b/libxo/xo_set_version.3 @@ -0,0 +1,59 @@ +.\" # +.\" # 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 2014 +.\" +.Dd December 4, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_set_version +.Nd record content version information in encoded output +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_set_version "const char *version" +.Ft void +.Fn xo_set_version_h "xo_handle_t *xop" "const char *version" +.Sh DESCRIPTION +The +.Nm xo_set_version +function records a version number to be emitted as +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 89f889f53d4594b0116c0c7c97888d5465990a02 Mon Sep 17 00:00:00 2001 From: Phil Shafer Date: Sun, 26 Apr 2015 01:58:37 -0400 Subject: [PATCH 90/90] add newline --- xohtml/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xohtml/Makefile.am b/xohtml/Makefile.am index f7b740e0..49dffedd 100644 --- a/xohtml/Makefile.am +++ b/xohtml/Makefile.am @@ -35,4 +35,4 @@ uninstall-hook: for file in ${INTERNAL_FILES} ${EXTERNAL_FILES}; do \ rm ${DESTDIR}${XO_SHAREDIR}/$$file ; done rmdir ${DESTDIR}${XO_SHAREDIR}/external - rm -f ${DESTDIR}${bindir}/xohtml \ No newline at end of file + rm -f ${DESTDIR}${bindir}/xohtml