Upgrade libxo to 0.4.5.

Local changes incorporated by 0.4.5: r284340
Local changes retained: r276260, r282117

Obtained from:	https://github.com/Juniper/libxo
This commit is contained in:
Marcel Moolenaar 2015-08-24 16:26:20 +00:00
parent 643e5ec210
commit d1a0d267b7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287111
182 changed files with 12066 additions and 2387 deletions

View file

@ -5,7 +5,7 @@
PROG= ls
SRCS= cmp.c ls.c print.c util.c
LIBADD= util xo
LIBADD= xo util
.if !defined(RELEASE_CRUNCH) && \
${MK_LS_COLORS} != no

View file

@ -11,6 +11,6 @@ SRCS= fmt.c keyword.c nlist.c print.c ps.c
# on large systems.
#
CFLAGS+=-DLAZY_PS
LIBADD= m kvm jail xo
LIBADD= m kvm jail xo util
.include <bsd.prog.mk>

View file

@ -27,14 +27,17 @@ config.guess
config.h.in
config.sub
depcomp
install-sh
ltmain.sh
missing
m4
Makefile.in
configure
.DS_Store
xoconfig.h.in
xo_config.h.in
.gdbinit
.gdbinit.local

View file

@ -1,6 +1,6 @@
language: c
script: printenv && uname -a && /bin/sh ./bin/setup.sh && cd build && ../configure --enable-warnings && make && sudo make install && make test
script: printenv && uname -a && ls -l && /bin/sh -x ./bin/setup.sh && cd build && ../configure --enable-warnings && make && sudo make install && make test
notifications:
recipients:

15
contrib/libxo/INSTALL.md Normal file
View file

@ -0,0 +1,15 @@
<!---
# $Id$
#
# Copyright 2015, Juniper Networks, Inc.
# All rights reserved.
# This SOFTWARE is licensed under the LICENSE provided in the
# ../Copyright file. By downloading, installing, copying, or otherwise
# using the SOFTWARE, you agree to be bound by the terms of that
# LICENSE.
#-->
## Instructions for building libxo
Instructions for building libxo are now available in the
[wiki](http://juniper.github.io/libxo/libxo-manual.html#getting-libxo).

View file

@ -10,7 +10,7 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libxo xo xolint xohtml tests doc
SUBDIRS = libxo xo xopo xolint xohtml tests doc encoder
bin_SCRIPTS=libxo-config
dist_doc_DATA = Copyright
@ -94,3 +94,9 @@ packages:
&& git commit -m 'new packaging data' \
${GH_PACKAGING_DIR} \
&& git push origin gh-pages ) ; true
ANALYZE_DIR = ~/trash/libxo
ANALYZE_CMD = scan-build-mp-3.6
analyze:
${ANALYZE_CMD} -o ${ANALYZE_DIR} ${MAKE}

View file

@ -6,6 +6,7 @@ set opts=' \
--enable-debug \
--enable-warnings \
--enable-printflike \
--with-gettext=/opt/local \
--prefix ${HOME}/work/root \
'
set opts=`echo $opts`
@ -22,3 +23,7 @@ cd build
alias xx 'cc -I.. -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Werror -Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wformat -Wimplicit -Wmissing-declarations -Wnested-externs -Wparentheses -Wreturn-type -Wshadow -Wswitch -Wtrigraphs -Wuninitialized -Wunused -Wwrite-strings -fno-inline-functions-called-once -g -O2 -o xtest -DUNIT_TEST libxo.c'
alias mm "make CFLAGS='-O0 -g'"
alias mmi 'mm && mi'

View file

@ -11,6 +11,8 @@ if [ ! -f configure ]; then
vers=`autoreconf --version | head -1`
echo "Using" $vers
mkdir -p m4
autoreconf --install
if [ ! -f configure ]; then

View file

@ -12,7 +12,7 @@
#
AC_PREREQ(2.2)
AC_INIT([libxo], [0.3.2], [phil@juniper.net])
AC_INIT([libxo], [0.4.5], [phil@juniper.net])
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
# Support silent build rules. Requires at least automake-1.11.
@ -54,11 +54,15 @@ AC_CHECK_FUNCS([sranddev srand strlcpy])
AC_CHECK_FUNCS([fdopen getrusage])
AC_CHECK_FUNCS([gettimeofday ctime])
AC_CHECK_FUNCS([getpass])
AC_CHECK_FUNCS([getprogname])
AC_CHECK_FUNCS([sysctlbyname])
AC_CHECK_FUNCS([flock])
AC_CHECK_FUNCS([asprintf])
AC_CHECK_FUNCS([__flbf])
AC_CHECK_FUNCS([sysctlbyname])
AC_CHECK_HEADERS([dlfcn.h])
AC_CHECK_HEADERS([dlfcn.h])
AC_CHECK_HEADERS([stdio_ext.h])
AC_CHECK_HEADERS([tzfile.h])
@ -69,10 +73,139 @@ AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_HEADERS([ctype.h errno.h stdio.h stdlib.h])
AC_CHECK_HEADERS([string.h sys/param.h unistd.h ])
AC_CHECK_HEADERS([sys/sysctl.h])
AC_CHECK_HEADERS([threads.h])
dnl humanize_number(3) is a great function, but it's not standard.
dnl Note Macosx has the function in libutil.a but doesn't ship the
dnl header file, so I'll need to carry my own implementation. See:
dnl https://devforums.apple.com/thread/271121
AC_CHECK_HEADERS([libutil.h])
AC_CHECK_LIB([util], [humanize_number],
[HAVE_HUMANIZE_NUMBER=$ac_cv_header_libutil_h],
[HAVE_HUMANIZE_NUMBER=no])
AC_MSG_RESULT(humanize_number results: :${HAVE_HUMANIZE_NUMBER}:${ac_cv_header_libutil_h}:)
if test "$HAVE_HUMANIZE_NUMBER" = "yes"; then
AC_DEFINE([HAVE_HUMANIZE_NUMBER], [1], [humanize_number(3)])
fi
AM_CONDITIONAL([HAVE_HUMANIZE_NUMBER], [test "$HAVE_HUMANIZE_NUMBER" = "yes"])
AC_ARG_ENABLE([gettext],
[ --disable-gettext Turn off support for gettext],
[GETTEXT_ENABLE=$enableval],
[GETTEXT_ENABLE=yes])
dnl Looking for gettext(), assumably in libintl
AC_ARG_WITH(gettext,
[ --with-gettext=[PFX] Specify location of gettext installation],
[GETTEXT_PREFIX=$withval],
[GETTEXT_PREFIX=/usr],
)
HAVE_GETTEXT=no
if test "$GETTEXT_ENABLE" != "no"; then
AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}])
_save_cflags="$CFLAGS"
CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl"
AC_LINK_IFELSE([AC_LANG_SOURCE([[#include <libintl.h>]
[int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])],
[HAVE_GETTEXT=yes],
[HAVE_GETTEXT=no])
CFLAGS="$_save_cflags"
AC_MSG_RESULT([$HAVE_GETTEXT])
if test "$HAVE_GETTEXT" != "yes"; then
GETTEXT_PREFIX=/opt/local
AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}])
_save_cflags="$CFLAGS"
CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl"
AC_LINK_IFELSE([AC_LANG_SOURCE([[#include <libintl.h>]
[int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])],
[HAVE_GETTEXT=yes],
[HAVE_GETTEXT=no])
CFLAGS="$_save_cflags"
AC_MSG_RESULT([$HAVE_GETTEXT])
fi
fi
if test "$HAVE_GETTEXT" = "yes"; then
AC_DEFINE([HAVE_GETTEXT], [1], [gettext(3)])
GETTEXT_CFLAGS="-I${GETTEXT_PREFIX}/include"
GETTEXT_LIBS="-L${GETTEXT_PREFIX}/lib -lintl"
else
GETTEXT_PREFIX=none
GETTEXT_CFLAGS=
GETTEXT_LIBS=
fi
AC_SUBST(GETTEXT_CFLAGS)
AC_SUBST(GETTEXT_LIBS)
GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin
AC_SUBST(GETTEXT_BINDIR)
GETTEXT_LIBDIR=${GETTEXT_PREFIX}/lib
AC_SUBST(GETTEXT_LIBDIR)
AM_CONDITIONAL([HAVE_GETTEXT], [test "$HAVE_GETTEXT" = "yes"])
dnl Looking for how to do thread-local variables
AC_ARG_WITH(threads,
[ --with-threads=[STYLE] Specify style of thread-local support (none)],
[THREAD_LOCAL=$withval],
[THREAD_LOCAL=unknown],
)
AC_MSG_CHECKING([thread-locals are ${THREAD_LOCAL}])
if test "$THREAD_LOCAL" = "unknown"; then
AC_LINK_IFELSE([AC_LANG_SOURCE([[]
[__thread int foo; int main() { foo++; return foo; }]])],
[THREAD_LOCAL=before],
[THREAD_LOCAL=unknown])
AC_MSG_RESULT([$THREAD_LOCAL])
fi
if test "$THREAD_LOCAL" = "unknown"; then
AC_LINK_IFELSE([AC_LANG_SOURCE([[]
[int __thread foo; int main() { foo++; return foo; }]])],
[THREAD_LOCAL=after],
[THREAD_LOCAL=unknown])
AC_MSG_RESULT([$THREAD_LOCAL])
fi
if test "$THREAD_LOCAL" = "unknown"; then
AC_LINK_IFELSE([AC_LANG_SOURCE([[]
[__declspec(int) foo; int main() { foo++; return foo; }]])],
[THREAD_LOCAL=declspec],
[THREAD_LOCAL=unknown])
AC_MSG_RESULT([$THREAD_LOCAL])
fi
if test "$THREAD_LOCAL" != "unknown"; then
AC_DEFINE_UNQUOTED([HAVE_THREAD_LOCAL],
THREAD_LOCAL_${THREAD_LOCAL}, [thread-local setting])
fi
dnl Looking for libcrypto....
AC_CHECK_LIB([crypto], [MD5_Init])
AM_CONDITIONAL([HAVE_LIBCRYPTO], [test "$HAVE_LIBCRYPTO" != "no"])
AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
[HAVE_SUN_LEN=yes ;
AC_DEFINE([HAVE_SUN_LEN], [1], [Have struct sockaddr_un.sun_len])],
[HAS_SUN_LEN=no], [[#include <sys/un.h>]])
AC_CHECK_DECLS([__isthreaded], [], [], [#include <stdio.h>])
HAVE_ISTHREADED=${ac_cv_have_decl___isthreaded}
dnl
dnl Some packages need to be checked against version numbers so we
dnl define a function here for later use
@ -107,12 +240,15 @@ then
SLAX_BINDIR="`$SLAX_CONFIG --bindir | head -1`"
SLAX_OXTRADOCDIR="`$SLAX_CONFIG --oxtradoc | head -1`"
AC_MSG_RESULT($LIBSLAX_VERSION found)
HAVE_OXTRADOC=yes
else
LIBSLAX_VERSION=
SLAX_BINDIR=
SLAX_OXTRADOCDIR=
AC_MSG_RESULT([no])
HAVE_OXTRADOC=no
fi
AM_CONDITIONAL([HAVE_OXTRADOC], [test "$HAVE_OXTRADOC" != "no"])
AC_SUBST(SLAX_BINDIR)
AC_SUBST(SLAX_OXTRADOCDIR)
@ -141,6 +277,16 @@ AC_ARG_ENABLE([text-only],
AC_MSG_RESULT([$LIBXO_TEXT_ONLY])
AM_CONDITIONAL([LIBXO_TEXT_ONLY], [test "$LIBXO_TEXT_ONLY" != "no"])
AC_MSG_CHECKING([whether to build with local wcwidth implementation])
AC_ARG_ENABLE([wcwidth],
[ --disable-wcwidth Disable local wcwidth implementation],
[LIBXO_WCWIDTH=$enableval],
[LIBXO_WCWIDTH=yes])
AC_MSG_RESULT([$LIBXO_WCWIDTH])
if test "${LIBXO_WCWIDTH}" != "no"; then
AC_DEFINE([LIBXO_WCWIDTH], [1], [Enable local wcwidth implementation])
fi
AC_CHECK_LIB([m], [lrint])
AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"])
@ -177,13 +323,16 @@ AM_CONDITIONAL([NO_LIBXO_OPTIONS], [test "$LIBXO_OPTS" != "yes"])
case $host_os in
darwin*)
LIBTOOL=glibtool
XO_LIBEXT=dylib
;;
Linux*|linux*)
CFLAGS="-D_GNU_SOURCE $CFLAGS"
LDFLAGS=-ldl
XO_LIBEXT=so
;;
cygwin*|CYGWIN*)
LDFLAGS=-no-undefined
XO_LIBEXT=ddl
;;
esac
@ -203,6 +352,14 @@ AC_SUBST(XO_SRCDIR)
AC_SUBST(XO_LIBDIR)
AC_SUBST(XO_BINDIR)
AC_SUBST(XO_INCLUDEDIR)
AC_SUBST(XO_LIBEXT)
AC_ARG_WITH(encoder-dir,
[ --with-encoder-dir=[DIR] Specify location of encoder libraries],
[XO_ENCODERDIR=$withval],
[XO_ENCODERDIR=$libdir/libxo/encoder]
)
AC_SUBST(XO_ENCODERDIR)
AC_ARG_WITH(share-dir,
[ --with-share-dir=[DIR] Specify location of shared files],
@ -232,20 +389,34 @@ AC_SUBST(LIBXO_VERSION)
AC_SUBST(LIBXO_VERSION_NUMBER)
AC_SUBST(LIBXO_VERSION_EXTRA)
AC_CONFIG_HEADERS([libxo/xoconfig.h])
AC_DEFINE_UNQUOTED(LIBXO_VERSION, ["$LIBXO_VERSION"],
[Version number as dotted value])
AC_DEFINE_UNQUOTED(LIBXO_VERSION_NUMBER, [$LIBXO_VERSION_NUMBER],
[Version number as a number])
AC_DEFINE_UNQUOTED(LIBXO_VERSION_STRING, ["$LIBXO_VERSION_NUMBER"],
[Version number as string])
AC_DEFINE_UNQUOTED(LIBXO_VERSION_EXTRA, ["$LIBXO_VERSION_EXTRA"],
[Version number extra information])
AC_CONFIG_HEADERS([libxo/xo_config.h])
AC_CONFIG_FILES([
Makefile
libxo-config
xohtml/xohtml.sh
libxo/Makefile
libxo/xoversion.h
libxo/add.man
encoder/Makefile
encoder/cbor/Makefile
encoder/test/Makefile
xo/Makefile
xolint/Makefile
xohtml/Makefile
xopo/Makefile
packaging/libxo.pc
doc/Makefile
tests/Makefile
tests/core/Makefile
tests/gettext/Makefile
tests/xo/Makefile
packaging/libxo.spec
packaging/libxo.rb.base
@ -262,6 +433,7 @@ AC_MSG_NOTICE([summary of build options:
bindir: ${XO_BINDIR}
includedir: ${XO_INCLUDEDIR}
share dir: ${XO_SHAREDIR}
extensions dir: ${XO_ENCODERDIR}
oxtradoc dir: ${SLAX_OXTRADOCDIR}
compiler: ${CC} (${HAVE_GCC:-no})
@ -273,4 +445,8 @@ AC_MSG_NOTICE([summary of build options:
printf-like: ${HAVE_PRINTFLIKE:-no}
libxo-options: ${LIBXO_OPTS:-no}
text-only: ${LIBXO_TEXT_ONLY:-no}
gettext: ${HAVE_GETTEXT:-no} (${GETTEXT_PREFIX})
isthreaded: ${HAVE_ISTHREADED:-no}
thread-local: ${THREAD_LOCAL:-no}
local wcwidth: ${LIBXO_WCWIDTH:-no}
])

View file

@ -8,6 +8,7 @@
# using the SOFTWARE, you agree to be bound by the terms of that
# LICENSE.
if HAVE_OXTRADOC
OXTRADOC_DIR = ${SLAX_OXTRADOCDIR}
OXTRADOC_PREFIX = ${OXTRADOC_DIR}
OXTRADOC = ${OXTRADOC_DIR}/oxtradoc
@ -38,28 +39,32 @@ OX_ARGS += -S ${SLAXPROC} -p doc
OX_CMD = ${PERL} ${PERLOPTS} ${OXTRADOC} ${OX_ARGS}
OXTRADOC_CMD = ${OX_CMD}
OUTPUT = libxo-manual
INPUT = libxo.txt
INPUT = libxo
EXTRA_DIST = \
${INPUT} \
${INPUT}.txt \
${OUTPUT}.html \
${OUTPUT}.txt
doc docs: ${OUTPUT}.txt ${OUTPUT}.html
${OUTPUT}.txt: ${INPUT} ${OXTRADOC} xolint.txt
${OUTPUT}.txt: ${INPUT}.txt ${OXTRADOC} xolint.txt
${OXTRADOC_CMD} -m text -o $@ $<
${OUTPUT}.html: ${INPUT} ${OXTRADOC} ${XML2HTMLBIN} xolint.txt
${OUTPUT}.html: ${INPUT}.txt ${OXTRADOC} ${XML2HTMLBIN} xolint.txt
${OXTRADOC_CMD} -m html -o $@ $<
xolint.txt: ${top_srcdir}/xolint/xolint.pl
perl ${top_srcdir}/xolint/xolint.pl -D > xolint.txt
CLEANFILES = \
${OUTPUT}.xml \
${OUTPUT}.txt \
${OUTPUT}.fxml \
${OUTPUT}.html
xolint.txt \
${INPUT}.xml \
${INPUT}.txt \
${INPUT}.fxml \
${INPUT}.html
else
doc docs:
@${ECHO} "The 'oxtradoc' tool is not installed; see libslax.org"
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
#
# Copyright 2015, Juniper Networks, Inc.
# All rights reserved.
# This SOFTWARE is licensed under the LICENSE provided in the
# ../Copyright file. By downloading, installing, copying, or otherwise
# using the SOFTWARE, you agree to be bound by the terms of that
# LICENSE.
SUBDIRS = cbor test

View file

@ -0,0 +1,51 @@
#
# $Id$
#
# Copyright 2015, Juniper Networks, Inc.
# All rights reserved.
# This SOFTWARE is licensed under the LICENSE provided in the
# ../Copyright file. By downloading, installing, copying, or otherwise
# using the SOFTWARE, you agree to be bound by the terms of that
# LICENSE.
if LIBXO_WARNINGS_HIGH
LIBXO_WARNINGS = HIGH
endif
if HAVE_GCC
GCC_WARNINGS = yes
endif
include ${top_srcdir}/warnings.mk
enc_cborincdir = ${includedir}/libxo
AM_CFLAGS = \
-I${top_srcdir}/libxo \
-I${top_builddir}/libxo \
${WARNINGS}
LIBNAME = libenc_cbor
pkglib_LTLIBRARIES = libenc_cbor.la
LIBS = \
-L${top_builddir}/libxo -lxo
LDADD = ${top_builddir}/libxo/libxo.la
libenc_cbor_la_SOURCES = \
enc_cbor.c
pkglibdir = ${XO_ENCODERDIR}
UGLY_NAME = cbor.enc
install-exec-hook:
@DLNAME=`sh -c '. ./libenc_cbor.la ; echo $$dlname'` ; \
if [ x"$$DLNAME" = x ]; \
then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \
if [ "$(build_os)" = "cygwin" ]; \
then DLNAME="../bin/$$DLNAME"; fi ; \
echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \
mkdir -p ${DESTDIR}${XO_ENCODERDIR} ; \
cd ${DESTDIR}${XO_ENCODERDIR} \
&& chmod +w . \
&& rm -f ${UGLY_NAME} \
&& ${LN_S} $$DLNAME ${UGLY_NAME}

View file

@ -0,0 +1,365 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
/*
* CBOR (RFC 7049) mades a suitable test case for libxo's external
* encoder API. It's simple, streaming, well documented, and an
* IETF standard.
*
* This encoder uses the "pretty" flag for diagnostics, which isn't
* really kosher, but it's example code.
*/
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdint.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
#include "xo.h"
#include "xo_encoder.h"
#include "xo_buf.h"
/*
* memdump(): dump memory contents in hex/ascii
0 1 2 3 4 5 6 7
0123456789012345678901234567890123456789012345678901234567890123456789012345
XX XX XX XX XX XX XX XX - XX XX XX XX XX XX XX XX abcdefghijklmnop
*/
static void
cbor_memdump (FILE *fp, const char *title, const char *data,
size_t len, const char *tag, int indent)
{
enum { MAX_PER_LINE = 16 };
char buf[ 80 ];
char text[ 80 ];
char *bp, *tp;
size_t i;
#if 0
static const int ends[ MAX_PER_LINE ] = { 2, 5, 8, 11, 15, 18, 21, 24,
29, 32, 35, 38, 42, 45, 48, 51 };
#endif
if (fp == NULL)
fp = stdout;
if (tag == NULL)
tag = "";
fprintf(fp, "%*s[%s] @ %p (%lx/%lu)\n", indent + 1, tag,
title, data, (unsigned long) len, (unsigned long) len);
while (len > 0) {
bp = buf;
tp = text;
for (i = 0; i < MAX_PER_LINE && i < len; i++) {
if (i && (i % 4) == 0) *bp++ = ' ';
if (i == 8) {
*bp++ = '-';
*bp++ = ' ';
}
sprintf(bp, "%02x ", (unsigned char) *data);
bp += strlen(bp);
*tp++ = (isprint((int) *data) && *data >= ' ') ? *data : '.';
data += 1;
}
*tp = 0;
*bp = 0;
fprintf(fp, "%*s%-54s%s\n", indent + 1, tag, buf, text);
len -= i;
}
}
/*
* CBOR breaks the first byte into two pieces, the major type in the
* top 3 bits and the minor value in the low 5 bits. The value can be
* a small value (0 .. 23), an 8-bit value (24), a 16-bit value (25),
* a 32-bit value (26), or a 64-bit value (27). A value of 31
* represents an unknown length, which we'll use extensively for
* streaming our content.
*/
#define CBOR_MAJOR_MASK 0xE0
#define CBOR_MINOR_MASK 0x1F
#define CBOR_MAJOR_SHIFT 5
#define CBOR_MAJOR(_x) ((_x) & CBOR_MAJOR_MASK)
#define CBOR_MAJOR_VAL(_x) ((_x) << CBOR_MAJOR_SHIFT)
#define CBOR_MINOR_VAL(_x) ((_x) & CBOR_MINOR_MASK)
/* Major type codes */
#define CBOR_UNSIGNED CBOR_MAJOR_VAL(0) /* 0x00 */
#define CBOR_NEGATIVE CBOR_MAJOR_VAL(1) /* 0x20 */
#define CBOR_BYTES CBOR_MAJOR_VAL(2) /* 0x40 */
#define CBOR_STRING CBOR_MAJOR_VAL(3) /* 0x60 */
#define CBOR_ARRAY CBOR_MAJOR_VAL(4) /* 0x80 */
#define CBOR_MAP CBOR_MAJOR_VAL(5) /* 0xa0 */
#define CBOR_SEMANTIC CBOR_MAJOR_VAL(6) /* 0xc0 */
#define CBOR_SPECIAL CBOR_MAJOR_VAL(7) /* 0xe0 */
#define CBOR_ULIMIT 24 /* Largest unsigned value */
#define CBOR_NLIMIT 23 /* Largest negative value */
#define CBOR_BREAK 0xFF
#define CBOR_INDEF 0x1F
#define CBOR_FALSE 0xF4
#define CBOR_TRUE 0xF5
#define CBOR_NULL 0xF6
#define CBOR_UNDEF 0xF7
#define CBOR_LEN8 0x18 /* 24 - 8-bit value */
#define CBOR_LEN16 0x19 /* 25 - 16-bit value */
#define CBOR_LEN32 0x1a /* 26 - 32-bit value */
#define CBOR_LEN64 0x1b /* 27 - 64-bit value */
#define CBOR_LEN128 0x1c /* 28 - 128-bit value */
typedef struct cbor_private_s {
xo_buffer_t c_data; /* Our data buffer */
unsigned c_indent; /* Indent level */
unsigned c_open_leaf_list; /* Open leaf list construct? */
} cbor_private_t;
static void
cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor, unsigned limit)
{
char *bp = xbp->xb_curp;
int i, m;
if (minor > (1UL<<32)) {
*bp++ |= CBOR_LEN64;
m = 64;
} else if (minor > (1<<16)) {
*bp++ |= CBOR_LEN32;
m = 32;
} else if (minor > (1<<8)) {
*bp++ |= CBOR_LEN16;
m = 16;
} else if (minor > limit) {
*bp++ |= CBOR_LEN8;
m = 8;
} else {
*bp++ |= minor & CBOR_MINOR_MASK;
m = 0;
}
if (m) {
for (i = m - 8; i >= 0; i -= 8)
*bp++ = minor >> i;
}
xbp->xb_curp = bp;
}
static void
cbor_append (xo_handle_t *xop, cbor_private_t *cbor, xo_buffer_t *xbp,
unsigned major, unsigned minor, const char *data)
{
if (!xo_buf_has_room(xbp, minor + 2))
return;
unsigned offset = xo_buf_offset(xbp);
*xbp->xb_curp = major;
cbor_encode_uint(xbp, minor, CBOR_ULIMIT);
if (data)
xo_buf_append(xbp, data, minor);
if (xo_get_flags(xop) & XOF_PRETTY)
cbor_memdump(stdout, "append", xo_buf_data(xbp, offset),
xbp->xb_curp - xbp->xb_bufp - offset, "",
cbor->c_indent * 2);
}
static int
cbor_create (xo_handle_t *xop)
{
cbor_private_t *cbor = xo_realloc(NULL, sizeof(*cbor));
if (cbor == NULL)
return -1;
bzero(cbor, sizeof(*cbor));
xo_buf_init(&cbor->c_data);
xo_set_private(xop, cbor);
cbor_append(xop, cbor, &cbor->c_data, CBOR_MAP | CBOR_INDEF, 0, NULL);
return 0;
}
static int
cbor_content (xo_handle_t *xop, cbor_private_t *cbor, xo_buffer_t *xbp,
const char *value)
{
int rc = 0;
unsigned offset = xo_buf_offset(xbp);
if (value == NULL || *value == '\0' || strcmp(value, "true") == 0)
cbor_append(xop, cbor, &cbor->c_data, CBOR_TRUE, 0, NULL);
else if (strcmp(value, "false") == 0)
cbor_append(xop, cbor, &cbor->c_data, CBOR_FALSE, 0, NULL);
else {
int negative = 0;
if (*value == '-') {
value += 1;
negative = 1;
}
char *ep;
unsigned long long ival;
ival = strtoull(value, &ep, 0);
if (ival == ULLONG_MAX) /* Sometimes a string is just a string */
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value);
else {
*xbp->xb_curp = negative ? CBOR_NEGATIVE : CBOR_UNSIGNED;
if (negative)
ival -= 1; /* Don't waste a negative zero */
cbor_encode_uint(xbp, ival, negative ? CBOR_NLIMIT : CBOR_ULIMIT);
}
}
if (xo_get_flags(xop) & XOF_PRETTY)
cbor_memdump(stdout, "content", xo_buf_data(xbp, offset),
xbp->xb_curp - xbp->xb_bufp - offset, "",
cbor->c_indent * 2);
return rc;
}
static int
cbor_handler (XO_ENCODER_HANDLER_ARGS)
{
int rc = 0;
cbor_private_t *cbor = private;
xo_buffer_t *xbp = cbor ? &cbor->c_data : NULL;
if (xo_get_flags(xop) & XOF_PRETTY) {
printf("%*sop %s: [%s] [%s]\n", cbor ? cbor->c_indent * 2 + 4 : 0, "",
xo_encoder_op_name(op), name ?: "", value ?: "");
fflush(stdout);
}
/* If we don't have private data, we're sunk */
if (cbor == NULL && op != XO_OP_CREATE)
return -1;
switch (op) {
case XO_OP_CREATE: /* Called when the handle is init'd */
rc = cbor_create(xop);
break;
case XO_OP_OPEN_CONTAINER:
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name);
cbor_append(xop, cbor, xbp, CBOR_MAP | CBOR_INDEF, 0, NULL);
cbor->c_indent += 1;
break;
case XO_OP_CLOSE_CONTAINER:
cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL);
cbor->c_indent -= 1;
break;
case XO_OP_OPEN_LIST:
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name);
cbor_append(xop, cbor, xbp, CBOR_ARRAY | CBOR_INDEF, 0, NULL);
cbor->c_indent += 1;
break;
case XO_OP_CLOSE_LIST:
cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL);
cbor->c_indent -= 1;
break;
case XO_OP_OPEN_LEAF_LIST:
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name);
cbor_append(xop, cbor, xbp, CBOR_ARRAY | CBOR_INDEF, 0, NULL);
cbor->c_indent += 1;
cbor->c_open_leaf_list = 1;
break;
case XO_OP_CLOSE_LEAF_LIST:
cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL);
cbor->c_indent -= 1;
cbor->c_open_leaf_list = 0;
break;
case XO_OP_OPEN_INSTANCE:
cbor_append(xop, cbor, xbp, CBOR_MAP | CBOR_INDEF, 0, NULL);
cbor->c_indent += 1;
break;
case XO_OP_CLOSE_INSTANCE:
cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL);
cbor->c_indent -= 1;
break;
case XO_OP_STRING: /* Quoted UTF-8 string */
if (!cbor->c_open_leaf_list)
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name);
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value);
break;
case XO_OP_CONTENT: /* Other content */
if (!cbor->c_open_leaf_list)
cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name);
/*
* It's content, not string, so we need to look at the
* string and build some content. Turns out we only
* care about true, false, null, and numbers.
*/
cbor_content(xop, cbor, xbp, value);
break;
case XO_OP_FINISH: /* Clean up function */
cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL);
cbor->c_indent -= 1;
break;
case XO_OP_FLUSH: /* Clean up function */
if (xo_get_flags(xop) & XOF_PRETTY)
cbor_memdump(stdout, "cbor",
xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp,
">", 0);
else {
rc = write(1, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp);
if (rc > 0)
rc = 0;
}
break;
case XO_OP_DESTROY: /* Clean up function */
break;
case XO_OP_ATTRIBUTE: /* Attribute name/value */
break;
case XO_OP_VERSION: /* Version string */
break;
}
return rc;
}
int
xo_encoder_library_init (XO_ENCODER_INIT_ARGS)
{
arg->xei_handler = cbor_handler;
return 0;
}

