Import libxo 1.0.2
This commit is contained in:
parent
b7a4d12840
commit
8daa90e98c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/Juniper/libxo/dist/; revision=345856 svn path=/vendor/Juniper/libxo/1.0.2/; revision=345857; tag=vendor/Juniper/libxo/1.0.2
@ -12,7 +12,7 @@
|
||||
#
|
||||
|
||||
AC_PREREQ(2.2)
|
||||
AC_INIT([libxo], [0.9.0], [phil@juniper.net])
|
||||
AC_INIT([libxo], [1.0.2], [phil@juniper.net])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
|
||||
|
||||
# Support silent build rules. Requires at least automake-1.11.
|
||||
|
32
doc/api.rst
32
doc/api.rst
@ -400,28 +400,28 @@ string, since an inappropriate cast can ruin your day. The vap
|
||||
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 format
|
||||
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 should be limited
|
||||
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.
|
||||
|
@ -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>
|
||||
|
88
doc/xo.rst
88
doc/xo.rst
@ -75,7 +75,7 @@ prepend data to the XPath values used for HTML output style::
|
||||
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 style::
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -35,6 +35,7 @@ libxoinc_HEADERS = \
|
||||
|
||||
noinst_HEADERS = \
|
||||
xo_buf.h \
|
||||
xo_explicit.h \
|
||||
xo_humanize.h \
|
||||
xo_wcwidth.h
|
||||
|
||||
|
341
libxo/libxo.c
341
libxo/libxo.c
@ -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
|
||||
@ -505,6 +476,20 @@ xo_style (xo_handle_t *xop UNUSED)
|
||||
#endif /* LIBXO_TEXT_ONLY */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@ -606,6 +591,28 @@ xo_no_setlocale (void)
|
||||
xo_locale_inited = 1; /* Skip initialization */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -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 flags UNUSED)
|
||||
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,6 +4253,21 @@ 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)
|
||||
{
|
||||
@ -4337,6 +4372,8 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
|
||||
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, ssize_t nlen,
|
||||
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, ssize_t nlen,
|
||||
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, ssize_t nlen,
|
||||
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 *fields,
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -6803,17 +6841,6 @@ xo_attr (const char *name, const char *fmt, ...)
|
||||
return rc;
|
||||
}
|
||||
|
||||
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 flags, const char *name)
|
||||
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 flags, const char *name)
|
||||
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 *name)
|
||||
}
|
||||
}
|
||||
|
||||
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 flags, const char *name)
|
||||
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 *name)
|
||||
}
|
||||
|
||||
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 flags, const char *name)
|
||||
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 flags, const char *name)
|
||||
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 *name)
|
||||
}
|
||||
}
|
||||
|
||||
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_state_t new_state)
|
||||
* 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, const char *name,
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -8402,3 +8456,46 @@ xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t encoder)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
38
libxo/xo.h
38
libxo/xo.h
@ -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 XO output */
|
||||
* 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;
|
||||
}
|
||||
|
||||
PRINTFLIKE(3, 0)
|
||||
static inline int
|
||||
static inline xo_ssize_t
|
||||
xo_emit_hvfp (xo_handle_t *xop, xo_emit_flags_t flags,
|
||||
const char *fmt, va_list vap)
|
||||
{
|
||||
@ -256,27 +257,30 @@ xo_emit_hvfp (xo_handle_t *xop, xo_emit_flags_t flags,
|
||||
}
|
||||
|
||||
PRINTFLIKE(3, 4)
|
||||
static inline int
|
||||
static inline xo_ssize_t
|
||||
xo_emit_hfp (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...)
|
||||
{
|
||||
va_list vap;
|
||||
va_start(vap, fmt);
|
||||
int rc = xo_emit_hvf(xop, flags, fmt, vap);
|
||||
xo_ssize_t rc = xo_emit_hvf(xop, flags, fmt, vap);
|
||||
va_end(vap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRINTFLIKE(2, 3)
|
||||
static inline int
|
||||
static inline xo_ssize_t
|
||||
xo_emit_fp (xo_emit_flags_t flags, const char *fmt, ...)
|
||||
{
|
||||
va_list vap;
|
||||
va_start(vap, fmt);
|
||||
int rc = xo_emit_hvf(NULL, flags, fmt, vap);
|
||||
xo_ssize_t rc = xo_emit_hvf(NULL, flags, fmt, vap);
|
||||
va_end(vap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
xo_ssize_t
|
||||
xo_open_container_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name);
|
||||
|
||||
xo_ssize_t
|
||||
xo_open_container_h (xo_handle_t *xop, const char *name);
|
||||
|
||||
@ -301,6 +305,9 @@ xo_close_container_hd (xo_handle_t *xop);
|
||||
xo_ssize_t
|
||||
xo_close_container_d (void);
|
||||
|
||||
xo_ssize_t
|
||||
xo_open_list_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name);
|
||||
|
||||
xo_ssize_t
|
||||
xo_open_list_h (xo_handle_t *xop, const char *name);
|
||||
|
||||
@ -325,6 +332,9 @@ xo_close_list_hd (xo_handle_t *xop);
|
||||
xo_ssize_t
|
||||
xo_close_list_d (void);
|
||||
|
||||
xo_ssize_t
|
||||
xo_open_instance_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name);
|
||||
|
||||
xo_ssize_t
|
||||
xo_open_instance_h (xo_handle_t *xop, const char *name);
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_attr "const char *name" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_attr_h "xo_handle_t *handle" "const char *name, const char *fmt" "..."
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_attr_hv "xo_handle_t *handle" "const char *name" "const char *fmt" "va_list vap"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
|
@ -114,7 +114,12 @@ static inline int
|
||||
xo_buf_has_room (xo_buffer_t *xbp, ssize_t len)
|
||||
{
|
||||
if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) {
|
||||
ssize_t sz = xbp->xb_size + XO_BUFSIZ;
|
||||
/*
|
||||
* Find out how much new space we need, round it up to XO_BUFSIZ
|
||||
*/
|
||||
ssize_t sz = (xbp->xb_curp + len) - xbp->xb_bufp;
|
||||
sz = (sz + XO_BUFSIZ - 1) & ~(XO_BUFSIZ - 1);
|
||||
|
||||
char *bp = xo_realloc(xbp->xb_bufp, sz);
|
||||
if (bp == NULL)
|
||||
return 0;
|
||||
|
@ -17,11 +17,11 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_emit "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_emit_h "xo_handle_t *xop" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_emit_hv "xo_handle_t *xop" "const char *fmt" "va_list vap"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
|
@ -17,11 +17,11 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_emit_f "xo_emit_flags_t flags" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_emit_hf "xo_handle_t *xop" "xo_emit_flags_t flags" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_emit_hvf "xo_handle_t *xop" "xo_emit_flags_t flags" "const char *fmt" "va_list vap"
|
||||
.Ft void
|
||||
.Fn xo_retain_clear_all "void"
|
||||
|
61
libxo/xo_explicit.h
Normal file
61
libxo/xo_explicit.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
* using the SOFTWARE, you agree to be bound by the terms of that
|
||||
* LICENSE.
|
||||
*
|
||||
* Phil Shafer, March 2019
|
||||
*/
|
||||
|
||||
#ifndef XO_EXPLICIT_H
|
||||
#define XO_EXPLICIT_H
|
||||
|
||||
/*
|
||||
* NOTE WELL: This file is needed to software that implements an
|
||||
* explicit transition between libxo states on its internal stack.
|
||||
* General libxo code should _never_ include this header file.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Stack frame states */
|
||||
typedef unsigned xo_state_t; /* XSS_* values */
|
||||
#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
|
||||
|
||||
void
|
||||
xo_explicit_transition (xo_handle_t *xop, xo_state_t new_state,
|
||||
const char *tag, xo_xof_flags_t flags);
|
||||
|
||||
#endif /* XO_EXPLICIT_H */
|
@ -17,9 +17,9 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft void
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_finish "void"
|
||||
.Ft void
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_finish_h "xo_handle_t *xop"
|
||||
.Sh DESCRIPTION
|
||||
When the program is ready to exit or close a handle, a call to
|
||||
|
@ -17,9 +17,9 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft void
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_flush "void"
|
||||
.Ft void
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_flush_h "xo_handle_t *handle"
|
||||
.Sh DESCRIPTION
|
||||
.Nm libxo
|
||||
|
@ -18,21 +18,21 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_container "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_container_h "xo_handle_t *handle" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_container_hd "xo_handle_t *handle" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_container_d "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_container "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_container_h "xo_handle_t *handle" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_container_hd "xo_handle_t *handle"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_container_d "void"
|
||||
.Sh DESCRIPTION
|
||||
.Nm libxo
|
||||
|
@ -20,37 +20,37 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_list_h "xo_handle_t *xop" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_list "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_list_hd "xo_handle_t *xop" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_list_d "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_instance_h "xo_handle_t *xop" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_instance "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_instance_hd "xo_handle_t *xop" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_instance_d "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_instance_h "xo_handle_t *xop" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_instance "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_instance_hd "xo_handle_t *xop"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_instance_d "void"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_list_h "xo_handle_t *xop" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_list "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_list_hd "xo_handle_t *xop"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_list_d "void"
|
||||
.Sh DESCRIPTION
|
||||
Lists are sequences of instances of homogeneous data objects.
|
||||
|
@ -17,13 +17,13 @@
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_marker "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_open_marker_h "xo_handle_t *handle" "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_marker "const char *name"
|
||||
.Ft int
|
||||
.Ft xo_ssize_t
|
||||
.Fn xo_close_marker_h "xo_handle_t *handle" "const char *name"
|
||||
.Sh DESCRIPTION
|
||||
.Nm libxo
|
||||
|
@ -18,7 +18,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft void
|
||||
.Sy typedef int (*xo_write_func_t)(void *, const char *);
|
||||
.Sy typedef xo_ssize_t (*xo_write_func_t)(void *, const char *);
|
||||
.Pp
|
||||
.Sy typedef void (*xo_close_func_t)(void *);
|
||||
.Pp
|
||||
|
@ -1,2 +1 @@
|
||||
{"top": {"type":"ethernet","type":"bridge","type":"18u","type":24,"address":"0x0","port":1,"address":"0x0","port":1,"address":"0x0","port":1,"used-percent":12,"kve_start":"0xdeadbeef","kve_end":"0xcabb1e","host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]","host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","pre":"that","links":3,"post":"this","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}
|
||||
}
|
||||
{"top": {"type":"ethernet","type":"bridge","type":"18u","type":24,"address":"0x0","port":1,"address":"0x0","port":1,"address":"0x0","port":1,"used-percent":12,"kve_start":"0xdeadbeef","kve_end":"0xcabb1e","host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]","host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","pre":"that","links":3,"post":"this","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"top": {"data": {"what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}
|
||||
}
|
||||
{"top": {"data": {"what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"employees": {"employee": [],"extra":"", "memory": [{"type":"name","in-use":12345,"memory-use":54321,"high-use":"-","requests":32145}], "employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]}
|
||||
}
|
||||
{"employees": {"employee": [],"extra":"", "memory": [{"type":"name","in-use":12345,"memory-use":54321,"high-use":"-","requests":32145}], "employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]}
|
||||
}
|
||||
{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]}}
|
||||
|
@ -1,3 +1 @@
|
||||
{"indian-languages": {"gurmukhi":"ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।","shahmukhi":"لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔","tranliteration":"lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē."}
|
||||
, "employees": {"wc": ["෴ - 0xdf4 - 1","ණ - 0xdab - 1","් - 0xdca - 0","ණ - 0xdab - 1","្ - 0x17d2 - 0","෴ - 0xdf4 - 1","1 - 0x31 - 1","͏ - 0x34f - 0","2 - 0x32 - 1","⃝ - 0x20dd - 0"],"fancy":"1͏2⃝","v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":4,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":8,"not-sinhala":"123456","tag":"ර්ඝ","width":2, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"benefits":"full"}, {"first-name":"෴ණ්ණ෴෴ණ්ණ෴","nic-name":"\"Mick\"","last-name":"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴","department":110,"percent-time":20}]}
|
||||
}
|
||||
{"indian-languages": {"gurmukhi":"ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।","shahmukhi":"لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔","tranliteration":"lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē."}, "employees": {"wc": ["෴ - 0xdf4 - 1","ණ - 0xdab - 1","් - 0xdca - 0","ණ - 0xdab - 1","្ - 0x17d2 - 0","෴ - 0xdf4 - 1","1 - 0x31 - 1","͏ - 0x34f - 0","2 - 0x32 - 1","⃝ - 0x20dd - 0"],"fancy":"1͏2⃝","v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":4,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","width":8,"not-sinhala":"123456","tag":"ර්ඝ","width":2, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"benefits":"full"}, {"first-name":"෴ණ්ණ෴෴ණ්ණ෴","nic-name":"\"Mick\"","last-name":"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴","department":110,"percent-time":20}]}}
|
||||
|
@ -3,8 +3,7 @@
|
||||
"gurmukhi": "ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।",
|
||||
"shahmukhi": "لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔",
|
||||
"tranliteration": "lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē."
|
||||
}
|
||||
,
|
||||
},
|
||||
"employees": {
|
||||
"wc": [
|
||||
"෴ - 0xdf4 - 1",
|
||||
|
@ -1,2 +1 @@
|
||||
{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]}
|
||||
}
|
||||
{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"employees": {"test": [{"filename":"(null)"}],"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","columns":28,"columns":2,"v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","columns":55,"columns":0, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"columns":23,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"columns":47,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"columns":25,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40,"columns":30}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40,"columns":49}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"columns":29,"benefits":"full"}]}
|
||||
}
|
||||
{"employees": {"test": [{"filename":"(null)"}],"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","columns":28,"columns":2,"v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","columns":55,"columns":0, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"columns":23,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"columns":47,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"columns":25,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40,"columns":30}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40,"columns":49}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"columns":29,"benefits":"full"}]}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"top": {"data": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data2": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data3": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17,"test":"one"}]}}, "data4": {"contents": {"item": [{"name":"gum","count":1412, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"rope","count":85, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"ladder","count":0, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"bolt","count":4123, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"water","count":17, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3,"test":"one"}]}}}
|
||||
}
|
||||
{"top": {"data": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data2": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17}]}}, "data3": {"contents": {"item": [{"name":"gum","count":1412}, {"name":"rope","count":85}, {"name":"ladder","count":0}, {"name":"bolt","count":4123}, {"name":"water","count":17,"test":"one"}]}}, "data4": {"contents": {"item": [{"name":"gum","count":1412, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"rope","count":85, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"ladder","count":0, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"bolt","count":4123, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3}, {"name":"water","count":17, "sub": [{"name":0,"next":1}, {"name":1,"next":2}, {"name":2,"next":3}],"last":3,"test":"one"}]}}}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"top": {"data": {"contents": {"name": ["gum","rope","ladder","bolt","water"]}, "contents": {"item": ["gum","rope","ladder","bolt","water"]}, "contents": {"item": ["gum","rope","ladder","bolt","water"],"total":"six","one":"one", "two": ["two"],"three":"three"}}}
|
||||
}
|
||||
{"top": {"data": {"contents": {"name": ["gum","rope","ladder","bolt","water"]}, "contents": {"item": ["gum","rope","ladder","bolt","water"]}, "contents": {"item": ["gum","rope","ladder","bolt","water"],"total":"six","one":"one", "two": ["two"],"three":"three"}}}}
|
||||
|
@ -1,2 +1 @@
|
||||
{"__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}
|
||||
}
|
||||
{"__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}}
|
||||
|
@ -14,5 +14,4 @@
|
||||
{{test-program: }}
|
||||
{{An application 1011 log entry}}
|
||||
|
||||
{"__version": "3.1.4", "top": {}
|
||||
}
|
||||
{"__version": "3.1.4", "top": {}}
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -83,6 +83,10 @@ op content: [time] [2:15] [0]
|
||||
op string: [hand] [left] [0]
|
||||
op string: [color] [blue] [0]
|
||||
op content: [time] [3:45] [0]
|
||||
op open_container: [2by4] [] [0x4040010]
|
||||
op string: [4x4] [truck] [0]
|
||||
op string: [2morrow] [tomorrow] [0]
|
||||
op close_container: [2by4] [] [0]
|
||||
op close_instance: [thing] [] [0]
|
||||
op close_list: [thing] [] [0]
|
||||
op close_container: [data] [] [0]
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -167,3 +167,9 @@
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">There is </div>
|
||||
<div class="data" data-tag="4x4" data-xpath="/top/data/thing[name = 'thing']/2by4/4x4">truck</div>
|
||||
<div class="text"> in </div>
|
||||
<div class="data" data-tag="2morrow" data-xpath="/top/data/thing[name = 'thing']/2by4/2morrow">tomorrow</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -167,3 +167,9 @@
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">There is </div>
|
||||
<div class="data" data-tag="4x4">truck</div>
|
||||
<div class="text"> in </div>
|
||||
<div class="data" data-tag="2morrow">tomorrow</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -1,2 +1 @@
|
||||
{"top": {"data": {"animal":"fish","animal":"fish", "thing": [{"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}]}}
|
||||
}
|
||||
{"top": {"data": {"animal":"fish","animal":"fish", "thing": [{"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45"}, {"name":"thing","color":"green","time":"2:15","hand":"left","color":"blue","time":"3:45", "2by4": {"4x4":"truck","2morrow":"tomorrow"}}]}}}
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -82,7 +82,11 @@
|
||||
"time": "2:15",
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": "3:45"
|
||||
"time": "3:45",
|
||||
"2by4": {
|
||||
"4x4": "truck",
|
||||
"2morrow": "tomorrow"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -20,3 +20,4 @@ The [31mthing[0m is [32mgreen[0m til 02:15
|
||||
My [31mleft[0m hand is [34mblue[0m til 03:45
|
||||
The [31mthing[0m is [32mgreen[0m til 02:15
|
||||
My [31mleft[0m hand is [34mblue[0m til 03:45
|
||||
There is truck in tomorrow
|
||||
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -1 +1 @@
|
||||
<top><data><animal>fish</animal><animal>fish</animal><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing></data></top>
|
||||
<top><data><animal>fish</animal><animal>fish</animal><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time><_2by4><_4x4>truck</_4x4><_2morrow>tomorrow</_2morrow></_2by4></thing></data></top>
|
@ -0,0 +1,4 @@
|
||||
test_12.test: invalid XML tag name: '2by4'
|
||||
test_12.test: invalid XML tag name: '4x4'
|
||||
test_12.test: invalid XML tag name: '2morrow'
|
||||
test_12.test: invalid XML tag name: '2by4'
|
@ -81,6 +81,10 @@
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
<_2by4>
|
||||
<_4x4>truck</_4x4>
|
||||
<_2morrow>tomorrow</_2morrow>
|
||||
</_2by4>
|
||||
</thing>
|
||||
</data>
|
||||
</top>
|
||||
|
@ -78,6 +78,11 @@ main (int argc, char **argv)
|
||||
xo_emit_f(flags, fmt2, "left", "blue", "blue", 3, 45);
|
||||
}
|
||||
|
||||
xo_open_container("2by4");
|
||||
xo_emit("There is {:4x4} in {:2morrow}\n", "truck", "tomorrow");
|
||||
xo_close_container("2by4");
|
||||
|
||||
|
||||
xo_close_container("data");
|
||||
xo_close_container_h(NULL, "top");
|
||||
|
||||
|
@ -457,3 +457,7 @@ msgstr "Atestay otnay ecoverableray"
|
||||
# 96 - EOWNERDEAD
|
||||
msgid "Previous owner died"
|
||||
msgstr "Eviouspray ownerway iedday"
|
||||
|
||||
# 97 - EINTEGRITY
|
||||
msgid "Integrity check failed"
|
||||
msgstr "Integrityway eckchey ailedfey"
|
||||
|
@ -1,2 +1 @@
|
||||
{"top": {"adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchcay","adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchcay", "bytes": [0,1,2,3,4],"total":1234,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"marzlevanes":3,"version":"1.2.3","date":"Tue Jun 23 18:47:09 UTC 2015", "__warning": {"program":"gt_01.test","message":"Nableuay otay ectulatobjay orwardfay elocipingvay","verb":"ectulatobjay","error":"Ermissionpay eniedday"}, "__warning": {"program":"gt_01.test","message":"automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay","style":"automaticyay","type":"ardinalyay","target":"ammetersgray","error":"Ermissionpay eniedday"},"marzlevanes":6,"windings":"otuslay-oyay-eltayay"}
|
||||
}
|
||||
{"top": {"adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchcay","adjective":"amingflay","noun":"ordsway","verb":"urningbay","owner":"ymay","target":"ouchcay", "bytes": [0,1,2,3,4],"total":1234,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"received":1234,"from":"foop","port":4321,"time":32,"marzlevanes":3,"version":"1.2.3","date":"Tue Jun 23 18:47:09 UTC 2015", "__warning": {"program":"gt_01.test","message":"Nableuay otay ectulatobjay orwardfay elocipingvay","verb":"ectulatobjay","error":"Ermissionpay eniedday"}, "__warning": {"program":"gt_01.test","message":"automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay","style":"automaticyay","type":"ardinalyay","target":"ammetersgray","error":"Ermissionpay eniedday"},"marzlevanes":6,"windings":"otuslay-oyay-eltayay"}}
|
||||
|
@ -466,3 +466,7 @@ msgstr ""
|
||||
# 96 - EOWNERDEAD
|
||||
msgid "Previous owner died"
|
||||
msgstr ""
|
||||
|
||||
# 97 - EINTEGRITY
|
||||
msgid "Integrity check failed"
|
||||
msgstr ""
|
||||
|
@ -12,14 +12,8 @@ AM_CFLAGS = -I${top_srcdir} -I${top_srcdir}/libxo
|
||||
|
||||
# Ick: maintained by hand!
|
||||
TEST_CASES = \
|
||||
xo_01.sh
|
||||
|
||||
X=\
|
||||
xo_02.sh \
|
||||
xo_03.sh \
|
||||
xo_04.sh \
|
||||
xo_05.sh \
|
||||
xo_06.sh
|
||||
xo_01.sh \
|
||||
xo_02.sh
|
||||
|
||||
# TEST_CASES := $(shell cd ${srcdir} ; echo *.c )
|
||||
|
||||
|
@ -1 +1 @@
|
||||
<div class="line"><div class="text">Item </div><div class="data" data-tag="name">one</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">001</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">red</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">two</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">002</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">blue</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">three</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">003</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">green</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">four</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">004</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">yellow</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div>
|
||||
<div class="line"><div class="text">Item </div><div class="data" data-tag="name">one</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">001</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">red</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">two</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">002</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">blue</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">three</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">003</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">green</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">four</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">004</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">yellow</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="padding"> </div><div class="line"><div class="data" data-tag="address">0xdeadbeef</div><div class="text">..</div><div class="data" data-tag="foo">1</div></div><div class="line"><div class="text">partial line</div><div class="text"> -- rest of line</div></div>
|
@ -74,3 +74,7 @@
|
||||
<div class="text">..</div>
|
||||
<div class="data" data-tag="foo" data-xpath="/anchor/foo">1</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">partial line</div>
|
||||
<div class="text"> -- rest of line</div>
|
||||
</div>
|
||||
|
@ -74,3 +74,7 @@
|
||||
<div class="text">..</div>
|
||||
<div class="data" data-tag="foo">1</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">partial line</div>
|
||||
<div class="text"> -- rest of line</div>
|
||||
</div>
|
||||
|
@ -1 +1 @@
|
||||
"top": {"item": {"name":"one","value":1,"color":"red"}, "item": {"name":"two","value":2,"color":"blue"}, "item": {"name":"three","value":3,"color":"green"}, "item": {"name":"four","value":4,"color":"yellow"}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}}
|
||||
"top": {"item": {"name":"one","value":1,"color":"red"}, "item": {"name":"two","value":2,"color":"blue"}, "item": {"name":"three","value":3,"color":"green"}, "item": {"name":"four","value":4,"color":"yellow"}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}}
|
@ -35,4 +35,4 @@
|
||||
"address": "0xdeadbeef",
|
||||
"foo": 1
|
||||
}
|
||||
}
|
||||
}
|
@ -6,3 +6,4 @@ Item four is number 004, color: yellow
|
||||
0xdeadbeef..1
|
||||
0xdeadbeef..1
|
||||
0xdeadbeef..1
|
||||
partial line -- rest of line
|
||||
|
25
tests/xo/saved/xo_02.H.err
Normal file
25
tests/xo/saved/xo_02.H.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
1
tests/xo/saved/xo_02.H.out
Normal file
1
tests/xo/saved/xo_02.H.out
Normal file
@ -0,0 +1 @@
|
||||
<div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><div class="line"><div class="text">test</div></div><div class="line"><div class="text">Answer:</div><div class="text">The capital of </div><div class="data" data-tag="state">North Carolina</div><div class="text"> is </div><div class="data" data-tag="city">Raleigh</div></div><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><div class="line"><div class="text">Machine </div><div class="data" data-tag="name">red</div><div class="text"> has </div><div class="data" data-tag="memory">55</div></div><div class="line"><div class="text">Machine </div><div class="data" data-tag="name">green</div><div class="text"> has </div><div class="data" data-tag="memory">55</div></div><div class="line"><div class="text">Machine </div><div class="data" data-tag="name">blue</div><div class="text"> has </div><div class="data" data-tag="memory">55</div></div>
|
25
tests/xo/saved/xo_02.HIPx.err
Normal file
25
tests/xo/saved/xo_02.HIPx.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
83
tests/xo/saved/xo_02.HIPx.out
Normal file
83
tests/xo/saved/xo_02.HIPx.out
Normal file
@ -0,0 +1,83 @@
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/a/b/c/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/a/b/c/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/a/b/c/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/a/b/c/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/a/b/c/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/a/b/c/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/d/e/f/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/d/e/f/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/a/b/c/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/a/b/c/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/a/b/c/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/a/b/c/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">test</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Answer:</div>
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state" data-xpath="/state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city" data-xpath="/city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">First </div>
|
||||
<div class="data" data-tag="tag" data-xpath="/tag">value1</div>
|
||||
<div class="text"> </div>
|
||||
<div class="text">and then </div>
|
||||
<div class="data" data-tag="tag" data-xpath="/tag">value2</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Machine </div>
|
||||
<div class="data" data-tag="name" data-xpath="/name">red</div>
|
||||
<div class="text"> has </div>
|
||||
<div class="data" data-tag="memory" data-xpath="/memory">55</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Machine </div>
|
||||
<div class="data" data-tag="name" data-xpath="/name">green</div>
|
||||
<div class="text"> has </div>
|
||||
<div class="data" data-tag="memory" data-xpath="/memory">55</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Machine </div>
|
||||
<div class="data" data-tag="name" data-xpath="/name">blue</div>
|
||||
<div class="text"> has </div>
|
||||
<div class="data" data-tag="memory" data-xpath="/memory">55</div>
|
||||
</div>
|
25
tests/xo/saved/xo_02.HP.err
Normal file
25
tests/xo/saved/xo_02.HP.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
83
tests/xo/saved/xo_02.HP.out
Normal file
83
tests/xo/saved/xo_02.HP.out
Normal file
@ -0,0 +1,83 @@
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">test</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Answer:</div>
|
||||
<div class="text">The capital of </div>
|
||||
<div class="data" data-tag="state">North Carolina</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="city">Raleigh</div>
|
||||
</div>
|
||||
<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>
|
||||
<div class="line">
|
||||
<div class="text">Machine </div>
|
||||
<div class="data" data-tag="name">red</div>
|
||||
<div class="text"> has </div>
|
||||
<div class="data" data-tag="memory">55</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Machine </div>
|
||||
<div class="data" data-tag="name">green</div>
|
||||
<div class="text"> has </div>
|
||||
<div class="data" data-tag="memory">55</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Machine </div>
|
||||
<div class="data" data-tag="name">blue</div>
|
||||
<div class="text"> has </div>
|
||||
<div class="data" data-tag="memory">55</div>
|
||||
</div>
|
25
tests/xo/saved/xo_02.J.err
Normal file
25
tests/xo/saved/xo_02.J.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
7
tests/xo/saved/xo_02.J.out
Normal file
7
tests/xo/saved/xo_02.J.out
Normal file
@ -0,0 +1,7 @@
|
||||
{"a": {"b": {"c": {"state":"North Carolina","city":"Raleigh","state":"North Carolina","city":"Raleigh"}}}}
|
||||
{"a": {"b": {"c": {"state":"North Carolina","city":"Raleigh"}}}}
|
||||
{"a": {"b": {"c": {"state":"North Carolina","city":"Raleigh", "d": {"e": {"f": {"state":"North Carolina","city":"Raleigh"}}},"state":"North Carolina","city":"Raleigh"}}}}
|
||||
"a": {"b": {"c": {"state":"North Carolina","city":"Raleigh"}}}{"a": {"b": {"c": {"state":"North Carolina","city":"Raleigh"}}}}
|
||||
{ }
|
||||
"answer": {"state":"North Carolina","city":"Raleigh"}{"top": {"data": {"tag":"value1""tag":"value2"}}}
|
||||
"machine": [{"name":"red","memory":"55"}, {"name":"green","memory":"55"}, {"name":"blue","memory":"55"}]
|
25
tests/xo/saved/xo_02.JP.err
Normal file
25
tests/xo/saved/xo_02.JP.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
84
tests/xo/saved/xo_02.JP.out
Normal file
84
tests/xo/saved/xo_02.JP.out
Normal file
@ -0,0 +1,84 @@
|
||||
{
|
||||
"a": {
|
||||
"b": {
|
||||
"c": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh",
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"a": {
|
||||
"b": {
|
||||
"c": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"a": {
|
||||
"b": {
|
||||
"c": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh",
|
||||
"d": {
|
||||
"e": {
|
||||
"f": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}
|
||||
}
|
||||
},
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"a": {
|
||||
"b": {
|
||||
"c": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}
|
||||
}
|
||||
}{
|
||||
"a": {
|
||||
"b": {
|
||||
"c": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{ }
|
||||
"answer": {
|
||||
"state": "North Carolina",
|
||||
"city": "Raleigh"
|
||||
}{
|
||||
"top": {
|
||||
"data": {
|
||||
"tag": "value1" "tag": "value2"
|
||||
}
|
||||
}
|
||||
}
|
||||
"machine": [
|
||||
{
|
||||
"name": "red",
|
||||
"memory": "55"
|
||||
},
|
||||
{
|
||||
"name": "green",
|
||||
"memory": "55"
|
||||
},
|
||||
{
|
||||
"name": "blue",
|
||||
"memory": "55"
|
||||
}
|
||||
]
|
25
tests/xo/saved/xo_02.T.err
Normal file
25
tests/xo/saved/xo_02.T.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
14
tests/xo/saved/xo_02.T.out
Normal file
14
tests/xo/saved/xo_02.T.out
Normal file
@ -0,0 +1,14 @@
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
The capital of North Carolina is Raleigh
|
||||
test
|
||||
Answer:The capital of North Carolina is Raleigh
|
||||
First value1 and then value2
|
||||
Machine red has 55
|
||||
Machine green has 55
|
||||
Machine blue has 55
|
25
tests/xo/saved/xo_02.X.err
Normal file
25
tests/xo/saved/xo_02.X.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
1
tests/xo/saved/xo_02.X.out
Normal file
1
tests/xo/saved/xo_02.X.out
Normal file
@ -0,0 +1 @@
|
||||
<a><b><c><state>North Carolina</state><city>Raleigh</city><state>North Carolina</state><city>Raleigh</city></c></b></a><a><b><c><state>North Carolina</state><city>Raleigh</city></c></b></a><a><b><c><state>North Carolina</state><city>Raleigh</city><d><e><f><state>North Carolina</state><city>Raleigh</city></f></e></d><state>North Carolina</state><city>Raleigh</city></c></b></a><a><b><c><state>North Carolina</state><city>Raleigh</city></c></b></a><a><b><c><state>North Carolina</state><city>Raleigh</city></c></b></a><answer><state>North Carolina</state><city>Raleigh</city></answer><top><data><tag>value1</tag><tag>value2</tag></data></top><machine><name>red</name><memory>55</memory></machine><machine><name>green</name><memory>55</memory></machine><machine><name>blue</name><memory>55</memory></machine>
|
25
tests/xo/saved/xo_02.XP.err
Normal file
25
tests/xo/saved/xo_02.XP.err
Normal file
@ -0,0 +1,25 @@
|
||||
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> OR -l <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> OR -s <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
|
||||
--wrap <path> Wrap output in a set of containers
|
||||
--xml OR -X Generate XML output
|
||||
--xpath Add XPath data to HTML output
|
74
tests/xo/saved/xo_02.XP.out
Normal file
74
tests/xo/saved/xo_02.XP.out
Normal file
@ -0,0 +1,74 @@
|
||||
<a>
|
||||
<b>
|
||||
<c>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</c>
|
||||
</b>
|
||||
</a>
|
||||
<a>
|
||||
<b>
|
||||
<c>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</c>
|
||||
</b>
|
||||
</a>
|
||||
<a>
|
||||
<b>
|
||||
<c>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
<d>
|
||||
<e>
|
||||
<f>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</f>
|
||||
</e>
|
||||
</d>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</c>
|
||||
</b>
|
||||
</a>
|
||||
<a>
|
||||
<b>
|
||||
<c>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</c>
|
||||
</b>
|
||||
</a>
|
||||
<a>
|
||||
<b>
|
||||
<c>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</c>
|
||||
</b>
|
||||
</a>
|
||||
<answer>
|
||||
<state>North Carolina</state>
|
||||
<city>Raleigh</city>
|
||||
</answer>
|
||||
<top>
|
||||
<data>
|
||||
<tag>value1</tag>
|
||||
<tag>value2</tag>
|
||||
</data>
|
||||
</top>
|
||||
<machine>
|
||||
<name>red</name>
|
||||
<memory>55</memory>
|
||||
</machine>
|
||||
<machine>
|
||||
<name>green</name>
|
||||
<memory>55</memory>
|
||||
</machine>
|
||||
<machine>
|
||||
<name>blue</name>
|
||||
<memory>55</memory>
|
||||
</machine>
|
@ -30,4 +30,7 @@ ${XOAN} "{[:/18}{:address/%p}..{:foo/%u}{]:}\n" 0xdeadbeef 1
|
||||
${XOAN} "{[:/%d}{:address/%p}..{:foo/%u}{]:}\n" 18 0xdeadbeef 1
|
||||
${XOAN} "{[:/%s}{:address/%p}..{:foo/%u}{]:}\n" 18 0xdeadbeef 1
|
||||
|
||||
${XO} "partial line"
|
||||
${XO} -C " -- rest of line\n"
|
||||
|
||||
${XO} --close top
|
||||
|
57
tests/xo/xo_02.sh
Executable file
57
tests/xo/xo_02.sh
Executable file
@ -0,0 +1,57 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Copyright 2019, 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.
|
||||
|
||||
XO=$1
|
||||
shift
|
||||
|
||||
XOP="${XO} --warn"
|
||||
|
||||
# This is testing --wrap, --open, --close, --top-wrap, etc, so
|
||||
# the output is not a single valid document
|
||||
|
||||
set -- 'The capital of {:state} is {:city}\n' 'North Carolina' Raleigh
|
||||
|
||||
${XOP} --top-wrap --open a/b/c "$@"
|
||||
${XOP} --top-wrap --close a/b/c --not-first "$@"
|
||||
|
||||
${XOP} --top-wrap --wrap a/b/c "$@"
|
||||
|
||||
${XOP} --top-wrap --open a/b/c "$@"
|
||||
${XOP} --depth 4 --not-first --wrap d/e/f "$@"
|
||||
${XOP} --top-wrap --close a/b/c --not-first "$@"
|
||||
|
||||
${XOP} --wrap a/b/c "$@"
|
||||
|
||||
${XOP} --top-wrap --wrap a/b/c "$@"
|
||||
|
||||
${XOP} --top-wrap "test\n"
|
||||
|
||||
${XOP} --open answer
|
||||
${XOP} "Answer:"
|
||||
${XOP} --continuation "$@"
|
||||
${XOP} --close answer
|
||||
|
||||
${XOP} --top-wrap --open top/data
|
||||
${XOP} --depth 2 'First {:tag} ' value1
|
||||
${XOP} --depth 2 --continuation 'and then {:tag}\n' value2
|
||||
${XOP} --top-wrap --close top/data
|
||||
|
||||
|
||||
${XOP} --help
|
||||
|
||||
${XOP} --open-list machine
|
||||
NF=
|
||||
for name in red green blue; do
|
||||
${XOP} --depth 1 $NF --open-instance machine
|
||||
${XOP} --depth 2 "Machine {k:name} has {:memory}\n" $name 55
|
||||
${XOP} --depth 1 --close-instance machine
|
||||
NF=--not-first
|
||||
done
|
||||
${XOP} $NF --close-list machine
|
11
xo/xo.1
11
xo/xo.1
@ -36,6 +36,10 @@ using the same commands that emit text output.
|
||||
.Bl -tag -width indent
|
||||
.It Ic --close Ar path
|
||||
Close tags for the given path
|
||||
.It Ic -C | Ic --continuation
|
||||
Indicates this output is a continuation of the previous output data
|
||||
and should appear on the same line.
|
||||
This is allows HTML output to be constructed correctly.
|
||||
.It Ic --depth Ar num
|
||||
Set the depth for pretty printing
|
||||
.It Ic --help
|
||||
@ -46,6 +50,10 @@ Generate HTML output
|
||||
Generate JSON output
|
||||
.It Ic --leading-xpath Ar path
|
||||
Add a prefix to generated XPaths (HTML)
|
||||
.It Ic --not-first
|
||||
Indicate that this content is not the first in a series of sibling
|
||||
objects, which is vital information for "JSON" output, which requires
|
||||
a comma between such objects.
|
||||
.It Ic --open Ar path
|
||||
Open tags for the given path
|
||||
.It Ic -p | Ic --pretty
|
||||
@ -54,6 +62,9 @@ Make 'pretty' output (add indent, newlines)
|
||||
Generate given style (xml, json, text, html)
|
||||
.It Ic -T | Ic --text
|
||||
Generate text output (the default style)
|
||||
.It Ic --top-warp
|
||||
Indicates the entire object should be placed inside a top-level
|
||||
object wrapper, specifically when generating JSON output.
|
||||
.It Ic --version
|
||||
Display version information
|
||||
.It Ic -W | Ic --warn
|
||||
|
120
xo/xo.c
120
xo/xo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "xo_config.h"
|
||||
#include "xo.h"
|
||||
#include "xo_explicit.h"
|
||||
|
||||
#include <getopt.h> /* Include after xo.h for testing */
|
||||
|
||||
@ -194,18 +195,25 @@ print_help (void)
|
||||
fprintf(stderr,
|
||||
"Usage: xo [options] format [fields]\n"
|
||||
" --close <path> Close tags for the given path\n"
|
||||
" --close-instance <name> Close an open instance name\n"
|
||||
" --close-list <name> Close an open list name\n"
|
||||
" --continuation OR -C Output belongs on same line as previous output\n"
|
||||
" --depth <num> Set the depth for pretty printing\n"
|
||||
" --help Display this help text\n"
|
||||
" --html OR -H Generate HTML output\n"
|
||||
" --json OR -J Generate JSON output\n"
|
||||
" --leading-xpath <path> OR -l <path> "
|
||||
"Add a prefix to generated XPaths (HTML)\n"
|
||||
" --not-first Indicate this object is not the first (JSON)\n"
|
||||
" --open <path> Open tags for the given path\n"
|
||||
" --open-instance <name> Open an instance given by name\n"
|
||||
" --open-list <name> Open a list given by name\n"
|
||||
" --option <opts> -or -O <opts> Give formatting options\n"
|
||||
" --pretty OR -p Make 'pretty' output (add indent, newlines)\n"
|
||||
" --style <style> OR -s <style> "
|
||||
"Generate given style (xml, json, text, html)\n"
|
||||
" --text OR -T Generate text output (the default style)\n"
|
||||
" --top-wrap Generate a top-level object wrapper (JSON)\n"
|
||||
" --version Display version information\n"
|
||||
" --warn OR -W Display warnings in text on stderr\n"
|
||||
" --warn-xml Display warnings in xml on stdout\n"
|
||||
@ -215,17 +223,25 @@ print_help (void)
|
||||
}
|
||||
|
||||
static struct opts {
|
||||
int o_close_instance;
|
||||
int o_close_list;
|
||||
int o_depth;
|
||||
int o_help;
|
||||
int o_not_first;
|
||||
int o_xpath;
|
||||
int o_open_instance;
|
||||
int o_open_list;
|
||||
int o_top_wrap;
|
||||
int o_version;
|
||||
int o_warn_xml;
|
||||
int o_wrap;
|
||||
int o_xpath;
|
||||
} opts;
|
||||
|
||||
static struct option long_opts[] = {
|
||||
{ "close", required_argument, NULL, 'c' },
|
||||
{ "close-instance", required_argument, &opts.o_close_instance, 1 },
|
||||
{ "close-list", required_argument, &opts.o_close_list, 1 },
|
||||
{ "continuation", no_argument, NULL, 'C' },
|
||||
{ "depth", required_argument, &opts.o_depth, 1 },
|
||||
{ "help", no_argument, &opts.o_help, 1 },
|
||||
{ "html", no_argument, NULL, 'H' },
|
||||
@ -233,10 +249,13 @@ static struct option long_opts[] = {
|
||||
{ "leading-xpath", required_argument, NULL, 'l' },
|
||||
{ "not-first", no_argument, &opts.o_not_first, 1 },
|
||||
{ "open", required_argument, NULL, 'o' },
|
||||
{ "open-instance", required_argument, &opts.o_open_instance, 1 },
|
||||
{ "open-list", required_argument, &opts.o_open_list, 1 },
|
||||
{ "option", required_argument, NULL, 'O' },
|
||||
{ "pretty", no_argument, NULL, 'p' },
|
||||
{ "style", required_argument, NULL, 's' },
|
||||
{ "text", no_argument, NULL, 'T' },
|
||||
{ "top-wrap", no_argument, &opts.o_top_wrap, 1 },
|
||||
{ "xml", no_argument, NULL, 'X' },
|
||||
{ "xpath", no_argument, &opts.o_xpath, 1 },
|
||||
{ "version", no_argument, &opts.o_version, 1 },
|
||||
@ -252,17 +271,24 @@ main (int argc UNUSED, char **argv)
|
||||
char *fmt = NULL, *cp, *np;
|
||||
char *opt_opener = NULL, *opt_closer = NULL, *opt_wrapper = NULL;
|
||||
char *opt_options = NULL;
|
||||
char *opt_name = NULL;
|
||||
xo_state_t new_state = 0;
|
||||
int opt_depth = 0;
|
||||
int opt_not_first = 0;
|
||||
int opt_top_wrap = 0;
|
||||
int rc;
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
if (argc < 0)
|
||||
return 1;
|
||||
|
||||
while ((rc = getopt_long(argc, argv, "c:HJl:O:o:ps:TXW",
|
||||
while ((rc = getopt_long(argc, argv, "Cc:HJl:O:o:ps:TXW",
|
||||
long_opts, NULL)) != -1) {
|
||||
switch (rc) {
|
||||
case 'C':
|
||||
xo_set_flags(NULL, XOF_CONTINUATION);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
opt_closer = optarg;
|
||||
xo_set_flags(NULL, XOF_IGNORE_CLOSE);
|
||||
@ -339,6 +365,41 @@ main (int argc UNUSED, char **argv)
|
||||
} else if (opts.o_wrap) {
|
||||
opt_wrapper = optarg;
|
||||
|
||||
} else if (opts.o_top_wrap) {
|
||||
opt_top_wrap = 1;
|
||||
|
||||
} else if (opts.o_open_list) {
|
||||
if (opt_name)
|
||||
xo_errx(1, "only one open/close list/instance allowed: %s",
|
||||
optarg);
|
||||
|
||||
opt_name = optarg;
|
||||
new_state = XSS_OPEN_LIST;
|
||||
|
||||
} else if (opts.o_open_instance) {
|
||||
if (opt_name)
|
||||
xo_errx(1, "only one open/close list/instance allowed: %s",
|
||||
optarg);
|
||||
|
||||
opt_name = optarg;
|
||||
new_state = XSS_OPEN_INSTANCE;
|
||||
|
||||
} else if (opts.o_close_list) {
|
||||
if (opt_name)
|
||||
xo_errx(1, "only one open/close list/instance allowed: %s",
|
||||
optarg);
|
||||
|
||||
opt_name = optarg;
|
||||
new_state = XSS_CLOSE_LIST;
|
||||
|
||||
} else if (opts.o_close_instance) {
|
||||
if (opt_name)
|
||||
xo_errx(1, "only one open/close list/instance allowed: %s",
|
||||
optarg);
|
||||
|
||||
opt_name = optarg;
|
||||
new_state = XSS_CLOSE_INSTANCE;
|
||||
|
||||
} else {
|
||||
print_help();
|
||||
return 1;
|
||||
@ -365,14 +426,34 @@ main (int argc UNUSED, char **argv)
|
||||
xo_set_formatter(NULL, formatter, checkpoint);
|
||||
xo_set_flags(NULL, XOF_NO_VA_ARG | XOF_NO_TOP | XOF_NO_CLOSE);
|
||||
|
||||
/*
|
||||
* If we have some explicit state change, handle it
|
||||
*/
|
||||
if (new_state) {
|
||||
if (opt_depth > 0)
|
||||
xo_set_depth(NULL, opt_depth);
|
||||
|
||||
if (opt_not_first)
|
||||
xo_set_flags(NULL, XOF_NOT_FIRST);
|
||||
|
||||
xo_explicit_transition(NULL, new_state, opt_name, 0);
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fmt = *argv++;
|
||||
if (opt_opener == NULL && opt_closer == NULL && fmt == NULL) {
|
||||
print_help();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (opt_not_first)
|
||||
xo_set_flags(NULL, XOF_NOT_FIRST);
|
||||
if (opt_top_wrap) {
|
||||
/* If we have a closing path, we'll be one extra level deeper */
|
||||
if (opt_closer && xo_get_style(NULL) == XO_STYLE_JSON)
|
||||
opt_depth += 1;
|
||||
else
|
||||
xo_clear_flags(NULL, XOF_NO_TOP);
|
||||
}
|
||||
|
||||
if (opt_closer) {
|
||||
opt_depth += 1;
|
||||
@ -388,6 +469,10 @@ main (int argc UNUSED, char **argv)
|
||||
if (opt_depth > 0)
|
||||
xo_set_depth(NULL, opt_depth);
|
||||
|
||||
if (opt_not_first)
|
||||
xo_set_flags(NULL, XOF_NOT_FIRST);
|
||||
|
||||
/* If there's an opening hierarchy, open each element as a container */
|
||||
if (opt_opener) {
|
||||
for (cp = opt_opener; cp && *cp; cp = np) {
|
||||
np = strchr(cp, '/');
|
||||
@ -395,10 +480,11 @@ main (int argc UNUSED, char **argv)
|
||||
*np = '\0';
|
||||
xo_open_container(cp);
|
||||
if (np)
|
||||
*np++ = '/';
|
||||
np += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's an wrapper hierarchy, open each element as a container */
|
||||
if (opt_wrapper) {
|
||||
for (cp = opt_wrapper; cp && *cp; cp = np) {
|
||||
np = strchr(cp, '/');
|
||||
@ -406,16 +492,18 @@ main (int argc UNUSED, char **argv)
|
||||
*np = '\0';
|
||||
xo_open_container(cp);
|
||||
if (np)
|
||||
*np++ = '/';
|
||||
*np++ = '/'; /* Put it back */
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's a format string, call xo_emit to emit the contents */
|
||||
if (fmt && *fmt) {
|
||||
save_argv = argv;
|
||||
prep_arg(fmt);
|
||||
xo_emit(fmt);
|
||||
xo_emit(fmt); /* This call does the real formatting */
|
||||
}
|
||||
|
||||
|
||||
/* If there's an wrapper hierarchy, close each element's container */
|
||||
while (opt_wrapper) {
|
||||
np = strrchr(opt_wrapper, '/');
|
||||
xo_close_container(np ? np + 1 : opt_wrapper);
|
||||
@ -425,6 +513,10 @@ main (int argc UNUSED, char **argv)
|
||||
opt_wrapper = NULL;
|
||||
}
|
||||
|
||||
/* Remember to undo the depth before calling xo_finish() */
|
||||
opt_depth = (opt_closer && opt_top_wrap) ? -1 : 0;
|
||||
|
||||
/* If there's an closing hierarchy, close each element's container */
|
||||
while (opt_closer) {
|
||||
np = strrchr(opt_closer, '/');
|
||||
xo_close_container(np ? np + 1 : opt_closer);
|
||||
@ -434,6 +526,16 @@ main (int argc UNUSED, char **argv)
|
||||
opt_closer = NULL;
|
||||
}
|
||||
|
||||
/* If there's a closer and a wrapper, we need to clean it up */
|
||||
if (opt_depth) {
|
||||
xo_set_depth(NULL, opt_depth);
|
||||
xo_clear_flags(NULL, XOF_NO_TOP);
|
||||
}
|
||||
|
||||
/* If we're wrapping the entire content, skip the closer */
|
||||
if (opt_top_wrap && opt_opener)
|
||||
xo_set_flags(NULL, XOF_NO_TOP);
|
||||
|
||||
xo_finish();
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user