svn commit: r345856 - in vendor/Juniper/libxo/dist: . doc libxo tests/core tests/core/saved tests/gettext tests/gettext/po/pig_latin tests/gettext/saved tests/xo tests/xo/saved xo
Phil Shafer
phil at FreeBSD.org
Wed Apr 3 21:47:22 UTC 2019
Author: phil
Date: Wed Apr 3 21:47:19 2019
New Revision: 345856
URL: https://svnweb.freebsd.org/changeset/base/345856
Log:
Import libxo 1.0.2
Added:
vendor/Juniper/libxo/dist/libxo/xo_explicit.h (contents, props changed)
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.H.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.H.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.HIPx.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.HIPx.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.HP.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.HP.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.J.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.J.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.JP.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.JP.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.T.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.T.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.X.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.X.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.XP.err
vendor/Juniper/libxo/dist/tests/xo/saved/xo_02.XP.out
vendor/Juniper/libxo/dist/tests/xo/xo_02.sh (contents, props changed)
Modified:
vendor/Juniper/libxo/dist/configure.ac
vendor/Juniper/libxo/dist/doc/api.rst
vendor/Juniper/libxo/dist/doc/libxo-manual.html
vendor/Juniper/libxo/dist/doc/xo.rst
vendor/Juniper/libxo/dist/libxo/Makefile.am
vendor/Juniper/libxo/dist/libxo/libxo.c
vendor/Juniper/libxo/dist/libxo/xo.h
vendor/Juniper/libxo/dist/libxo/xo_attr.3
vendor/Juniper/libxo/dist/libxo/xo_buf.h
vendor/Juniper/libxo/dist/libxo/xo_emit.3
vendor/Juniper/libxo/dist/libxo/xo_emit_f.3
vendor/Juniper/libxo/dist/libxo/xo_finish.3
vendor/Juniper/libxo/dist/libxo/xo_flush.3
vendor/Juniper/libxo/dist/libxo/xo_open_container.3
vendor/Juniper/libxo/dist/libxo/xo_open_list.3
vendor/Juniper/libxo/dist/libxo/xo_open_marker.3
vendor/Juniper/libxo/dist/libxo/xo_set_writer.3
vendor/Juniper/libxo/dist/tests/core/saved/test_01.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_02.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_03.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_04.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_05.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_05.JP.out
vendor/Juniper/libxo/dist/tests/core/saved/test_06.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_07.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_08.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_09.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_10.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_11.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.E.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.E.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.H.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.H.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.HIPx.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.HIPx.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.HP.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.HP.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.J.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.J.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.JP.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.JP.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.T.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.T.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.X.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.X.out
vendor/Juniper/libxo/dist/tests/core/saved/test_12.XP.err
vendor/Juniper/libxo/dist/tests/core/saved/test_12.XP.out
vendor/Juniper/libxo/dist/tests/core/test_12.c
vendor/Juniper/libxo/dist/tests/gettext/po/pig_latin/strerror.po
vendor/Juniper/libxo/dist/tests/gettext/saved/gt_01.J.out
vendor/Juniper/libxo/dist/tests/gettext/strerror.pot
vendor/Juniper/libxo/dist/tests/xo/Makefile.am
vendor/Juniper/libxo/dist/tests/xo/saved/xo_01.H.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_01.HIPx.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_01.HP.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_01.J.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_01.JP.out
vendor/Juniper/libxo/dist/tests/xo/saved/xo_01.T.out
vendor/Juniper/libxo/dist/tests/xo/xo_01.sh
vendor/Juniper/libxo/dist/xo/xo.1
vendor/Juniper/libxo/dist/xo/xo.c
Modified: vendor/Juniper/libxo/dist/configure.ac
==============================================================================
--- vendor/Juniper/libxo/dist/configure.ac Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/configure.ac Wed Apr 3 21:47:19 2019 (r345856)
@@ -12,7 +12,7 @@
#
AC_PREREQ(2.2)
-AC_INIT([libxo], [0.9.0], [phil at juniper.net])
+AC_INIT([libxo], [1.0.2], [phil at juniper.net])
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
# Support silent build rules. Requires at least automake-1.11.
Modified: vendor/Juniper/libxo/dist/doc/api.rst
==============================================================================
--- vendor/Juniper/libxo/dist/doc/api.rst Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/doc/api.rst Wed Apr 3 21:47:19 2019 (r345856)
@@ -400,28 +400,28 @@ string, since an inappropriate cast can ruin your day.
argument to `xo_emit_hv` points to a variable argument list that can
be used to retrieve arguments via `va_arg`.
-.. c:function:: int xo_emit (const char *fmt, ...)
+.. c:function:: xo_ssize_t xo_emit (const char *fmt, ...)
:param fmt: The format string, followed by zero or more arguments
:returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
- :rtype: int
+ :rtype: xo_ssize_t
-.. c:function:: int xo_emit_h (xo_handle_t *xop, const char *fmt, ...)
+.. c:function:: xo_ssize_t xo_emit_h (xo_handle_t *xop, const char *fmt, ...)
:param xop: Handle for modify (or NULL for default handle)
:type xop: xo_handle_t \*
:param fmt: The format string, followed by zero or more arguments
:returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
- :rtype: int
+ :rtype: xo_ssize_t
-.. c:function:: int xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap)
+.. c:function:: xo_ssize_t xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap)
:param xop: Handle for modify (or NULL for default handle)
:type xop: xo_handle_t \*
:param fmt: The format string
:param va_list vap: A set of variadic arguments
:returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
- :rtype: int
+ :rtype: xo_ssize_t
.. index:: xo_emit_field
@@ -434,7 +434,7 @@ scenario where one would otherwise need to compose a f
descriptors using `snprintf`. The individual parts of the format
descriptor are passed in distinctly.
-.. c:function:: int xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)
+.. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)
:param rolmod: A comma-separated list of field roles and field modifiers
:type rolmod: const char *
@@ -445,7 +445,7 @@ descriptor are passed in distinctly.
:param efmt: Encoding format string, followed by additional arguments
:type efmt: const char *
:returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
- :rtype: int
+ :rtype: xo_ssize_t
::
@@ -453,7 +453,7 @@ descriptor are passed in distinctly.
xo_emit_field("T", "Host name is ", NULL, NULL);
xo_emit_field("V", "host-name", NULL, NULL, host-name);
-.. c:function:: int xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)
+.. c:function:: xo_ssize_t xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)
:param xop: Handle for modify (or NULL for default handle)
:type xop: xo_handle_t \*
@@ -466,9 +466,9 @@ descriptor are passed in distinctly.
:param efmt: Encoding format string, followed by additional arguments
:type efmt: const char *
:returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
- :rtype: int
+ :rtype: xo_ssize_t
-.. c:function:: int xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, va_list vap)
+.. c:function:: xo_ssize_t xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, va_list vap)
:param xop: Handle for modify (or NULL for default handle)
:type xop: xo_handle_t \*
@@ -482,7 +482,7 @@ descriptor are passed in distinctly.
:type efmt: const char *
:param va_list vap: A set of variadic arguments
:returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
- :rtype: int
+ :rtype: xo_ssize_t
.. index:: xo_attr
.. _xo_attr:
@@ -505,14 +505,14 @@ Since attributes are only emitted in XML, their use sh
to meta-data and additional or redundant representations of data
already emitted in other form.
-.. c:function:: int xo_attr (const char *name, const char *fmt, ...)
+.. c:function:: xo_ssize_t xo_attr (const char *name, const char *fmt, ...)
:param name: Attribute name
:type name: const char *
:param fmt: Attribute value, as variadic arguments
:type fmt: const char *
:returns: -1 for error, or the number of bytes in the formatted attribute value
- :rtype: int
+ :rtype: xo_ssize_t
::
@@ -525,7 +525,7 @@ already emitted in other form.
<login-time seconds="1408336270">00:14</login-time>
-.. c:function:: int xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...)
+.. c:function:: xo_ssize_t xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...)
:param xop: Handle for modify (or NULL for default handle)
:type xop: xo_handle_t \*
@@ -533,7 +533,7 @@ already emitted in other form.
The `xo_attr_h` function follows the conventions of `xo_attr` but
adds an explicit libxo handle.
-.. c:function:: int xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)
+.. c:function:: xo_ssize_t xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)
The `xo_attr_h` function follows the conventions of `xo_attr_h`
but replaced the variadic list with a variadic pointer.
Modified: vendor/Juniper/libxo/dist/doc/libxo-manual.html
==============================================================================
--- vendor/Juniper/libxo/dist/doc/libxo-manual.html Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/doc/libxo-manual.html Wed Apr 3 21:47:19 2019 (r345856)
@@ -515,7 +515,7 @@ li.indline1 {
}
@top-right {
- content: "May 2018";
+ content: "April 2019";
}
@top-center {
@@ -22011,7 +22011,7 @@ jQuery(function ($) {
</tr>
<tr>
<td class="header left"></td>
-<td class="header right">May 21, 2018</td>
+<td class="header right">April 2, 2019</td>
</tr>
</table></div>
<p id="title" class="title">libxo: The Easy Way to Generate text, XML, JSON, and HTML output<br><span class="filename">libxo-manual</span></p>
Modified: vendor/Juniper/libxo/dist/doc/xo.rst
==============================================================================
--- vendor/Juniper/libxo/dist/doc/xo.rst Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/doc/xo.rst Wed Apr 3 21:47:19 2019 (r345856)
@@ -75,7 +75,7 @@ prepend data to the XPath values used for HTML output
EXAMPLE;
#!/bin/sh
xo --open top/data
- xo --depth 2 '{tag}' value
+ xo --depth 2 '{:tag}' value
xo --close top/data
XML:
<top>
@@ -90,6 +90,84 @@ prepend data to the XPath values used for HTML output
}
}
+When making partial lines of output (where the format string does not
+include a newline), use the `--continuation` option to let secondary
+invocations know they are adding data to an existing line.
+
+When emitting a series of objects, use the `--not-first` option to
+ensure that any details from the previous object (e.g. commas in JSON)
+are handled correctly.
+
+Use the `--top-wrap` option to ensure any top-level object details are
+handled correctly, e.g. wrap the entire output in a top-level set of
+braces for JSON output.
+
+ EXAMPLE;
+ #!/bin/sh
+ xo --top-wrap --open top/data
+ xo --depth 2 'First {:tag} ' value1
+ xo --depth 2 --continuation 'and then {:tag}\n' value2
+ xo --top-wrap --close top/data
+ TEXT:
+ First value1 and then value2
+ HTML:
+ <div class="line">
+ <div class="text">First </div>
+ <div class="data" data-tag="tag">value1</div>
+ <div class="text"> </div>
+ <div class="text">and then </div>
+ <div class="data" data-tag="tag">value2</div>
+ </div>
+ XML:
+ <top>
+ <data>
+ <tag>value1</tag>
+ <tag>value2</tag>
+ </data>
+ </top>
+ JSON:
+ {
+ "top": {
+ "data": {
+ "tag": "value1",
+ "tag": "value2"
+ }
+ }
+ }
+
+Lists and Instances
+-------------------
+
+A "*list*" is set of one or more instances that appear under the same
+parent. The instances contain details about a specific object. One
+can think of instances as objects or records. A call is needed to
+open and close the list, while a distinct call is needed to open and
+close each instance of the list.
+
+Use the `--open-list` and `--open-instances` to open lists and
+instances. Use the `--close-list` and `--close-instances` to close
+them. Each of these options take a `name` parameter, providing the
+name of the list and instance.
+
+In the following example, a list named "machine" is created with three
+instances:
+
+ opts="--json"
+ xo $opts --open-list machine
+ NF=
+ for name in red green blue; do
+ xo $opts --depth 1 $NF --open-instance machine
+ xo $opts --depth 2 "Machine {k:name} has {:memory}\n" $name 55
+ xo $opts --depth 1 --close-instance machine
+ NF=--not-first
+ done
+ xo $opts $NF --close-list machine
+
+The normal `libxo` functions use a state machine to help these
+transitions, but since each `xo` command is invoked independent of the
+previous calls, the state must be passed in explicitly via these
+command line options.
+
Command Line Options
--------------------
@@ -97,15 +175,23 @@ Command Line Options
Usage: xo [options] format [fields]
--close <path> Close tags for the given path
+ --close-instance <name> Close an open instance name
+ --close-list <name> Close an open list name
+ --continuation OR -C Output belongs on same line as previous output
--depth <num> Set the depth for pretty printing
--help Display this help text
--html OR -H Generate HTML output
--json OR -J Generate JSON output
--leading-xpath <path> Add a prefix to generated XPaths (HTML)
+ --not-first Indicate this object is not the first (JSON)
--open <path> Open tags for the given path
+ --open-instance <name> Open an instance given by name
+ --open-list <name> Open a list given by name
+ --option <opts> -or -O <opts> Give formatting options
--pretty OR -p Make 'pretty' output (add indent, newlines)
--style <style> Generate given style (xml, json, text, html)
--text OR -T Generate text output (the default style)
+ --top-wrap Generate a top-level object wrapper (JSON)
--version Display version information
--warn OR -W Display warnings in text on stderr
--warn-xml Display warnings in xml on stdout
Modified: vendor/Juniper/libxo/dist/libxo/Makefile.am
==============================================================================
--- vendor/Juniper/libxo/dist/libxo/Makefile.am Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/libxo/Makefile.am Wed Apr 3 21:47:19 2019 (r345856)
@@ -35,6 +35,7 @@ libxoinc_HEADERS = \
noinst_HEADERS = \
xo_buf.h \
+ xo_explicit.h \
xo_humanize.h \
xo_wcwidth.h
Modified: vendor/Juniper/libxo/dist/libxo/libxo.c
==============================================================================
--- vendor/Juniper/libxo/dist/libxo/libxo.c Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/libxo/libxo.c Wed Apr 3 21:47:19 2019 (r345856)
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, Juniper Networks, Inc.
+ * Copyright (c) 2014-2018, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
@@ -47,6 +47,7 @@
#include "xo.h"
#include "xo_encoder.h"
#include "xo_buf.h"
+#include "xo_explicit.h"
/*
* We ask wcwidth() to do an impossible job, really. It's supposed to
@@ -158,40 +159,9 @@ typedef unsigned xo_xsf_flags_t; /* XSF_* flags */
(XSF_NOT_FIRST | XSF_CONTENT | XSF_EMIT | XSF_EMIT_KEY | XSF_EMIT_LEAF_LIST )
/*
- * A word about states: We use a finite state machine (FMS) approach
- * to help remove fragility from the caller's code. Instead of
- * requiring a specific order of calls, we'll allow the caller more
- * flexibility and make the library responsible for recovering from
- * missed steps. The goal is that the library should not be capable
- * of emitting invalid xml or json, but the developer shouldn't need
- * to know or understand all the details about these encodings.
- *
- * You can think of states as either states or events, since they
- * function rather like both. None of the XO_CLOSE_* events will
- * persist as states, since the matching stack frame will be popped.
- * Same is true of XSS_EMIT, which is an event that asks us to
- * prep for emitting output fields.
+ * Turn the transition between two states into a number suitable for
+ * a "switch" statement.
*/
-
-/* Stack frame states */
-typedef unsigned xo_state_t;
-#define XSS_INIT 0 /* Initial stack state */
-#define XSS_OPEN_CONTAINER 1
-#define XSS_CLOSE_CONTAINER 2
-#define XSS_OPEN_LIST 3
-#define XSS_CLOSE_LIST 4
-#define XSS_OPEN_INSTANCE 5
-#define XSS_CLOSE_INSTANCE 6
-#define XSS_OPEN_LEAF_LIST 7
-#define XSS_CLOSE_LEAF_LIST 8
-#define XSS_DISCARDING 9 /* Discarding data until recovered */
-#define XSS_MARKER 10 /* xo_open_marker's marker */
-#define XSS_EMIT 11 /* xo_emit has a leaf field */
-#define XSS_EMIT_LEAF_LIST 12 /* xo_emit has a leaf-list ({l:}) */
-#define XSS_FINISH 13 /* xo_finish was called */
-
-#define XSS_MAX 13
-
#define XSS_TRANSITION(_old, _new) ((_old) << 8 | (_new))
/*
@@ -288,8 +258,8 @@ struct xo_handle_s {
ssize_t xo_units_offset; /* Start of units insertion point */
ssize_t xo_columns; /* Columns emitted during this xo_emit call */
#ifndef LIBXO_TEXT_ONLY
- uint8_t xo_color_map_fg[XO_NUM_COLORS]; /* Foreground color mappings */
- uint8_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */
+ xo_color_t xo_color_map_fg[XO_NUM_COLORS]; /* Foreground color mappings */
+ xo_color_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */
#endif /* LIBXO_TEXT_ONLY */
xo_colors_t xo_colors; /* Current color and effect values */
xo_buffer_t xo_color_buf; /* HTML: buffer of colors and effects */
@@ -321,6 +291,7 @@ struct xo_handle_s {
#define XOIF_UNITS_PENDING XOF_BIT(4) /* We have a units-insertion pending */
#define XOIF_INIT_IN_PROGRESS XOF_BIT(5) /* Init of handle is in progress */
+#define XOIF_MADE_OUTPUT XOF_BIT(6) /* Have already made output */
/* Flags for formatting functions */
typedef unsigned long xo_xff_flags_t;
@@ -468,7 +439,7 @@ static void
xo_failure (xo_handle_t *xop, const char *fmt, ...);
static ssize_t
-xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
+xo_transition (xo_handle_t *xop, xo_xof_flags_t flags, const char *name,
xo_state_t new_state);
static int
@@ -506,6 +477,20 @@ xo_style (xo_handle_t *xop UNUSED)
}
/*
+ * Allow the compiler to optimize out non-text-only code while
+ * still compiling it.
+ */
+static inline int
+xo_text_only (void)
+{
+#ifdef LIBXO_TEXT_ONLY
+ return TRUE;
+#else /* LIBXO_TEXT_ONLY */
+ return FALSE;
+#endif /* LIBXO_TEXT_ONLY */
+}
+
+/*
* Callback to write data to a FILE pointer
*/
static xo_ssize_t
@@ -607,6 +592,28 @@ xo_no_setlocale (void)
}
/*
+ * For XML, the first character of a tag cannot be numeric, but people
+ * will likely not notice. So we people-proof them by forcing a leading
+ * underscore if they use invalid tags. Note that this doesn't cover
+ * all broken tags, just this fairly specific case.
+ */
+static const char *
+xo_xml_leader_len (xo_handle_t *xop, const char *name, xo_ssize_t nlen)
+{
+ if (isalpha(name[0]) || name[0] == '_')
+ return "";
+
+ xo_failure(xop, "invalid XML tag name: '%.*s'", nlen, name);
+ return "_";
+}
+
+static const char *
+xo_xml_leader (xo_handle_t *xop, const char *name)
+{
+ return xo_xml_leader_len(xop, name, strlen(name));
+}
+
+/*
* 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
@@ -2194,9 +2201,8 @@ xo_set_style_name (xo_handle_t *xop, const char *name)
static void
xo_set_color_map (xo_handle_t *xop, char *value)
{
-#ifdef LIBXO_TEXT_ONLY
- return;
-#endif /* LIBXO_TEXT_ONLY */
+ if (xo_text_only())
+ return;
char *cp, *ep, *vp, *np;
ssize_t len = value ? strlen(value) + 1 : 0;
@@ -2214,8 +2220,11 @@ xo_set_color_map (xo_handle_t *xop, char *value)
fg = *cp ? xo_color_find(cp) : -1;
bg = (vp && *vp) ? xo_color_find(vp) : -1;
+#ifndef LIBXO_TEXT_ONLY
xop->xo_color_map_fg[num] = (fg < 0) ? num : fg;
xop->xo_color_map_bg[num] = (bg < 0) ? num : bg;
+#endif /* LIBXO_TEXT_ONLY */
+
if (++num > XO_NUM_COLORS)
break;
}
@@ -2226,9 +2235,11 @@ xo_set_color_map (xo_handle_t *xop, char *value)
else
XOF_CLEAR(xop, XOF_COLOR_MAP);
+#ifndef LIBXO_TEXT_ONLY
/* Fill in the rest of the colors with the defaults */
for ( ; num < XO_NUM_COLORS; num++)
xop->xo_color_map_fg[num] = xop->xo_color_map_bg[num] = num;
+#endif /* LIBXO_TEXT_ONLY */
}
static int
@@ -2600,6 +2611,12 @@ xo_line_ensure_open (xo_handle_t *xop, xo_xff_flags_t
static char div_open[] = "<div class=\"line\">";
static char div_open_blank[] = "<div class=\"blank-line\">";
+ if (XOF_ISSET(xop, XOF_CONTINUATION)) {
+ XOF_CLEAR(xop, XOF_CONTINUATION);
+ XOIF_SET(xop, XOIF_DIV_OPEN);
+ return;
+ }
+
if (XOIF_ISSET(xop, XOIF_DIV_OPEN))
return;
@@ -3505,51 +3522,54 @@ xo_do_format_field (xo_handle_t *xop, xo_buffer_t *xbp
ssize_t columns = rc = xo_vsnprintf(xop, xbp, newfmt,
xop->xo_vap);
- /*
- * For XML and HTML, we need "&<>" processing; for JSON,
- * it's quotes. Text gets nothing.
- */
- switch (style) {
- case XO_STYLE_XML:
- if (flags & XFF_TRIM_WS)
- columns = rc = xo_trim_ws(xbp, rc);
- /* FALLTHRU */
- case XO_STYLE_HTML:
- rc = xo_escape_xml(xbp, rc, (flags & XFF_ATTR));
- break;
+ if (rc > 0) {
+ /*
+ * For XML and HTML, we need "&<>" processing; for JSON,
+ * it's quotes. Text gets nothing.
+ */
+ switch (style) {
+ case XO_STYLE_XML:
+ if (flags & XFF_TRIM_WS)
+ columns = rc = xo_trim_ws(xbp, rc);
+ /* FALLTHRU */
+ case XO_STYLE_HTML:
+ rc = xo_escape_xml(xbp, rc, (flags & XFF_ATTR));
+ break;
- case XO_STYLE_JSON:
- if (flags & XFF_TRIM_WS)
- columns = rc = xo_trim_ws(xbp, rc);
- rc = xo_escape_json(xbp, rc, 0);
- break;
+ case XO_STYLE_JSON:
+ if (flags & XFF_TRIM_WS)
+ columns = rc = xo_trim_ws(xbp, rc);
+ rc = xo_escape_json(xbp, rc, 0);
+ break;
- case XO_STYLE_SDPARAMS:
- if (flags & XFF_TRIM_WS)
- columns = rc = xo_trim_ws(xbp, rc);
- rc = xo_escape_sdparams(xbp, rc, 0);
- break;
+ case XO_STYLE_SDPARAMS:
+ if (flags & XFF_TRIM_WS)
+ columns = rc = xo_trim_ws(xbp, rc);
+ rc = xo_escape_sdparams(xbp, rc, 0);
+ break;
- case XO_STYLE_ENCODER:
- if (flags & XFF_TRIM_WS)
- columns = rc = xo_trim_ws(xbp, rc);
- break;
- }
+ case XO_STYLE_ENCODER:
+ if (flags & XFF_TRIM_WS)
+ columns = rc = xo_trim_ws(xbp, rc);
+ break;
+ }
- /*
- * We can assume all the non-%s data we've
- * added is ASCII, so the columns and bytes are the
- * same. xo_format_string handles all the fancy
- * string conversions and updates xo_anchor_columns
- * accordingly.
- */
- if (XOF_ISSET(xop, XOF_COLUMNS))
- xop->xo_columns += columns;
- if (XOIF_ISSET(xop, XOIF_ANCHOR))
- xop->xo_anchor_columns += columns;
+ /*
+ * We can assume all the non-%s data we've
+ * added is ASCII, so the columns and bytes are the
+ * same. xo_format_string handles all the fancy
+ * string conversions and updates xo_anchor_columns
+ * accordingly.
+ */
+ if (XOF_ISSET(xop, XOF_COLUMNS))
+ xop->xo_columns += columns;
+ if (XOIF_ISSET(xop, XOIF_ANCHOR))
+ xop->xo_anchor_columns += columns;
+ }
}
- xbp->xb_curp += rc;
+ if (rc > 0)
+ xbp->xb_curp += rc;
}
/*
@@ -4233,7 +4253,22 @@ xo_format_is_numeric (const char *fmt, ssize_t flen)
return (strchr("diouDOUeEfFgG", *fmt) == NULL) ? FALSE : TRUE;
}
+/*
+ * Update the stack flags using the object flags, allowing callers
+ * to monkey with the stack flags without even knowing they exist.
+ */
static void
+xo_stack_set_flags (xo_handle_t *xop)
+{
+ if (XOF_ISSET(xop, XOF_NOT_FIRST)) {
+ xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth];
+
+ xsp->xs_flags |= XSF_NOT_FIRST;
+ XOF_CLEAR(xop, XOF_NOT_FIRST);
+ }
+}
+
+static void
xo_format_prep (xo_handle_t *xop, xo_xff_flags_t flags)
{
if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) {
@@ -4337,6 +4372,8 @@ xo_format_value (xo_handle_t *xop, const char *name, s
xo_buffer_t *xbp = &xop->xo_data;
xo_humanize_save_t save; /* Save values for humanizing logic */
+ const char *leader = xo_xml_leader_len(xop, name, nlen);
+
switch (xo_style(xop)) {
case XO_STYLE_TEXT:
if (flags & XFF_ENCODE_ONLY)
@@ -4391,6 +4428,8 @@ xo_format_value (xo_handle_t *xop, const char *name, s
if (pretty)
xo_buf_indent(xop, -1);
xo_data_append(xop, "<", 1);
+ if (*leader)
+ xo_data_append(xop, leader, 1);
xo_data_escape(xop, name, nlen);
if (xop->xo_attrs.xb_curp != xop->xo_attrs.xb_bufp) {
@@ -4423,6 +4462,8 @@ xo_format_value (xo_handle_t *xop, const char *name, s
xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
xo_data_append(xop, "</", 2);
+ if (*leader)
+ xo_data_append(xop, leader, 1);
xo_data_escape(xop, name, nlen);
xo_data_append(xop, ">", 1);
if (pretty)
@@ -4446,6 +4487,8 @@ xo_format_value (xo_handle_t *xop, const char *name, s
flen = strlen(fmt);
}
+ xo_stack_set_flags(xop);
+
int first = (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST)
? 0 : 1;
@@ -4751,9 +4794,8 @@ xo_effect_find (const char *str)
static void
xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp, char *str)
{
-#ifdef LIBXO_TEXT_ONLY
- return;
-#endif /* LIBXO_TEXT_ONLY */
+ if (xo_text_only())
+ return;
char *cp, *ep, *np, *xp;
ssize_t len = strlen(str);
@@ -4837,12 +4879,9 @@ xo_colors_enabled (xo_handle_t *xop UNUSED)
* the incoming foreground and background colors from the map.
*/
static void
-xo_colors_update (xo_handle_t *xop, xo_colors_t *newp)
+xo_colors_update (xo_handle_t *xop UNUSED, xo_colors_t *newp UNUSED)
{
-#ifdef LIBXO_TEXT_ONLY
- return;
-#endif /* LIBXO_TEXT_ONLY */
-
+#ifndef LIBXO_TEXT_ONLY
xo_color_t fg = newp->xoc_col_fg;
if (XOF_ISSET(xop, XOF_COLOR_MAP) && fg < XO_NUM_COLORS)
fg = xop->xo_color_map_fg[fg]; /* Fetch from color map */
@@ -4852,6 +4891,7 @@ xo_colors_update (xo_handle_t *xop, xo_colors_t *newp)
if (XOF_ISSET(xop, XOF_COLOR_MAP) && bg < XO_NUM_COLORS)
bg = xop->xo_color_map_bg[bg]; /* Fetch from color map */
newp->xoc_col_bg = bg;
+#endif /* LIBXO_TEXT_ONLY */
}
static void
@@ -6454,9 +6494,7 @@ xo_do_emit_fields (xo_handle_t *xop, xo_field_info_t *
/* If we don't have an anchor, write the text out */
if (flush && !XOIF_ISSET(xop, XOIF_ANCHOR)) {
- if (xo_write(xop) < 0)
- rc = -1; /* Report failure */
- else if (xo_flush_h(xop) < 0)
+ if (xo_flush_h(xop) < 0)
rc = -1;
}
@@ -6804,17 +6842,6 @@ xo_attr (const char *name, const char *fmt, ...)
}
static void
-xo_stack_set_flags (xo_handle_t *xop)
-{
- if (XOF_ISSET(xop, XOF_NOT_FIRST)) {
- xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth];
-
- xsp->xs_flags |= XSF_NOT_FIRST;
- XOF_CLEAR(xop, XOF_NOT_FIRST);
- }
-}
-
-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)
{
@@ -6889,6 +6916,15 @@ xo_set_depth (xo_handle_t *xop, int depth)
xop->xo_depth += depth;
xop->xo_indent += depth;
+
+ /*
+ * Handling the "top wrapper" for JSON is a bit of a pain. Here
+ * we need to detect that the depth has been changed to set the
+ * "XOIF_TOP_EMITTED" flag correctly.
+ */
+ if (xop->xo_style == XO_STYLE_JSON
+ && !XOF_ISSET(xop, XOF_NO_TOP) && xop->xo_depth > 0)
+ XOIF_SET(xop, XOIF_TOP_EMITTED);
}
static xo_xsf_flags_t
@@ -6925,11 +6961,12 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t
name = XO_FAILURE_NAME;
}
+ const char *leader = xo_xml_leader(xop, name);
flags |= xop->xo_flags; /* Pick up handle flags */
switch (xo_style(xop)) {
case XO_STYLE_XML:
- rc = xo_printf(xop, "%*s<%s", xo_indent(xop), "", name);
+ rc = xo_printf(xop, "%*s<%s%s", xo_indent(xop), "", leader, name);
if (xop->xo_attrs.xb_curp != xop->xo_attrs.xb_bufp) {
rc += xop->xo_attrs.xb_curp - xop->xo_attrs.xb_bufp;
@@ -6970,7 +7007,7 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t
return rc;
}
-static int
+xo_ssize_t
xo_open_container_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
return xo_transition(xop, flags, name, XSS_OPEN_CONTAINER);
@@ -7025,15 +7062,20 @@ xo_do_close_container (xo_handle_t *xop, const char *n
}
}
+ const char *leader = xo_xml_leader(xop, name);
+
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>%s", xo_indent(xop), "", name, ppn);
+ rc = xo_printf(xop, "%*s</%s%s>%s", xo_indent(xop), "", leader, name, ppn);
break;
case XO_STYLE_JSON:
+ xo_stack_set_flags(xop);
+
pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : "";
- ppn = (xop->xo_depth <= 1) ? "\n" : "";
+ ppn = (xop->xo_depth <= 1) ? pre_nl : "";
+ ppn = "";
xo_depth_change(xop, name, -1, -1, XSS_CLOSE_CONTAINER, 0);
rc = xo_printf(xop, "%s%*s}%s", pre_nl, xo_indent(xop), "", ppn);
@@ -7082,7 +7124,7 @@ xo_close_container_d (void)
}
static int
-xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
+xo_do_open_list (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
ssize_t rc = 0;
int indent = 0;
@@ -7126,8 +7168,8 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flag
return rc;
}
-static int
-xo_open_list_hf (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
+xo_ssize_t
+xo_open_list_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
return xo_transition(xop, flags, name, XSS_OPEN_LIST);
}
@@ -7228,7 +7270,7 @@ xo_close_list_d (void)
}
static int
-xo_do_open_leaf_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
+xo_do_open_leaf_list (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
ssize_t rc = 0;
int indent = 0;
@@ -7322,7 +7364,7 @@ xo_do_close_leaf_list (xo_handle_t *xop, const char *n
}
static int
-xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
+xo_do_open_instance (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
xop = xo_default(xop);
@@ -7330,16 +7372,17 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t
const char *ppn = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : "";
const char *pre_nl = "";
- flags |= xop->xo_flags;
-
if (name == NULL) {
xo_failure(xop, "NULL passed for instance name");
name = XO_FAILURE_NAME;
}
+ const char *leader = xo_xml_leader(xop, name);
+ flags |= xop->xo_flags;
+
switch (xo_style(xop)) {
case XO_STYLE_XML:
- rc = xo_printf(xop, "%*s<%s", xo_indent(xop), "", name);
+ rc = xo_printf(xop, "%*s<%s%s", xo_indent(xop), "", leader, name);
if (xop->xo_attrs.xb_curp != xop->xo_attrs.xb_bufp) {
rc += xop->xo_attrs.xb_curp - xop->xo_attrs.xb_bufp;
@@ -7375,8 +7418,8 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t
return rc;
}
-static int
-xo_open_instance_hf (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
+xo_ssize_t
+xo_open_instance_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
return xo_transition(xop, flags, name, XSS_OPEN_INSTANCE);
}
@@ -7430,10 +7473,12 @@ xo_do_close_instance (xo_handle_t *xop, const char *na
}
}
+ const char *leader = xo_xml_leader(xop, name);
+
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>%s", xo_indent(xop), "", name, ppn);
+ rc = xo_printf(xop, "%*s</%s%s>%s", xo_indent(xop), "", leader, name, ppn);
break;
case XO_STYLE_JSON:
@@ -7599,7 +7644,7 @@ xo_do_close (xo_handle_t *xop, const char *name, xo_st
* We are in a given state and need to transition to the new state.
*/
static ssize_t
-xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
+xo_transition (xo_handle_t *xop, xo_xof_flags_t flags, const char *name,
xo_state_t new_state)
{
xo_stack_t *xsp;
@@ -7855,9 +7900,12 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags,
/* Handle the flush flag */
if (rc >= 0 && XOF_ISSET(xop, XOF_FLUSH))
- if (xo_flush_h(xop))
+ if (xo_flush_h(xop) < 0)
rc = -1;
+ /* We have now official made output */
+ XOIF_SET(xop, XOIF_MADE_OUTPUT);
+
return rc;
marker_prevents_close:
@@ -7950,7 +7998,7 @@ xo_flush (void)
xo_ssize_t
xo_finish_h (xo_handle_t *xop)
{
- const char *cp = "";
+ const char *open_if_empty = "";
xop = xo_default(xop);
if (!XOF_ISSET(xop, XOF_NO_CLOSE))
@@ -7959,11 +8007,17 @@ xo_finish_h (xo_handle_t *xop)
switch (xo_style(xop)) {
case XO_STYLE_JSON:
if (!XOF_ISSET(xop, XOF_NO_TOP)) {
+ const char *pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : "";
+
if (XOIF_ISSET(xop, XOIF_TOP_EMITTED))
XOIF_CLEAR(xop, XOIF_TOP_EMITTED); /* Turn off before output */
- else
- cp = "{ ";
- xo_printf(xop, "%*s%s}\n",xo_indent(xop), "", cp);
+ else if (!XOIF_ISSET(xop, XOIF_MADE_OUTPUT)) {
+ open_if_empty = "{ ";
+ pre_nl = "";
+ }
+
+ xo_printf(xop, "%s%*s%s}\n",
+ pre_nl, xo_indent(xop), "", open_if_empty);
}
break;
@@ -8401,4 +8455,47 @@ xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t en
xop->xo_style = XO_STYLE_ENCODER;
xop->xo_encoder = encoder;
+}
+
+/*
+ * The xo(1) utility needs to be able to open and close lists and
+ * instances, but since it's called without "state", we cannot
+ * rely on the state transitions (in xo_transition) to DTRT, so
+ * we have a mechanism for external parties to "force" transitions
+ * that would otherwise be impossible. This is not a general
+ * mechanism, and is really tailored only for xo(1).
+ */
+void
+xo_explicit_transition (xo_handle_t *xop, xo_state_t new_state,
+ const char *name, xo_xof_flags_t flags)
+{
+ xo_xsf_flags_t xsf_flags;
+
+ xop = xo_default(xop);
+
+ switch (new_state) {
+
+ case XSS_OPEN_LIST:
+ xo_do_open_list(xop, flags, name);
+ break;
+
+ case XSS_OPEN_INSTANCE:
+ xo_do_open_instance(xop, flags, name);
+ break;
+
+ case XSS_CLOSE_INSTANCE:
+ xo_depth_change(xop, name, 1, 1, XSS_OPEN_INSTANCE,
+ xo_stack_flags(flags));
+ xo_stack_set_flags(xop);
+ xo_do_close_instance(xop, name);
+ break;
+
+ case XSS_CLOSE_LIST:
+ xsf_flags = XOF_ISSET(xop, XOF_NOT_FIRST) ? XSF_NOT_FIRST : 0;
+
+ xo_depth_change(xop, name, 1, 1, XSS_OPEN_LIST,
+ XSF_LIST | xsf_flags | xo_stack_flags(flags));
+ xo_do_close_list(xop, name);
+ break;
+ }
}
Modified: vendor/Juniper/libxo/dist/libxo/xo.h
==============================================================================
--- vendor/Juniper/libxo/dist/libxo/xo.h Wed Apr 3 21:01:53 2019 (r345855)
+++ vendor/Juniper/libxo/dist/libxo/xo.h Wed Apr 3 21:47:19 2019 (r345856)
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, Juniper Networks, Inc.
+ * Copyright (c) 2014-2018, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
@@ -102,6 +102,7 @@ typedef unsigned long long xo_xof_flags_t;
#define XOF_RETAIN_NONE XOF_BIT(31) /** Prevent use of XOEF_RETAIN */
#define XOF_COLOR_MAP XOF_BIT(32) /** Color map has been initialized */
+#define XOF_CONTINUATION XOF_BIT(33) /** Continuation of previous line */
typedef unsigned xo_emit_flags_t; /* Flags to xo_emit() and friends */
#define XOEF_RETAIN (1<<0) /* Retain parsed formatting information */
@@ -126,11 +127,11 @@ typedef struct xo_handle_s xo_handle_t; /* Handle for
* sizes. We want to fix this but allow for backwards compatibility
* where needed.
*/
-#ifdef USE_INT_RETURN_CODES
+#ifdef XO_USE_INT_RETURN_CODES
typedef int xo_ssize_t; /* Buffer size */
-#else /* USE_INT_RETURN_CODES */
+#else /* XO_USE_INT_RETURN_CODES */
typedef ssize_t xo_ssize_t; /* Buffer size */
-#endif /* USE_INT_RETURN_CODES */
+#endif /* XO_USE_INT_RETURN_CODES */
typedef xo_ssize_t (*xo_write_func_t)(void *, const char *);
typedef void (*xo_close_func_t)(void *);
@@ -219,36 +220,36 @@ xo_ssize_t
xo_emit_f (xo_emit_flags_t flags, const char *fmt, ...);
PRINTFLIKE(2, 0)
-static inline int
+static inline xo_ssize_t
xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
{
return xo_emit_hv(xop, fmt, vap);
}
PRINTFLIKE(2, 3)
-static inline int
+static inline xo_ssize_t
xo_emit_hp (xo_handle_t *xop, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
- int rc = xo_emit_hv(xop, fmt, vap);
+ xo_ssize_t rc = xo_emit_hv(xop, fmt, vap);
va_end(vap);
return rc;
}
PRINTFLIKE(1, 2)
-static inline int
+static inline xo_ssize_t
xo_emit_p (const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
- int rc = xo_emit_hv(NULL, fmt, vap);
+ xo_ssize_t rc = xo_emit_hv(NULL, fmt, vap);
va_end(vap);
return rc;
}
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list