View file

@ -0,0 +1,51 @@
#
# $Id$
#
# Copyright 2015, Juniper Networks, Inc.
# All rights reserved.
# This SOFTWARE is licensed under the LICENSE provided in the
# ../Copyright file. By downloading, installing, copying, or otherwise
# using the SOFTWARE, you agree to be bound by the terms of that
# LICENSE.
if LIBXO_WARNINGS_HIGH
LIBXO_WARNINGS = HIGH
endif
if HAVE_GCC
GCC_WARNINGS = yes
endif
include ${top_srcdir}/warnings.mk
enc_testincdir = ${includedir}/libxo
AM_CFLAGS = \
-I${top_srcdir}/libxo \
-I${top_builddir}/libxo \
${WARNINGS}
LIBNAME = libenc_test
pkglib_LTLIBRARIES = libenc_test.la
LIBS = \
-L${top_builddir}/libxo -lxo
LDADD = ${top_builddir}/libxo/libxo.la
libenc_test_la_SOURCES = \
enc_test.c
pkglibdir = ${XO_ENCODERDIR}
UGLY_NAME = test.enc
install-exec-hook:
@DLNAME=`sh -c '. ./libenc_test.la ; echo $$dlname'` ; \
if [ x"$$DLNAME" = x ]; \
then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \
if [ "$(build_os)" = "cygwin" ]; \
then DLNAME="../bin/$$DLNAME"; fi ; \
echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \
mkdir -p ${DESTDIR}${XO_ENCODERDIR} ; \
cd ${DESTDIR}${XO_ENCODERDIR} \
&& chmod +w . \
&& rm -f ${UGLY_NAME} \
&& ${LN_S} $$DLNAME ${UGLY_NAME}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
#include "xo.h"
#include "xo_encoder.h"
static int
test_handler (XO_ENCODER_HANDLER_ARGS)
{
printf("op %s: [%s] [%s]\n", xo_encoder_op_name(op),
name ?: "", value ?: "");
return 0;
}
int
xo_encoder_library_init (XO_ENCODER_INIT_ARGS)
{
arg->xei_version = XO_ENCODER_VERSION;
arg->xei_handler = test_handler;
return 0;
}

View file

@ -16,25 +16,44 @@ include ${top_srcdir}/warnings.mk
libxoincdir = ${includedir}/libxo
AM_CFLAGS = -I${top_srcdir} ${WARNINGS}
AM_CFLAGS = \
-I${top_srcdir} \
${WARNINGS} \
${GETTEXT_CFLAGS}
AM_CFLAGS += \
-DXO_ENCODERDIR=\"${XO_ENCODERDIR}\"
lib_LTLIBRARIES = libxo.la
LIBS = \
${GETTEXT_LIBS}
libxoinc_HEADERS = \
xo.h
xo.h \
xo_encoder.h
noinst_HEADERS = \
xo_buf.h \
xo_humanize.h \
xo_wcwidth.h
libxo_la_SOURCES = \
libxo.c
libxo.c \
xo_encoder.c \
xo_syslog.c
man_MANS = \
man3_files = \
libxo.3 \
xo_attr.3 \
xo_create.3 \
xo_emit.3 \
xo_emit_err.3 \
xo_err.3 \
xo_error.3 \
xo_finish.3 \
xo_flush.3 \
xo_format.5 \
xo_message.3 \
xo_no_setlocale.3 \
xo_open_container.3 \
xo_open_list.3 \
@ -45,8 +64,26 @@ man_MANS = \
xo_set_info.3 \
xo_set_options.3 \
xo_set_style.3 \
xo_set_syslog_enterprise_id.3 \
xo_set_version.3 \
xo_set_writer.3
xo_set_writer.3 \
xo_syslog.3
EXTRA_DIST = ${man_MANS}
man5_files = \
xo_format.5
man_MANS = ${man3_files} ${man5_files}
EXTRA_DIST = \
${man_MANS}
call-graph:
${RM} libxo.o
${MAKE} CC="clang -Xclang -analyze -Xclang \
-analyzer-checker=debug.ViewCallGraph" libxo.o
install-data-hook:
for file in ${man3_files}; do \
cat ../libxo/add.man >> ${DESTDIR}${man3dir}/$$file ; done
for file in ${man5_files}; do \
cat ../libxo/add.man >> ${DESTDIR}${man5dir}/$$file ; done

View file

@ -0,0 +1,29 @@
.Sh ADDITIONAL DOCUMENTATION
.Fx
uses
.Nm libxo
version 0.4.3.
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/0.4.3/libxo\-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer

View file

@ -0,0 +1,29 @@
.Sh ADDITIONAL DOCUMENTATION
.Fx
uses
.Nm libxo
version @LIBXO_VERSION@.
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/@LIBXO_VERSION@/libxo\-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer

View file

@ -66,17 +66,25 @@ output, with attributes that detail how to render the data.
.Pp
There are four encoding styles supported by
.Nm :
TEXT, HTML, JSON,
and XML.
JSON and XML are suitable for encoding data, while TEXT and
HTML are suited for display to the user.
TEXT output can be display
on a terminal session, allowing compatibility with traditional usage.
.Bl -bullet
.It
TEXT output can be display on a terminal session, allowing
compatibility with traditional command line usage.
.It
XML output is suitable for tools like XPath and protocols like
NETCONF.
.It
JSON output can be used for RESTful APIs and integration with
languages like Javascript and Python.
.It
HTML can be matched with a small CSS file to permit rendering in any
HTML5 browser.
XML output is suitable for tools like XPath and
protocols like NETCONF.
JSON output can be used for RESTful APIs.
.El
.Pp
In general, XML and JSON are suitable for encoding data, while TEXT is
suited for terminal output and HTML is suited for display in a web
browser (see
.Xr xohtml 1 ).
.Pp
The
.Nm
@ -177,6 +185,19 @@ formatted output.
See
.Xr xo_format 5
for details.
.It Fn xo_emit_warn
.It Fn xo_emit_warnx
.It Fn xo_emit_warn_c
.It Fn xo_emit_warn_hc
.It Fn xo_emit_err
.It Fn xo_emit_errc
.It Fn xo_emit_errx
These functions are mildly compatible with their standard libc
namesakes, but use the format string defined in
.Xr xo_format 5 .
While there is an increased cost for converting the strings, the
output provided can be richer and more useful. See also
.Xr xo_err 3
.It Fn xo_warn
.It Fn xo_warnx
.It Fn xo_warn_c
@ -269,30 +290,13 @@ Instructs
.Nm
to use an alternative set of low-level output functions.
.El
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo 1 ,
.Xr xolint 1 ,
.Xr xo_attr 3 ,
.Xr xo_create 3 ,
.Xr xo_emit 3 ,
.Xr xo_emit_err 3 ,
.Xr xo_err 3 ,
.Xr xo_finish 3 ,
.Xr xo_flush 3 ,
@ -307,10 +311,3 @@ https://github.com/Juniper/libxo/releases
.Xr xo_set_style 3 ,
.Xr xo_set_writer 3 ,
.Xr xo_format 5
.Sh HISTORY
The
.Nm
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Juniper Networks, Inc.
* Copyright (c) 2014-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
@ -12,12 +12,19 @@
* libxo provides a means of generating text, XML, JSON, and HTML output
* using a single set of function calls, maximizing the value of output
* while minimizing the cost/impact on the code.
*
* Full documentation is available in ./doc/libxo.txt or online at:
* http://juniper.github.io/libxo/libxo-manual.html
*/
#ifndef INCLUDE_XO_H
#define INCLUDE_XO_H
#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#ifdef __dead2
#define NORETURN __dead2
@ -39,19 +46,21 @@
#endif /* NO_PRINTFLIKE */
/** Formatting types */
typedef unsigned xo_style_t;
typedef unsigned short xo_style_t;
#define XO_STYLE_TEXT 0 /** Generate text output */
#define XO_STYLE_XML 1 /** Generate XML output */
#define XO_STYLE_JSON 2 /** Generate JSON output */
#define XO_STYLE_HTML 3 /** Generate HTML output */
#define XO_STYLE_SDPARAMS 4 /* Generate syslog structured data params */
#define XO_STYLE_ENCODER 5 /* Generate calls to external encoder */
/** Flags for libxo */
typedef unsigned long long xo_xof_flags_t;
#define XOF_BIT(_n) ((xo_xof_flags_t) 1 << (_n))
#define XOF_CLOSE_FP XOF_BIT(0) /** Close file pointer on xo_close() */
#define XOF_PRETTY XOF_BIT(1) /** Make 'pretty printed' output */
#define XOF_DIV_OPEN XOF_BIT(2) /** Internal use only: a <div> is open */
#define XOF_LINE_OPEN XOF_BIT(3) /** Internal use only: <div class="line"> */
#define XOF_LOG_SYSLOG XOF_BIT(2) /** Log (on stderr) our syslog content */
#define XOF_RESV3 XOF_BIT(3) /* Unused */
#define XOF_WARN XOF_BIT(4) /** Generate warnings for broken calls */
#define XOF_XPATH XOF_BIT(5) /** Emit XPath attributes in HTML */
@ -66,12 +75,12 @@ typedef unsigned long long xo_xof_flags_t;
#define XOF_IGNORE_CLOSE XOF_BIT(12) /** Ignore errors on close tags */
#define XOF_NOT_FIRST XOF_BIT(13) /* Not the first item (JSON) */
#define XOF_NO_LOCALE XOF_BIT(14) /** Don't bother with locale */
#define XOF_TOP_EMITTED XOF_BIT(15) /* The top JSON braces have been emitted */
#define XOF_RESV15 XOF_BIT(15) /* Unused */
#define XOF_NO_TOP XOF_BIT(16) /** Don't emit the top braces in JSON */
#define XOF_ANCHOR XOF_BIT(17) /** An anchor is in place */
#define XOF_RESV17 XOF_BIT(17) /* Unused */
#define XOF_UNITS XOF_BIT(18) /** Encode units in XML */
#define XOF_UNITS_PENDING XOF_BIT(19) /** We have a units-insertion pending */
#define XOF_RESV19 XOF_BIT(19) /* Unused */
#define XOF_UNDERSCORES XOF_BIT(20) /** Replace dashes with underscores (JSON)*/
#define XOF_COLUMNS XOF_BIT(21) /** xo_emit should return a column count */
@ -81,6 +90,10 @@ typedef unsigned long long xo_xof_flags_t;
#define XOF_NO_CLOSE XOF_BIT(24) /** xo_finish won't close open elements */
#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */
#define XOF_COLOR XOF_BIT(26) /** Enable color and effects */
#define XOF_NO_HUMANIZE XOF_BIT(27) /** Block the {h:} modifier */
#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */
#define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */
/*
* The xo_info_t structure provides a mapping between names and
@ -92,6 +105,8 @@ typedef struct xo_info_s {
const char *xi_help; /* Description of field */
} xo_info_t;
#define XO_INFO_NULL NULL, NULL, NULL /* Use '{ XO_INFO_NULL }' to end lists */
struct xo_handle_s; /* Opaque structure forward */
typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */
@ -165,6 +180,35 @@ xo_emit_h (xo_handle_t *xop, const char *fmt, ...);
int
xo_emit (const char *fmt, ...);
PRINTFLIKE(2, 0)
static inline int
xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
{
return xo_emit_hv(xop, fmt, vap);
}
PRINTFLIKE(2, 3)
static inline int
xo_emit_hp (xo_handle_t *xop, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
int rc = xo_emit_hv(xop, fmt, vap);
va_end(vap);
return rc;
}
PRINTFLIKE(1, 2)
static inline int
xo_emit_p (const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
int rc = xo_emit_hv(NULL, fmt, vap);
va_end(vap);
return rc;
}
int
xo_open_container_h (xo_handle_t *xop, const char *name);
@ -279,6 +323,9 @@ xo_finish_h (xo_handle_t *xop);
int
xo_finish (void);
void
xo_finish_atexit (void);
void
xo_set_leading_xpath (xo_handle_t *xop, const char *path);
@ -304,7 +351,7 @@ void
xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
void
xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap);
xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0);
void
xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
@ -312,9 +359,124 @@ xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4
void
xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
void
xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
const char *fmt, va_list vap);
void
xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
void
xo_emit_warn_c (int code, const char *fmt, ...);
void
xo_emit_warn (const char *fmt, ...);
void
xo_emit_warnx (const char *fmt, ...);
void
xo_emit_err (int eval, const char *fmt, ...) NORETURN;
void
xo_emit_errx (int eval, const char *fmt, ...) NORETURN;
void
xo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN;
PRINTFLIKE(4, 0)
static inline void
xo_emit_warn_hcvp (xo_handle_t *xop, int as_warning, int code,
const char *fmt, va_list vap)
{
xo_emit_warn_hcv(xop, as_warning, code, fmt, vap);
}
PRINTFLIKE(3, 4)
static inline void
xo_emit_warn_hcp (xo_handle_t *xop, int code, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(xop, 1, code, fmt, vap);
va_end(vap);
}
PRINTFLIKE(2, 3)
static inline void
xo_emit_warn_cp (int code, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
va_end(vap);
}
PRINTFLIKE(1, 2)
static inline void
xo_emit_warn_p (const char *fmt, ...)
{
int code = errno;
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
va_end(vap);
}
PRINTFLIKE(1, 2)
static inline void
xo_emit_warnx_p (const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 1, -1, fmt, vap);
va_end(vap);
}
NORETURN PRINTFLIKE(2, 3)
static inline void
xo_emit_err_p (int eval, const char *fmt, ...)
{
int code = errno;
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
va_end(vap);
exit(eval);
}
PRINTFLIKE(2, 3)
static inline void
xo_emit_errx_p (int eval, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 0, -1, fmt, vap);
va_end(vap);
exit(eval);
}
PRINTFLIKE(3, 4)
static inline void
xo_emit_errc_p (int eval, int code, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
va_end(vap);
exit(eval);
}
void
xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0);
void
xo_no_setlocale (void);
@ -395,4 +557,40 @@ xo_set_version (const char *version);
void
xo_set_version_h (xo_handle_t *xop, const char *version);
void
xo_open_log (const char *ident, int logopt, int facility);
void
xo_close_log (void);
int
xo_set_logmask (int maskpri);
void
xo_set_unit_test_mode (int value);
void
xo_syslog (int priority, const char *name, const char *message, ...);
void
xo_vsyslog (int priority, const char *name, const char *message, va_list args);
typedef void (*xo_syslog_open_t)(void);
typedef void (*xo_syslog_send_t)(const char *full_msg,
const char *v0_hdr, const char *text_only);
typedef void (*xo_syslog_close_t)(void);
void
xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func,
xo_syslog_close_t close_func);
void
xo_set_syslog_enterprise_id (unsigned short eid);
typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int);
char *
xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
xo_simplify_field_func_t field_cb);
#endif /* INCLUDE_XO_H */

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_attr , xo_attr_h , xo_attr_hv
.Nd Add attribute name/value pairs to formatted output
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -55,27 +55,6 @@ parameter as passed to
Since attributes are only emitted in XML, their use should be limited
to meta-data and additional or redundant representations of data
already emitted in other form.
.Sh ADDITIONAL DOCUMENTATION
.Pp
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
libxo lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of libxo is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Fa libxo
library was added in FreeBSD 11.0.
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
/*
* This file is an _internal_ part of the libxo plumbing, not suitable
* for external use. It is not considered part of the libxo API and
* will not be a stable part of that API. Mine, not your's, dude...
* The real hope is that something like this will become a standard part
* of libc and I can kill this off.
*/
#ifndef XO_BUF_H
#define XO_BUF_H
#define XO_BUFSIZ (8*1024) /* Initial buffer size */
/*
* xo_buffer_t: a memory buffer that can be grown as needed. We
* use them for building format strings and output data.
*/
typedef struct xo_buffer_s {
char *xb_bufp; /* Buffer memory */
char *xb_curp; /* Current insertion point */
unsigned xb_size; /* Size of buffer */
} xo_buffer_t;
/*
* Initialize the contents of an xo_buffer_t.
*/
static inline void
xo_buf_init (xo_buffer_t *xbp)
{
xbp->xb_size = XO_BUFSIZ;
xbp->xb_bufp = xo_realloc(NULL, xbp->xb_size);
xbp->xb_curp = xbp->xb_bufp;
}
/*
* Reset the buffer to empty
*/
static inline void
xo_buf_reset (xo_buffer_t *xbp)
{
xbp->xb_curp = xbp->xb_bufp;
}
/*
* Return the number of bytes left in the buffer
*/
static inline int
xo_buf_left (xo_buffer_t *xbp)
{
return xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
}
/*
* See if the buffer to empty
*/
static inline int
xo_buf_is_empty (xo_buffer_t *xbp)
{
return (xbp->xb_curp == xbp->xb_bufp);
}
/*
* Return the current offset
*/
static inline unsigned
xo_buf_offset (xo_buffer_t *xbp)
{
return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0;
}
static inline char *
xo_buf_data (xo_buffer_t *xbp, unsigned offset)
{
if (xbp == NULL)
return NULL;
return xbp->xb_bufp + offset;
}
static inline char *
xo_buf_cur (xo_buffer_t *xbp)
{
if (xbp == NULL)
return NULL;
return xbp->xb_curp;
}
/*
* Initialize the contents of an xo_buffer_t.
*/
static inline void
xo_buf_cleanup (xo_buffer_t *xbp)
{
if (xbp->xb_bufp)
xo_free(xbp->xb_bufp);
bzero(xbp, sizeof(*xbp));
}
/*
* Does the buffer have room for the given number of bytes of data?
* If not, realloc the buffer to make room. If that fails, we
* return 0 to tell the caller they are in trouble.
*/
static inline int
xo_buf_has_room (xo_buffer_t *xbp, int len)
{
if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) {
int sz = xbp->xb_size + XO_BUFSIZ;
char *bp = xo_realloc(xbp->xb_bufp, sz);
if (bp == NULL)
return 0;
xbp->xb_curp = bp + (xbp->xb_curp - xbp->xb_bufp);
xbp->xb_bufp = bp;
xbp->xb_size = sz;
}
return 1;
}
/*
* Append the given string to the given buffer
*/
static inline void
xo_buf_append (xo_buffer_t *xbp, const char *str, int len)
{
if (!xo_buf_has_room(xbp, len))
return;
memcpy(xbp->xb_curp, str, len);
xbp->xb_curp += len;
}
/*
* Append the given NUL-terminated string to the given buffer
*/
static inline void
xo_buf_append_str (xo_buffer_t *xbp, const char *str)
{
int len = strlen(str);
if (!xo_buf_has_room(xbp, len))
return;
memcpy(xbp->xb_curp, str, len);
xbp->xb_curp += len;
}
#endif /* XO_BUF_H */

View file

@ -1,5 +1,5 @@
/* libxo/xoconfig.h. Generated from xoconfig.h.in by configure. */
/* libxo/xoconfig.h.in. Generated from configure.ac by autoheader. */
/* libxo/xo_config.h. Generated from xo_config.h.in by configure. */
/* libxo/xo_config.h.in. Generated from configure.ac by autoheader. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
@ -28,6 +28,10 @@
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define to 1 if you have the declaration of `__isthreaded', and to 0 if you
don't. */
#define HAVE_DECL___ISTHREADED 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
@ -46,12 +50,21 @@
/* Define to 1 if you have the `getpass' function. */
#define HAVE_GETPASS 1
/* Define to 1 if you have the `getprogname' function. */
#define HAVE_GETPROGNAME 1
/* Define to 1 if you have the `getrusage' function. */
#define HAVE_GETRUSAGE 1
/* gettext(3) */
/* #undef HAVE_GETTEXT */
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* humanize_number(3) */
#define HAVE_HUMANIZE_NUMBER 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
@ -61,6 +74,9 @@
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the <libutil.h> header file. */
#define HAVE_LIBUTIL_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
@ -120,6 +136,9 @@
/* Define to 1 if you have the `strspn' function. */
#define HAVE_STRSPN 1
/* Have struct sockaddr_un.sun_len */
#define HAVE_SUN_LEN 1
/* Define to 1 if you have the `sysctlbyname' function. */
#define HAVE_SYSCTLBYNAME 1
@ -138,6 +157,12 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <threads.h> header file. */
#define HAVE_THREADS_H 1
/* thread-local setting */
#define HAVE_THREAD_LOCAL THREAD_LOCAL_before
/* Define to 1 if you have the <tzfile.h> header file. */
/* #undef HAVE_TZFILE_H */
@ -153,6 +178,21 @@
/* Enable text-only rendering */
/* #undef LIBXO_TEXT_ONLY */
/* Version number as dotted value */
#define LIBXO_VERSION "0.4.3"
/* Version number extra information */
#define LIBXO_VERSION_EXTRA ""
/* Version number as a number */
#define LIBXO_VERSION_NUMBER 4003
/* Version number as string */
#define LIBXO_VERSION_STRING "4003"
/* Enable local wcwidth implementation */
#define LIBXO_WCWIDTH 1
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
@ -166,7 +206,7 @@
#define PACKAGE_NAME "libxo"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libxo 0.3.2"
#define PACKAGE_STRING "libxo 0.4.3"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libxo"
@ -175,7 +215,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.3.2"
#define PACKAGE_VERSION "0.4.3"
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
@ -189,7 +229,7 @@
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.3.2"
#define VERSION "0.4.3"
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_create , xo_create_to_file , xo_destroy
.Nd create and destroy libxo output handles
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -61,31 +61,7 @@ with a
.Dv NULL
handle will release any
resources associated with the default handle.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3 ,
.Xr xo_set_options 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_set_options 3 ,
.Xr libxo 3

View file

@ -11,7 +11,7 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nm xo_emit , xo_emit_h , xo_emit_hv
.Nd emit formatted output based on format string and arguments
.Sh LIBRARY
.Lb libxo
@ -43,30 +43,62 @@ uses an explicit handle.
accepts a
.Fa va_list
for additional flexibility.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Sh EXAMPLES
In this example, a set of four values is emitted using the following
source code:
.Bd -literal -offset indent
xo_emit(" {:lines/%7ju} {:words/%7ju} "
"{:characters/%7ju} {d:filename/%s}\n",
linect, wordct, charct, file);
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of libxo is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
Output can then be generated in various style, using
the "--libxo" option:
.Bd -literal -offset indent
% wc /etc/motd
25 165 1140 /etc/motd
% wc --libxo xml,pretty,warn /etc/motd
<wc>
<file>
<lines>25</lines>
<words>165</words>
<characters>1140</characters>
<filename>/etc/motd</filename>
</file>
</wc>
% wc --libxo json,pretty,warn /etc/motd
{
"wc": {
"file": [
{
"lines": 25,
"words": 165,
"characters": 1140,
"filename": "/etc/motd"
}
]
}
}
% wc --libxo html,pretty,warn /etc/motd
<div class="line">
<div class="text"> </div>
<div class="data" data-tag="lines"> 25</div>
<div class="text"> </div>
<div class="data" data-tag="words"> 165</div>
<div class="text"> </div>
<div class="data" data-tag="characters"> 1140</div>
<div class="text"> </div>
<div class="data" data-tag="filename">/etc/motd</div>
</div>
.Ed
.Sh RETURN CODE
.Nm
returns a negative value on error. If the
.Nm XOF_COLUMNS
flag has been turned on for the specific handle using
.Xr xo_set_flags 3 ,
then the number of display columns consumed by the output will be returned.
.Sh SEE ALSO
.Xr xo_open_container 3 ,
.Xr xo_open_list 3 ,
.Xr xo_format 5
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_format 5 ,
.Xr libxo 3

View file

@ -0,0 +1,72 @@
.\" #
.\" # Copyright (c) 2014, Juniper Networks, Inc.
.\" # All rights reserved.
.\" # This SOFTWARE is licensed under the LICENSE provided in the
.\" # ../Copyright file. By downloading, installing, copying, or
.\" # using the SOFTWARE, you agree to be bound by the terms of that
.\" # LICENSE.
.\" # Phil Shafer, July 2014
.\"
.Dd December 4, 2014
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit_err , xo_emit_errc , xo_emit_errx
.Nm xo_emit_warn , xo_emit_warnx , xo_emit_warn_c , xo_emit_warn_hc
.Nd emit errors and warnings in multiple output styles
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Ft void
.Fn xo_emit_warn "const char *fmt" "..."
.Ft void
.Fn xo_emit_warnx "const char *fmt" "..."
.Ft void
.Fn xo_emit_warn_c "int code" "const char *fmt" "..."
.Ft void
.Fn xo_emit_warn_hc "xo_handle_t *xop" "int code, const char *fmt" "..."
.Ft void
.Fn xo_emit_err "int eval" "const char *fmt" "..."
.Ft void
.Fn xo_emit_errc "int eval" "int code" "const char *fmt" "..."
.Ft void
.Fn xo_emit_errx "int eval" "const char *fmt" "..."
.Sh DESCRIPTION
Many programs make use of the standard library functions
.Xr err 3
and
.Xr warn 3
to generate errors and warnings for the user.
.Nm libxo
wants to
pass that information via the current output style, and provides
compatible functions to allow this.
.Pp
The
.Fa fmt
argument is one compatible with
.Xr xo_emit 3
which allows these functions make structured data.
To generate unstructured data,
use the
.Xr xo_err 3
functions.
.Pp
These functions display the program name, a colon, a formatted message
based on the arguments, and then optionally a colon and an error
message associated with either
.Fa errno
or the
.Fa code
parameter.
.Bd -literal -offset indent
EXAMPLE:
if (open(filename, O_RDONLY) < 0)
xo_err(1, "cannot open file '%s'", filename);
.Ed
.Sh SEE ALSO
.Xr xo_emit 3 ,
.Xr xo_format 5 ,
.Xr xo_err 3 ,
.Xr libxo 3

View file

@ -0,0 +1,375 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
/**
* libxo includes a number of fixed encoding styles. But other
* external encoders are need to deal with new encoders. Rather
* than expose a swarm of libxo internals, we create a distinct
* API, with a simpler API than we use internally.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/queue.h>
#include <sys/param.h>
#include <dlfcn.h>
#include "xo_config.h"
#include "xo.h"
#include "xo_encoder.h"
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#if !defined(HAVE_DLFUNC)
#define dlfunc(_p, _n) dlsym(_p, _n)
#endif
#else /* HAVE_DLFCN_H */
#define dlopen(_n, _f) NULL /* Fail */
#define dlsym(_p, _n) NULL /* Fail */
#define dlfunc(_p, _n) NULL /* Fail */
#endif /* HAVE_DLFCN_H */
static void xo_encoder_setup (void); /* Forward decl */
/*
* Need a simple string collection
*/
typedef struct xo_string_node_s {
TAILQ_ENTRY(xo_string_node_s) xs_link; /* Next string */
char xs_data[0]; /* String data */
} xo_string_node_t;
typedef TAILQ_HEAD(xo_string_list_s, xo_string_node_s) xo_string_list_t;
static inline void
xo_string_list_init (xo_string_list_t *listp)
{
if (listp->tqh_last == NULL)
TAILQ_INIT(listp);
}
static inline xo_string_node_t *
xo_string_add (xo_string_list_t *listp, const char *str)
{
if (listp == NULL || str == NULL)
return NULL;
xo_string_list_init(listp);
size_t len = strlen(str);
xo_string_node_t *xsp;
xsp = xo_realloc(NULL, sizeof(*xsp) + len + 1);
if (xsp) {
memcpy(xsp->xs_data, str, len);
xsp->xs_data[len] = '\0';
TAILQ_INSERT_TAIL(listp, xsp, xs_link);
}
return xsp;
}
#define XO_STRING_LIST_FOREACH(_xsp, _listp) \
xo_string_list_init(_listp); \
TAILQ_FOREACH(_xsp, _listp, xs_link)
static inline void
xo_string_list_clean (xo_string_list_t *listp)
{
xo_string_node_t *xsp;
xo_string_list_init(listp);
for (;;) {
xsp = TAILQ_FIRST(listp);
if (xsp == NULL)
break;
TAILQ_REMOVE(listp, xsp, xs_link);
xo_free(xsp);
}
}
static xo_string_list_t xo_encoder_path;
void
xo_encoder_path_add (const char *path)
{
xo_encoder_setup();
if (path)
xo_string_add(&xo_encoder_path, path);
}
/* ---------------------------------------------------------------------- */
typedef struct xo_encoder_node_s {
TAILQ_ENTRY(xo_encoder_node_s) xe_link; /* Next session */
char *xe_name; /* Name for this encoder */
xo_encoder_func_t xe_handler; /* Callback function */
void *xe_dlhandle; /* dlopen handle */
} xo_encoder_node_t;
typedef TAILQ_HEAD(xo_encoder_list_s, xo_encoder_node_s) xo_encoder_list_t;
#define XO_ENCODER_LIST_FOREACH(_xep, _listp) \
xo_encoder_list_init(_listp); \
TAILQ_FOREACH(_xep, _listp, xe_link)
static xo_encoder_list_t xo_encoders;
static void
xo_encoder_list_init (xo_encoder_list_t *listp)
{
if (listp->tqh_last == NULL)
TAILQ_INIT(listp);
}
static xo_encoder_node_t *
xo_encoder_list_add (const char *name)
{
if (name == NULL)
return NULL;
xo_encoder_node_t *xep = xo_realloc(NULL, sizeof(*xep));
if (xep) {
int len = strlen(name) + 1;
xep->xe_name = xo_realloc(NULL, len);
if (xep->xe_name == NULL) {
xo_free(xep);
return NULL;
}
memcpy(xep->xe_name, name, len);
TAILQ_INSERT_TAIL(&xo_encoders, xep, xe_link);
}
return xep;
}
void
xo_encoders_clean (void)
{
xo_encoder_node_t *xep;
xo_encoder_setup();
for (;;) {
xep = TAILQ_FIRST(&xo_encoders);
if (xep == NULL)
break;
TAILQ_REMOVE(&xo_encoders, xep, xe_link);
if (xep->xe_dlhandle)
dlclose(xep->xe_dlhandle);
xo_free(xep);
}
xo_string_list_clean(&xo_encoder_path);
}
static void
xo_encoder_setup (void)
{
static int initted;
if (!initted) {
initted = 1;
xo_string_list_init(&xo_encoder_path);
xo_encoder_list_init(&xo_encoders);
xo_encoder_path_add(XO_ENCODERDIR);
}
}
static xo_encoder_node_t *
xo_encoder_find (const char *name)
{
xo_encoder_node_t *xep;
xo_encoder_list_init(&xo_encoders);
XO_ENCODER_LIST_FOREACH(xep, &xo_encoders) {
if (strcmp(xep->xe_name, name) == 0)
return xep;
}
return NULL;
}
static xo_encoder_node_t *
xo_encoder_discover (const char *name)
{
void *dlp = NULL;
char buf[MAXPATHLEN];
xo_string_node_t *xsp;
xo_encoder_node_t *xep = NULL;
XO_STRING_LIST_FOREACH(xsp, &xo_encoder_path) {
static const char fmt[] = "%s/%s.enc";
char *dir = xsp->xs_data;
size_t len = snprintf(buf, sizeof(buf), fmt, dir, name);
if (len > sizeof(buf)) /* Should not occur */
continue;
dlp = dlopen((const char *) buf, RTLD_NOW);
if (dlp)
break;
}
if (dlp) {
/*
* If the library exists, find the initializer function and
* call it.
*/
xo_encoder_init_func_t func;
func = (xo_encoder_init_func_t) dlfunc(dlp, XO_ENCODER_INIT_NAME);
if (func) {
xo_encoder_init_args_t xei;
bzero(&xei, sizeof(xei));
xei.xei_version = XO_ENCODER_VERSION;
int rc = func(&xei);
if (rc == 0 && xei.xei_handler) {
xep = xo_encoder_list_add(name);
if (xep) {
xep->xe_handler = xei.xei_handler;
xep->xe_dlhandle = dlp;
}
}
}
if (xep == NULL)
dlclose(dlp);
}
return xep;
}
void
xo_encoder_register (const char *name, xo_encoder_func_t func)
{
xo_encoder_setup();
xo_encoder_node_t *xep = xo_encoder_find(name);
if (xep) /* "We alla-ready got one" */
return;
xep = xo_encoder_list_add(name);
if (xep)
xep->xe_handler = func;
}
void
xo_encoder_unregister (const char *name)
{
xo_encoder_setup();
xo_encoder_node_t *xep = xo_encoder_find(name);
if (xep) {
TAILQ_REMOVE(&xo_encoders, xep, xe_link);
xo_free(xep);
}
}
int
xo_encoder_init (xo_handle_t *xop, const char *name)
{
xo_encoder_setup();
/* Can't have names containing '/' or ':' */
if (strchr(name, '/') != NULL || strchr(name, ':') != NULL)
return -1;
/*
* First we look on the list of known (registered) encoders.
* If we don't find it, we follow the set of paths to find
* the encoding library.
*/
xo_encoder_node_t *xep = xo_encoder_find(name);
if (xep == NULL) {
xep = xo_encoder_discover(name);
if (xep == NULL)
return -1;
}
xo_set_encoder(xop, xep->xe_handler);
return xo_encoder_handle(xop, XO_OP_CREATE, NULL, NULL);
}
/*
* A couple of function varieties here, to allow for multiple
* use cases. This varient is for when the main program knows
* its own encoder needs.
*/
xo_handle_t *
xo_encoder_create (const char *name, xo_xof_flags_t flags)
{
xo_handle_t *xop;
xop = xo_create(XO_STYLE_ENCODER, flags);
if (xop) {
if (xo_encoder_init(xop, name)) {
xo_destroy(xop);
xop = NULL;
}
}
return xop;
}
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
const char *name, const char *value)
{
void *private = xo_get_private(xop);
xo_encoder_func_t func = xo_get_encoder(xop);
if (func == NULL)
return -1;
return func(xop, op, name, value, private);
}
const char *
xo_encoder_op_name (xo_encoder_op_t op)
{
static const char *names[] = {
/* 0 */ "unknown",
/* 1 */ "create",
/* 2 */ "open_container",
/* 3 */ "close_container",
/* 4 */ "open_list",
/* 5 */ "close_list",
/* 6 */ "open_leaf_list",
/* 7 */ "close_leaf_list",
/* 8 */ "open_instance",
/* 9 */ "close_instance",
/* 10 */ "string",
/* 11 */ "content",
/* 12 */ "finish",
/* 13 */ "flush",
/* 14 */ "destroy",
/* 15 */ "attr",
/* 16 */ "version",
};
if (op > sizeof(names) / sizeof(names[0]))
return "unknown";
return names[op];
}

View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
/*
* NOTE WELL: This file is needed to software that implements an
* external encoder for libxo that allows libxo data to be encoded in
* new and bizarre formats. General libxo code should _never_
* include this header file.
*/
#ifndef XO_ENCODER_H
#define XO_ENCODER_H
/*
* Expose libxo's memory allocation functions
*/
extern xo_realloc_func_t xo_realloc;
extern xo_free_func_t xo_free;
typedef unsigned xo_encoder_op_t;
/* Encoder operations; names are in xo_encoder.c:xo_encoder_op_name() */
#define XO_OP_UNKNOWN 0
#define XO_OP_CREATE 1 /* Called when the handle is init'd */
#define XO_OP_OPEN_CONTAINER 2
#define XO_OP_CLOSE_CONTAINER 3
#define XO_OP_OPEN_LIST 4
#define XO_OP_CLOSE_LIST 5
#define XO_OP_OPEN_LEAF_LIST 6
#define XO_OP_CLOSE_LEAF_LIST 7
#define XO_OP_OPEN_INSTANCE 8
#define XO_OP_CLOSE_INSTANCE 9
#define XO_OP_STRING 10 /* Quoted UTF-8 string */
#define XO_OP_CONTENT 11 /* Other content */
#define XO_OP_FINISH 12 /* Finish any pending output */
#define XO_OP_FLUSH 13 /* Flush any buffered output */
#define XO_OP_DESTROY 14 /* Clean up function */
#define XO_OP_ATTRIBUTE 15 /* Attribute name/value */
#define XO_OP_VERSION 16 /* Version string */
#define XO_ENCODER_HANDLER_ARGS \
xo_handle_t *xop __attribute__ ((__unused__)), \
xo_encoder_op_t op __attribute__ ((__unused__)), \
const char *name __attribute__ ((__unused__)), \
const char *value __attribute__ ((__unused__)), \
void *private __attribute__ ((__unused__))
typedef int (*xo_encoder_func_t)(XO_ENCODER_HANDLER_ARGS);
typedef struct xo_encoder_init_args_s {
unsigned xei_version; /* Current version */
xo_encoder_func_t xei_handler; /* Encoding handler */
} xo_encoder_init_args_t;
#define XO_ENCODER_VERSION 1 /* Current version */
#define XO_ENCODER_INIT_ARGS \
xo_encoder_init_args_t *arg __attribute__ ((__unused__))
typedef int (*xo_encoder_init_func_t)(XO_ENCODER_INIT_ARGS);
/*
* Each encoder library must define a function named xo_encoder_init
* that takes the arguments defined in XO_ENCODER_INIT_ARGS. It
* should return zero for success.
*/
#define XO_ENCODER_INIT_NAME_TOKEN xo_encoder_library_init
#define XO_STRINGIFY(_x) #_x
#define XO_STRINGIFY2(_x) XO_STRINGIFY(_x)
#define XO_ENCODER_INIT_NAME XO_STRINGIFY2(XO_ENCODER_INIT_NAME_TOKEN)
extern int XO_ENCODER_INIT_NAME_TOKEN (XO_ENCODER_INIT_ARGS);
void
xo_encoder_register (const char *name, xo_encoder_func_t func);
void
xo_encoder_unregister (const char *name);
void *
xo_get_private (xo_handle_t *xop);
void
xo_encoder_path_add (const char *path);
void
xo_set_private (xo_handle_t *xop, void *opaque);
xo_encoder_func_t
xo_get_encoder (xo_handle_t *xop);
void
xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t encoder);
int
xo_encoder_init (xo_handle_t *xop, const char *name);
xo_handle_t *
xo_encoder_create (const char *name, xo_xof_flags_t flags);
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
const char *name, const char *value);
void
xo_encoders_clean (void);
const char *
xo_encoder_op_name (xo_encoder_op_t op);
#endif /* XO_ENCODER_H */

View file

@ -11,8 +11,9 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_err
.Nd emit errors and warnings in multiple formats
.Nm xo_err , xo_errc , xo_errx
.Nm xo_warn , xo_warnx , xo_warn_c , xo_warn_hc
.Nd emit errors and warnings in multiple output styles
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -31,14 +32,6 @@
.Fn xo_errc "int eval" "int code" "const char *fmt" "..."
.Ft void
.Fn xo_errx "int eval" "const char *fmt" "..."
.Ft void
.Fn xo_message "const char *fmt" "..."
.Ft void
.Fn xo_message_c "int code" "const char *fmt" "..."
.Ft void
.Fn xo_message_hc "xo_handle_t *xop" "int code, const char *fmt" "..."
.Ft void
.Fn xo_message_hcv "xo_handle_t *xop" "int code" "const char *fmt" "va_list vap"
.Sh DESCRIPTION
Many programs make use of the standard library functions
.Xr err 3
@ -50,6 +43,19 @@ wants to
pass that information via the current output style, and provides
compatible functions to allow this.
.Pp
The
.Fa fmt
argument is one compatible with
.Xr printf 3
rather than
.Xr xo_emit 3
to aid in simple conversion. This means
these functions make unstructured data.
To generate structured data,
use the
.Xr xo_emit_err 3
functions.
.Pp
These functions display the program name, a colon, a formatted message
based on the arguments, and then optionally a colon and an error
message associated with either
@ -62,30 +68,7 @@ parameter.
if (open(filename, O_RDONLY) < 0)
xo_err(1, "cannot open file '%s'", filename);
.Ed
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr xo_emit_err 3 ,
.Xr libxo 3

View file

@ -12,7 +12,7 @@
.Os
.Sh NAME
.Nm xo_error
.Nd generate error messages
.Nd generate simple error messages in multiple output styles
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -35,31 +35,7 @@ one can replace
calls with
.Fn xo_error
calls.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr printf 3 ,
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_finish , xo_finish_h
.Nd finish formatting output
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -34,30 +34,6 @@ Calling this function is
.Em vital
to the proper operation of libxo,
especially for the non-TEXT output styles.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_flush , xo_flush_h
.Nd flush formatted output from libxo handle
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -30,30 +30,6 @@ caller may wish to flush any data buffered within the library.
The
.Fn xo_flush
function is used for this.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -2,11 +2,11 @@
.\" # Copyright (c) 2014, Juniper Networks, Inc.
.\" # All rights reserved.
.\" # This SOFTWARE is licensed under the LICENSE provided in the
.\" # ../Copyright file. By downloading, installing, copying, or
.\" # ../Copyright file. By downloading, installing, copying, or
.\" # using the SOFTWARE, you agree to be bound by the terms of that
.\" # LICENSE.
.\" # Phil Shafer, July 2014
.\"
.\"
.Dd December 4, 2014
.Dt LIBXO 3
.Os
@ -20,18 +20,18 @@ uses format strings to control the rendering of data into
various output styles, including
.Em text ,
.Em XML ,
.EM JSON ,
.Em JSON ,
and
.Em HTML .
Each format string contains a set of zero or more
.Dq field descriptions ,
.Dq "field descriptions" ,
which describe independent data fields.
Each field description contains a set of
.Dq modifiers ,
a
.Dq content string ,
.Dq "content string" ,
and zero, one, or two
.Dq format descriptors .
.Dq "format descriptors" .
The modifiers tell
.Nm libxo
what the field is and how to treat it, while the format descriptors are
@ -51,7 +51,7 @@ field descriptions within the format string.
.Pp
The field description is given as follows:
.Bd -literal -offset indent
'{' [ role | modifier ]* ':' [ content ]
'{' [ role | modifier ]* [',' long-names ]* ':' [ content ]
[ '/' field-format [ '/' encoding-format ]] '}'
.Ed
.Pp
@ -61,6 +61,10 @@ The contents, field-format, and
encoding-format are used in varying ways, based on the role.
These are described in the following sections.
.Pp
Braces can be escaped by using double braces, similar to "%%" in
.Xr printf 3 .
The format string "{{braces}}" would emit "{braces}".
.Pp
In the following example, three field descriptors appear.
The first
is a padding field containing three spaces of padding, the second is a
@ -70,19 +74,28 @@ passed to the
.Xr xo_emit 3 ,
function as an unsigned integer.
.Bd -literal -offset indent
xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\\n", 65);
xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\\n", 65);
.Ed
.Pp
This single line of code can generate text ("In stock: 65\\n"), XML
("<in-stock>65</in-stock>"), JSON ('"in-stock": 65'), or HTML (too
lengthy to be listed here).
.Ss Modifier Roles
Modifiers are optional, and indicate the role and formatting of the
.Pp
While roles and modifiers typically use single character for brevity,
there are alternative names for each which allow more verbose
formatting strings.
These names must be preceded by a comma, and may follow any
single-character values:
.Bd -literal -offset indent
xo_emit("{L,white,colon:In stock}{,key:in-stock/%u}\n", 65);
.Ed
.Ss "Field Roles"
Field roles are optional, and indicate the role and formatting of the
content.
The roles are listed below; only one role is permitted:
.Pp
.Bl -column "M" "Name12341234"
.It Sy "M Name Description"
.It Sy "M" "Name " "Description"
.It C "color " "Field is a color or effect"
.It D "decoration " "Field is non-text (e.g. colon, comma)"
.It E "error " "Field is an error message"
.It L "label " "Field is text that prefixes a value"
@ -92,38 +105,74 @@ The roles are listed below; only one role is permitted:
.It U "units " "Field is the units for the previous value field"
.It V "value " "Field is the name of field (the default)"
.It W "warning " "Field is a warning message"
.It \&[ "start anchor" "Begin a section of anchored variable-width text"
.It \&] "stop anchor " "End a section of anchored variable-width text"
.It \&[ "start-anchor" "Begin a section of anchored variable-width text"
.It \&] "stop-anchor " "End a section of anchored variable-width text"
.El
.Bd -literal -offset indent
EXAMPLE:
xo_emit("{L:Free}{D::}{P: }{:free/%u} {U:Blocks}\n",
free_blocks);
.Ed
.Pp
.Ss The Color Role ({C:})
When a role is not provided, the "value" role is used as the default.
.Pp
Roles and modifiers can also use more verbose names, when preceeded by
a comma:
.Bd -literal -offset indent
EXAMPLE:
xo_emit("{,label:Free}{,decoration::}{,padding: }"
"{,value:free/%u} {,units:Blocks}\n",
free_blocks);
.Ed
.Ss "The Color Role ({C:})"
Colors and effects control how text values are displayed; they are
used for display styles (TEXT and HTML).
The color content can be
either static, when placed directly within the field descriptor, or a
printf-style format descriptor can be used, if preceded by a slash ("/"):
.Bd -literal -offset indent
xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost);
xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
fg_color, bg_color, cost);
xo_emit("{C:bold}{:value}{C:no-bold}\n", value);
.Ed
.Pp
Colors and effects remain in effect until modified by other "C"-role
fields.
.Bd -literal -offset indent
xo_emit("{C:bold}{C:inverse}both{C:no-bold}only inverse\n");
.Ed
.Pp
If the content is empty, the "reset" action is performed.
.Bd -literal -offset indent
xo_emit("{C:both,underline}{:value}{C:}\n", value);
.Ed
.Pp
The content should be a comma-separated list of zero or more colors or
display effects.
.Bd -literal -offset indent
xo_emit("{C:bold,underline,inverse}All three{C:no-bold,no-inverse}\n");
.Ed
.Pp
Colors and effects remain in effect until modified by other "C" roles.
The color content can be either static, when placed directly within
the field descriptor, or a printf-style format descriptor can be used,
if preceded by a slash ("/"):
.Bd -literal -offset indent
xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "",
need_underline ? "underline" : "", value);
.Ed
.Pp
If the content is empty, the "reset" action is performed.
Color names are prefixed with either "fg-" or "bg-" to change the
foreground and background colors, respectively.
.Bd -literal -offset indent
xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
fg_color, bg_color, cost);
.Ed
.Pp
The following table lists the supported effects:
.Bl -column "no-underline"
.It Sy "Name Description"
.It "bg-xxxxx " "Change background color"
.It Sy "Name " "Description"
.It "bg\-xxxxx " "Change background color"
.It "bold " "Start bold text effect"
.It "fg-xxxxx " "Change foreground color"
.It "fg\-xxxxx " "Change foreground color"
.It "inverse " "Start inverse (aka reverse) text effect"
.It "no-bold " "Stop bold text effect"
.It "no-inverse " "Stop inverse (aka reverse) text effect"
.It "no-underline " "Stop underline text effect"
.It "no\-bold " "Stop bold text effect"
.It "no\-inverse " "Stop inverse (aka reverse) text effect"
.It "no\-underline " "Stop underline text effect"
.It "normal " "Reset effects (only)"
.It "reset " "Reset colors and effects (restore defaults)"
.It "underline " "Start underline text effect"
@ -142,10 +191,7 @@ The following color names are supported:
.It white
.It yellow
.El
.Pp
Color names are prefixed with either "fg-" or "bg-" to change the
foreground and background colors, respectively.
.Ss The Decoration Role ({D:})
.Ss "The Decoration Role ({D:})"
Decorations are typically punctuation marks such as colons,
semi-colons, and commas used to decorate the text and make it simpler
for human readers.
@ -154,17 +200,53 @@ can use CSS to direct their display parameters.
.Bd -literal -offset indent
xo_emit("{D:((}{:name}{D:))}\\n", name);
.Ed
.Ss The Label Role ({L:})
.Ss "The Gettext Role ({G:})"
.Nm libxo
supports internationalization (i18n) through its use of
.Xr gettext 3 .
Use the "{G:}" role to request that the remaining part of
the format string, following the "{G:}" field, be handled using
.Fn gettext .
Since
.Fn gettext
uses the string as the key into the message catalog,
.Nm libxo
uses a simplified version of the format string that removes
unimportant field formatting and modifiers, stopping minor formatting
changes from impacting the expensive translation process.
A developer
change such as changing "/%06d" to "/%08d" should not force hand
inspection of all .po files.
.Pp
The simplified version can be generated for a single message using the
"xopo -s <text>" command, or an entire .pot can be translated using
the "xopo -f <input> -o <output>" command.
.Bd -literal -offset indent
xo_emit("{G:}Invalid token\n");
.Ed
The {G:} role allows a domain name to be set.
.Fn gettext
calls will
continue to use that domain name until the current format string
processing is complete, enabling a library function to emit strings
using it's own catalog.
The domain name can be either static as the
content of the field, or a format can be used to get the domain name
from the arguments.
.Bd -literal -offset indent
xo_emit("{G:libc}Service unavailable in restricted mode\n");
.Ed
.Ss "The Label Role ({L:})"
Labels are text that appears before a value.
.Bd -literal -offset indent
xo_emit("{Lwc:Cost}{:cost/%u}\\n", cost);
.Ed
.Ss The Note Role ({N:})
.Ss "The Note Role ({N:})"
Notes are text that appears after a value.
.Bd -literal -offset indent
xo_emit("{:cost/%u} {N:per year}\\n", cost);
.Ed
.Ss The Padding Role ({P:})
.Ss "The Padding Role ({P:})"
Padding represents whitespace used before and between fields.
The padding content can be either static, when placed directly within
the field descriptor, or a printf-style format descriptor can be used,
@ -173,7 +255,7 @@ if preceded by a slash ("/"):
xo_emit("{P: }{Lwc:Cost}{:cost/%u}\\n", cost);
xo_emit("{P:/30s}{Lwc:Cost}{:cost/%u}\\n", "", cost);
.Ed
.Ss The Title Role ({T:})
.Ss "The Title Role ({T:})"
Titles are heading or column headers that are meant to be displayed to
the user.
The title can be either static, when placed directly within
@ -183,7 +265,7 @@ if preceded by a slash ("/"):
xo_emit("{T:Interface Statistics}\\n");
xo_emit("{T:/%20.20s}{T:/%6.6s}\\n", "Item Name", "Cost");
.Ed
.Ss The Units Role ({U:})
.Ss "The Units Role ({U:})"
Units are the dimension by which values are measured, such as degrees,
miles, bytes, and decibels.
The units field carries this information
@ -209,7 +291,7 @@ Units can also be rendered in HTML as the "data-units" attribute:
<div class="data" data-tag="distance" data-units="miles"
data-xpath="/top/data/distance">50</div>
.Ed
.Ss The Value Role ({V:} and {:})
.Ss "The Value Role ({V:} and {:})"
The value role is used to represent the a data value that is
interesting for the non-display output styles (XML and JSON).
Value
@ -231,7 +313,7 @@ format descriptors default to "%s".
xo_emit("{:author} wrote \"{:poem}\" in {:year/%4d}\\n,
author, poem, year);
.Ed
.Ss The Anchor Modifiers ({[:} and {]:})
.Ss "The Anchor Roles ({[:} and {]:})"
The anchor roles allow a set of strings by be padded as a group,
but still be visible to
.Xr xo_emit 3
@ -269,20 +351,24 @@ Widths over 8k are considered probable errors and not supported.
If
.Dv XOF_WARN
is set, a warning will be generated.
.Ss Modifier Flags
The modifiers can also include the following flags, which modify the
content emitted for some output styles:
.Pp
.Bl -column M "Name12341234"
.It Sy M "Name Description"
.It c "colon " "A colon ("":"") is appended after the label"
.It d "display " "Only emit field for display styles (text/HTML)"
.It e "encoding " "Only emit for encoding styles (XML/JSON)"
.It k "key " "Field is a key, suitable for XPath predicates"
.It l "leaf " "Field is a leaf-list, a list of leaf values"
.It n "no-quotes " "Do not quote the field when using JSON style"
.It q "quotes " "Quote the field when using JSON style"
.It w "white space " "A blank ("" "") is appended after the label"
.Ss "Field Modifiers"
Field modifiers are flags which modify the way content emitted for
particular output styles:
.Bl -column M "Name123456789"
.It Sy M "Name " "Description"
.It c "colon " "A colon ("":"") is appended after the label"
.It d "display " "Only emit field for display styles (text/HTML)"
.It e "encoding " "Only emit for encoding styles (XML/JSON)"
.It h "humanize (hn) " "Format large numbers in human-readable style"
.It " " "hn-space " "Humanize: Place space between numeric and unit"
.It " " "hn-decimal " "Humanize: Add a decimal digit, if number < 10"
.It " " "hn-1000 " "Humanize: Use 1000 as divisor instead of 1024"
.It k "key " "Field is a key, suitable for XPath predicates"
.It l "leaf-list " "Field is a leaf-list, a list of leaf values"
.It n "no-quotes " "Do not quote the field when using JSON style"
.It q "quotes " "Quote the field when using JSON style"
.It q "trim " "Trim leading and trailing whitespace"
.It w "white space " "A blank ("" "") is appended after the label"
.El
.Pp
For example, the modifier string "Lwc" means the field has a label
@ -291,7 +377,16 @@ colon ('c') and a space ('w').
The modifier string "Vkq" means the
field has a value role, that it is a key for the current instance, and
that the value should be quoted when encoded for JSON.
.Ss The Colon Modifier ({c:})
.Pp
Roles and modifiers can also use more verbose names, when preceeded by
a comma.
For example, the modifier string "Lwc" (or "L,white,colon")
means the field has a label role (text that describes the next field)
and should be followed by a colon ('c') and a space ('w').
The modifier string "Vkq" (or ":key,quote") means the field has a value
role (the default role), that it is a key for the current instance,
and that the value should be quoted when encoded for JSON.
.Ss "The Colon Modifier ({c:})"
The colon modifier appends a single colon to the data value:
.Bd -literal -offset indent
EXAMPLE:
@ -304,7 +399,7 @@ The colon modifier is only used for the TEXT and HTML output
styles.
It is commonly combined with the space modifier ('{w:}').
It is purely a convenience feature.
.Ss The Display Modifier ({d:})
.Ss "The Display Modifier ({d:})"
The display modifier indicated the field should only be generated for
the display output styles, TEXT and HTML.
.Bd -literal -offset indent
@ -318,7 +413,7 @@ the display output styles, TEXT and HTML.
.Pp
The display modifier is the opposite of the encoding modifier, and
they are often used to give to distinct views of the underlying data.
.Ss The Encoding Modifier ({e:})
.Ss "The Encoding Modifier ({e:})"
The encoding modifier indicated the field should only be generated for
the encoding output styles, such as JSON and XML.
.Bd -literal -offset indent
@ -332,7 +427,60 @@ the encoding output styles, such as JSON and XML.
.Pp
The encoding modifier is the opposite of the display modifier, and
they are often used to give to distinct views of the underlying data.
.Ss The Key Modifier ({k:})
.Ss "The Humanize Modifier ({h:})"
The humanize modifier is used to render large numbers as in a
human-readable format.
While numbers like "44470272" are completely readable to computers and
savants, humans will generally find "44M" more meaningful.
.Pp
"hn" can be used as an alias for "humanize".
.Pp
The humanize modifier only affects display styles (TEXT and HMTL).
The "no-humanize" option will block the function of the humanize modifier.
.Pp
There are a number of modifiers that affect details of humanization.
These are only available in as full names, not single characters.
The "hn-space" modifier places a space between the number and any
multiplier symbol, such as "M" or "K" (ex: "44 K").
The "hn-decimal" modifier will add a decimal point and a single tenths digit
when the number is less than 10 (ex: "4.4K").
The "hn-1000" modifier will use 1000 as divisor instead of 1024, following the
JEDEC-standard instead of the more natural binary powers-of-two
tradition.
.Bd -literal -offset indent
EXAMPLE:
xo_emit("{h:input/%u}, {h,hn-space:output/%u}, "
"{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, "
"{h,hn-decimal:remaining/%u}\n",
input, output, errors, capacity, remaining);
TEXT:
21, 57 K, 96M, 44M, 1.2G
.Ed
.Pp
In the HTML style, the original numeric value is rendered in the
"data-number" attribute on the <div> element:
.Bd -literal -offset indent
<div class="data" data-tag="errors"
data-number="100663296">96M</div>
.Ed
.Ss "The Gettext Modifier ({g:})"
The gettext modifier is used to translate individual fields using the
gettext domain (typically set using the "{G:}" role) and current
language settings.
Once libxo renders the field value, it is passed
to
.Xr gettext 3 ,
where it is used as a key to find the native language
translation.
.Pp
In the following example, the strings "State" and "full" are passed
to
.Fn gettext
to find locale-based translated strings.
.Bd -literal -offset indent
xo_emit("{Lgwc:State}{g:state}\n", "full");
.Ed
.Ss "The Key Modifier ({k:})"
The key modifier is used to indicate that a particular field helps
uniquely identify an instance of list data.
.Bd -literal -offset indent
@ -351,7 +499,7 @@ Currently the key modifier is only used when generating XPath values
for the HTML output style when
.Dv XOF_XPATH
is set, but other uses are likely in the near future.
.Ss The Leaf-List Modifier ({l:})
.Ss "The Leaf-List Modifier ({l:})"
The leaf-list modifier is used to distinguish lists where each
instance consists of only a single value. In XML, these are
rendered as single elements, where JSON renders them as arrays.
@ -368,7 +516,7 @@ rendered as single elements, where JSON renders them as arrays.
JSON:
"user": [ "phil", "pallavi" ]
.Ed
.Ss The No-Quotes Modifier ({n:})
.Ss "The No-Quotes Modifier ({n:})"
The no-quotes modifier (and its twin, the 'quotes' modifier) affect
the quoting of values in the JSON output style.
JSON uses quotes for
@ -383,7 +531,29 @@ needed, but often this needs to be controlled by the caller.
JSON:
"fancy": true
.Ed
.Ss The Quotes Modifier ({q:})
.Ss "The Plural Modifier ({p:})"
The plural modifier selects the appropriate plural form of an
expression based on the most recent number emitted and the current
language settings.
The contents of the field should be the singular
and plural English values, separated by a comma:
.Bd -literal -offset indent
xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes);
.Ed
The plural modifier is meant to work with the gettext modifier ({g:})
but can work independently.
.Pp
When used without the gettext modifier or when the message does not
appear in the message catalog, the first token is chosen when the last
numeric value is equal to 1; otherwise the second value is used,
mimicking the simple pluralization rules of English.
.Pp
When used with the gettext modifier, the
.Xr ngettext 3
function is
called to handle the heavy lifting, using the message catalog to
convert the singular and plural forms into the native language.
.Ss "The Quotes Modifier ({q:})"
The quotes modifier (and its twin, the 'no-quotes' modifier) affect
the quoting of values in the JSON output style.
JSON uses quotes for
@ -397,7 +567,7 @@ needed, but often this needs to be controlled by the caller.
JSON:
"year": "2014"
.Ed
.Ss The White Space Modifier ({w:})
.Ss "The White Space Modifier ({w:})"
The white space modifier appends a single space to the data value:
.Bd -literal -offset indent
EXAMPLE:
@ -413,7 +583,7 @@ It is purely a convenience feature.
.Pp
Note that the sense of the 'w' modifier is reversed for the units role
({Uw:}); a blank is added before the contents, rather than after it.
.Ss Field Formatting
.Ss "Field Formatting"
The field format is similar to the format string for
.Xr printf 3 .
Its use varies based on the role of the field, but generally is used to
@ -440,7 +610,7 @@ The format- modifier can be:
.Bl -bullet
.It
a '#' character, indicating the output value should be prefixed with
'0x', typically to indicate a base 16 (hex) value.
"0x", typically to indicate a base 16 (hex) value.
.It
a minus sign ('-'), indicating the output value should be padded on
the right instead of the left.
@ -464,7 +634,7 @@ will never dereference memory beyond the given number of bytes.
.It
a second period followed by one or more digits indicating the maximum
width for a string argument.
This modifier cannot be given for non-string arguments.
This modifier cannot be given for non-string arguments.
.It
one or more 'h' characters, indicating shorter input data.
.It
@ -484,9 +654,8 @@ Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be
removed eventually.
.Pp
The format character is described in the following table:
.Pp
.Bl -column C "Argument Type12"
.It Sy "C Argument Type Format"
.It Sy "C" "Argument Type " "Format"
.It d "int " "base 10 (decimal)"
.It i "int " "base 10 (decimal)"
.It o "int " "base 8 (octal)"
@ -524,8 +693,7 @@ argument:
.It "z " "size_t " "size_t"
.It "q " "quad_t " "u_quad_t"
.El
.Pp
.Ss UTF-8 and Locale Strings
.Ss "UTF-8 and Locale Strings"
All strings for
.Nm libxo
must be UTF-8.
@ -542,10 +710,10 @@ Since UTF-8 is compatible with
data, a normal 7-bit
.Em ASCII
string can be used.
'%ls' expects a
'wchar_t *' pointer to a wide-character string, encoded as 32-bit
"%ls" expects a
"wchar_t *" pointer to a wide-character string, encoded as 32-bit
Unicode values.
'%hs' expects a 'char *' pointer to a multi-byte
"%hs" expects a "char *" pointer to a multi-byte
string encoded with the current locale, as given by the
.Ev LC_CTYPE ,
.Ev LANG ,
@ -612,11 +780,11 @@ and adds a third value for specifying the maximum number of columns.
.Pp
In this example, the name field is printed with a minimum of 3 columns
and a maximum of 6.
Up to ten bytes are in used in filling those columns.
Up to ten bytes are in used in filling those columns.
.Bd -literal -offset indent
xo_emit("{:name/%3.10.6s}", name);
.Ed
.Ss Characters Outside of Field Definitions
.Ss "Characters Outside of Field Definitions"
Characters in the format string that are not part of a field definition are
copied to the output for the TEXT style, and are ignored for the JSON
and XML styles.
@ -635,12 +803,12 @@ For HTML, these characters are placed in a <div> with class "text".
<div class="data" data-tag="size">extra small</div>
<div class="text">.</div>
.Ed
.Ss "%n" is Not Supported
.Ss "'%n' is Not Supported"
.Nm libxo
does not support the '%n' directive.
It is a bad idea and we
just do not do it.
.Ss The Encoding Format (eformat)
.Ss "The Encoding Format (eformat)"
The "eformat" string is the format string used when encoding the field
for JSON and XML.
If not provided, it defaults to the primary format
@ -655,7 +823,7 @@ In this example, the value for the number of items in stock is emitted:
.Pp
This call will generate the following output:
.Bd -literal -offset indent
TEXT:
TEXT:
In stock: 144
XML:
<in-stock>144</in-stock>
@ -685,25 +853,24 @@ data, which would expand the penultimate line to:
.Ed
.Sh WHAT MAKES A GOOD FIELD NAME?
To make useful, consistent field names, follow these guidelines:
.Pp
.Ss Use lower case, even for TLAs
.Ss "Use lower case, even for TLAs"
Lower case is more civilized.
Even TLAs should be lower case
to avoid scenarios where the differences between "XPath" and
"Xpath" drive your users crazy.
Using "xpath" is simpler and better.
.Ss Use hyphens, not underscores
.Ss "Use hyphens, not underscores"
Use of hyphens is traditional in XML, and the
.Dv XOF_UNDERSCORES
flag can be used to generate underscores in JSON, if desired.
But the raw field name should use hyphens.
.Ss Use full words
.Ss "Use full words"
Do not abbreviate especially when the abbreviation is not obvious or
not widely used.
Use "data-size", not "dsz" or "dsize".
Use
"interface" instead of "ifname", "if-name", "iface", "if", or "intf".
.Ss Use <verb>-<units>
.Ss "Use <verb>-<units>"
Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in
making consistent, useful names, avoiding the situation where one app
uses "sent-packet" and another "packets-sent" and another
@ -712,10 +879,10 @@ The <units> can be dropped when it is
obvious, as can obvious words in the classification.
Use "receive-after-window-packets" instead of
"received-packets-of-data-after-window".
.Ss Reuse existing field names
.Ss "Reuse existing field names"
Nothing is worse than writing expressions like:
.Bd -literal -offset indent
if ($src1/process[pid == $pid]/name ==
if ($src1/process[pid == $pid]/name ==
$src2/proc-table/proc/p[process-id == $pid]/proc-name) {
...
}
@ -724,16 +891,16 @@ Nothing is worse than writing expressions like:
Find someone else who is expressing similar data and follow their
fields and hierarchy.
Remember the quote is not
.Dq Consistency is the hobgoblin of little minds
.Dq "Consistency is the hobgoblin of little minds"
but
.Dq A foolish consistency is the hobgoblin of little minds .
.Ss Think about your users
.Dq "A foolish consistency is the hobgoblin of little minds" .
.Ss "Think about your users"
Have empathy for your users, choosing clear and useful fields that
contain clear and useful data.
You may need to augment the display content with
.Xr xo_attr 3
calls or "{e:}" fields to make the data useful.
.Ss Do not use an arbitrary number postfix
.Ss "Do not use an arbitrary number postfix"
What does "errors2" mean?
No one will know.
"errors-after-restart" would be a better choice.
@ -741,7 +908,7 @@ Think of your users, and think of the future.
If you make "errors2", the next guy will happily make
"errors3" and before you know it, someone will be asking what is the
difference between errors37 and errors63.
.Ss Be consistent, uniform, unsurprising, and predictable
.Ss "Be consistent, uniform, unsurprising, and predictable"
Think of your field vocabulary as an API.
You want it useful,
expressive, meaningful, direct, and obvious.
@ -770,31 +937,7 @@ If there is no difference,
use only one of the field names.
If there is a difference, change the
names to make that difference more obvious.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr libxo 3 ,
.Xr xolint 1 ,
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer

View file

@ -0,0 +1,169 @@
/* $NetBSD: humanize_number.c,v 1.8 2004/07/27 01:56:24 enami Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <stdint.h>
#include <limits.h>
#include <unistd.h>
#include <stdbool.h>
/* humanize_number(3) */
#define HN_DECIMAL 0x01
#define HN_NOSPACE 0x02
#define HN_B 0x04
#define HN_DIVISOR_1000 0x08
#define HN_GETSCALE 0x10
#define HN_AUTOSCALE 0x20
static int
xo_humanize_number (char *buf, size_t len, int64_t bytes,
const char *suffix, int scale, int flags)
{
const char *prefixes, *sep;
int b, i, r, maxscale, s1, s2, sign;
int64_t divisor, max;
// We multiply bytes by 100 to deal with rounding, so we need something
// big enough to hold LLONG_MAX * 100. On 64-bit we can use 128-bit wide
// integers with __int128_t, but on 32-bit we have to use long double.
#ifdef __LP64__
__int128_t scalable = (__int128_t)bytes;
#else
long double scalable = (long double)bytes;
#endif
size_t baselen;
assert(buf != NULL);
assert(suffix != NULL);
assert(scale >= 0);
if (flags & HN_DIVISOR_1000) {
/* SI for decimal multiplies */
divisor = 1000;
if (flags & HN_B)
prefixes = "B\0k\0M\0G\0T\0P\0E";
else
prefixes = "\0\0k\0M\0G\0T\0P\0E";
} else {
/*
* binary multiplies
* XXX IEC 60027-2 recommends Ki, Mi, Gi...
*/
divisor = 1024;
if (flags & HN_B)
prefixes = "B\0K\0M\0G\0T\0P\0E";
else
prefixes = "\0\0K\0M\0G\0T\0P\0E";
}
#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
maxscale = 7;
if (scale >= maxscale &&
(scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
return (-1);
if (buf == NULL || suffix == NULL)
return (-1);
if (len > 0)
buf[0] = '\0';
if (bytes < 0) {
sign = -1;
scalable *= -100;
baselen = 3; /* sign, digit, prefix */
} else {
sign = 1;
scalable *= 100;
baselen = 2; /* digit, prefix */
}
if (flags & HN_NOSPACE)
sep = "";
else {
sep = " ";
baselen++;
}
baselen += strlen(suffix);
/* Check if enough room for `x y' + suffix + `\0' */
if (len < baselen + 1)
return (-1);
if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
/* See if there is additional columns can be used. */
for (max = 100, i = len - baselen; i-- > 0;)
max *= 10;
for (i = 0; scalable >= max && i < maxscale; i++)
scalable /= divisor;
if (scale & HN_GETSCALE)
return (i);
} else
for (i = 0; i < scale && i < maxscale; i++)
scalable /= divisor;
/* If a value <= 9.9 after rounding and ... */
if (scalable < 995 && i > 0 && flags & HN_DECIMAL) {
/* baselen + \0 + .N */
if (len < baselen + 1 + 2)
return (-1);
b = ((int)scalable + 5) / 10;
s1 = b / 10;
s2 = b % 10;
r = snprintf(buf, len, "%s%d%s%d%s%s%s",
((sign == -1) ? "-" : ""),
s1, localeconv()->decimal_point, s2,
sep, SCALE2PREFIX(i), suffix);
} else
r = snprintf(buf, len, "%s%lld%s%s%s",
/* LONGLONG */
((sign == -1) ? "-" : ""),
(long long)((scalable + 50) / 100),
sep, SCALE2PREFIX(i), suffix);
return (r);
}

View file

@ -0,0 +1,68 @@
.\" #
.\" # Copyright (c) 2014, Juniper Networks, Inc.
.\" # All rights reserved.
.\" # This SOFTWARE is licensed under the LICENSE provided in the
.\" # ../Copyright file. By downloading, installing, copying, or
.\" # using the SOFTWARE, you agree to be bound by the terms of that
.\" # LICENSE.
.\" # Phil Shafer, July 2014
.\"
.Dd December 4, 2014
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_message , xo_message_c , xo_message_hc , xo_message_hcv
.Nd emit messages in multiple output styles
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Ft void
.Fn xo_message "const char *fmt" "..."
.Ft void
.Fn xo_message_e "const char *fmt" "..."
.Ft void
.Fn xo_message_c "int code" "const char *fmt" "..."
.Ft void
.Fn xo_message_hc "xo_handle_t *xop" "int code, const char *fmt" "..."
.Ft void
.Fn xo_message_hcv "xo_handle_t *xop" "int code" "const char *fmt" "va_list vap"
.Sh DESCRIPTION
.Nm xo_message
generates text message which lack any sort of structure.
These functions should not be used under normal conditions, since
they completely defeat the value of using libxo. They are provided
for scenarios when the output's content is genuinely unknown and
unusable.
It is used in converting programs where err/warn where not used,
and error messages went to
.Nm stdout ,
not
.Nm stderr .
Use of
.Nm xo_message
allows backwards compatibility with that output, but does not put
the error in a useful form.
.Pp
The
.Nm xo_message
function generates output strings using the printf-style format string
and arguments provided.
If the format string does not end in a newline,
.Nm xo_message_e
will appear a colon, a space, and the error associated with the current
.Nm errno
value.
.Nm xo_message_c behaves similarly for the value passed in the
.Fa code
parameter.
.Nm xo_message_hc
accepts a
.Fa handle
as opened by
.Xr xo_create 3
and
.Nm xo_message_hcv accepts a va_list parameter of arguments.
.Sh SEE ALSO
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -12,8 +12,7 @@
.Os
.Sh NAME
.Nm xo_no_setlocale
.Nd prevent implicit call to
.Fn setlocale
.Nd prevent implicit call to setlocale
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -36,33 +35,9 @@ The caller may wish to avoid this behavior, and
can do so by calling the
.Fn xo_no_setlocale
function.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3 ,
.Xr xo_open_container 3 ,
.Xr xo_open_list 3 ,
.Xr xo_format 5
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_format 5 ,
.Xr libxo 3

View file

@ -11,25 +11,13 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_open_container
.Nm xo_open_container , xo_open_container_h , xo_open_container_hd , xo_open_container_d
.Nm xo_close_container , xo_close_container_h , xo_close_container_hd , xo_close_container_d
.Nd open (and close) container constructs
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Sh NAME
.Nm xo_open_container
.Nm xo_open_container_h
.Nm xo_open_container_hd
.Nm xo_open_container_d
.Nm xo_close_container
.Nm xo_close_container_h
.Nm xo_close_container_hd
.Nm xo_close_container_d
.Nd open and close containers
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.Ft int
.Fn xo_open_container "const char *name"
.Ft int
@ -195,30 +183,6 @@ to track open
containers, lists, and instances.
A warning is generated when the name given to the close function
and the name recorded do not match.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,33 +11,15 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Sh NAME
.Nm xo_open_list
.Nm xo_open_list_h
.Nm xo_open_list_hd
.Nm xo_open_list_d
.Nm xo_open_instance
.Nm xo_open_instance_h
.Nm xo_open_instance_hd
.Nm xo_open_instance_d
.Nm xo_close_instance
.Nm xo_close_instance_h
.Nm xo_close_instance_hd
.Nm xo_close_instance_d
.Nm xo_close_list
.Nm xo_close_list_h
.Nm xo_close_list_hd
.Nm xo_close_list_d
.Nm xo_open_list , xo_open_list_h , xo_open_list_hd , xo_open_list_d
.Nm xo_open_instance , xo_open_instance_h , xo_open_instance_hd , xo_open_instance_d
.Nm xo_close_instance , xo_close_instance_h , xo_close_instance_hd , xo_close_instnace_d
.Nm xo_close_list , xo_close_list_h , xo_close_list_hd , xo_close_list_d
.Nd open and close lists and instances
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Ft int
.Fn xo_open_list_h "xo_handle_t *xop" "const char *name"
.Ft int
@ -171,30 +153,6 @@ are rendered as multiple leaf elements.
<item>hammer</item>
<item>nail</item>
.Ed
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,21 +11,12 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_open_marker
.Nm xo_open_marker , xo_open_marker_h , xo_close_marker , xo_close_marker_h
.Nd prevent and allow closing of open constructs
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Sh NAME
.Nm xo_open_marker
.Nm xo_open_marker_h
.Nm xo_close_marker
.Nm xo_close_marker_h
.Nd open and close markers
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.Ft int
.Fn xo_open_marker "const char *name"
.Ft int
@ -109,30 +100,6 @@ properly.
xo_close_marker("fish-guts");
}
.Ed
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,7 +11,7 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_parse_args
.Nm xo_parse_args , xo_set_program
.Nd detect, parse, and remove arguments for libxo
.Sh LIBRARY
.Lb libxo
@ -35,7 +35,7 @@ On failure, a message it emitted and -1 is returned.
.Bd -literal -offset indent
argc = xo_parse_args(argc, argv);
if (argc < 0)
exit(1);
exit(EXIT_FAILURE);
.Ed
.Pp
Following the call to
@ -72,6 +72,15 @@ Add info attributes (HTML)
Emit JSON output
.It Dv keys
Emit the key attribute for keys (XML)
.It Dv log-gettext
Log (via stderr) each
.Xr gettext 3
string lookup
.It Dv log-syslog
Log (via stderr) each syslog message (via
.Xr xo_syslog 3 )
.If Dv no-humanize
Ignore the {h:} modifier (TEXT, HTML)
.It Dv no-locale
Do not initialize the locale setting
.It Dv no-top
@ -82,6 +91,8 @@ Pretend the 1st output item was not 1st (JSON)
Emit pretty-printed output
.It Dv text
Emit TEXT output
.If Dv underscores
Replace XML-friendly "-"s with JSON friendly "_"s e
.It Dv units
Add the 'units' (XML) or 'data-units (HTML) attribute
.It Dv warn
@ -132,30 +143,6 @@ Note that the value is not copied, so the memory passed to
.Fn xo_parse_args )
must be maintained by the caller.
.Pp
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_set_allocator
.Nd set allocation functions for libxo
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -49,30 +49,6 @@ By default, the standard
and
.Xr free 3
functions are used.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_set_flags , xo_clear_flags
.Nd set operational flags for a libxo handle
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -42,12 +42,21 @@ This flag will trigger the call of the
(provided via
.Xr xo_set_writer 3 )
when the handle is destroyed.
.It Dv XOF_DTRT
Enable "do the right thing" mode
.It Dv XOF_COLOR
Enable color and effects in output regardless of output device.
.It Dv XOF_COLOR_ALLOWED
Allow color and effects if the output device is a terminal.
.It Dv XOF_INFO
Display info data attributes (HTML)
.It Dv XOF_KEYS
Emit the key attribute (XML)
.It Dv XOF_LOG_GETTEXT
Log (via stderr) each
.Xr gettext 3
string lookup
.It Dv XOF_LOG_SYSLOG
Log (via stderr) each syslog message (via
.Xr xo_syslog 3 )
.It Dv XOF_NO_ENV
Do not use the
.Ev LIBXO_OPTIONS
@ -125,30 +134,6 @@ The
.Fn xo_clear_flags
function turns off the given flags in a specific
handle.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_set_info
.Nd set the field information data for libxo
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -97,30 +97,6 @@ and "data-help" attributes:
<div class="data" data-tag="sku" data-type="string"
data-help="Stock Keeping Unit">GRO-000-533</div>
.Ed
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -12,7 +12,7 @@
.Os
.Sh NAME
.Nm xo_set_options
.Nd change options used by a handle
.Nd change options used by a libxo handle
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -26,30 +26,6 @@ function accepts a comma-separated list of styles
and flags and enables them for a specific handle.
The options are identical to those listed in
.Xr xo_parse_args 3 .
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_set_style , xo_set_style_name
.Nd set the output style for a libxo handle
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -48,30 +48,6 @@ The name can be any of the styles: "text", "xml", "json", or "html".
EXAMPLE:
xo_set_style_name(NULL, "html");
.Ed
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -0,0 +1,36 @@
.\" #
.\" # Copyright (c) 2015, Juniper Networks, Inc.
.\" # All rights reserved.
.\" # This SOFTWARE is licensed under the LICENSE provided in the
.\" # ../Copyright file. By downloading, installing, copying, or
.\" # using the SOFTWARE, you agree to be bound by the terms of that
.\" # LICENSE.
.\" # Phil Shafer, July 2015
.\"
.Dd July 20, 2015
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_set_syslog_enterprise_id
.Nd Set the enterprise identifier for syslog content
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Ft void
.Fn xo_set_syslog_enterprise_id "unsigned short eid"
.Ft void
.Sh DESCRIPTION
The
.Fn xo_set_syslog_enterprise_id
function records an enterprise identifier used for subsequent
.Xr xo_syslog 3
calls.
Enterprise IDs are
defined by IANA, the Internet Assigned Numbers Authority:
.Bd -literal -offset indent
https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
.Ed
.Sh SEE ALSO
.Xr xo_syslog 3 ,
.Xr libxo 3

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_set_version
.Nd record content version information in encoded output
.Nm xo_set_version , xo_set_version_h
.Nd record content-version information in encoded output
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -29,31 +29,6 @@ part of the data for encoding styles (XML and JSON).
This version number is suitable for tracking changes in the content,
allowing a user of the data to discern which version of the data model
is in use.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3 ,
.Xr libxo 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer

View file

@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_emit
.Nd emit formatted output based on format string and arguments
.Nm xo_set_writer
.Nd set custom writer functions for a libxo handle
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@ -51,30 +51,6 @@ The
.Fa flush_func
function should
flush any pending data associated with the opaque pointer.
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
http://juniper.github.io/libxo/libxo-manual.html
.Ed
.Pp
.Nm libxo
lives on github as:
.Bd -literal -offset indent
https://github.com/Juniper/libxo
.Ed
.Pp
The latest release of
.Nm libxo
is available at:
.Bd -literal -offset indent
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
.Xr xo_emit 3
.Sh HISTORY
The
.Nm libxo
library was added in
.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
.Xr xo_emit 3 ,
.Xr libxo 3

View file

@ -0,0 +1,79 @@
.\" #
.\" # Copyright (c) 2015, Juniper Networks, Inc.
.\" # All rights reserved.
.\" # This SOFTWARE is licensed under the LICENSE provided in the
.\" # ../Copyright file. By downloading, installing, copying, or
.\" # using the SOFTWARE, you agree to be bound by the terms of that
.\" # LICENSE.
.\" # Phil Shafer, July 2015
.\"
.Dd July 20, 2015
.Dt LIBXO 3
.Os
.Sh NAME
.Nm xo_syslog , xo_vsyslog , xo_open_log , xo_close_log , xo_set_logmask
.Nd create SYSLOG (RFC5424) log records using libxo formatting
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
.In libxo/xo.h
.Ft void
.Fn xo_syslog "int pri" "const char *name" "const char *fmt" "..."
.Ft void
.Fn xo_vsyslog "int pri" "const char *name" "const char *fmt" "va_list vap"
.Ft void
.Fn xo_close_log "void"
.Ft void
.Fn xo_open_log "const char *ident" "int logstat" "int logfac"
.Ft int
.Fn xo_set_logmask "int pmask"
.Sh DESCRIPTION
The
.Fn xo_syslog
function creates log entries following the standard defined in
RFC5424.
These messages are sent to the log
.Xr syslogd 8
daemon, where they can be filtered, forwarded, and archived.
.Nm libxo
format strings are used to create both the message text and the
.Nm SD-PARAMS
content, containing name/value pairs that can be parsed by suitable
automation software.
.Pp
Refer to
.Xr xo_format 5
for basic information about formatting strings.
.Nm xo_syslog
encodes all value fields at SD-PARAMS within the syslog message.
An exception is made for fields with the "{d:}" modifier; such fields
appear in the message text only, with fields with the "{e:}" modifier
appear as SD-PARAMS, but not in the message text.
.Pp
.Fn xo_vsyslog
accepts a
.Fa va_list
for additional flexibility.
.Pp
.Fn xo_open_log ,
.Fn xo_close_log , and
.Fn xo_set_logmask
are all analogous to their libs counterparts,
.Xr openlog 3 ,
.Xr closelog 3 , and
.Xr setlogmask 3 .
The extra underscores in the names are unfortunate, but keep
consistency in
.Nm libxo
function names.
.Sh EXAMPLES
.Bd -literal -offset indent
xo_syslog(LOG_LOCAL4 | LOG_NOTICE, "ID47",
"{e:iut/%u}An {:event-source} {:event-id/%u} log entry",
iut, source, id);
.Ed
.Sh SEE ALSO
.Xr xo_syslog 3 ,
.Xr xo_set_syslog_enterprise_id 3 ,
.Xr xo_format 5 ,
.Xr libxo 3

View file

@ -0,0 +1,706 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, June 2015
*/
/*
* Portions of this file are:
* Copyright (c) 1983, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include "xo_config.h"
#include "xo.h"
#include "xo_encoder.h" /* For xo_realloc */
#include "xo_buf.h"
/*
* SYSLOG (RFC 5424) requires an enterprise identifier. This turns
* out to be a fickle little issue. For a single-vendor box, the
* system should have a single EID that all software can use. When
* VendorX turns FreeBSD into a product, all software (kernel and
* utilities) should report VendorX's EID. But when software is
* installed on top of an external operating system, the application
* should report it's own EID, distinct from the base OS.
*
* To make this happen, the kernel should support a sysctl to assign a
* custom enterprise-id ("kern.syslog.enterprise_id"). libxo then
* allows an application to set a custom EID to override that system
* wide value, if needed.
*
* We try to set the stock IANA assigned Enterprise ID value for the
* vendors we know about (FreeBSD, macosx), but fallback to the
* "example" EID defined by IANA. See:
* https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
*/
#define XO_SYSLOG_ENTERPRISE_ID "kern.syslog.enterprise_id"
#if defined(__FreeBSD__)
#define XO_DEFAULT_EID 2238
#elif defined(__macosx__)
#define XO_DEFAULT_EID 63
#else
#define XO_DEFAULT_EID 32473 /* Bail; use "example" number */
#endif
#ifdef _SC_HOST_NAME_MAX
#define HOST_NAME_MAX _SC_HOST_NAME_MAX
#else
#define HOST_NAME_MAX 255
#endif /* _SC_HOST_NAME_MAX */
#ifndef UNUSED
#define UNUSED __attribute__ ((__unused__))
#endif /* UNUSED */
static int xo_logfile = -1; /* fd for log */
static int xo_status; /* connection xo_status */
static int xo_opened; /* have done openlog() */
static int xo_logstat = 0; /* xo_status bits, set by openlog() */
static const char *xo_logtag = NULL; /* string to tag the entry with */
static int xo_logfacility = LOG_USER; /* default facility code */
static int xo_logmask = 0xff; /* mask of priorities to be logged */
static pthread_mutex_t xo_syslog_mutex UNUSED = PTHREAD_MUTEX_INITIALIZER;
static int xo_unit_test; /* Fake data for unit test */
#define REAL_VOID(_x) \
do { int really_ignored = _x; if (really_ignored) { }} while (0)
#if !defined(HAVE_DECL___ISTHREADED) || !HAVE_DECL___ISTHREADED
#define __isthreaded 1
#endif
#define THREAD_LOCK() \
do { \
if (__isthreaded) pthread_mutex_lock(&xo_syslog_mutex); \
} while(0)
#define THREAD_UNLOCK() \
do { \
if (__isthreaded) pthread_mutex_unlock(&xo_syslog_mutex); \
} while(0)
static void xo_disconnect_log(void); /* disconnect from syslogd */
static void xo_connect_log(void); /* (re)connect to syslogd */
static void xo_open_log_unlocked(const char *, int, int);
enum {
NOCONN = 0,
CONNDEF,
CONNPRIV,
};
static xo_syslog_open_t xo_syslog_open;
static xo_syslog_send_t xo_syslog_send;
static xo_syslog_close_t xo_syslog_close;
static char xo_syslog_enterprise_id[12];
/*
* Record an enterprise ID, which functions as a namespace for syslog
* messages. The value is pre-formatted into a string. This allows
* applications to customize their syslog message set, when needed.
*/
void
xo_set_syslog_enterprise_id (unsigned short eid)
{
snprintf(xo_syslog_enterprise_id, sizeof(xo_syslog_enterprise_id),
"%u", eid);
}
/*
* Handle the work of transmitting the syslog message
*/
static void
xo_send_syslog (char *full_msg, char *v0_hdr,
char *text_only)
{
if (xo_syslog_send) {
xo_syslog_send(full_msg, v0_hdr, text_only);
return;
}
int fd;
int full_len = strlen(full_msg);
/* Output to stderr if requested. */
if (xo_logstat & LOG_PERROR) {
struct iovec iov[3];
struct iovec *v = iov;
char newline[] = "\n";
v->iov_base = v0_hdr;
v->iov_len = strlen(v0_hdr);
v += 1;
v->iov_base = text_only;
v->iov_len = strlen(text_only);
v += 1;
v->iov_base = newline;
v->iov_len = 1;
v += 1;
REAL_VOID(writev(STDERR_FILENO, iov, 3));
}
/* Get connected, output the message to the local logger. */
if (!xo_opened)
xo_open_log_unlocked(xo_logtag, xo_logstat | LOG_NDELAY, 0);
xo_connect_log();
/*
* If the send() fails, there are two likely scenarios:
* 1) syslogd was restarted
* 2) /var/run/log is out of socket buffer space, which
* in most cases means local DoS.
* If the error does not indicate a full buffer, we address
* case #1 by attempting to reconnect to /var/run/log[priv]
* and resending the message once.
*
* If we are working with a privileged socket, the retry
* attempts end there, because we don't want to freeze a
* critical application like su(1) or sshd(8).
*
* Otherwise, we address case #2 by repeatedly retrying the
* send() to give syslogd a chance to empty its socket buffer.
*/
if (send(xo_logfile, full_msg, full_len, 0) < 0) {
if (errno != ENOBUFS) {
/*
* Scenario 1: syslogd was restarted
* reconnect and resend once
*/
xo_disconnect_log();
xo_connect_log();
if (send(xo_logfile, full_msg, full_len, 0) >= 0) {
return;
}
/*
* if the resend failed, fall through to
* possible scenario 2
*/
}
while (errno == ENOBUFS) {
/*
* Scenario 2: out of socket buffer space
* possible DoS, fail fast on a privileged
* socket
*/
if (xo_status == CONNPRIV)
break;
usleep(1);
if (send(xo_logfile, full_msg, full_len, 0) >= 0) {
return;
}
}
} else {
return;
}
/*
* Output the message to the console; try not to block
* as a blocking console should not stop other processes.
* Make sure the error reported is the one from the syslogd failure.
*/
int flags = O_WRONLY | O_NONBLOCK;
#ifdef O_CLOEXEC
flags |= O_CLOEXEC;
#endif /* O_CLOEXEC */
if (xo_logstat & LOG_CONS
&& (fd = open(_PATH_CONSOLE, flags, 0)) >= 0) {
struct iovec iov[2];
struct iovec *v = iov;
char crnl[] = "\r\n";
char *p;
p = strchr(full_msg, '>') + 1;
v->iov_base = p;
v->iov_len = full_len - (p - full_msg);
++v;
v->iov_base = crnl;
v->iov_len = 2;
REAL_VOID(writev(fd, iov, 2));
(void) close(fd);
}
}
/* Should be called with mutex acquired */
static void
xo_disconnect_log (void)
{
if (xo_syslog_close) {
xo_syslog_close();
return;
}
/*
* If the user closed the FD and opened another in the same slot,
* that's their problem. They should close it before calling on
* system services.
*/
if (xo_logfile != -1) {
close(xo_logfile);
xo_logfile = -1;
}
xo_status = NOCONN; /* retry connect */
}
/* Should be called with mutex acquired */
static void
xo_connect_log (void)
{
if (xo_syslog_open) {
xo_syslog_open();
return;
}
struct sockaddr_un saddr; /* AF_UNIX address of local logger */
if (xo_logfile == -1) {
int flags = SOCK_DGRAM;
#ifdef SOCK_CLOEXEC
flags |= SOCK_CLOEXEC;
#endif /* SOCK_CLOEXEC */
if ((xo_logfile = socket(AF_UNIX, flags, 0)) == -1)
return;
}
if (xo_logfile != -1 && xo_status == NOCONN) {
#ifdef HAVE_SUN_LEN
saddr.sun_len = sizeof(saddr);
#endif /* HAVE_SUN_LEN */
saddr.sun_family = AF_UNIX;
/*
* First try privileged socket. If no success,
* then try default socket.
*/
#ifdef _PATH_LOG_PRIV
(void) strncpy(saddr.sun_path, _PATH_LOG_PRIV,
sizeof saddr.sun_path);
if (connect(xo_logfile, (struct sockaddr *) &saddr,
sizeof(saddr)) != -1)
xo_status = CONNPRIV;
#endif /* _PATH_LOG_PRIV */
#ifdef _PATH_LOG
if (xo_status == NOCONN) {
(void) strncpy(saddr.sun_path, _PATH_LOG,
sizeof saddr.sun_path);
if (connect(xo_logfile, (struct sockaddr *)&saddr,
sizeof(saddr)) != -1)
xo_status = CONNDEF;
}
#endif /* _PATH_LOG */
#ifdef _PATH_OLDLOG
if (xo_status == NOCONN) {
/*
* Try the old "/dev/log" path, for backward
* compatibility.
*/
(void) strncpy(saddr.sun_path, _PATH_OLDLOG,
sizeof saddr.sun_path);
if (connect(xo_logfile, (struct sockaddr *)&saddr,
sizeof(saddr)) != -1)
xo_status = CONNDEF;
}
#endif /* _PATH_OLDLOG */
if (xo_status == NOCONN) {
(void) close(xo_logfile);
xo_logfile = -1;
}
}
}
static void
xo_open_log_unlocked (const char *ident, int logstat, int logfac)
{
if (ident != NULL)
xo_logtag = ident;
xo_logstat = logstat;
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
xo_logfacility = logfac;
if (xo_logstat & LOG_NDELAY) /* open immediately */
xo_connect_log();
xo_opened = 1; /* ident and facility has been set */
}
void
xo_open_log (const char *ident, int logstat, int logfac)
{
THREAD_LOCK();
xo_open_log_unlocked(ident, logstat, logfac);
THREAD_UNLOCK();
}
void
xo_close_log (void)
{
THREAD_LOCK();
if (xo_logfile != -1) {
(void) close(xo_logfile);
xo_logfile = -1;
}
xo_logtag = NULL;
xo_status = NOCONN;
THREAD_UNLOCK();
}
/* xo_set_logmask -- set the log mask level */
int
xo_set_logmask (int pmask)
{
int omask;
THREAD_LOCK();
omask = xo_logmask;
if (pmask != 0)
xo_logmask = pmask;
THREAD_UNLOCK();
return (omask);
}
void
xo_set_syslog_handler (xo_syslog_open_t open_func,
xo_syslog_send_t send_func,
xo_syslog_close_t close_func)
{
xo_syslog_open = open_func;
xo_syslog_send = send_func;
xo_syslog_close = close_func;
}
static size_t
xo_snprintf (char *out, size_t outsize, const char *fmt, ...)
{
int status;
size_t retval = 0;
va_list ap;
if (out && outsize) {
va_start(ap, fmt);
status = vsnprintf(out, outsize, fmt, ap);
if (status < 0) { /* this should never happen, */
*out = 0; /* handle it in the safest way possible if it does */
retval = 0;
} else {
retval = status;
retval = retval > outsize ? outsize : retval;
}
va_end(ap);
}
return retval;
}
static int
xo_syslog_handle_write (void *opaque, const char *data)
{
xo_buffer_t *xbp = opaque;
int len = strlen(data);
int left = xo_buf_left(xbp);
if (len > left - 1)
len = left - 1;
memcpy(xbp->xb_curp, data, len);
xbp->xb_curp += len;
*xbp->xb_curp = '\0';
return len;
}
static void
xo_syslog_handle_close (void *opaque UNUSED)
{
}
static int
xo_syslog_handle_flush (void *opaque UNUSED)
{
return 0;
}
void
xo_set_unit_test_mode (int value)
{
xo_unit_test = value;
}
void
xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap)
{
int saved_errno = errno;
char tbuf[2048];
char *tp = NULL, *ep = NULL;
unsigned start_of_msg = 0;
char *v0_hdr = NULL;
xo_buffer_t xb;
static pid_t my_pid;
unsigned log_offset;
if (my_pid == 0)
my_pid = xo_unit_test ? 222 : getpid();
/* Check for invalid bits */
if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
xo_syslog(LOG_ERR | LOG_CONS | LOG_PERROR | LOG_PID,
"syslog-unknown-priority",
"syslog: unknown facility/priority: %#x", pri);
pri &= LOG_PRIMASK|LOG_FACMASK;
}
THREAD_LOCK();
/* Check priority against setlogmask values. */
if (!(LOG_MASK(LOG_PRI(pri)) & xo_logmask)) {
THREAD_UNLOCK();
return;
}
/* Set default facility if none specified. */
if ((pri & LOG_FACMASK) == 0)
pri |= xo_logfacility;
/* Create the primary stdio hook */
xb.xb_bufp = tbuf;
xb.xb_curp = tbuf;
xb.xb_size = sizeof(tbuf);
xo_handle_t *xop = xo_create(XO_STYLE_SDPARAMS, 0);
if (xop == NULL) {
THREAD_UNLOCK();
return;
}
#ifdef HAVE_GETPROGNAME
if (xo_logtag == NULL)
xo_logtag = getprogname();
#endif /* HAVE_GETPROGNAME */
xo_set_writer(xop, &xb, xo_syslog_handle_write, xo_syslog_handle_close,
xo_syslog_handle_flush);
/* Build the message; start by getting the time */
struct tm tm;
struct timeval tv;
/* Unit test hack: fake a fixed time */
if (xo_unit_test) {
tv.tv_sec = 1435085229;
tv.tv_usec = 123456;
} else
gettimeofday(&tv, NULL);
(void) localtime_r(&tv.tv_sec, &tm);
if (xo_logstat & LOG_PERROR) {
/*
* For backwards compatibility, we need to make the old-style
* message. This message can be emitted to the console/tty.
*/
v0_hdr = alloca(2048);
tp = v0_hdr;
ep = v0_hdr + 2048;
if (xo_logtag != NULL)
tp += xo_snprintf(tp, ep - tp, "%s", xo_logtag);
if (xo_logstat & LOG_PID)
tp += xo_snprintf(tp, ep - tp, "[%d]", my_pid);
if (xo_logtag)
tp += xo_snprintf(tp, ep - tp, ": ");
}
log_offset = xb.xb_curp - xb.xb_bufp;
/* Add PRI, PRIVAL, and VERSION */
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "<%d>1 ", pri);
/* Add TIMESTAMP with milliseconds and TZOFFSET */
xb.xb_curp += strftime(xb.xb_curp, xo_buf_left(&xb), "%FT%T", &tm);
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb),
".%03.3u", tv.tv_usec / 1000);
xb.xb_curp += strftime(xb.xb_curp, xo_buf_left(&xb), "%z ", &tm);
/*
* Add HOSTNAME; we rely on gethostname and don't fluff with
* ip addresses. Might need to revisit.....
*/
char hostname[HOST_NAME_MAX];
hostname[0] = '\0';
if (xo_unit_test)
strcpy(hostname, "worker-host");
else
(void) gethostname(hostname, sizeof(hostname));
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%s ",
hostname[0] ? hostname : "-");
/* Add APP-NAME */
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%s ",
xo_logtag ?: "-");
/* Add PROCID */
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%d ", my_pid);
/*
* Add MSGID. The user should provide us with a name, which we
* prefix with the current enterprise ID, as learned from the kernel.
* If the kernel won't tell us, we use the stock/builtin number.
*/
char *buf UNUSED = NULL;
const char *eid = xo_syslog_enterprise_id;
const char *at_sign = "@";
if (name == NULL) {
name = "-";
eid = at_sign = "";
} else if (*name == '@') {
/* Our convention is to prefix IANA-defined names with an "@" */
name += 1;
eid = at_sign = "";
} else if (eid[0] == '\0') {
#ifdef HAVE_SYSCTLBYNAME
/*
* See if the kernel knows the sysctl for the enterprise ID
*/
size_t size = 0;
if (sysctlbyname(XO_SYSLOG_ENTERPRISE_ID, NULL, &size, NULL, 0) == 0
&& size > 0) {
buf = alloca(size);
if (sysctlbyname(XO_SYSLOG_ENTERPRISE_ID, buf, &size, NULL, 0) == 0
&& size > 0)
eid = buf;
}
#endif /* HAVE_SYSCTLBYNAME */
if (eid[0] == '\0') {
/* Fallback to our base default */
xo_set_syslog_enterprise_id(XO_DEFAULT_EID);
eid = xo_syslog_enterprise_id;
}
}
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "%s [%s%s%s ",
name, name, at_sign, eid);
/*
* Now for the real content. We make two distinct passes thru the
* xo_emit engine, first for the SD-PARAMS and then for the text
* message.
*/
va_list ap;
va_copy(ap, vap);
errno = saved_errno; /* Restore saved error value */
xo_emit_hv(xop, fmt, ap);
xo_flush_h(xop);
va_end(ap);
/* Trim trailing space */
if (xb.xb_curp[-1] == ' ')
xb.xb_curp -= 1;
/* Close the structured data (SD-ELEMENT) */
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb), "] ");
/*
* Since our MSG is known to be UTF-8, we MUST prefix it with
* that most-annoying-of-all-UTF-8 features, the BOM (0xEF.BB.BF).
*/
xb.xb_curp += xo_snprintf(xb.xb_curp, xo_buf_left(&xb),
"%c%c%c", 0xEF, 0xBB, 0xBF);
/* Save the start of the message */
if (xo_logstat & LOG_PERROR)
start_of_msg = xb.xb_curp - xb.xb_bufp;
xo_set_style(xop, XO_STYLE_TEXT);
xo_set_flags(xop, XOF_UTF8);
errno = saved_errno; /* Restore saved error value */
xo_emit_hv(xop, fmt, ap);
xo_flush_h(xop);
/* Remove a trailing newline */
if (xb.xb_curp[-1] == '\n')
*--xb.xb_curp = '\0';
if (xo_get_flags(xop) & XOF_LOG_SYSLOG)
fprintf(stderr, "xo: syslog: %s\n", xb.xb_bufp + log_offset);
xo_send_syslog(xb.xb_bufp, v0_hdr, xb.xb_bufp + start_of_msg);
xo_destroy(xop);
THREAD_UNLOCK();
}
/*
* syslog - print message on log file; output is intended for syslogd(8).
*/
void
xo_syslog (int pri, const char *name, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
xo_vsyslog(pri, name, fmt, ap);
va_end(ap);
}

View file

@ -0,0 +1,313 @@
/*
* This is an implementation of wcwidth() and wcswidth() (defined in
* IEEE Std 1002.1-2001) for Unicode.
*
* http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
* http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
*
* In fixed-width output devices, Latin characters all occupy a single
* "cell" position of equal width, whereas ideographic CJK characters
* occupy two such cells. Interoperability between terminal-line
* applications and (teletype-style) character terminals using the
* UTF-8 encoding requires agreement on which character should advance
* the cursor by how many cell positions. No established formal
* standards exist at present on which Unicode character shall occupy
* how many cell positions on character terminals. These routines are
* a first attempt of defining such behavior based on simple rules
* applied to data provided by the Unicode Consortium.
*
* For some graphical characters, the Unicode standard explicitly
* defines a character-cell width via the definition of the East Asian
* FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
* In all these cases, there is no ambiguity about which width a
* terminal shall use. For characters in the East Asian Ambiguous (A)
* class, the width choice depends purely on a preference of backward
* compatibility with either historic CJK or Western practice.
* Choosing single-width for these characters is easy to justify as
* the appropriate long-term solution, as the CJK practice of
* displaying these characters as double-width comes from historic
* implementation simplicity (8-bit encoded characters were displayed
* single-width and 16-bit ones double-width, even for Greek,
* Cyrillic, etc.) and not any typographic considerations.
*
* Much less clear is the choice of width for the Not East Asian
* (Neutral) class. Existing practice does not dictate a width for any
* of these characters. It would nevertheless make sense
* typographically to allocate two character cells to characters such
* as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
* represented adequately with a single-width glyph. The following
* routines at present merely assign a single-cell width to all
* neutral characters, in the interest of simplicity. This is not
* entirely satisfactory and should be reconsidered before
* establishing a formal standard in this area. At the moment, the
* decision which Not East Asian (Neutral) characters should be
* represented by double-width glyphs cannot yet be answered by
* applying a simple rule from the Unicode database content. Setting
* up a proper standard for the behavior of UTF-8 character terminals
* will require a careful analysis not only of each Unicode character,
* but also of each presentation form, something the author of these
* routines has avoided to do so far.
*
* http://www.unicode.org/unicode/reports/tr11/
*
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
*
* Permission to use, copy, modify, and distribute this software
* for any purpose and without fee is hereby granted. The author
* disclaims all warranties with regard to this software.
*
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
*/
#include <wchar.h>
struct interval {
int first;
int last;
};
/* auxiliary function for binary search in interval table */
static int
xo_bisearch (wchar_t ucs, const struct interval *table, int max)
{
int min = 0;
int mid;
if (ucs < table[0].first || ucs > table[max].last)
return 0;
while (max >= min) {
mid = (min + max) / 2;
if (ucs > table[mid].last)
min = mid + 1;
else if (ucs < table[mid].first)
max = mid - 1;
else
return 1;
}
return 0;
}
/* The following two functions define the column width of an ISO 10646
* character as follows:
*
* - The null character (U+0000) has a column width of 0.
*
* - Other C0/C1 control characters and DEL will lead to a return
* value of -1.
*
* - Non-spacing and enclosing combining characters (general
* category code Mn or Me in the Unicode database) have a
* column width of 0.
*
* - SOFT HYPHEN (U+00AD) has a column width of 1.
*
* - Other format characters (general category code Cf in the Unicode
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
*
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
* have a column width of 0.
*
* - Spacing characters in the East Asian Wide (W) or East Asian
* Full-width (F) category as defined in Unicode Technical
* Report #11 have a column width of 2.
*
* - All remaining characters (including all printable
* ISO 8859-1 and WGL4 characters, Unicode control characters,
* etc.) have a column width of 1.
*
* This implementation assumes that wchar_t characters are encoded
* in ISO 10646.
*/
static int
xo_wcwidth (wchar_t ucs)
{
/* sorted list of non-overlapping intervals of non-spacing characters */
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
static const struct interval combining[] = {
{ 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
{ 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
{ 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
{ 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
{ 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
{ 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
{ 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
{ 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
{ 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
{ 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
{ 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
{ 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
{ 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
{ 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
{ 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
{ 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
{ 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
{ 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
{ 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
{ 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
{ 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
{ 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
{ 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
{ 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
{ 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
{ 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
{ 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
{ 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
{ 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
{ 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
{ 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
{ 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
{ 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
{ 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
{ 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
{ 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
{ 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
{ 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
{ 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
{ 0xE0100, 0xE01EF }
};
/* test for 8-bit control characters */
if (ucs == 0)
return 0;
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
return -1;
/* binary search in table of non-spacing characters */
if (xo_bisearch(ucs, combining,
sizeof(combining) / sizeof(struct interval) - 1))
return 0;
/* if we arrive here, ucs is not a combining or C0/C1 control character */
return 1 +
(ucs >= 0x1100 &&
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
ucs == 0x2329 || ucs == 0x232a ||
(ucs >= 0x2e80 && ucs <= 0xa4cf &&
ucs != 0x303f) || /* CJK ... Yi */
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
(ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
(ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
(ucs >= 0xffe0 && ucs <= 0xffe6) ||
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
(ucs >= 0x30000 && ucs <= 0x3fffd)));
}
#if UNUSED_CODE
static int xo_wcswidth(const wchar_t *pwcs, size_t n)
{
int w, width = 0;
for (;*pwcs && n-- > 0; pwcs++)
if ((w = mk_wcwidth(*pwcs)) < 0)
return -1;
else
width += w;
return width;
}
/*
* The following functions are the same as mk_wcwidth() and
* mk_wcswidth(), except that spacing characters in the East Asian
* Ambiguous (A) category as defined in Unicode Technical Report #11
* have a column width of 2. This variant might be useful for users of
* CJK legacy encodings who want to migrate to UCS without changing
* the traditional terminal character-width behaviour. It is not
* otherwise recommended for general use.
*/
int mk_wcwidth_cjk(wchar_t ucs)
{
/* sorted list of non-overlapping intervals of East Asian Ambiguous
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
static const struct interval ambiguous[] = {
{ 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
{ 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
{ 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
{ 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
{ 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
{ 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
{ 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
{ 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
{ 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
{ 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
{ 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
{ 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
{ 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
{ 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
{ 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
{ 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
{ 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
{ 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
{ 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
{ 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
{ 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
{ 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
{ 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
{ 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
{ 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
{ 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
{ 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
{ 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
{ 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
{ 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
{ 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
{ 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
{ 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
{ 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
{ 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
{ 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
{ 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
{ 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
{ 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
{ 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
{ 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
{ 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
{ 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
{ 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
{ 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
{ 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
{ 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
{ 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
{ 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
{ 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
{ 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
{ 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
};
/* binary search in table of non-spacing characters */
if (xo_bisearch(ucs, ambiguous,
sizeof(ambiguous) / sizeof(struct interval) - 1))
return 2;
return mk_wcwidth(ucs);
}
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
{
int w, width = 0;
for (;*pwcs && n-- > 0; pwcs++)
if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
return -1;
else
width += w;
return width;
}
#endif /* UNUSED_CODE */

View file

@ -1,206 +0,0 @@
/* libxo/xoconfig.h.in. Generated from configure.ac by autoheader. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
/* Define to 1 if you have the `ctime' function. */
#undef HAVE_CTIME
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `dlfunc' function. */
#undef HAVE_DLFUNC
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the `fdopen' function. */
#undef HAVE_FDOPEN
/* Define to 1 if you have the `flock' function. */
#undef HAVE_FLOCK
/* Define to 1 if you have the `getpass' function. */
#undef HAVE_GETPASS
/* Define to 1 if you have the `getrusage' function. */
#undef HAVE_GETRUSAGE
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Support printflike */
#undef HAVE_PRINTFLIKE
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#undef HAVE_REALLOC
/* Define to 1 if you have the `srand' function. */
#undef HAVE_SRAND
/* Define to 1 if you have the `sranddev' function. */
#undef HAVE_SRANDDEV
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio_ext.h> header file. */
#undef HAVE_STDIO_EXT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <stdtime/tzfile.h> header file. */
#undef HAVE_STDTIME_TZFILE_H
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strcspn' function. */
#undef HAVE_STRCSPN
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strspn' function. */
#undef HAVE_STRSPN
/* Define to 1 if you have the `sysctlbyname' function. */
#undef HAVE_SYSCTLBYNAME
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <tzfile.h> header file. */
#undef HAVE_TZFILE_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `__flbf' function. */
#undef HAVE___FLBF
/* Enable debugging */
#undef LIBXO_DEBUG
/* Enable text-only rendering */
#undef LIBXO_TEXT_ONLY
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to rpl_realloc if the replacement function should be used. */
#undef realloc
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

View file

@ -1,38 +0,0 @@
/*
* $Id$
*
* Copyright (c) 2014, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
*
* xoversion.h -- compile time constants for libxo
* NOTE: This file is generated from xoversion.h.in.
*/
#ifndef LIBXO_XOVERSION_H
#define LIBXO_XOVERSION_H
/**
* The version string
*/
#define LIBXO_VERSION "0.3.2"
/**
* The version number
*/
#define LIBXO_VERSION_NUMBER 3002
/**
* The version number as a string
*/
#define LIBXO_VERSION_STRING "3002"
/**
* The version number extra info as a string
*/
#define LIBXO_VERSION_EXTRA ""
#endif /* LIBXO_XOVERSION_H */

View file

@ -1,38 +0,0 @@
/*
* $Id$
*
* Copyright (c) 2014, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
*
* xoversion.h -- compile time constants for libxo
* NOTE: This file is generated from xoversion.h.in.
*/
#ifndef LIBXO_XOVERSION_H
#define LIBXO_XOVERSION_H
/**
* The version string
*/
#define LIBXO_VERSION "@PACKAGE_VERSION@"
/**
* The version number
*/
#define LIBXO_VERSION_NUMBER @LIBXO_VERSION_NUMBER@
/**
* The version number as a string
*/
#define LIBXO_VERSION_STRING "@LIBXO_VERSION_NUMBER@"
/**
* The version number extra info as a string
*/
#define LIBXO_VERSION_EXTRA "@LIBXO_VERSION_EXTRA@"
#endif /* LIBXO_XOVERSION_H */

View file

@ -6,7 +6,11 @@
# using the SOFTWARE, you agree to be bound by the terms of that
# LICENSE.
SUBDIRS=core xo
SUBDIRS = core xo
if HAVE_GETTEXT
SUBDIRS += gettext
endif
test tests:
@(cur=`pwd` ; for dir in $(SUBDIRS) ; do \

View file

@ -21,7 +21,8 @@ test_06.c \
test_07.c \
test_08.c \
test_09.c \
test_10.c
test_10.c \
test_11.c
test_01_test_SOURCES = test_01.c
test_02_test_SOURCES = test_02.c
@ -33,6 +34,7 @@ test_07_test_SOURCES = test_07.c
test_08_test_SOURCES = test_08.c
test_09_test_SOURCES = test_09.c
test_10_test_SOURCES = test_10.c
test_11_test_SOURCES = test_11.c
# TEST_CASES := $(shell cd ${srcdir} ; echo *.c )
@ -41,6 +43,10 @@ noinst_PROGRAMS = ${TEST_CASES:.c=.test}
LDADD = \
${top_builddir}/libxo/libxo.la
if HAVE_HUMANIZE_NUMBER
LDADD += -lutil
endif
EXTRA_DIST = \
${TEST_CASES} \
${addprefix saved/, ${TEST_CASES:.c=.T.err}} \
@ -70,13 +76,18 @@ valgrind:
#TEST_TRACE = set -x ;
TEST_ONE = \
LIBXO_OPTIONS=:W$$fmt \
TEST_JIG = \
${CHECKER} ./$$base.test ${TEST_OPTS} \
> out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \
${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \
${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O}
TEST_ONE = \
LIBXO_OPTIONS=:W$$fmt ${TEST_JIG}
TEST_TWO = \
LIBXO_OPTIONS=warn,encoder=test ${TEST_JIG}
TEST_FORMATS = T XP JP HP X J H HIPx
test tests: ${bin_PROGRAMS}
@ -87,6 +98,11 @@ test tests: ${bin_PROGRAMS}
echo "... $$test ... $$fmt ..."; \
${TEST_ONE}; \
true; \
done) ; \
(for fmt in E; do \
echo "... $$test ... $$fmt ..."; \
${TEST_TWO}; \
true; \
done) \
done)
@ -96,7 +112,7 @@ one:
accept:
-@(for test in ${TEST_CASES} ; do \
base=`${BASENAME} $$test .c` ; \
(for fmt in ${TEST_FORMATS}; do \
(for fmt in ${TEST_FORMATS} E; do \
echo "... $$test ... $$fmt ..."; \
${CP} out/$$base.$$fmt.out ${srcdir}/saved/$$base.$$fmt.out ; \
${CP} out/$$base.$$fmt.err ${srcdir}/saved/$$base.$$fmt.err ; \

View file

@ -0,0 +1,119 @@
op create: [] []
op open_container: [top] []
op string: [host] [my-box]
op string: [domain] [example.com]
op attr: [test] [value]
op open_container: [data] []
op open_list: [item] []
op attr: [test2] [value2]
op open_instance: [item] []
op attr: [test3] [value3]
op string: [sku] [GRO-000-415]
op string: [name] [gum]
op content: [sold] [1412]
op content: [in-stock] [54]
op content: [on-order] [10]
op close_instance: [item] []
op open_instance: [item] []
op attr: [test3] [value3]
op string: [sku] [HRD-000-212]
op string: [name] [rope]
op content: [sold] [85]
op content: [in-stock] [4]
op content: [on-order] [2]
op close_instance: [item] []
op open_instance: [item] []
op attr: [test3] [value3]
op string: [sku] [HRD-000-517]
op string: [name] [ladder]
op content: [sold] [0]
op content: [in-stock] [2]
op content: [on-order] [1]
op close_instance: [item] []
op open_instance: [item] []
op attr: [test3] [value3]
op string: [sku] [HRD-000-632]
op string: [name] [bolt]
op content: [sold] [4123]
op content: [in-stock] [144]
op content: [on-order] [42]
op close_instance: [item] []
op open_instance: [item] []
op attr: [test3] [value3]
op string: [sku] [GRO-000-2331]
op string: [name] [water]
op content: [sold] [17]
op content: [in-stock] [14]
op content: [on-order] [2]
op close_instance: [item] []
op close_list: [item] []
op close_container: [data] []
op open_container: [data2] []
op open_list: [item] []
op open_instance: [item] []
op string: [sku] [GRO-000-415]
op string: [name] [gum]
op content: [sold] [1412.0]
op content: [in-stock] [54]
op content: [on-order] [10]
op close_instance: [item] []
op open_instance: [item] []
op string: [sku] [HRD-000-212]
op string: [name] [rope]
op content: [sold] [85.0]
op content: [in-stock] [4]
op content: [on-order] [2]
op close_instance: [item] []
op open_instance: [item] []
op string: [sku] [HRD-000-517]
op string: [name] [ladder]
op content: [sold] [0]
op content: [in-stock] [2]
op content: [on-order] [1]
op close_instance: [item] []
op open_instance: [item] []
op string: [sku] [HRD-000-632]
op string: [name] [bolt]
op content: [sold] [4123.0]
op content: [in-stock] [144]
op content: [on-order] [42]
op close_instance: [item] []
op open_instance: [item] []
op string: [sku] [GRO-000-2331]
op string: [name] [water]
op content: [sold] [17.0]
op content: [in-stock] [14]
op content: [on-order] [2]
op close_instance: [item] []
op close_list: [item] []
op close_container: [data2] []
op open_container: [data3] []
op open_list: [item] []
op open_instance: [item] []
op string: [sku] [GRO-000-533]
op string: [name] [fish]
op content: [sold] [1321.0]
op content: [in-stock] [45]
op content: [on-order] [1]
op close_instance: [item] []
op close_list: [item] []
op close_container: [data3] []
op open_container: [data4] []
op open_list: [item] []
op attr: [test4] [value4]
op string: [item] [gum]
op attr: [test4] [value4]
op string: [item] [rope]
op attr: [test4] [value4]
op string: [item] [ladder]
op attr: [test4] [value4]
op string: [item] [bolt]
op attr: [test4] [value4]
op string: [item] [water]
op close_list: [item] []
op close_container: [data4] []
op content: [cost] [425]
op content: [cost] [455]
op close_container: [top] []
op finish: [] []
op flush: [] []

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,10 @@
<div class="line">
<div class="text">Connecting to </div>
<div class="data" data-tag="host" data-xpath="/top/host">my-box</div>
<div class="text">.</div>
<div class="data" data-tag="domain" data-xpath="/top/domain">example.com</div>
<div class="text">...</div>
</div>
<div class="line">
<div class="title">Item </div>
<div class="title"> Total Sold</div>
@ -47,224 +54,224 @@
<div class="line">
<div class="label">Item</div>
<div class="text"> '</div>
<div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">gum</div>
<div class="data" data-tag="name" data-xpath="/top/data2/item/name" data-type="string" data-help="Name of the item" data-key="key">gum</div>
<div class="text">':</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">Total sold</div>
<div class="text">: </div>
<div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/sold" data-type="number" data-help="Number of items sold">1412.0</div>
<div class="data" data-tag="sold" data-xpath="/top/data2/item[sku = 'GRO-000-415'][name = 'gum']/sold" data-type="number" data-help="Number of items sold">1412.0</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">In stock</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/in-stock" data-type="number" data-help="Number of items in stock">54</div>
<div class="data" data-tag="in-stock" data-xpath="/top/data2/item[sku = 'GRO-000-415'][name = 'gum']/in-stock" data-type="number" data-help="Number of items in stock">54</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">On order</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/on-order" data-type="number" data-help="Number of items on order">10</div>
<div class="data" data-tag="on-order" data-xpath="/top/data2/item[sku = 'GRO-000-415'][name = 'gum']/on-order" data-type="number" data-help="Number of items on order">10</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">SKU</div>
<div class="text">: </div>
<div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-415</div>
<div class="data" data-tag="sku" data-xpath="/top/data2/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-415</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="text"> '</div>
<div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">rope</div>
<div class="data" data-tag="name" data-xpath="/top/data2/item/name" data-type="string" data-help="Name of the item" data-key="key">rope</div>
<div class="text">':</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">Total sold</div>
<div class="text">: </div>
<div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/sold" data-type="number" data-help="Number of items sold">85.0</div>
<div class="data" data-tag="sold" data-xpath="/top/data2/item[sku = 'HRD-000-212'][name = 'rope']/sold" data-type="number" data-help="Number of items sold">85.0</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">In stock</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/in-stock" data-type="number" data-help="Number of items in stock">4</div>
<div class="data" data-tag="in-stock" data-xpath="/top/data2/item[sku = 'HRD-000-212'][name = 'rope']/in-stock" data-type="number" data-help="Number of items in stock">4</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">On order</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/on-order" data-type="number" data-help="Number of items on order">2</div>
<div class="data" data-tag="on-order" data-xpath="/top/data2/item[sku = 'HRD-000-212'][name = 'rope']/on-order" data-type="number" data-help="Number of items on order">2</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">SKU</div>
<div class="text">: </div>
<div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-212</div>
<div class="data" data-tag="sku" data-xpath="/top/data2/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-212</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="text"> '</div>
<div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">ladder</div>
<div class="data" data-tag="name" data-xpath="/top/data2/item/name" data-type="string" data-help="Name of the item" data-key="key">ladder</div>
<div class="text">':</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">Total sold</div>
<div class="text">: </div>
<div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/sold" data-type="number" data-help="Number of items sold">0</div>
<div class="data" data-tag="sold" data-xpath="/top/data2/item[sku = 'HRD-000-517'][name = 'ladder']/sold" data-type="number" data-help="Number of items sold">0</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">In stock</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/in-stock" data-type="number" data-help="Number of items in stock">2</div>
<div class="data" data-tag="in-stock" data-xpath="/top/data2/item[sku = 'HRD-000-517'][name = 'ladder']/in-stock" data-type="number" data-help="Number of items in stock">2</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">On order</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/on-order" data-type="number" data-help="Number of items on order">1</div>
<div class="data" data-tag="on-order" data-xpath="/top/data2/item[sku = 'HRD-000-517'][name = 'ladder']/on-order" data-type="number" data-help="Number of items on order">1</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">SKU</div>
<div class="text">: </div>
<div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-517</div>
<div class="data" data-tag="sku" data-xpath="/top/data2/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-517</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="text"> '</div>
<div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">bolt</div>
<div class="data" data-tag="name" data-xpath="/top/data2/item/name" data-type="string" data-help="Name of the item" data-key="key">bolt</div>
<div class="text">':</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">Total sold</div>
<div class="text">: </div>
<div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/sold" data-type="number" data-help="Number of items sold">4123.0</div>
<div class="data" data-tag="sold" data-xpath="/top/data2/item[sku = 'HRD-000-632'][name = 'bolt']/sold" data-type="number" data-help="Number of items sold">4123.0</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">In stock</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/in-stock" data-type="number" data-help="Number of items in stock">144</div>
<div class="data" data-tag="in-stock" data-xpath="/top/data2/item[sku = 'HRD-000-632'][name = 'bolt']/in-stock" data-type="number" data-help="Number of items in stock">144</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">On order</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/on-order" data-type="number" data-help="Number of items on order">42</div>
<div class="data" data-tag="on-order" data-xpath="/top/data2/item[sku = 'HRD-000-632'][name = 'bolt']/on-order" data-type="number" data-help="Number of items on order">42</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">SKU</div>
<div class="text">: </div>
<div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-632</div>
<div class="data" data-tag="sku" data-xpath="/top/data2/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-632</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="text"> '</div>
<div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">water</div>
<div class="data" data-tag="name" data-xpath="/top/data2/item/name" data-type="string" data-help="Name of the item" data-key="key">water</div>
<div class="text">':</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">Total sold</div>
<div class="text">: </div>
<div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/sold" data-type="number" data-help="Number of items sold">17.0</div>
<div class="data" data-tag="sold" data-xpath="/top/data2/item[sku = 'GRO-000-2331'][name = 'water']/sold" data-type="number" data-help="Number of items sold">17.0</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">In stock</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/in-stock" data-type="number" data-help="Number of items in stock">14</div>
<div class="data" data-tag="in-stock" data-xpath="/top/data2/item[sku = 'GRO-000-2331'][name = 'water']/in-stock" data-type="number" data-help="Number of items in stock">14</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">On order</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/on-order" data-type="number" data-help="Number of items on order">2</div>
<div class="data" data-tag="on-order" data-xpath="/top/data2/item[sku = 'GRO-000-2331'][name = 'water']/on-order" data-type="number" data-help="Number of items on order">2</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">SKU</div>
<div class="text">: </div>
<div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-2331</div>
<div class="data" data-tag="sku" data-xpath="/top/data2/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-2331</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="text"> '</div>
<div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">fish</div>
<div class="data" data-tag="name" data-xpath="/top/data3/item/name" data-type="string" data-help="Name of the item" data-key="key">fish</div>
<div class="text">':</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">Total sold</div>
<div class="text">: </div>
<div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/sold" data-type="number" data-help="Number of items sold">1321.0</div>
<div class="data" data-tag="sold" data-xpath="/top/data3/item[sku = 'GRO-000-533'][name = 'fish']/sold" data-type="number" data-help="Number of items sold">1321.0</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">In stock</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/in-stock" data-type="number" data-help="Number of items in stock">45</div>
<div class="data" data-tag="in-stock" data-xpath="/top/data3/item[sku = 'GRO-000-533'][name = 'fish']/in-stock" data-type="number" data-help="Number of items in stock">45</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">On order</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/on-order" data-type="number" data-help="Number of items on order">1</div>
<div class="data" data-tag="on-order" data-xpath="/top/data3/item[sku = 'GRO-000-533'][name = 'fish']/on-order" data-type="number" data-help="Number of items on order">1</div>
</div>
<div class="line">
<div class="padding"> </div>
<div class="label">SKU</div>
<div class="text">: </div>
<div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-533</div>
<div class="data" data-tag="sku" data-xpath="/top/data3/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-533</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="item" data-xpath="/top/data/item">gum</div>
<div class="data" data-tag="item" data-xpath="/top/data4/item">gum</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="item" data-xpath="/top/data/item">rope</div>
<div class="data" data-tag="item" data-xpath="/top/data4/item">rope</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="item" data-xpath="/top/data/item">ladder</div>
<div class="data" data-tag="item" data-xpath="/top/data4/item">ladder</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="item" data-xpath="/top/data/item">bolt</div>
<div class="data" data-tag="item" data-xpath="/top/data4/item">bolt</div>
</div>
<div class="line">
<div class="label">Item</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="item" data-xpath="/top/data/item">water</div>
<div class="data" data-tag="item" data-xpath="/top/data4/item">water</div>
</div>
<div class="line">
<div class="text">X</div>

View file

@ -1,3 +1,10 @@
<div class="line">
<div class="text">Connecting to </div>
<div class="data" data-tag="host">my-box</div>
<div class="text">.</div>
<div class="data" data-tag="domain">example.com</div>
<div class="text">...</div>
</div>
<div class="line">
<div class="title">Item </div>
<div class="title"> Total Sold</div>

View file

@ -1,2 +1,2 @@
{"top": {"data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455}
{"top": {"host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455}
}

View file

@ -1,5 +1,7 @@
{
"top": {
"host": "my-box",
"domain": "example.com",
"data": {
"item": [
{
@ -39,7 +41,7 @@
}
]
},
"data": {
"data2": {
"item": [
{
"sku": "GRO-000-415",
@ -78,7 +80,7 @@
}
]
},
"data": {
"data3": {
"item": [
{
"sku": "GRO-000-533",
@ -89,7 +91,7 @@
}
]
},
"data": {
"data4": {
"item": [
"gum",
"rope",

View file

@ -1,3 +1,4 @@
Connecting to my-box.example.com...
Item Total Sold In Stock On Order SKU
gum 1412 54 10 GRO-000-415
rope 85 4 2 HRD-000-212

View file

@ -1 +1 @@
<top><data test="value"><item test2="value2"><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="key">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data><data><item test4="value4">gum</item><item test4="value4">rope</item><item test4="value4">ladder</item><item test4="value4">bolt</item><item test4="value4">water</item></data><cost>425</cost><cost>455</cost></top>
<top><host>my-box</host><domain>example.com</domain><data test="value"><item test2="value2"><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="key">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data2><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data2><data3><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data3><data4><item test4="value4">gum</item><item test4="value4">rope</item><item test4="value4">ladder</item><item test4="value4">bolt</item><item test4="value4">water</item></data4><cost>425</cost><cost>455</cost></top>

View file

@ -1,4 +1,6 @@
<top>
<host>my-box</host>
<domain>example.com</domain>
<data test="value">
<item test2="value2">
<sku test3="value3" key="key">GRO-000-415</sku>
@ -36,7 +38,7 @@
<on-order>2</on-order>
</item>
</data>
<data>
<data2>
<item>
<sku key="key">GRO-000-415</sku>
<name key="key">gum</name>
@ -72,8 +74,8 @@
<in-stock>14</in-stock>
<on-order>2</on-order>
</item>
</data>
<data>
</data2>
<data3>
<item>
<sku key="key">GRO-000-533</sku>
<name key="key">fish</name>
@ -81,14 +83,14 @@
<in-stock>45</in-stock>
<on-order>1</on-order>
</item>
</data>
<data>
</data3>
<data4>
<item test4="value4">gum</item>
<item test4="value4">rope</item>
<item test4="value4">ladder</item>
<item test4="value4">bolt</item>
<item test4="value4">water</item>
</data>
</data4>
<cost>425</cost>
<cost>455</cost>
</top>

View file

@ -0,0 +1,68 @@
op create: [] []
op open_container: [top] []
op open_container: [data] []
op string: [what] [braces]
op string: [length] [abcdef]
op content: [fd] [-1]
op string: [error] [Bad file descriptor]
op string: [test] [good]
op content: [fd] [-1]
op string: [error] [Bad fi]
op string: [test] [good]
op content: [lines] [20]
op content: [words] [30]
op content: [characters] [40]
op open_leaf_list: [bytes] []
op content: [bytes] [0]
op content: [bytes] [1]
op content: [bytes] [2]
op content: [bytes] [3]
op content: [bytes] [4]
op close_leaf_list: [bytes] []
op content: [mbuf-current] [10]
op content: [mbuf-cache] [20]
op content: [mbuf-total] [30]
op content: [distance] [50]
op string: [location] [Boston]
op content: [memory] [64]
op content: [total] [640]
op content: [memory] [64]
op content: [total] [640]
op content: [ten] [10]
op content: [eleven] [11]
op content: [unknown] [1010]
op content: [unknown] [1010]
op content: [min] [15]
op content: [cur] [20]
op content: [max] [30]
op content: [min] [15]
op content: [cur] [20]
op content: [max] [125]
op content: [min] [15]
op content: [cur] [20]
op content: [max] [125]
op content: [min] [15]
op content: [cur] [20]
op content: [max] [125]
op content: [val1] [21]
op content: [val2] [58368]
op content: [val3] [100663296]
op content: [val4] [44470272]
op content: [val5] [1342172800]
op open_list: [flag] []
op string: [flag] [one]
op string: [flag] [two]
op string: [flag] [three]
op close_list: [flag] []
op content: [works] [null]
op content: [empty-tag] [true]
op string: [t1] [1000]
op string: [t2] [test5000]
op string: [t3] [ten-longx]
op string: [t4] [xtest]
op content: [count] [10]
op content: [test] [4]
op close_container: [data] []
op close_container: [top] []
op finish: [] []
op flush: [] []

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,81 @@
<div class="line">
<div class="text">We are </div>
<div class="text">{emit}</div>
<div class="text">{ting}</div>
<div class="text"> some </div>
<div class="data" data-tag="what" data-xpath="/top/data/what">braces</div>
</div>
<div class="line">
<div class="message">abcdef
</div>
</div>
<div class="line">
<div class="message">abcdef: Bad file descriptor
</div>
</div>
<div class="line">
<div class="message">improper use of profanity; ten yard penalty; first down
</div>
</div>
<div class="line">
<div class="text">length </div>
<div class="data" data-tag="length" data-xpath="/top/data/length">abcdef</div>
</div>
<div class="line">
<div class="text">close </div>
<div class="data" data-tag="fd" data-xpath="/top/data/fd">-1</div>
<div class="text"> returned </div>
<div class="data" data-tag="error" data-xpath="/top/data/error">Bad file descriptor</div>
<div class="text"> </div>
<div class="data" data-tag="test" data-xpath="/top/data/test">good</div>
</div>
<div class="line">
<div class="text">close </div>
<div class="data" data-tag="fd" data-xpath="/top/data/fd">-1</div>
<div class="text"> returned </div>
<div class="data" data-tag="error" data-xpath="/top/data/error">Bad fi</div>
<div class="text"> </div>
<div class="data" data-tag="test" data-xpath="/top/data/test">good</div>
</div>
<div class="line">
<div class="message">improper use of profanity; ten yard penalty; first down
</div>
</div>
<div class="line">
<div class="text"> </div>
<div class="data" data-tag="lines" data-xpath="/top/data/lines"> 20</div>
<div class="text"> </div>
<div class="data" data-tag="words" data-xpath="/top/data/words"> 30</div>
<div class="text"> </div>
<div class="data" data-tag="characters" data-xpath="/top/data/characters"> 40</div>
<div class="text"> </div>
<div class="data" data-tag="filename" data-xpath="/top/data/filename">file</div>
</div>
<div class="line">
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">0</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">1</div>
<div class="padding"> </div>
<div class="note">byte</div>
</div>
<div class="line">
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">2</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">3</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">4</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="mbuf-current" data-xpath="/top/data/mbuf-current">10</div>
<div class="text">/</div>
@ -28,6 +106,8 @@
</div>
<div class="line">
<div class="data" data-tag="some" data-xpath="/top/data/some">string</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="ten" data-xpath="/top/data/ten">10</div>
<div class="data" data-tag="eleven" data-xpath="/top/data/eleven">11</div>
</div>
@ -36,6 +116,11 @@
<div class="text"> </div>
<div class="note">packets here/there/everywhere</div>
</div>
<div class="line">
<div class="data" data-tag="unknown" data-xpath="/top/data/unknown">1010</div>
<div class="text"> </div>
<div class="note">packets here/there/everywhere</div>
</div>
<div class="line">
<div class="text">(</div>
<div class="padding"> </div>
@ -76,6 +161,18 @@
<div class="padding"> </div>
<div class="text">)</div>
</div>
<div class="line">
<div class="text">Humanize: </div>
<div class="data" data-tag="val1" data-xpath="/top/data/val1" data-number="21">21</div>
<div class="text">, </div>
<div class="data" data-tag="val2" data-xpath="/top/data/val2" data-number="58368">57 K</div>
<div class="text">, </div>
<div class="data" data-tag="val3" data-xpath="/top/data/val3" data-number="100663296">96M</div>
<div class="text">, </div>
<div class="data" data-tag="val4" data-xpath="/top/data/val4" data-number="44470272">44M</div>
<div class="text">, </div>
<div class="data" data-tag="val5" data-xpath="/top/data/val5" data-number="1342172800">1.2G</div>
</div>
<div class="line">
<div class="data" data-tag="flag" data-xpath="/top/data/flag">one</div>
<div class="text"> </div>
@ -83,6 +180,9 @@
<div class="text"> </div>
<div class="data" data-tag="flag" data-xpath="/top/data/flag">three</div>
</div>
<div class="line">
<div class="data" data-tag="works" data-xpath="/top/data/works">(null)</div>
</div>
<div class="line">
<div class="text">1:</div>
<div class="data" data-tag="t1" data-xpath="/top/data/t1"> 1000</div>

View file

@ -1,3 +1,81 @@
<div class="line">
<div class="text">We are </div>
<div class="text">{emit}</div>
<div class="text">{ting}</div>
<div class="text"> some </div>
<div class="data" data-tag="what">braces</div>
</div>
<div class="line">
<div class="message">abcdef
</div>
</div>
<div class="line">
<div class="message">abcdef: Bad file descriptor
</div>
</div>
<div class="line">
<div class="message">improper use of profanity; ten yard penalty; first down
</div>
</div>
<div class="line">
<div class="text">length </div>
<div class="data" data-tag="length">abcdef</div>
</div>
<div class="line">
<div class="text">close </div>
<div class="data" data-tag="fd">-1</div>
<div class="text"> returned </div>
<div class="data" data-tag="error">Bad file descriptor</div>
<div class="text"> </div>
<div class="data" data-tag="test">good</div>
</div>
<div class="line">
<div class="text">close </div>
<div class="data" data-tag="fd">-1</div>
<div class="text"> returned </div>
<div class="data" data-tag="error">Bad fi</div>
<div class="text"> </div>
<div class="data" data-tag="test">good</div>
</div>
<div class="line">
<div class="message">improper use of profanity; ten yard penalty; first down
</div>
</div>
<div class="line">
<div class="text"> </div>
<div class="data" data-tag="lines"> 20</div>
<div class="text"> </div>
<div class="data" data-tag="words"> 30</div>
<div class="text"> </div>
<div class="data" data-tag="characters"> 40</div>
<div class="text"> </div>
<div class="data" data-tag="filename">file</div>
</div>
<div class="line">
<div class="data" data-tag="bytes">0</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="bytes">1</div>
<div class="padding"> </div>
<div class="note">byte</div>
</div>
<div class="line">
<div class="data" data-tag="bytes">2</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="bytes">3</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="bytes">4</div>
<div class="padding"> </div>
<div class="note">bytes</div>
</div>
<div class="line">
<div class="data" data-tag="mbuf-current">10</div>
<div class="text">/</div>
@ -28,6 +106,8 @@
</div>
<div class="line">
<div class="data" data-tag="some">string</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="ten">10</div>
<div class="data" data-tag="eleven">11</div>
</div>
@ -36,6 +116,11 @@
<div class="text"> </div>
<div class="note">packets here/there/everywhere</div>
</div>
<div class="line">
<div class="data" data-tag="unknown">1010</div>
<div class="text"> </div>
<div class="note">packets here/there/everywhere</div>
</div>
<div class="line">
<div class="text">(</div>
<div class="padding"> </div>
@ -76,6 +161,18 @@
<div class="padding"> </div>
<div class="text">)</div>
</div>
<div class="line">
<div class="text">Humanize: </div>
<div class="data" data-tag="val1" data-number="21">21</div>
<div class="text">, </div>
<div class="data" data-tag="val2" data-number="58368">57 K</div>
<div class="text">, </div>
<div class="data" data-tag="val3" data-number="100663296">96M</div>
<div class="text">, </div>
<div class="data" data-tag="val4" data-number="44470272">44M</div>
<div class="text">, </div>
<div class="data" data-tag="val5" data-number="1342172800">1.2G</div>
</div>
<div class="line">
<div class="data" data-tag="flag">one</div>
<div class="text"> </div>
@ -83,6 +180,9 @@
<div class="text"> </div>
<div class="data" data-tag="flag">three</div>
</div>
<div class="line">
<div class="data" data-tag="works">(null)</div>
</div>
<div class="line">
<div class="text">1:</div>
<div class="data" data-tag="t1"> 1000</div>

View file

@ -1,2 +1,2 @@
{"top": {"data": {"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"min":15,"cur":20,"max":30,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125, "flag": ["one","two","three"],"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest","count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}
{"top": {"data": {"what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":30,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":this is an warning}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}
}

View file

@ -1,6 +1,24 @@
{
"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,
@ -13,6 +31,7 @@
"ten": 10,
"eleven": 11,
"unknown": 1010,
"unknown": 1010,
"min": 15,
"cur": 20,
"max": 30,
@ -25,16 +44,34 @@
"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": {

View file

@ -1,15 +1,32 @@
We are {emit}{ting} some braces
abcdef
abcdef: Bad file descriptor
improper use of profanity; ten yard penalty; first down
length abcdef
close -1 returned Bad file descriptor good
close -1 returned Bad fi good
improper use of profanity; ten yard penalty; first down
20 30 40 file
0 bytes
1 byte
2 bytes
3 bytes
4 bytes
10/20/30 mbufs <&> in use (current/cache/total)
50 miles from Boston
64k left out of 640kb
64k left out of 640kilobytes
beforeworkingafter:
string1011
string: 1011
1010 packets here/there/everywhere
1010 packets here/there/everywhere
( 15/20/125)
( 15/20/125)
(15/20/125 )
(15/20/125 )
Humanize: 21, 57 K, 96M, 44M, 1.2G
one two three
(null)
1: 1000 2:test5000 3: ten-longx 4:xtest
this is an error
two more errors

View file

@ -1,3 +1,7 @@
<top><data><mbuf-current>10</mbuf-current><mbuf-cache>20</mbuf-cache><mbuf-total>30</mbuf-total><distance units="miles">50</distance><location>Boston</location><memory units="k">64</memory><total units="kb">640</total><memory units="k">64</memory><total units="kilobytes">640</total><ten>10</ten><eleven>11</eleven><unknown>1010</unknown><min>15</min><cur>20</cur><max>30</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><flag>one</flag><flag>two</flag><flag>three</flag><empty-tag></empty-tag><t1>1000</t1><t2>test5000</t2><t3>ten-longx</t3><t4>xtest</t4><error><message>this is an error</message></error><error><message>two more errors</message></error><warning><message>this is an warning</message></warning><warning><message>two more warnings</message></warning><count>10</count><test>4</test><message>improper use of profanity; ten yard penalty; first down</message>
<error><message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
<top><data><what>braces</what><message>abcdef
</message><message>abcdef: Bad file descriptor
</message><message>improper use of profanity; ten yard penalty; first down
</message><length>abcdef</length><fd>-1</fd><error>Bad file descriptor</error><test>good</test><fd>-1</fd><error>Bad fi</error><test>good</test><message>improper use of profanity; ten yard penalty; first down
</message><lines>20</lines><words>30</words><characters>40</characters><bytes>0</bytes><bytes>1</bytes><bytes>2</bytes><bytes>3</bytes><bytes>4</bytes><mbuf-current>10</mbuf-current><mbuf-cache>20</mbuf-cache><mbuf-total>30</mbuf-total><distance units="miles">50</distance><location>Boston</location><memory units="k">64</memory><total units="kb">640</total><memory units="k">64</memory><total units="kilobytes">640</total><ten>10</ten><eleven>11</eleven><unknown>1010</unknown><unknown>1010</unknown><min>15</min><cur>20</cur><max>30</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><val1>21</val1><val2>58368</val2><val3>100663296</val3><val4>44470272</val4><val5>1342172800</val5><flag>one</flag><flag>two</flag><flag>three</flag><works>null</works><empty-tag></empty-tag><t1>1000</t1><t2>test5000</t2><t3>ten-longx</t3><t4>xtest</t4><__error><message>this is an error</message></__error><__error><message>two more errors</message></__error><__warning><message>this is an warning</message></__warning><__warning><message>two more warnings</message></__warning><count>10</count><test>4</test><message>improper use of profanity; ten yard penalty; first down
</message><error><message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</message></error></data></top>

View file

@ -1,5 +1,29 @@
<top>
<data>
<what>braces</what>
<message>abcdef
</message>
<message>abcdef: Bad file descriptor
</message>
<message>improper use of profanity; ten yard penalty; first down
</message>
<length>abcdef</length>
<fd>-1</fd>
<error>Bad file descriptor</error>
<test>good</test>
<fd>-1</fd>
<error>Bad fi</error>
<test>good</test>
<message>improper use of profanity; ten yard penalty; first down
</message>
<lines>20</lines>
<words>30</words>
<characters>40</characters>
<bytes>0</bytes>
<bytes>1</bytes>
<bytes>2</bytes>
<bytes>3</bytes>
<bytes>4</bytes>
<mbuf-current>10</mbuf-current>
<mbuf-cache>20</mbuf-cache>
<mbuf-total>30</mbuf-total>
@ -12,6 +36,7 @@
<ten>10</ten>
<eleven>11</eleven>
<unknown>1010</unknown>
<unknown>1010</unknown>
<min>15</min>
<cur>20</cur>
<max>30</max>
@ -24,29 +49,36 @@
<min>15</min>
<cur>20</cur>
<max>125</max>
<val1>21</val1>
<val2>58368</val2>
<val3>100663296</val3>
<val4>44470272</val4>
<val5>1342172800</val5>
<flag>one</flag>
<flag>two</flag>
<flag>three</flag>
<works>null</works>
<empty-tag></empty-tag>
<t1>1000</t1>
<t2>test5000</t2>
<t3>ten-longx</t3>
<t4>xtest</t4>
<error>
<__error>
<message>this is an error</message>
</error>
<error>
</__error>
<__error>
<message>two more errors</message>
</error>
<warning>
</__error>
<__warning>
<message>this is an warning</message>
</warning>
<warning>
</__warning>
<__warning>
<message>two more warnings</message>
</warning>
</__warning>
<count>10</count>
<test>4</test>
<message>improper use of profanity; ten yard penalty; first down</message>
<message>improper use of profanity; ten yard penalty; first down
</message>
<error>
<message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</message>

View file

@ -0,0 +1,22 @@
op create: [] []
op open_container: [employees] []
op open_list: [employee] []
op open_instance: [employee] []
op string: [first-name] [Terry]
op string: [last-name] [Jones]
op content: [department] [660]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Leslie]
op string: [last-name] [Patterson]
op content: [department] [341]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Ashley]
op string: [last-name] [Smith]
op content: [department] [1440]
op close_instance: [employee] []
op close_list: [employee] []
op close_container: [employees] []
op finish: [] []
op flush: [] []

View file

@ -0,0 +1,22 @@
op create: [] []
op open_container: [employees] []
op open_list: [employee] []
op open_instance: [employee] []
op string: [first-name] [Terry]
op string: [last-name] [Jones]
op content: [department] [660]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Leslie]
op string: [last-name] [Patterson]
op content: [department] [341]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Ashley]
op string: [last-name] [Smith]
op content: [department] [1440]
op close_instance: [employee] []
op close_list: [employee] []
op close_container: [employees] []
op finish: [] []
op flush: [] []

View file

@ -0,0 +1,96 @@
op create: [] []
op open_container: [indian-languages] []
op string: [gurmukhi] [ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।]
op string: [shahmukhi] [لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔]
op string: [tranliteration] [lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.]
op close_container: [indian-languages] []
op open_container: [employees] []
op open_leaf_list: [wc] []
op string: [wc] [෴ - 0xdf4 - 1]
op string: [wc] [ණ - 0xdab - 1]
op string: [wc] [් - 0xdca - 0]
op string: [wc] [ණ - 0xdab - 1]
op string: [wc] [្ - 0x17d2 - 0]
op string: [wc] [෴ - 0xdf4 - 1]
op string: [wc] [1 - 0x31 - 1]
op string: [wc] [͏ - 0x34f - 0]
op string: [wc] [2 - 0x32 - 1]
op string: [wc] [⃝ - 0x20dd - 0]
op close_leaf_list: [wc] []
op string: [fancy] [1͏2⃝]
op string: [v1] [γιγνώσκειν]
op string: [v2] [ὦ ἄνδρες ᾿Αθηναῖοι]
op string: [v1] [ახლავე გაიაროთ რეგისტრაცია]
op string: [v2] [Unicode-ის მეათე საერთაშორისო]
op content: [width] [55]
op string: [sinhala] [෴ණ්ණ෴]
op content: [width] [4]
op string: [sinhala] [෴]
op content: [width] [1]
op string: [sinhala] [෴ණ්ණ෴෴ණ්ණ෴]
op content: [width] [8]
op string: [not-sinhala] [123456]
op string: [tag] [ර්‍ඝ]
op content: [width] [2]
op open_list: [employee] []
op open_instance: [employee] []
op string: [first-name] [Jim]
op string: [nic-name] ["რეგტ"]
op string: [last-name] [გთხოვთ ახ]
op content: [department] [431]
op content: [percent-time] [90]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Terry]
op string: [nic-name] ["<one"]
op string: [last-name] [Οὐχὶ ταὐτὰ παρίσταταί μοι Jones]
op content: [department] [660]
op content: [percent-time] [90]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Leslie]
op string: [nic-name] ["Les"]
op string: [last-name] [Patterson]
op content: [department] [341]
op content: [percent-time] [60]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Ashley]
op string: [nic-name] ["Ash"]
op string: [last-name] [Meter & Smith]
op content: [department] [1440]
op content: [percent-time] [40]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [0123456789]
op string: [nic-name] ["0123456789"]
op string: [last-name] [012345678901234567890]
op content: [department] [1440]
op content: [percent-time] [40]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [ახლა]
op string: [nic-name] ["გაიარო"]
op string: [last-name] [საერთაშორისო]
op content: [department] [123]
op content: [percent-time] [90]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [෴ණ්ණ෴෴ණ්ණ෴]
op string: [nic-name] ["Mick"]
op string: [last-name] [෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴]
op content: [department] [110]
op content: [percent-time] [20]
op close_instance: [employee] []
op close_list: [employee] []
op close_container: [employees] []
op finish: [] []
op flush: [] []

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,73 @@
<div class="line">
<div class="title">Sample text</div>
</div>
<div class="line">
<div class="text">This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.</div>
</div>
<div class="line">
<div class="title">Gurmukhi:</div>
</div>
<div class="line">
<div class="data" data-tag="gurmukhi" data-xpath="/indian-languages/gurmukhi">ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।</div>
</div>
<div class="line">
<div class="title">Shahmukhi:</div>
</div>
<div class="line">
<div class="data" data-tag="shahmukhi" data-xpath="/indian-languages/shahmukhi">لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔</div>
</div>
<div class="line">
<div class="title">Transliteration</div>
<div class="text">:</div>
</div>
<div class="line">
<div class="data" data-tag="tranliteration" data-xpath="/indian-languages/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ēṛē ē.</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">෴ - 0xdf4 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">ණ - 0xdab - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">් - 0xdca - 0</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">ණ - 0xdab - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">្ - 0x17d2 - 0</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">෴ - 0xdf4 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">1 - 0x31 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">͏ - 0x34f - 0</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">2 - 0x32 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc" data-xpath="/employees/wc">⃝ - 0x20dd - 0</div>
</div>
<div class="line">
<div class="text">Cool: [</div>
<div class="data" data-tag="fancy" data-xpath="/employees/fancy">1͏2⃝</div>
<div class="text">]</div>
</div>
<div class="line">
<div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div>
<div class="data" data-tag="v1" data-xpath="/employees/v1">γιγνώσκειν</div>
@ -25,7 +95,7 @@
<div class="title">Width</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="width" data-xpath="/employees/width">7</div>
<div class="data" data-tag="width" data-xpath="/employees/width">6</div>
</div>
<div class="line">
<div class="text">[</div>
@ -40,9 +110,15 @@
</div>
<div class="line">
<div class="text">[</div>
<div class="data" data-tag="sinhala" data-xpath="/employees/sinhala">෴ණ්ණ</div>
<div class="data" data-tag="sinhala" data-xpath="/employees/sinhala">෴ණ්ණ</div>
<div class="text">]</div>
</div>
<div class="line">
<div class="title">Width</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="width" data-xpath="/employees/width">6</div>
</div>
<div class="line">
<div class="text">[</div>
<div class="data" data-tag="not-sinhala" data-xpath="/employees/not-sinhala">1234</div>
@ -57,7 +133,7 @@
<div class="title">Width</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="width" data-xpath="/employees/width">5</div>
<div class="data" data-tag="width" data-xpath="/employees/width">4</div>
</div>
<div class="line">
<div class="title">First Name </div>
@ -129,8 +205,8 @@
<div class="text"> (</div>
<div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"Mick"</div>
<div class="text">)</div>
<div class="padding"> </div>
<div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ</div>
<div class="padding"> </div>
<div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴</div>
<div class="data" data-tag="department" data-xpath="/employees/employee/department"> 110</div>
<div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full &amp; part time (%)"> 20</div>
</div>

View file

@ -1,3 +1,73 @@
<div class="line">
<div class="title">Sample text</div>
</div>
<div class="line">
<div class="text">This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.</div>
</div>
<div class="line">
<div class="title">Gurmukhi:</div>
</div>
<div class="line">
<div class="data" data-tag="gurmukhi">ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।</div>
</div>
<div class="line">
<div class="title">Shahmukhi:</div>
</div>
<div class="line">
<div class="data" data-tag="shahmukhi">لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔</div>
</div>
<div class="line">
<div class="title">Transliteration</div>
<div class="text">:</div>
</div>
<div class="line">
<div class="data" data-tag="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ēṛē ē.</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">෴ - 0xdf4 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">ණ - 0xdab - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">් - 0xdca - 0</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">ණ - 0xdab - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">្ - 0x17d2 - 0</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">෴ - 0xdf4 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">1 - 0x31 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">͏ - 0x34f - 0</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">2 - 0x32 - 1</div>
</div>
<div class="line">
<div class="text">Wide char: </div>
<div class="data" data-tag="wc">⃝ - 0x20dd - 0</div>
</div>
<div class="line">
<div class="text">Cool: [</div>
<div class="data" data-tag="fancy">1͏2⃝</div>
<div class="text">]</div>
</div>
<div class="line">
<div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div>
<div class="data" data-tag="v1">γιγνώσκειν</div>
@ -25,7 +95,7 @@
<div class="title">Width</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="width">7</div>
<div class="data" data-tag="width">6</div>
</div>
<div class="line">
<div class="text">[</div>
@ -40,9 +110,15 @@
</div>
<div class="line">
<div class="text">[</div>
<div class="data" data-tag="sinhala">෴ණ්ණ</div>
<div class="data" data-tag="sinhala">෴ණ්ණ</div>
<div class="text">]</div>
</div>
<div class="line">
<div class="title">Width</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="width">6</div>
</div>
<div class="line">
<div class="text">[</div>
<div class="data" data-tag="not-sinhala">1234</div>
@ -57,7 +133,7 @@
<div class="title">Width</div>
<div class="decoration">:</div>
<div class="padding"> </div>
<div class="data" data-tag="width">5</div>
<div class="data" data-tag="width">4</div>
</div>
<div class="line">
<div class="title">First Name </div>
@ -129,8 +205,8 @@
<div class="text"> (</div>
<div class="data" data-tag="nic-name">"Mick"</div>
<div class="text">)</div>
<div class="padding"> </div>
<div class="data" data-tag="last-name">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ</div>
<div class="padding"> </div>
<div class="data" data-tag="last-name">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴</div>
<div class="data" data-tag="department"> 110</div>
<div class="data" data-tag="percent-time"> 20</div>
</div>

View file

@ -1,2 +1,3 @@
{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":5,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","not-sinhala":"123456","tag":"ර්‍ඝ","width":3, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<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}]}
}

View file

@ -1,18 +1,38 @@
{
"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": 5,
"width": 4,
"sinhala": "෴",
"width": 1,
"sinhala": "෴ණ්ණ෴෴ණ්ණ෴",
"width": 8,
"not-sinhala": "123456",
"tag": "ර්‍ඝ",
"width": 3,
"width": 2,
"employee": [
{
"first-name": "Jim",

View file

@ -1,14 +1,34 @@
Sample text
This sample text was taken from the Punjabi Wikipedia article on Lahore and transliterated into the Latin script.
Gurmukhi:
ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।
Shahmukhi:
لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔
Transliteration:
lahor pākistān panjāb dā dārul hakūmat ē. lōk giṇtī dē nāḷ karācī tō᷈ bāad lahor dūjā sab tō᷈ vaḍḍā shahr ē. lahor pākistān dā siāsī, rahtalī tē paṛā̀ī dā gā́ṛ ē tē is laī ihnū᷈ pākistān dā dil vī kehā jāndā ē. lahor dariāē rāvī dē kanḍē tē vasdā ē. isdī lōk giṇtī ikk karōṛ dē nēṛē ē.
Wide char: ෴ - 0xdf4 - 1
Wide char: ණ - 0xdab - 1
Wide char: ් - 0xdca - 0
Wide char: ණ - 0xdab - 1
Wide char: ្ - 0x17d2 - 0
Wide char: ෴ - 0xdf4 - 1
Wide char: 1 - 0x31 - 1
Wide char: ͏ - 0x34f - 0
Wide char: 2 - 0x32 - 1
Wide char: ⃝ - 0x20dd - 0
Cool: [1͏2⃝]
Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
Width: 63
[෴ණ්ණ෴]
Width: 7
Width: 6
[෴]
Width: 3
[෴ණ්ණ]
[෴ණ්ණ෴]
Width: 6
[1234]
[ර්‍ඝ]
Width: 5
Width: 4
First Name Last Name Department Time (%)
Jim ("რეგტ") გთხოვთ ახ 431 90
Terry ("<one") Οὐχὶ ταὐτὰ παρ 660 90
@ -16,4 +36,4 @@ Leslie ("Les") Patterson 341 60
Ashley ("Ash") Meter & Smith 1440 40
0123456789 ("0123456789")01234567890123 1440 40
ახლა ("გაიარო") საერთაშორისო 123 90
෴ණ්ණ෴෴ණ්ණ෴ ("Mick") ෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ 110 20
෴ණ්ණ෴෴ණ්ණ෴ ("Mick") ෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴ 110 20

View file

@ -1 +1 @@
<employees><v1>γιγνώσκειν</v1><v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2><v1>ახლავე გაიაროთ რეგისტრაცია</v1><v2>Unicode-ის მეათე საერთაშორისო</v2><width>55</width><sinhala>෴ණ්ණ෴</sinhala><width>5</width><sinhala>෴</sinhala><width>1</width><sinhala>෴ණ්ණ෴෴ණ්ණ෴</sinhala><not-sinhala>123456</not-sinhala><tag>ර්‍ඝ</tag><width>3</width><employee><first-name>Jim</first-name><nic-name>"რეგტ"</nic-name><last-name>გთხოვთ ახ</last-name><department>431</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Terry</first-name><nic-name>"&lt;one"</nic-name><last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name><department>660</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Leslie</first-name><nic-name>"Les"</nic-name><last-name>Patterson</last-name><department>341</department><percent-time>60</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Ashley</first-name><nic-name>"Ash"</nic-name><last-name>Meter &amp; Smith</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>0123456789</first-name><nic-name>"0123456789"</nic-name><last-name>012345678901234567890</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>ახლა</first-name><nic-name>"გაიარო"</nic-name><last-name>საერთაშორისო</last-name><department>123</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>෴ණ්ණ෴෴ණ්ණ෴</first-name><nic-name>"Mick"</nic-name><last-name>෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴</last-name><department>110</department><percent-time>20</percent-time></employee></employees>
<indian-languages><gurmukhi>ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।</gurmukhi><shahmukhi>لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔</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ēṛē ē.</tranliteration></indian-languages><employees><wc>෴ - 0xdf4 - 1</wc><wc>ණ - 0xdab - 1</wc><wc>් - 0xdca - 0</wc><wc>ණ - 0xdab - 1</wc><wc>្ - 0x17d2 - 0</wc><wc>෴ - 0xdf4 - 1</wc><wc>1 - 0x31 - 1</wc><wc>͏ - 0x34f - 0</wc><wc>2 - 0x32 - 1</wc><wc>⃝ - 0x20dd - 0</wc><fancy>1͏2⃝</fancy><v1>γιγνώσκειν</v1><v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2><v1>ახლავე გაიაროთ რეგისტრაცია</v1><v2>Unicode-ის მეათე საერთაშორისო</v2><width>55</width><sinhala>෴ණ්ණ෴</sinhala><width>4</width><sinhala>෴</sinhala><width>1</width><sinhala>෴ණ්ණ෴෴ණ්ණ෴</sinhala><width>8</width><not-sinhala>123456</not-sinhala><tag>ර්‍ඝ</tag><width>2</width><employee><first-name>Jim</first-name><nic-name>"რეგტ"</nic-name><last-name>გთხოვთ ახ</last-name><department>431</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Terry</first-name><nic-name>"&lt;one"</nic-name><last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name><department>660</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Leslie</first-name><nic-name>"Les"</nic-name><last-name>Patterson</last-name><department>341</department><percent-time>60</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Ashley</first-name><nic-name>"Ash"</nic-name><last-name>Meter &amp; Smith</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>0123456789</first-name><nic-name>"0123456789"</nic-name><last-name>012345678901234567890</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>ახლა</first-name><nic-name>"გაიარო"</nic-name><last-name>საერთაშორისო</last-name><department>123</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>෴ණ්ණ෴෴ණ්ණ෴</first-name><nic-name>"Mick"</nic-name><last-name>෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴</last-name><department>110</department><percent-time>20</percent-time></employee></employees>

View file

@ -1,17 +1,34 @@
<indian-languages>
<gurmukhi>ਲਹੌਰ ਪਾਕਿਸਤਾਨੀ ਪੰਜਾਬ ਦੀ ਰਾਜਧਾਨੀ ਹੈ । ਲੋਕ ਗਿਣਤੀ ਦੇ ਨਾਲ ਕਰਾਚੀ ਤੋਂ ਬਾਅਦ ਲਹੌਰ ਦੂਜਾ ਸਭ ਤੋਂ ਵੱਡਾ ਸ਼ਹਿਰ ਹੈ । ਲਹੌਰ ਪਾਕਿਸਤਾਨ ਦਾ ਸਿਆਸੀ, ਰਹਤਲੀ ਤੇ ਪੜ੍ਹਾਈ ਦਾ ਗੜ੍ਹ ਹੈ ਅਤੇ ਇਸ ਲਈ ਇਹਨੂੰ ਪਾਕਿਸਤਾਨ ਦਾ ਦਿਲ ਵੀ ਕਿਹਾ ਜਾਂਦਾ ਹੈ । ਲਹੌਰ ਦਰਿਆ-ਏ-ਰਾਵੀ ਦੇ ਕੰਢੇ ਤੇ ਵਸਦਾ ਹੈ ਤੇ ਇਸਦੀ ਲੋਕ ਗਿਣਤੀ ਇੱਕ ਕਰੋੜ ਦੇ ਨੇੜੇ ਹੈ ।</gurmukhi>
<shahmukhi>لہور پاکستانی پنجاب دا دارالحکومت اے۔ لوک گنتی دے نال کراچی توں بعد لہور دوجا سبھ توں وڈا شہر اے۔ لہور پاکستان دا سیاسی، رہتلی تے پڑھائی دا گڑھ اے تے اس لئی ایھنوں پاکستان دا دل وی کیھا جاندا اے۔ لہور دریاۓ راوی دے کنڈھے تے وسدا اے اسدی لوک گنتی اک کروڑ دے نیڑے اے ۔</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ēṛē ē.</tranliteration>
</indian-languages>
<employees>
<wc>෴ - 0xdf4 - 1</wc>
<wc>ණ - 0xdab - 1</wc>
<wc>් - 0xdca - 0</wc>
<wc>ණ - 0xdab - 1</wc>
<wc>្ - 0x17d2 - 0</wc>
<wc>෴ - 0xdf4 - 1</wc>
<wc>1 - 0x31 - 1</wc>
<wc>͏ - 0x34f - 0</wc>
<wc>2 - 0x32 - 1</wc>
<wc>⃝ - 0x20dd - 0</wc>
<fancy>1͏2⃝</fancy>
<v1>γιγνώσκειν</v1>
<v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2>
<v1>ახლავე გაიაროთ რეგისტრაცია</v1>
<v2>Unicode-ის მეათე საერთაშორისო</v2>
<width>55</width>
<sinhala>෴ණ්ණ෴</sinhala>
<width>5</width>
<width>4</width>
<sinhala>෴</sinhala>
<width>1</width>
<sinhala>෴ණ්ණ෴෴ණ්ණ෴</sinhala>
<width>8</width>
<not-sinhala>123456</not-sinhala>
<tag>ර්‍ඝ</tag>
<width>3</width>
<width>2</width>
<employee>
<first-name>Jim</first-name>
<nic-name>"რეგტ"</nic-name>

View file

@ -0,0 +1,22 @@
op create: [] []
op open_container: [employees] []
op open_list: [employee] []
op open_instance: [employee] []
op string: [first-name] [Terry]
op string: [last-name] [Jones]
op content: [department] [660]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Leslie]
op string: [last-name] [Patterson]
op content: [department] [341]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Ashley]
op string: [last-name] [Smith]
op content: [department] [1440]
op close_instance: [employee] []
op close_list: [employee] []
op close_container: [employees] []
op finish: [] []
op flush: [] []

View file

@ -0,0 +1,76 @@
op create: [] []
op open_container: [employees] []
op open_list: [test] []
op open_instance: [test] []
op string: [filename] [(null)]
op close_instance: [test] []
op close_list: [test] []
op string: [v1] [γιγνώσκειν]
op string: [v2] [ὦ ἄνδρες ᾿Αθηναῖοι]
op content: [columns] [28]
op content: [columns] [2]
op string: [v1] [ახლავე გაიაროთ რეგისტრაცია]
op string: [v2] [Unicode-ის მეათე საერთაშორისო]
op content: [columns] [55]
op content: [columns] [0]
op open_list: [employee] []
op open_instance: [employee] []
op string: [first-name] [Jim]
op string: [nic-name] ["რეგტ"]
op string: [last-name] [გთხოვთ ახ]
op content: [department] [431]
op content: [percent-time] [90]
op content: [columns] [23]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Terry]
op string: [nic-name] ["<one"]
op string: [last-name] [Οὐχὶ ταὐτὰ παρίσταταί μοι Jones]
op content: [department] [660]
op content: [percent-time] [90]
op content: [columns] [47]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Leslie]
op string: [nic-name] ["Les"]
op string: [last-name] [Patterson]
op content: [department] [341]
op content: [percent-time] [60]
op content: [columns] [25]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [Ashley]
op string: [nic-name] ["Ash"]
op string: [last-name] [Meter & Smith]
op content: [department] [1440]
op content: [percent-time] [40]
op content: [columns] [30]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [0123456789]
op string: [nic-name] ["0123456789"]
op string: [last-name] [012345678901234567890]
op content: [department] [1440]
op content: [percent-time] [40]
op content: [columns] [49]
op close_instance: [employee] []
op open_instance: [employee] []
op string: [first-name] [ახლა]
op string: [nic-name] ["გაიარო"]
op string: [last-name] [საერთაშორისო]
op content: [department] [123]
op content: [percent-time] [90]
op content: [columns] [29]
op attr: [full-time] [honest & for true]
op string: [benefits] [full]
op close_instance: [employee] []
op close_list: [employee] []
op close_container: [employees] []
op finish: [] []
op flush: [] []

View file

@ -0,0 +1,18 @@
test: close (xo_close_container) fails at marker 'm1'; not found 'data3'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm1'; not found 'data4'
test: close (xo_close_container) fails at marker 'm1'; not found 'top'

View file

@ -0,0 +1,186 @@
op create: [] []
op open_container: [top] []
op open_container: [data] []
op open_container: [contents] []
op open_list: [item] []
op open_instance: [item] []
op string: [name] [gum]
op content: [count] [1412]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [rope]
op content: [count] [85]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [ladder]
op content: [count] [0]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [bolt]
op content: [count] [4123]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [water]
op content: [count] [17]
op close_instance: [item] []
op close_list: [item] []
op close_container: [contents] []
op close_container: [data] []
op open_container: [data2] []
op open_container: [contents] []
op open_list: [item] []
op open_instance: [item] []
op string: [name] [gum]
op content: [count] [1412]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [rope]
op content: [count] [85]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [ladder]
op content: [count] [0]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [bolt]
op content: [count] [4123]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [water]
op content: [count] [17]
op close_instance: [item] []
op close_list: [item] []
op close_container: [contents] []
op close_container: [data2] []
op open_container: [data3] []
op open_container: [contents] []
op open_list: [item] []
op open_instance: [item] []
op string: [name] [gum]
op content: [count] [1412]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [rope]
op content: [count] [85]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [ladder]
op content: [count] [0]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [bolt]
op content: [count] [4123]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [water]
op content: [count] [17]
op string: [test] [one]
op close_instance: [item] []
op close_list: [item] []
op close_container: [contents] []
op close_container: [data3] []
op open_container: [data4] []
op open_container: [contents] []
op open_list: [item] []
op open_instance: [item] []
op string: [name] [gum]
op content: [count] [1412]
op open_list: [sub] []
op open_instance: [sub] []
op content: [name] [0]
op content: [next] [1]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [1]
op content: [next] [2]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [2]
op content: [next] [3]
op close_instance: [sub] []
op close_list: [sub] []
op content: [last] [3]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [rope]
op content: [count] [85]
op open_list: [sub] []
op open_instance: [sub] []
op content: [name] [0]
op content: [next] [1]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [1]
op content: [next] [2]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [2]
op content: [next] [3]
op close_instance: [sub] []
op close_list: [sub] []
op content: [last] [3]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [ladder]
op content: [count] [0]
op open_list: [sub] []
op open_instance: [sub] []
op content: [name] [0]
op content: [next] [1]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [1]
op content: [next] [2]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [2]
op content: [next] [3]
op close_instance: [sub] []
op close_list: [sub] []
op content: [last] [3]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [bolt]
op content: [count] [4123]
op open_list: [sub] []
op open_instance: [sub] []
op content: [name] [0]
op content: [next] [1]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [1]
op content: [next] [2]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [2]
op content: [next] [3]
op close_instance: [sub] []
op close_list: [sub] []
op content: [last] [3]
op close_instance: [item] []
op open_instance: [item] []
op string: [name] [water]
op content: [count] [17]
op open_list: [sub] []
op open_instance: [sub] []
op content: [name] [0]
op content: [next] [1]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [1]
op content: [next] [2]
op close_instance: [sub] []
op open_instance: [sub] []
op content: [name] [2]
op content: [next] [3]
op close_instance: [sub] []
op close_list: [sub] []
op content: [last] [3]
op string: [test] [one]
op close_instance: [item] []
op close_list: [item] []
op close_container: [contents] []
op close_container: [data4] []
op close_container: [top] []
op finish: [] []
op flush: [] []

View file

@ -1,18 +1,18 @@
test: close (xo_close_container) fails at marker 'm1'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm1'; not found 'data'
test: close (xo_close_container) fails at marker 'm1'; not found 'data3'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm1'; not found 'data4'
test: close (xo_close_container) fails at marker 'm1'; not found 'top'

View file

@ -1,18 +1,18 @@
test: close (xo_close_container) fails at marker 'm1'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm2'; not found 'data'
test: close (xo_close_container) fails at marker 'm1'; not found 'data'
test: close (xo_close_container) fails at marker 'm1'; not found 'data3'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm2'; not found 'data4'
test: close (xo_close_container) fails at marker 'm1'; not found 'data4'
test: close (xo_close_container) fails at marker 'm1'; not found 'top'

Some files were not shown because too many files have changed in this diff Show more