diff --git a/contrib/libxo/.gitignore b/contrib/libxo/.gitignore index 8d70b6cc155..f4ace8fe0a8 100644 --- a/contrib/libxo/.gitignore +++ b/contrib/libxo/.gitignore @@ -1,46 +1,32 @@ -# Object files -*.o - -# Libraries -*.lib -*.a - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.app - -*~ -*.orig - +tag.sh +Makefile.in aclocal.m4 ar-lib autom4te.cache -build +bin +build* compile +configure config.guess -config.h.in config.sub depcomp +doc/Makefile.in +info* install-sh ltmain.sh -missing m4 - -Makefile.in -configure -.DS_Store - -xoconfig.h.in -xo_config.h.in - -.gdbinit -.gdbinit.local -xtest -xtest.dSYM -tests/w +missing +patches* +doc/Makefile.in +encoder/Makefile.in +encoder/cbor/Makefile.in +encoder/test/Makefile.in +libxo/Makefile.in +tests/Makefile.in +tests/core/Makefile.in +tests/gettext/Makefile.in +tests/xo/Makefile.in +xo/Makefile.in +xohtml/Makefile.in +xolint/Makefile.in +xopo/Makefile.in diff --git a/contrib/libxo/.svnignore b/contrib/libxo/.svnignore deleted file mode 100644 index 8327c93fdd1..00000000000 --- a/contrib/libxo/.svnignore +++ /dev/null @@ -1,18 +0,0 @@ -Makefile.in -aclocal.m4 -ar-lib -autom4te.cache -bin* -build* -compile -configure -config.guess -config.sub -depcomp -doc/Makefile.in -info* -install-sh -ltmain.sh -m4 -missing -patches* diff --git a/contrib/libxo/Makefile.am b/contrib/libxo/Makefile.am index 8a524738858..617e3b1af87 100644 --- a/contrib/libxo/Makefile.am +++ b/contrib/libxo/Makefile.am @@ -10,7 +10,7 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libxo xo xopo xolint xohtml tests doc encoder +SUBDIRS = bin libxo xo xopo xolint xohtml tests doc encoder bin_SCRIPTS=libxo-config dist_doc_DATA = Copyright diff --git a/contrib/libxo/configure.ac b/contrib/libxo/configure.ac index e28db939608..2f5681d4276 100644 --- a/contrib/libxo/configure.ac +++ b/contrib/libxo/configure.ac @@ -11,8 +11,8 @@ # a particular user has the dist or svn release. # -AC_PREREQ(2.2) -AC_INIT([libxo], [1.4.0], [phil@juniper.net]) +AC_PREREQ([2.69]) +AC_INIT([libxo],[1.6.0],[phil@juniper.net]) AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability]) # Support silent build rules. Requires at least automake-1.11. @@ -38,8 +38,6 @@ AC_PATH_PROG(MV, mv, /bin/mv) AC_PATH_PROG(RM, rm, /bin/rm) AC_PATH_PROG(SED, sed, /bin/sed) -AC_STDC_HEADERS - # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE AC_TYPE_SIZE_T @@ -335,9 +333,10 @@ AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"]) AC_MSG_CHECKING([compiler for gcc]) HAVE_GCC=no if test "${CC}" != ""; then - HAVE_GCC=`${CC} --version 2>&1 | grep GCC` + HAVE_GCC=`${CC} --version 2>&1 | grep -i GCC` if test "${HAVE_GCC}" != ""; then HAVE_GCC=yes + AC_DEFINE([HAVE_GCC], [1], [Using real gcc]) else HAVE_GCC=no fi @@ -450,6 +449,7 @@ AC_CONFIG_FILES([ xohtml/xohtml.sh libxo/Makefile libxo/add.man + bin/Makefile encoder/Makefile encoder/cbor/Makefile encoder/csv/Makefile diff --git a/contrib/libxo/doc/Makefile.am b/contrib/libxo/doc/Makefile.am index eb9ce364653..dcd155e95f2 100644 --- a/contrib/libxo/doc/Makefile.am +++ b/contrib/libxo/doc/Makefile.am @@ -8,7 +8,7 @@ # using the SOFTWARE, you agree to be bound by the terms of that # LICENSE. -doc docs: xolint.rst html +doc docs: xolint-errors.rst html # # The contents of xolint.rst is generated based on xolint.pl, since we @@ -17,8 +17,8 @@ doc docs: xolint.rst html # the developer needs to commit any changes. # -xolint.rst: ${top_srcdir}/xolint/xolint.pl - perl ${top_srcdir}/xolint/xolint.pl -D > ${top_srcdir}/doc/xolint.rst +xolint-errors.rst: ${top_srcdir}/xolint/xolint.pl + perl ${top_srcdir}/xolint/xolint.pl -D > ${top_srcdir}/doc/xolint-errors.rst SPHINX = python3 -msphinx diff --git a/contrib/libxo/doc/api.rst b/contrib/libxo/doc/api.rst index 94358489f07..8a9b7bb5cef 100644 --- a/contrib/libxo/doc/api.rst +++ b/contrib/libxo/doc/api.rst @@ -386,19 +386,18 @@ xo_destroy Emitting Content (xo_emit) -------------------------- -The functions in this section are used to emit output. - -The "fmt" argument is a string containing field descriptors as -specified in :ref:`format-strings`. The use of a handle is optional and -`NULL` can be passed to access the internal "default" handle. See +The functions in this section are used to emit output. They use a +`format` string containing field descriptors as specified in +:ref:`format-strings`. The use of a handle is optional and `NULL` can +be passed to access the internal "default" handle. See :ref:`handles`. The remaining arguments to `xo_emit` and `xo_emit_h` are a set of arguments corresponding to the fields in the format string. Care must be taken to ensure the argument types match the fields in the format -string, since an inappropriate cast can ruin your day. The vap -argument to `xo_emit_hv` points to a variable argument list that can -be used to retrieve arguments via `va_arg`. +string, since an inappropriate or missing argument can ruin your day. +The `vap` argument to `xo_emit_hv` points to a variable argument list +that can be used to retrieve arguments via `va_arg`. .. c:function:: xo_ssize_t xo_emit (const char *fmt, ...) @@ -428,19 +427,40 @@ be used to retrieve arguments via `va_arg`. Single Field Emitting Functions (xo_emit_field) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The functions in this section can also make output, but only make a -single field at a time. These functions are intended to avoid the -scenario where one would otherwise need to compose a format -descriptors using `snprintf`. The individual parts of the format -descriptor are passed in distinctly. +The functions in this section emit formatted output similar to +`xo_emit` but where `xo_emit` uses a single string argument containing +the description for multiple fields, `xo_emit_field` emits a single +field using multiple ar- guments to contain the field description. +`xo_emit_field_h` adds an ex- plicit handle to use instead of the +default handle, while `xo_emit_field_hv` accepts a va_list for +additional flexibility. -.. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...) +The arguments `rolmod`, `content`, `fmt`, and `efmt` are detailed in +:ref:`field-formatting`. Using distinct arguments allows callers to +pass the field description in pieces, rather than having to use +something like `snprintf` to build the format string required by +`xo_emit`. The arguments are each NUL-terminated strings. The `rolmod` +argument contains the `role` and `modifier` portions of the field +description, the `content` argument contains the `content` portion, and +the `fmt` and `efmt` contain the `field-format` and `encoding-format` por- +tions, respectively. + +As with `xo_emit`, the `fmt` and `efmt` values are both optional, +since the `field-format` string defaults to "%s", and the +`encoding-format`'s default value is derived from the `field-format` +per :ref:`field-formatting`. However, care must be taken to avoid +using a value directly as the format, since characters like '{', '%', +and '}' will be interpreted as formatting directives, and may cause +xo_emit_field to dereference arbitrary values off the stack, leading +to bugs, core files, and gnashing of teeth. + +.. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *content, const char *fmt, const char *efmt, ...) :param rolmod: A comma-separated list of field roles and field modifiers :type rolmod: const char * - :param contents: The "contents" portion of the field description string - :type contents: const char * - :param fmt: Content format string + :param content: The "content" portion of the field description string + :type content: const char * + :param fmt: Contents format string :type fmt: const char * :param efmt: Encoding format string, followed by additional arguments :type efmt: const char * @@ -450,8 +470,11 @@ descriptor are passed in distinctly. :: EXAMPLE:: + xo_emit_field("T", title, NULL, NULL, NULL); xo_emit_field("T", "Host name is ", NULL, NULL); xo_emit_field("V", "host-name", NULL, NULL, host-name); + xo_emit_field(",leaf-list,quotes", "sku", "%s-%u", "%s-000-%u", + "gum", 1412); .. c:function:: xo_ssize_t xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...) diff --git a/contrib/libxo/doc/faq.rst b/contrib/libxo/doc/faq.rst index 087ef710d0e..5232a727168 100644 --- a/contrib/libxo/doc/faq.rst +++ b/contrib/libxo/doc/faq.rst @@ -205,4 +205,7 @@ a difference, change the names to make that difference more obvious. What does this message mean? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. include:: xolint.rst +.. toctree:: + :maxdepth: 2 + + xolint-errors.rst diff --git a/contrib/libxo/doc/field-formatting.rst b/contrib/libxo/doc/field-formatting.rst index b182fcee999..1a4a29af6e6 100644 --- a/contrib/libxo/doc/field-formatting.rst +++ b/contrib/libxo/doc/field-formatting.rst @@ -1,5 +1,6 @@ .. index:: Field Formatting +.. _field-formatting: Field Formatting ---------------- diff --git a/contrib/libxo/doc/field-roles.rst b/contrib/libxo/doc/field-roles.rst index 4de810c6465..3499aea81ab 100644 --- a/contrib/libxo/doc/field-roles.rst +++ b/contrib/libxo/doc/field-roles.rst @@ -180,6 +180,11 @@ Labels are text that appears before a value:: xo_emit("{Lwc:Cost}{:cost/%u}\n", cost); +If a label needs to include a slash, it must be escaped using two +backslashes, one for the C compiler and one for libxo:: + + xo_emit("{Lc:Low\\/warn level}{:level/%s}\n", level); + .. index:: Field Roles; Note .. _note-role: diff --git a/contrib/libxo/doc/xolint-errors.rst b/contrib/libxo/doc/xolint-errors.rst new file mode 100644 index 00000000000..c3e518b9cdd --- /dev/null +++ b/contrib/libxo/doc/xolint-errors.rst @@ -0,0 +1,444 @@ +'A percent sign appearing in text is a literal' ++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "A percent sign appearing in text is a literal" can be caused by code like: + +:: + + xo_emit("cost: %d", cost); + +This code should be replaced with code like: + +:: + + xo_emit("{L:cost}: {:cost/%d}", cost); + +This can be a bit surprising and could be a field that was not +properly converted to a libxo-style format string. + + +'Unknown long name for role/modifier' ++++++++++++++++++++++++++++++++++++++ + +The message "Unknown long name for role/modifier" can be caused by code like: + +:: + + xo_emit("{,humanization:value}", value); + +This code should be replaced with code like: + +:: + + xo_emit("{,humanize:value}", value); + +The hn-* modifiers (hn-decimal, hn-space, hn-1000) +are only valid for fields with the {h:} modifier. + + +'Last character before field definition is a field type' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Last character before field definition is a field type" can be caused by code like: +A common typo: + +:: + + xo_emit("{T:Min} T{:Max}"); + +This code should be replaced with code like: + +:: + + xo_emit("{T:Min} {T:Max}"); + +Twiddling the "{" and the field role is a common typo. + + +'Encoding format uses different number of arguments' +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Encoding format uses different number of arguments" can be caused by code like: + +:: + + xo_emit("{:name/%6.6s %%04d/%s}", name, number); + +This code should be replaced with code like: + +:: + + xo_emit("{:name/%6.6s %04d/%s-%d}", name, number); + +Both format should consume the same number of arguments off the stack + + +'Only one field role can be used' ++++++++++++++++++++++++++++++++++ + +The message "Only one field role can be used" can be caused by code like: + +:: + + xo_emit("{LT:Max}"); + +This code should be replaced with code like: + +:: + + xo_emit("{T:Max}"); + +'Potential missing slash after C, D, N, L, or T with format' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Potential missing slash after C, D, N, L, or T with format" can be caused by code like: + +:: + + xo_emit("{T:%6.6s}\n", "Max"); + +This code should be replaced with code like: + +:: + + xo_emit("{T:/%6.6s}\n", "Max"); + +The "%6.6s" will be a literal, not a field format. While +it's possibly valid, it's likely a missing "/". + + +'An encoding format cannot be given (roles: DNLT)' +++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "An encoding format cannot be given (roles: DNLT)" can be caused by code like: + +:: + + xo_emit("{T:Max//%s}", "Max"); + +Fields with the C, D, N, L, and T roles are not emitted in +the 'encoding' style (JSON, XML), so an encoding format +would make no sense. + + +'Format cannot be given when content is present (roles: CDLN)' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Format cannot be given when content is present (roles: CDLN)" can be caused by code like: + +:: + + xo_emit("{N:Max/%6.6s}", "Max"); + +Fields with the C, D, L, or N roles can't have both +static literal content ("{L:Label}") and a +format ("{L:/%s}"). +This error will also occur when the content has a backslash +in it, like "{N:Type of I/O}"; backslashes should be escaped, +like "{N:Type of I\\/O}". Note the double backslash, one for +handling 'C' strings, and one for libxo. + + +'Field has color without fg- or bg- (role: C)' +++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Field has color without fg- or bg- (role: C)" can be caused by code like: + +:: + + xo_emit("{C:green}{:foo}{C:}", x); + +This code should be replaced with code like: + +:: + + xo_emit("{C:fg-green}{:foo}{C:}", x); + +Colors must be prefixed by either "fg-" or "bg-". + + +'Field has invalid color or effect (role: C)' ++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Field has invalid color or effect (role: C)" can be caused by code like: + +:: + + xo_emit("{C:fg-purple,bold}{:foo}{C:gween}", x); + +This code should be replaced with code like: + +:: + + xo_emit("{C:fg-red,bold}{:foo}{C:fg-green}", x); + +The list of colors and effects are limited. The +set of colors includes default, black, red, green, +yellow, blue, magenta, cyan, and white, which must +be prefixed by either "fg-" or "bg-". Effects are +limited to bold, no-bold, underline, no-underline, +inverse, no-inverse, normal, and reset. Values must +be separated by commas. + + +'Field has humanize modifier but no format string' +++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Field has humanize modifier but no format string" can be caused by code like: + +:: + + xo_emit("{h:value}", value); + +This code should be replaced with code like: + +:: + + xo_emit("{h:value/%d}", value); + +Humanization is only value for numbers, which are not +likely to use the default format ("%s"). + + +'Field has hn-* modifier but not 'h' modifier' +++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Field has hn-* modifier but not 'h' modifier" can be caused by code like: + +:: + + xo_emit("{,hn-1000:value}", value); + +This code should be replaced with code like: + +:: + + xo_emit("{h,hn-1000:value}", value); + +The hn-* modifiers (hn-decimal, hn-space, hn-1000) +are only valid for fields with the {h:} modifier. + + +'Value field must have a name (as content)")' ++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Value field must have a name (as content)")" can be caused by code like: + +:: + + xo_emit("{:/%s}", "value"); + +This code should be replaced with code like: + +:: + + xo_emit("{:tag-name/%s}", "value"); + +The field name is used for XML and JSON encodings. These +tags names are static and must appear directly in the +field descriptor. + + +'Use hyphens, not underscores, for value field name' +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Use hyphens, not underscores, for value field name" can be caused by code like: + +:: + + xo_emit("{:no_under_scores}", "bad"); + +This code should be replaced with code like: + +:: + + xo_emit("{:no-under-scores}", "bad"); + +Use of hyphens is traditional in XML, and the XOF_UNDERSCORES +flag can be used to generate underscores in JSON, if desired. +But the raw field name should use hyphens. + + +'Value field name cannot start with digit' +++++++++++++++++++++++++++++++++++++++++++ + +The message "Value field name cannot start with digit" can be caused by code like: + +:: + + xo_emit("{:10-gig/}"); + +This code should be replaced with code like: + +:: + + xo_emit("{:ten-gig/}"); + +XML element names cannot start with a digit. + + +'Value field name should be lower case' ++++++++++++++++++++++++++++++++++++++++ + +The message "Value field name should be lower case" can be caused by code like: + +:: + + xo_emit("{:WHY-ARE-YOU-SHOUTING}", "NO REASON"); + +This code should be replaced with code like: + +:: + + xo_emit("{:why-are-you-shouting}", "no reason"); + +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. Lower case rules the seas. + + +'Value field name should be longer than two characters' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Value field name should be longer than two characters" can be caused by code like: + +:: + + xo_emit("{:x}", "mumble"); + +This code should be replaced with code like: + +:: + + xo_emit("{:something-meaningful}", "mumble"); + +Field names should be descriptive, and it's hard to +be descriptive in less than two characters. Consider +your users and try to make something more useful. +Note that this error often occurs when the field type +is placed after the colon ("{:T/%20s}"), instead of before +it ("{T:/20s}"). + + +'Value field name contains invalid character' ++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Value field name contains invalid character" can be caused by code like: + +:: + + xo_emit("{:cost-in-$$/%u}", 15); + +This code should be replaced with code like: + +:: + + xo_emit("{:cost-in-dollars/%u}", 15); + +An invalid character is often a sign of a typo, like "{:]}" +instead of "{]:}". Field names are restricted to lower-case +characters, digits, and hyphens. + + +'decoration field contains invalid character' ++++++++++++++++++++++++++++++++++++++++++++++ + +The message "decoration field contains invalid character" can be caused by code like: + +:: + + xo_emit("{D:not good}"); + +This code should be replaced with code like: + +:: + + xo_emit("{D:((}{:good}{D:))}", "yes"); + +This is minor, but fields should use proper roles. Decoration +fields are meant to hold punctuation and other characters used +to decorate the content, typically to make it more readable +to human readers. + + +'Anchor content should be decimal width' +++++++++++++++++++++++++++++++++++++++++ + +The message "Anchor content should be decimal width" can be caused by code like: + +:: + + xo_emit("{[:mumble}"); + +This code should be replaced with code like: + +:: + + xo_emit("{[:32}"); + +Anchors need an integer value to specify the width of +the set of anchored fields. The value can be positive +(for left padding/right justification) or negative (for +right padding/left justification) and can appear in +either the start or stop anchor field descriptor. + + +'Anchor format should be "%d"' +++++++++++++++++++++++++++++++ + +The message "Anchor format should be "%d"" can be caused by code like: + +:: + + xo_emit("{[:/%s}"); + +This code should be replaced with code like: + +:: + + xo_emit("{[:/%d}"); + +Anchors only grok integer values, and if the value is not static, +if must be in an 'int' argument, represented by the "%d" format. +Anything else is an error. + + +'Anchor cannot have both format and encoding format")' +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The message "Anchor cannot have both format and encoding format")" can be caused by code like: + +:: + + xo_emit("{[:32/%d}"); + +This code should be replaced with code like: + +:: + + xo_emit("{[:32}"); + +Anchors can have a static value or argument for the width, +but cannot have both. + + +'Max width only valid for strings' +++++++++++++++++++++++++++++++++++ + +The message "Max width only valid for strings" can be caused by code like: + +:: + + xo_emit("{:tag/%2.4.6d}", 55); + +This code should be replaced with code like: + +:: + + xo_emit("{:tag/%2.6d}", 55); + +libxo allows a true 'max width' in addition to the traditional +printf-style 'max number of bytes to use for input'. But this +is supported only for string values, since it makes no sense +for non-strings. This error may occur from a typo, +like "{:tag/%6..6d}" where only one period should be used. diff --git a/contrib/libxo/doc/xolint.rst b/contrib/libxo/doc/xolint.rst index c3e518b9cdd..739fa18558f 100644 --- a/contrib/libxo/doc/xolint.rst +++ b/contrib/libxo/doc/xolint.rst @@ -1,444 +1,40 @@ -'A percent sign appearing in text is a literal' -+++++++++++++++++++++++++++++++++++++++++++++++ - -The message "A percent sign appearing in text is a literal" can be caused by code like: - -:: - - xo_emit("cost: %d", cost); - -This code should be replaced with code like: - -:: - - xo_emit("{L:cost}: {:cost/%d}", cost); - -This can be a bit surprising and could be a field that was not -properly converted to a libxo-style format string. - - -'Unknown long name for role/modifier' -+++++++++++++++++++++++++++++++++++++ - -The message "Unknown long name for role/modifier" can be caused by code like: - -:: - - xo_emit("{,humanization:value}", value); - -This code should be replaced with code like: - -:: - - xo_emit("{,humanize:value}", value); - -The hn-* modifiers (hn-decimal, hn-space, hn-1000) -are only valid for fields with the {h:} modifier. - - -'Last character before field definition is a field type' -++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Last character before field definition is a field type" can be caused by code like: -A common typo: - -:: - - xo_emit("{T:Min} T{:Max}"); - -This code should be replaced with code like: - -:: - - xo_emit("{T:Min} {T:Max}"); - -Twiddling the "{" and the field role is a common typo. - - -'Encoding format uses different number of arguments' -++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Encoding format uses different number of arguments" can be caused by code like: - -:: - - xo_emit("{:name/%6.6s %%04d/%s}", name, number); - -This code should be replaced with code like: - -:: - - xo_emit("{:name/%6.6s %04d/%s-%d}", name, number); - -Both format should consume the same number of arguments off the stack - - -'Only one field role can be used' -+++++++++++++++++++++++++++++++++ - -The message "Only one field role can be used" can be caused by code like: - -:: - - xo_emit("{LT:Max}"); - -This code should be replaced with code like: - -:: - - xo_emit("{T:Max}"); - -'Potential missing slash after C, D, N, L, or T with format' -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Potential missing slash after C, D, N, L, or T with format" can be caused by code like: - -:: - - xo_emit("{T:%6.6s}\n", "Max"); - -This code should be replaced with code like: - -:: - - xo_emit("{T:/%6.6s}\n", "Max"); - -The "%6.6s" will be a literal, not a field format. While -it's possibly valid, it's likely a missing "/". - - -'An encoding format cannot be given (roles: DNLT)' -++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "An encoding format cannot be given (roles: DNLT)" can be caused by code like: - -:: - - xo_emit("{T:Max//%s}", "Max"); - -Fields with the C, D, N, L, and T roles are not emitted in -the 'encoding' style (JSON, XML), so an encoding format -would make no sense. - - -'Format cannot be given when content is present (roles: CDLN)' -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Format cannot be given when content is present (roles: CDLN)" can be caused by code like: - -:: - - xo_emit("{N:Max/%6.6s}", "Max"); - -Fields with the C, D, L, or N roles can't have both -static literal content ("{L:Label}") and a -format ("{L:/%s}"). -This error will also occur when the content has a backslash -in it, like "{N:Type of I/O}"; backslashes should be escaped, -like "{N:Type of I\\/O}". Note the double backslash, one for -handling 'C' strings, and one for libxo. - - -'Field has color without fg- or bg- (role: C)' -++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Field has color without fg- or bg- (role: C)" can be caused by code like: - -:: - - xo_emit("{C:green}{:foo}{C:}", x); - -This code should be replaced with code like: - -:: - - xo_emit("{C:fg-green}{:foo}{C:}", x); - -Colors must be prefixed by either "fg-" or "bg-". - - -'Field has invalid color or effect (role: C)' -+++++++++++++++++++++++++++++++++++++++++++++ - -The message "Field has invalid color or effect (role: C)" can be caused by code like: - -:: - - xo_emit("{C:fg-purple,bold}{:foo}{C:gween}", x); - -This code should be replaced with code like: - -:: - - xo_emit("{C:fg-red,bold}{:foo}{C:fg-green}", x); - -The list of colors and effects are limited. The -set of colors includes default, black, red, green, -yellow, blue, magenta, cyan, and white, which must -be prefixed by either "fg-" or "bg-". Effects are -limited to bold, no-bold, underline, no-underline, -inverse, no-inverse, normal, and reset. Values must -be separated by commas. - - -'Field has humanize modifier but no format string' -++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Field has humanize modifier but no format string" can be caused by code like: - -:: - - xo_emit("{h:value}", value); - -This code should be replaced with code like: - -:: - - xo_emit("{h:value/%d}", value); - -Humanization is only value for numbers, which are not -likely to use the default format ("%s"). - - -'Field has hn-* modifier but not 'h' modifier' -++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Field has hn-* modifier but not 'h' modifier" can be caused by code like: - -:: - - xo_emit("{,hn-1000:value}", value); - -This code should be replaced with code like: - -:: - - xo_emit("{h,hn-1000:value}", value); - -The hn-* modifiers (hn-decimal, hn-space, hn-1000) -are only valid for fields with the {h:} modifier. - - -'Value field must have a name (as content)")' -+++++++++++++++++++++++++++++++++++++++++++++ - -The message "Value field must have a name (as content)")" can be caused by code like: - -:: - - xo_emit("{:/%s}", "value"); - -This code should be replaced with code like: - -:: - - xo_emit("{:tag-name/%s}", "value"); - -The field name is used for XML and JSON encodings. These -tags names are static and must appear directly in the -field descriptor. - - -'Use hyphens, not underscores, for value field name' -++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Use hyphens, not underscores, for value field name" can be caused by code like: - -:: - - xo_emit("{:no_under_scores}", "bad"); - -This code should be replaced with code like: - -:: - - xo_emit("{:no-under-scores}", "bad"); - -Use of hyphens is traditional in XML, and the XOF_UNDERSCORES -flag can be used to generate underscores in JSON, if desired. -But the raw field name should use hyphens. - - -'Value field name cannot start with digit' -++++++++++++++++++++++++++++++++++++++++++ - -The message "Value field name cannot start with digit" can be caused by code like: - -:: - - xo_emit("{:10-gig/}"); - -This code should be replaced with code like: - -:: - - xo_emit("{:ten-gig/}"); - -XML element names cannot start with a digit. - - -'Value field name should be lower case' -+++++++++++++++++++++++++++++++++++++++ - -The message "Value field name should be lower case" can be caused by code like: - -:: - - xo_emit("{:WHY-ARE-YOU-SHOUTING}", "NO REASON"); - -This code should be replaced with code like: - -:: - - xo_emit("{:why-are-you-shouting}", "no reason"); - -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. Lower case rules the seas. - - -'Value field name should be longer than two characters' -+++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Value field name should be longer than two characters" can be caused by code like: - -:: - - xo_emit("{:x}", "mumble"); - -This code should be replaced with code like: - -:: - - xo_emit("{:something-meaningful}", "mumble"); - -Field names should be descriptive, and it's hard to -be descriptive in less than two characters. Consider -your users and try to make something more useful. -Note that this error often occurs when the field type -is placed after the colon ("{:T/%20s}"), instead of before -it ("{T:/20s}"). - - -'Value field name contains invalid character' -+++++++++++++++++++++++++++++++++++++++++++++ - -The message "Value field name contains invalid character" can be caused by code like: - -:: - - xo_emit("{:cost-in-$$/%u}", 15); - -This code should be replaced with code like: - -:: - - xo_emit("{:cost-in-dollars/%u}", 15); - -An invalid character is often a sign of a typo, like "{:]}" -instead of "{]:}". Field names are restricted to lower-case -characters, digits, and hyphens. - - -'decoration field contains invalid character' -+++++++++++++++++++++++++++++++++++++++++++++ - -The message "decoration field contains invalid character" can be caused by code like: - -:: - - xo_emit("{D:not good}"); - -This code should be replaced with code like: - -:: - - xo_emit("{D:((}{:good}{D:))}", "yes"); - -This is minor, but fields should use proper roles. Decoration -fields are meant to hold punctuation and other characters used -to decorate the content, typically to make it more readable -to human readers. - - -'Anchor content should be decimal width' -++++++++++++++++++++++++++++++++++++++++ - -The message "Anchor content should be decimal width" can be caused by code like: - -:: - - xo_emit("{[:mumble}"); - -This code should be replaced with code like: - -:: - - xo_emit("{[:32}"); - -Anchors need an integer value to specify the width of -the set of anchored fields. The value can be positive -(for left padding/right justification) or negative (for -right padding/left justification) and can appear in -either the start or stop anchor field descriptor. - - -'Anchor format should be "%d"' -++++++++++++++++++++++++++++++ - -The message "Anchor format should be "%d"" can be caused by code like: - -:: - - xo_emit("{[:/%s}"); - -This code should be replaced with code like: - -:: - - xo_emit("{[:/%d}"); - -Anchors only grok integer values, and if the value is not static, -if must be in an 'int' argument, represented by the "%d" format. -Anything else is an error. - - -'Anchor cannot have both format and encoding format")' -++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -The message "Anchor cannot have both format and encoding format")" can be caused by code like: - -:: - - xo_emit("{[:32/%d}"); - -This code should be replaced with code like: - -:: - - xo_emit("{[:32}"); - -Anchors can have a static value or argument for the width, -but cannot have both. - - -'Max width only valid for strings' -++++++++++++++++++++++++++++++++++ - -The message "Max width only valid for strings" can be caused by code like: - -:: - - xo_emit("{:tag/%2.4.6d}", 55); - -This code should be replaced with code like: - -:: - - xo_emit("{:tag/%2.6d}", 55); - -libxo allows a true 'max width' in addition to the traditional -printf-style 'max number of bytes to use for input'. But this -is supported only for string values, since it makes no sense -for non-strings. This error may occur from a typo, -like "{:tag/%6..6d}" where only one period should be used. +====== +xolint +====== + +`xolint` is a tool for reporting common mistakes in format strings +in source code that invokes `xo_emit`. It allows these errors +to be diagnosed at build time, rather than waiting until runtime. + +`xolint` takes the one or more C files as arguments, and reports +and errors, warning, or informational messages as needed: + + ============ =================================================== + Option Meaning + ============ =================================================== + -c Invoke 'cpp' against the input file + -C Flags that are passed to 'cpp + -d Enable debug output + -D Generate documentation for all xolint messages + -I Generate info table code + -p Print the offending lines after the message + -V Print vocabulary of all field names + -X Extract samples from xolint, suitable for testing + ============ =================================================== + +The output message will contain the source filename and line number, the +class of the message, the message, and, if -p is given, the +line that contains the error:: + + % xolint.pl -t xolint.c + xolint.c: 16: error: anchor format should be "%d" + 16 xo_emit("{[:/%s}"); + +The "-I" option will generate a table of `xo_info_t`_ structures, +suitable for inclusion in source code. + +.. _xo_info_t: :ref:`field-information` + +The "-V" option does not report errors, but prints a complete list of +all field names, sorted alphabetically. The output can help spot +inconsistencies and spelling errors. diff --git a/contrib/libxo/libxo/Makefile.am b/contrib/libxo/libxo/Makefile.am index a4d94acae19..9f17527e68e 100644 --- a/contrib/libxo/libxo/Makefile.am +++ b/contrib/libxo/libxo/Makefile.am @@ -74,6 +74,7 @@ man5_files = \ xo_format.5 man7_files = \ + libxo-csv.7 \ xo_options.7 man_MANS = ${man3_files} ${man5_files} ${man7_files} diff --git a/contrib/libxo/libxo/gen-wide.sh b/contrib/libxo/libxo/gen-wide.sh old mode 100755 new mode 100644 diff --git a/contrib/libxo/libxo/libxo-csv.7 b/contrib/libxo/libxo/libxo-csv.7 new file mode 100644 index 00000000000..6e043820a01 --- /dev/null +++ b/contrib/libxo/libxo/libxo-csv.7 @@ -0,0 +1,274 @@ +.\" # +.\" # Copyright (c) 2021, 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, May 2021 +.\" +.Dd May 13, 2021 +.Dt LIBXO-CSV 7 +.Os +.Sh NAME +.Nm --libxo encoder=csv[+options] +.Nd a CVS encoder for libxo\-based commands +.Sh DESCRIPTION +The +.Nm libxo +library supports a "pluggable" encoder mechanism, and ships with an +encoder for CSV (comma separated values) files. The encoder allows +paths and fields to be selected out of the output contents: +.Bd -literal -offset indent + % df --libxo @csv + name,total-blocks,used-blocks,available-blocks,used-percent,mounted-on + zroot/ROOT/default,3825984331,29376725,3796607605,1,/ + devfs,1,1,0,100,/dev + zroot/usr/home,3808301289,11693684,3796607605,0,/usr/home + zroot/var/audit,3796607806,201,3796607605,0,/var/audit + ... + % df --libxo @csv+leafs=name.used-percent + name,used-percent + zroot/ROOT/default,1 + devfs,100 + zroot/usr/home,0 + zroot/var/audit,0 + ... + % df --libxo @csv+leafs=available-blocks+no-header / + 3796607605 +.Ed + contains software to generate four "built-in" +formats: text, XML, JSON, and HTML. +These formats are common and useful, but there are other common and +useful formats that users will want, and including them all in the +libxo software would be difficult and cumbersome. +.Pp +To allow support for additional encodings, libxo includes a +"pluggable" extension mechanism for dynamically loading new encoders. +.Nm libxo -based +applications can automatically use any installed encoder. +.Pp +Use the "encoder=XXX" option to access encoders. The following +example uses the "cbor" encoder, saving the output into a file: +.Bd -literal -offset indent + df --libxo encoder=cbor > df-output.cbor +.Ed +.Pp +Encoders can support specific options that can be accessed by +following the encoder name with a colon (':') or a plus sign ('+') and +one of more options, separated by the same character: +.Bd -literal -offset indent + df --libxo encoder=csv+path=filesystem+leaf=name+no-header + df --libxo encoder=csv:path=filesystem:leaf=name:no-header +.Ed +.Pp +These examples instructs libxo to load the "csv" encoder and pass the +following options: +.Bd -literal -offset indent + path=filesystem + leaf=name + no-header +.Ed +.Pp +Each of these option is interpreted by the encoder, and all such +options names and semantics are specific to the particular encoder. +Refer to the intended encoder for documentation on its options. +.Pp +The string "@" can be used in place of the string "encoder=". +.Bd -literal -offset indent + df --libxo @csv:no-header +.Ed +.Sh The CSV (Comma Separated Values) Encoder +.Nm libxo +ships with a custom encoder for "CSV" files, a common format for +comma separated values. The output of the CSV encoder can be loaded +directly into spreadsheets or similar applications. +.Pp +A standard for CSV files is provided in RFC 4180, but since the +format predates that standard by decades, there are many minor +differences in CSV file consumers and their expectations. The CSV +encoder has a number of options to tailor output to those +expectations. +.Pp +Consider the following XML: +.Bd -literal -offset indent + % list-items --libxo xml,pretty + + + + GRO-000-415 + gum + 1412 + 54 + 10 + + + HRD-000-212 + rope + 85 + 4 + 2 + + + HRD-000-517 + ladder + 0 + 2 + 1 + + + +.Ed +.Pp +This output is a list of `instances` (named "item"), each containing a +set of `leafs` ("sku", "name", etc). +.Pp +The CSV encoder will emit the leaf values in this output as `fields` +inside a CSV `record`, which is a line containing a set of +comma-separated values: +.Bd -literal -offset indent + % list-items --libxo encoder=csv + sku,name,sold,in-stock,on-order + GRO-000-415,gum,1412,54,10 + HRD-000-212,rope,85,4,2 + HRD-000-517,ladder,0,2,1 +.Ed +.Pp +Be aware that since the CSV encoder looks for data instances, when +used with +.Nm xo , +the `--instance` option will be needed: +.Bd -literal -offset indent + % xo --libxo encoder=csv --instance foo 'The {:product} is {:status}\n' stereo "in route" + product,status + stereo,in route +.Ed +.Sh The "path" Option +By default, the CSV encoder will attempt to emit any list instance +generated by the application. +In some cases, this may be unacceptable, and a specific list may be +desired. +.Pp +Use the "path" option to limit the processing of output to a specific +hierarchy. The path should be one or more names of containers or +lists. +.Pp +For example, if the "list-items" application generates other lists, +the user can give "path=top/data/item" as a path: +.Bd -literal -offset indent + % list-items --libxo encoder=csv:path=top/data/item + sku,name,sold,in-stock,on-order + GRO-000-415,gum,1412,54,10 + HRD-000-212,rope,85,4,2 + HRD-000-517,ladder,0,2,1 +.Ed +.Pp +Paths are "relative", meaning they need not be a complete set +of names to the list. This means that "path=item" may be sufficient +for the above example. +.Sh The "leafs" Option +The CSV encoding requires that all lines of output have the same +number of fields with the same order. In contrast, XML and JSON allow +any order (though libxo forces key leafs to appear before other +leafs). +.Pp +To maintain a consistent set of fields inside the CSV file, the same +set of leafs must be selected from each list item. By default, the +CSV encoder records the set of leafs that appear in the first list +instance it processes, and extract only those leafs from future +instances. If the first instance is missing a leaf that is desired by +the consumer, the "leaf" option can be used to ensure that an empty +value is recorded for instances that lack a particular leaf. +.Pp +The "leafs" option can also be used to exclude leafs, limiting the +output to only those leafs provided. +.Pp +In addition, the order of the output fields follows the order in which +the leafs are listed. "leafs=one.two" and "leafs=two.one" give +distinct output. +.Pp +So the "leafs" option can be used to expand, limit, and order the set +of leafs. +.Pp +The value of the leafs option should be one or more leaf names, +separated by a period ("."): +.Bd -literal -offset indent + % list-items --libxo encoder=csv:leafs=sku.on-order + sku,on-order + GRO-000-415,10 + HRD-000-212,2 + HRD-000-517,1 + % list-items -libxo encoder=csv:leafs=on-order.sku + on-order,sku + 10,GRO-000-415 + 2,HRD-000-212 + 1,HRD-000-517 +.Ed +.Pp +Note that since libxo uses terminology from YANG (:RFC:`7950`), the +data modeling language for NETCONF (:RFC:`6241`), which uses "leafs" +as the plural form of "leaf". libxo follows that convention. +.Sh The "no-header" Option +CSV files typical begin with a line that defines the fields included +in that file, in an attempt to make the contents self-defining: +.Bd -literal -offset indent + sku,name,sold,in-stock,on-order + GRO-000-415,gum,1412,54,10 + HRD-000-212,rope,85,4,2 + HRD-000-517,ladder,0,2,1 +.Ed +.Pp +There is no reliable mechanism for determining whether this header +line is included, so the consumer must make an assumption. +.Pp +The csv encoder defaults to producing the header line, but the +"no-header" option can be included to avoid the header line. +.Sh The "no-quotes" Option +RFC 4180 specifies that fields containing spaces should be quoted, but +many CSV consumers do not handle quotes. The "no-quotes" option +instruct the CSV encoder to avoid the use of quotes. +.Sh The "dos" Option +RFC 4180 defines the end-of-line marker as a carriage return +followed by a newline. This "CRLF" convention dates from the distant +past, but its use was anchored in the 1980s by the `DOS` operating +system. +.Pp +The CSV encoder defaults to using the standard Unix end-of-line +marker, a simple newline. Use the "dos" option to use the `CRLF` +convention. +.Sh Option Handling +The handling of command-line options is complex, since there are three +hierarchies in use, but the rules are: +.Bl -bullet +.It +commas separate +.Nm libxo +options +.Bd -literal -ofset indent + \-\-libxo json,pretty,warn +.Ed +.It +pluses separate encoder options +.Bd -literal -ofset indent +\-\-libxo @csv+dos+no-header,warn +.Ed +.It +periods separate tag names +.Bd -literal -ofset indent +\-\-libxo @csv+leafs=name.used.free+dos,warn +.El +.Sh SEE ALSO +.Xr libxo 3 , +.Xr xo_options 7 +.Sh HISTORY +The +.Nm libxo +library first appeared in +.Fx 11.0 . +The CSV encoder first appeared in +.Fx 13.0 . +.Sh AUTHORS +.Nm libxo +was written by +.An Phil Shafer Aq Mt phil@freebsd.org . + diff --git a/contrib/libxo/libxo/libxo.3 b/contrib/libxo/libxo/libxo.3 index f07962036e0..95c0059865b 100644 --- a/contrib/libxo/libxo/libxo.3 +++ b/contrib/libxo/libxo/libxo.3 @@ -86,6 +86,95 @@ suited for terminal output and HTML is suited for display in a web browser (see .Xr xohtml 1 ). .Pp +.Nm libxo +uses command line options to trigger rendering behavior. +The following options are recognised: +.Pp +.Bl -tag -width "--libxo" +.It +\-\^\-libxo +.It +\-\^\-libxo= +.It +\-\^\-libxo: +.El +.Pp +Options is a comma-separated list of tokens that correspond to output +styles, flags, or features: +.Pp +.Bl -tag -width "12345678" +.It Sy "Token Action" +.It Dv dtrt +Enable "Do The Right Thing" mode +.It Dv html +Emit HTML output +.It Dv indent=xx +Set the indentation level +.It Dv info +Add info attributes (HTML) +.It Dv json +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 ) +.It Dv no-humanize +Ignore the {h:} modifier (TEXT, HTML) +.It Dv no-locale +Do not initialize the locale setting +.It Dv no-retain +Prevent retaining formatting information +.It Dv no-top +Do not emit a top set of braces (JSON) +.It Dv not-first +Pretend the 1st output item was not 1st (JSON) +.It Dv pretty +Emit pretty-printed output +.It Dv retain +Force retaining formatting information +.It Dv text +Emit TEXT output +.It 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 +Emit warnings when libxo detects bad calls +.It Dv warn-xml +Emit warnings in XML +.It Dv xml +Emit XML output +.It Dv xpath +Add XPath expressions (HTML) +.El +.Pp +The +.Dq brief-options +are single letter commands, designed for those with +too little patience to use real tokens. +No comma separator is used. +.Bl -column "i" +.It Sy "Token Action" +.It "H " "Enable HTML output (XO_STYLE_HTML)" +.It "I " "Enable info output (XOF_INFO)" +.It "i " "Indent by " +.It "J " "Enable JSON output (XO_STYLE_JSON)" +.It "P " "Enable pretty-printed output (XOF_PRETTY)" +.It "T " "Enable text output (XO_STYLE_TEXT)" +.It "W " "Enable warnings (XOF_WARN)" +.It "X " "Enable XML output (XO_STYLE_XML)" +.It "x " "Enable XPath data (XOF_XPATH)" +.El +.Pp +Refer to +.Xr xo_options 7 +for additional option information. +.Pp The .Nm library allows an application to generate text, XML, JSON, @@ -291,6 +380,7 @@ Instructs to use an alternative set of low-level output functions. .El .Sh SEE ALSO +.Xr libxo-csv 7, .Xr xo 1 , .Xr xolint 1 , .Xr xo_attr 3 , @@ -303,6 +393,7 @@ to use an alternative set of low-level output functions. .Xr xo_no_setlocale 3 , .Xr xo_open_container 3 , .Xr xo_open_list 3 , +.Xr xo_options 7, .Xr xo_parse_args 3 , .Xr xo_set_allocator 3 , .Xr xo_set_flags 3 , diff --git a/contrib/libxo/libxo/libxo.c b/contrib/libxo/libxo/libxo.c index ea64feb8274..916a111f5af 100644 --- a/contrib/libxo/libxo/libxo.c +++ b/contrib/libxo/libxo/libxo.c @@ -6979,8 +6979,21 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? ",\n" : ", "; xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + /* If we need underscores, make a local copy and doctor it */ + const char *new_name = name; + if (XOF_ISSET(xop, XOF_UNDERSCORES)) { + size_t len = strlen(name); + const char *old_name = name; + char *buf, *cp, *ep; + + buf = alloca(len + 1); + for (cp = buf, ep = buf + len + 1; cp < ep; cp++, old_name++) + *cp = (*old_name == '-') ? '_' : *old_name; + new_name = buf; + } + rc = xo_printf(xop, "%s%*s\"%s\": {%s", - pre_nl, xo_indent(xop), "", name, ppn); + pre_nl, xo_indent(xop), "", new_name, ppn); break; case XO_STYLE_SDPARAMS: @@ -7142,8 +7155,21 @@ xo_do_open_list (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? ",\n" : ", "; xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + /* If we need underscores, make a local copy and doctor it */ + const char *new_name = name; + if (XOF_ISSET(xop, XOF_UNDERSCORES)) { + size_t len = strlen(name); + const char *old_name = name; + char *buf, *cp, *ep; + + buf = alloca(len + 1); + for (cp = buf, ep = buf + len + 1; cp < ep; cp++, old_name++) + *cp = (*old_name == '-') ? '_' : *old_name; + new_name = buf; + } + rc = xo_printf(xop, "%s%*s\"%s\": [%s", - pre_nl, xo_indent(xop), "", name, ppn); + pre_nl, xo_indent(xop), "", new_name, ppn); break; case XO_STYLE_ENCODER: diff --git a/contrib/libxo/libxo/xo_create.3 b/contrib/libxo/libxo/xo_create.3 index 03d51764b8a..ea811c27e5c 100644 --- a/contrib/libxo/libxo/xo_create.3 +++ b/contrib/libxo/libxo/xo_create.3 @@ -33,7 +33,7 @@ function. Example: xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN); .... - xo_emit_h(xop, "testing\n"); + xo_emit_h(xop, "testing\\n"); .Ed .Pp By default, diff --git a/contrib/libxo/libxo/xo_emit.3 b/contrib/libxo/libxo/xo_emit.3 index 9e3ec85b676..cbf9d2b11eb 100644 --- a/contrib/libxo/libxo/xo_emit.3 +++ b/contrib/libxo/libxo/xo_emit.3 @@ -48,7 +48,7 @@ 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", + "{:characters/%7ju} {d:filename/%s}\\n", linect, wordct, charct, file); .Ed Output can then be generated in various style, using @@ -100,6 +100,8 @@ 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_emit_f 3 , +.Xo xo_emit_field 3 , .Xr xo_format 5 , .Xr libxo 3 .Sh HISTORY diff --git a/contrib/libxo/libxo/xo_emit_f.3 b/contrib/libxo/libxo/xo_emit_f.3 index 7c340175aef..f8ac013256a 100644 --- a/contrib/libxo/libxo/xo_emit_f.3 +++ b/contrib/libxo/libxo/xo_emit_f.3 @@ -84,14 +84,14 @@ clear this information; they are not generally needed. .Bd -literal -offset indent for (i = 0; i < 1000; i++) { xo_open_instance("item"); - xo_emit_f(XOEF_RETAIN, "{:name} {:count/%d}\n", + xo_emit_f(XOEF_RETAIN, "{:name} {:count/%d}\\n", name[i], count[i]); } .Ed .Pp In this example, the caller desires to clear the retained information. .Bd -literal -offset indent - const char *fmt = "{:name} {:count/%d}\n"; + const char *fmt = "{:name} {:count/%d}\\n"; for (i = 0; i < 1000; i++) { xo_open_instance("item"); xo_emit_f(XOEF_RETAIN, fmt, name[i], count[i]); diff --git a/contrib/libxo/libxo/xo_emit_field.3 b/contrib/libxo/libxo/xo_emit_field.3 new file mode 100644 index 00000000000..4f9636cee8e --- /dev/null +++ b/contrib/libxo/libxo/xo_emit_field.3 @@ -0,0 +1,113 @@ +.\" # +.\" # Copyright (c) 2021, 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_field +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft xo_ssize_t +.Fn xo_emit_field "const char *rolmod" "const char *content" "const char *fmt" "const char *efmt" "..." +.Ft xo_ssize_t +.Fn xo_emit_field_h "xo_handle_t *xop" "const char *rolmod" "const char *content" "const char *fmt" const char *efmt" "..." +.Ft xo_ssize_t +.Fn xo_emit_field_hv "xo_handle_t *xop" "const char *rolmod" "const char *content" "const char *fmt" "const char *efmt" "va_list vap" +.Sh DESCRIPTION +The +.Fn xo_emit_field +function emits formatted output similar to +.Xr xo_emit 3 +but where +.Fn xo_emit +uses a single string argument containing the description +for multiple fields, +.Fn xo_emit_field +emits a single field using multiple arguments to contain the +field description. +.Fn xo_emit_field_h +adds an explicit handle to use instead of the default +handle, while +.Fn xo_emit_field_hv +accepts a +.Fa va_list +for additional flexibility. +.Pp +The arguments +.Fa rolmod , +.Fa content , +.Fa fmt , +and +.Fa efmt +are detailed in +.Xr xo_format 5 . +Using distinct arguments allows callers to pass the field description +in pieces, rather than having to use something like +.Xr snprintf 3 +to build the format string required by +.Fn xo_emit . +The arguments are each NUL-terminated strings. The +.Fa rolmod +argument contains the "role" and "modifier" portions of +the field description, the +.Fa content +argument contains the "content" portion, and the +.Fa fmt +and +.Fa efmt +contain the "field-format" and "encoding-format" portions, respectively. +.Pp +As with xo_emit, the +.Fa fmt +and +.Fa efmt +values are both optional, since the field-format string +defaults to "%s", and the encoding-format's default value is +derived from the field-format +per +.Xr xo_format 5 . +However, care must be taken to avoid using a value directly as the +format, since characters like '{', '%', and '}' will be interpreted +as formatting directives, and may cause +.Nm +to dereference arbitrary values off the stack, leading to bugs, +core files, and gnashing of teeth. +.Sh EXAMPLES +In this example, a set of four values is emitted using the following +source code: +.Bd -literal -offset indent + xo_emit_field("T", title, NULL, NULL, NULL); + xo_emit_field("Vt", "max-chaos", NULL, NULL, " very "); + xo_emit_field("V", "min-chaos", "%02d", "%d", 42); + xo_emit_field_h(NULL, ",leaf-list,quotes", "sku", "%s-%u", "%s-000-%u", + "gum", 1412); +.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_format 5 , +.Xr libxo 3 +.Sh HISTORY +The +.Nm libxo +library first appeared in +.Fx 11.0 . +.Sh AUTHORS +.Nm libxo +was written by +.An Phil Shafer Aq Mt phil@freebsd.org . diff --git a/contrib/libxo/libxo/xo_encoder.c b/contrib/libxo/libxo/xo_encoder.c index 475b6d70fa9..5d195e06a2a 100644 --- a/contrib/libxo/libxo/xo_encoder.c +++ b/contrib/libxo/libxo/xo_encoder.c @@ -206,6 +206,33 @@ xo_encoder_find (const char *name) return NULL; } +/* + * Return the encoder function for a specific shared library. This is + * really just a means of keeping the annoying gcc verbiage out of the + * main code. And that's only need because gcc breaks dlfunc's + * promise that I can cast it's return value to a function: "The + * precise return type of dlfunc() is unspecified; applications must + * cast it to an appropriate function pointer type." + */ +static xo_encoder_init_func_t +xo_encoder_func (void *dlp) +{ + xo_encoder_init_func_t func; + +#if defined(HAVE_GCC) && __GNUC__ > 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif /* HAVE_GCC */ + + func = (xo_encoder_init_func_t) dlfunc(dlp, XO_ENCODER_INIT_NAME); + +#if defined(HAVE_GCC) && __GNUC__ > 8 +#pragma GCC diagnostic pop /* Restore previous setting */ +#endif /* HAVE_GCC */ + + return func; +} + static xo_encoder_node_t * xo_encoder_discover (const char *name) { @@ -234,7 +261,7 @@ xo_encoder_discover (const char *name) */ xo_encoder_init_func_t func; - func = (xo_encoder_init_func_t) dlfunc(dlp, XO_ENCODER_INIT_NAME); + func = xo_encoder_func(dlp); if (func) { xo_encoder_init_args_t xei; diff --git a/contrib/libxo/libxo/xo_format.5 b/contrib/libxo/libxo/xo_format.5 index 5265359866b..3c7ddc9dd1a 100644 --- a/contrib/libxo/libxo/xo_format.5 +++ b/contrib/libxo/libxo/xo_format.5 @@ -242,6 +242,13 @@ Labels are text that appears before a value. .Bd -literal -offset indent xo_emit("{Lwc:Cost}{:cost/%u}\\n", cost); .Ed +.Pp +If a label needs to include a slash, it must be escaped using two +backslashes, one for the C compiler and one for +.Nm libxo . +.Bd -literal -offset indent + xo_emit("{Lc:Low\\\\/warn level}{:level/%s}\\n", level); +.Ed .Ss "The Note Role ({N:})" Notes are text that appears after a value. .Bd -literal -offset indent diff --git a/contrib/libxo/libxo/xo_open_container.3 b/contrib/libxo/libxo/xo_open_container.3 index 7037974d2c4..303f3f06fd0 100644 --- a/contrib/libxo/libxo/xo_open_container.3 +++ b/contrib/libxo/libxo/xo_open_container.3 @@ -141,7 +141,7 @@ flag is set. .Bd -literal -offset indent -compact EXAMPLE: xo_open_container("system"); - xo_emit("The host name is {:host-name}\n", hn); + xo_emit("The host name is {:host-name}\\n", hn); xo_close_container("system"); XML: foo diff --git a/contrib/libxo/libxo/xo_open_list.3 b/contrib/libxo/libxo/xo_open_list.3 index f28c9b63ac3..e61e15939c8 100644 --- a/contrib/libxo/libxo/xo_open_list.3 +++ b/contrib/libxo/libxo/xo_open_list.3 @@ -77,7 +77,7 @@ close each instance of the list: for (ip = list; ip->i_title; ip++) { xo_open_instance("item"); - xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); + xo_emit("{L:Item} '{:name/%s}':\\n", ip->i_title); xo_close_instance("item"); } @@ -91,7 +91,7 @@ generation of XML and JSON data. xo_open_list("user"); for (i = 0; i < num_users; i++) { xo_open_instance("user"); - xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n", + xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\\n", pw[i].pw_name, pw[i].pw_uid, pw[i].pw_gid, pw[i].pw_dir); xo_close_instance("user"); @@ -138,7 +138,7 @@ To emit a leaf list, call the function using the ""l"" modifier: .Bd -literal -offset indent -compact for (ip = list; ip->i_title; ip++) { - xo_emit("{Lwc:Item}{l:item}\n", ip->i_title); + xo_emit("{Lwc:Item}{l:item}\\n", ip->i_title); } .Ed .Pp diff --git a/contrib/libxo/libxo/xo_parse_args.3 b/contrib/libxo/libxo/xo_parse_args.3 index b014e608a0d..e631af639e0 100644 --- a/contrib/libxo/libxo/xo_parse_args.3 +++ b/contrib/libxo/libxo/xo_parse_args.3 @@ -7,7 +7,7 @@ .\" # LICENSE. .\" # Phil Shafer, July 2014 .\" -.Dd December 4, 2014 +.Dd November 17, 2020 .Dt LIBXO 3 .Os .Sh NAME @@ -24,7 +24,9 @@ .Sh DESCRIPTION The .Fn xo_parse_args -function is used to process command-line arguments. +function is used to process command-line arguments, which are +described in +.Xr xo_options 7 . .Nm libxo specific options are processed and removed @@ -42,91 +44,6 @@ Following the call to .Fn xo_parse_args , the application can process the remaining arguments in a normal manner. .Pp -.Nm libxo -uses command line options to trigger rendering behavior. -The following options are recognised: -.Pp -.Bl -tag -width "--libxo" -.It -\-\^\-libxo -.It -\-\^\-libxo= -.It -\-\^\-libxo: -.El -.Pp -Options is a comma-separated list of tokens that correspond to output -styles, flags, or features: -.Pp -.Bl -tag -width "12345678" -.It Sy "Token Action" -.It Dv dtrt -Enable "Do The Right Thing" mode -.It Dv html -Emit HTML output -.It Dv indent=xx -Set the indentation level -.It Dv info -Add info attributes (HTML) -.It Dv json -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-retain -Prevent retaining formatting information -.It Dv no-top -Do not emit a top set of braces (JSON) -.It Dv not-first -Pretend the 1st output item was not 1st (JSON) -.It Dv pretty -Emit pretty-printed output -.It Dv retain -Force retaining formatting information -.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 -Emit warnings when libxo detects bad calls -.It Dv warn-xml -Emit warnings in XML -.It Dv xml -Emit XML output -.It Dv xpath -Add XPath expressions (HTML) -.El -.Pp -The -.Dq brief-options -are single letter commands, designed for those with -too little patience to use real tokens. -No comma separator is used. -.Bl -column "i" -.It Sy "Token Action" -.It "H " "Enable HTML output (XO_STYLE_HTML)" -.It "I " "Enable info output (XOF_INFO)" -.It "i " "Indent by " -.It "J " "Enable JSON output (XO_STYLE_JSON)" -.It "P " "Enable pretty-printed output (XOF_PRETTY)" -.It "T " "Enable text output (XO_STYLE_TEXT)" -.It "W " "Enable warnings (XOF_WARN)" -.It "X " "Enable XML output (XO_STYLE_XML)" -.It "x " "Enable XPath data (XOF_XPATH)" -.El -.Pp The .Fn xo_set_program function sets name of the program as reported by @@ -149,6 +66,7 @@ must be maintained by the caller. .Pp .Sh SEE ALSO .Xr xo_emit 3 , +.Xr xo_options 7, .Xr libxo 3 .Sh HISTORY The diff --git a/contrib/libxo/tests/core/Makefile.am b/contrib/libxo/tests/core/Makefile.am index a1dad2cc96a..1e701071175 100644 --- a/contrib/libxo/tests/core/Makefile.am +++ b/contrib/libxo/tests/core/Makefile.am @@ -51,24 +51,32 @@ endif EXTRA_DIST = \ ${TEST_CASES} \ - ${addprefix saved/, ${TEST_CASES:.c=.T.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.T.out}} \ - ${addprefix saved/, ${TEST_CASES:.c=.XP.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.XP.out}} \ - ${addprefix saved/, ${TEST_CASES:.c=.JP.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.JP.out}} \ - ${addprefix saved/, ${TEST_CASES:.c=.HP.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.HP.out}} \ - ${addprefix saved/, ${TEST_CASES:.c=.X.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.X.out}} \ - ${addprefix saved/, ${TEST_CASES:.c=.J.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.J.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.E.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.E.out}} \ ${addprefix saved/, ${TEST_CASES:.c=.H.err}} \ ${addprefix saved/, ${TEST_CASES:.c=.H.out}} \ ${addprefix saved/, ${TEST_CASES:.c=.HIPx.err}} \ ${addprefix saved/, ${TEST_CASES:.c=.HIPx.out}} \ - ${addprefix saved/, ${TEST_CASES:.c=.E.err}} \ - ${addprefix saved/, ${TEST_CASES:.c=.E.out}} + ${addprefix saved/, ${TEST_CASES:.c=.HP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.J.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.J.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JPu.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JPu.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.T.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.T.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.X.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.X.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.XP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.XP.out}} \ + ${addprefix saved/, test_01.Ecsv1.out} \ + ${addprefix saved/, test_01.Ecsv1.err} \ + ${addprefix saved/, test_01.Ecsv2.out} \ + ${addprefix saved/, test_01.Ecsv2.err} \ + ${addprefix saved/, test_01.Ecsv3.out} \ + ${addprefix saved/, test_01.Ecsv3.err} S2O = | ${SED} '1,/@@/d' @@ -91,7 +99,7 @@ echo "... $$test ... $$fmt ..."; \ xoopts==warn,$$csv ; \ ${TEST_JIG}; true; -TEST_FORMATS = T XP JP HP X J H HIPx +TEST_FORMATS = T XP JP JPu HP X J H HIPx test tests: ${bin_PROGRAMS} @${MKDIR} -p out @@ -113,7 +121,7 @@ test tests: ${bin_PROGRAMS} -@ (${TEST_TRACE} test=test_01.c; base=test_01; \ ( fmt=Ecsv1; csv=encoder=csv ; \ ${TEST_JIG2} ); \ - ( fmt=Ecsv2; csv=encoder=csv:path=top/data/item:no-header ; \ + ( fmt=Ecsv2; csv=encoder=csv:path=top-level/data/item:no-header ; \ ${TEST_JIG2} ); \ ( fmt=Ecsv3; csv=@csv:path=item:leafs=sku.sold:no-quotes ; \ ${TEST_JIG2} ); \ diff --git a/contrib/libxo/tests/core/saved/test_01.E.out b/contrib/libxo/tests/core/saved/test_01.E.out index ba063634585..506bfa83526 100644 --- a/contrib/libxo/tests/core/saved/test_01.E.out +++ b/contrib/libxo/tests/core/saved/test_01.E.out @@ -1,5 +1,5 @@ op create: [test] [] [0] -op open_container: [top] [] [0x810] +op open_container: [top-level] [] [0x810] op string: [type] [ethernet] [0] op content: [type] [bridge] [0] op content: [type] [18u] [0] @@ -21,6 +21,10 @@ op string: [label] [value] [0x200000] op string: [max-chaos] [very] [0x1000] op content: [min-chaos] [42] [0] op string: [some-chaos] [[42]] [0] +op attr: [test-attr] [attr-value] [0] +op open_leaf_list: [sku] [] [0] +op string: [sku] [gum-000-1412] [0x2010] +op close_leaf_list: [sku] [] [0] op string: [host] [my-box] [0] op string: [domain] [example.com] [0] op attr: [test] [value] [0] @@ -197,6 +201,6 @@ op content: [mode_octal] [640] [0x8] op content: [links] [1] [0x1000] op string: [user] [user] [0x1000] op string: [group] [group] [0x1000] -op close_container: [top] [] [0] +op close_container: [top-level] [] [0] op finish: [] [] [0] op flush: [] [] [0] diff --git a/contrib/libxo/tests/core/saved/test_01.H.out b/contrib/libxo/tests/core/saved/test_01.H.out index e8ea9fe96e7..b58816d8617 100644 --- a/contrib/libxo/tests/core/saved/test_01.H.out +++ b/contrib/libxo/tests/core/saved/test_01.H.out @@ -1,2 +1,3 @@ -
static
ethernet
bridge
18u
24
anchor
0x0
..
1
anchor
0x0
..
1
anchor
0x0
..
1
df
12
%
testing argument modifier
my-box
.
example.com
...
testing argument modifier with encoding to
.
example.com
...
Label text
value
very
42
42 -
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
ladder
0
2
1
HRD-000-517
bolt
4123
144
42
HRD-000-632
water
17
14
2
GRO-000-2331
Item
'
gum
':
Total sold
:
1412.0
In stock
:
54
On order
:
10
SKU
:
GRO-000-415
Item
'
rope
':
Total sold
:
85.0
In stock
:
4
On order
:
2
SKU
:
HRD-000-212
Item
'
ladder
':
Total sold
:
0
In stock
:
2
On order
:
1
SKU
:
HRD-000-517
Item
'
bolt
':
Total sold
:
4123.0
In stock
:
144
On order
:
42
SKU
:
HRD-000-632
Item
'
water
':
Total sold
:
17.0
In stock
:
14
On order
:
2
SKU
:
GRO-000-2331
Item
'
fish
':
Total sold
:
1321.0
In stock
:
45
On order
:
1
SKU
:
GRO-000-533
Item
:
gum
Item
:
rope
Item
:
ladder
Item
:
bolt
Item
:
water
Item
Total Sold
In Stock
On Order
SKU
gum
1412
10
54
GRO-000-415
rope
85
Extra:
special
2
4
HRD-000-212
ladder
0
Extra:
special
1
2
HRD-000-517
bolt
4123
42
144
HRD-000-632
water
17
Extra:
special
2
14
GRO-000-2331
X
X
X
X
X
X
X
X
X
X
Cost
:
425
X
X
Cost
:
455
links
user
group
3
this
/some/file
1
user
group
\ No newline at end of file +
static
ethernet
bridge
18u
24
anchor
0x0
..
1
anchor
0x0
..
1
anchor
0x0
..
1
df
12
%
testing argument modifier
my-box
.
example.com
...
testing argument modifier with encoding to
.
example.com
...
Label text
value
My Title +
very
42
42 +
gum-1412
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
ladder
0
2
1
HRD-000-517
bolt
4123
144
42
HRD-000-632
water
17
14
2
GRO-000-2331
Item
'
gum
':
Total sold
:
1412.0
In stock
:
54
On order
:
10
SKU
:
GRO-000-415
Item
'
rope
':
Total sold
:
85.0
In stock
:
4
On order
:
2
SKU
:
HRD-000-212
Item
'
ladder
':
Total sold
:
0
In stock
:
2
On order
:
1
SKU
:
HRD-000-517
Item
'
bolt
':
Total sold
:
4123.0
In stock
:
144
On order
:
42
SKU
:
HRD-000-632
Item
'
water
':
Total sold
:
17.0
In stock
:
14
On order
:
2
SKU
:
GRO-000-2331
Item
'
fish
':
Total sold
:
1321.0
In stock
:
45
On order
:
1
SKU
:
GRO-000-533
Item
:
gum
Item
:
rope
Item
:
ladder
Item
:
bolt
Item
:
water
Item
Total Sold
In Stock
On Order
SKU
gum
1412
10
54
GRO-000-415
rope
85
Extra:
special
2
4
HRD-000-212
ladder
0
Extra:
special
1
2
HRD-000-517
bolt
4123
42
144
HRD-000-632
water
17
Extra:
special
2
14
GRO-000-2331
X
X
X
X
X
X
X
X
X
X
Cost
:
425
X
X
Cost
:
455
links
user
group
3
this
/some/file
1
user
group
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_01.HIPx.out b/contrib/libxo/tests/core/saved/test_01.HIPx.out index fa5fd8314e7..da30b72ab7e 100644 --- a/contrib/libxo/tests/core/saved/test_01.HIPx.out +++ b/contrib/libxo/tests/core/saved/test_01.HIPx.out @@ -1,64 +1,67 @@
static
-
ethernet
+
ethernet
-
bridge
+
bridge
-
18u
+
18u
-
24
+
24
anchor
-
0x0
+
0x0
..
-
1
+
1
anchor
-
0x0
+
0x0
..
-
1
+
1
anchor
-
0x0
+
0x0
..
-
1
+
1
df
-
12
+
12
%
testing argument modifier
-
my-box
+
my-box
.
-
example.com
+
example.com
...
testing argument modifier with encoding to
.
-
example.com
+
example.com
...
Label text
-
value
+
value
-
very
-
42
-
42 +
My Title
+
very
+
42
+
42 +
+
gum-1412
Connecting to
-
my-box
+
my-box
.
-
example.com
+
example.com
...
@@ -69,39 +72,39 @@
SKU
-
gum
-
1412
-
54
-
10
-
GRO-000-415
+
gum
+
1412
+
54
+
10
+
GRO-000-415
-
rope
-
85
-
4
-
2
-
HRD-000-212
+
rope
+
85
+
4
+
2
+
HRD-000-212
-
ladder
-
0
-
2
-
1
-
HRD-000-517
+
ladder
+
0
+
2
+
1
+
HRD-000-517
-
bolt
-
4123
-
144
-
42
-
HRD-000-632
+
bolt
+
4123
+
144
+
42
+
HRD-000-632
-
water
-
17
-
14
-
2
-
GRO-000-2331
+
water
+
17
+
14
+
2
+
GRO-000-2331
@@ -110,224 +113,224 @@
Item
'
-
gum
+
gum
':
Total sold
:
-
1412.0
+
1412.0
In stock
:
-
54
+
54
On order
:
-
10
+
10
SKU
:
-
GRO-000-415
+
GRO-000-415
Item
'
-
rope
+
rope
':
Total sold
:
-
85.0
+
85.0
In stock
:
-
4
+
4
On order
:
-
2
+
2
SKU
:
-
HRD-000-212
+
HRD-000-212
Item
'
-
ladder
+
ladder
':
Total sold
:
-
0
+
0
In stock
:
-
2
+
2
On order
:
-
1
+
1
SKU
:
-
HRD-000-517
+
HRD-000-517
Item
'
-
bolt
+
bolt
':
Total sold
:
-
4123.0
+
4123.0
In stock
:
-
144
+
144
On order
:
-
42
+
42
SKU
:
-
HRD-000-632
+
HRD-000-632
Item
'
-
water
+
water
':
Total sold
:
-
17.0
+
17.0
In stock
:
-
14
+
14
On order
:
-
2
+
2
SKU
:
-
GRO-000-2331
+
GRO-000-2331
Item
'
-
fish
+
fish
':
Total sold
:
-
1321.0
+
1321.0
In stock
:
-
45
+
45
On order
:
-
1
+
1
SKU
:
-
GRO-000-533
+
GRO-000-533
Item
:
-
gum
+
gum
Item
:
-
rope
+
rope
Item
:
-
ladder
+
ladder
Item
:
-
bolt
+
bolt
Item
:
-
water
+
water
Item
@@ -337,45 +340,45 @@
SKU
-
gum
-
1412
-
10
-
54
-
GRO-000-415
+
gum
+
1412
+
10
+
54
+
GRO-000-415
-
rope
-
85
+
rope
+
85
Extra:
-
special
-
2
-
4
-
HRD-000-212
+
special
+
2
+
4
+
HRD-000-212
-
ladder
-
0
+
ladder
+
0
Extra:
-
special
-
1
-
2
-
HRD-000-517
+
special
+
1
+
2
+
HRD-000-517
-
bolt
-
4123
-
42
-
144
-
HRD-000-632
+
bolt
+
4123
+
42
+
144
+
HRD-000-632
-
water
-
17
+
water
+
17
Extra:
-
special
-
2
-
14
-
GRO-000-2331
+
special
+
2
+
14
+
GRO-000-2331
@@ -398,7 +401,7 @@
Cost
:
-
425
+
425
X
@@ -407,28 +410,28 @@
Cost
:
-
455
+
455
-
links
+
links
-
user
+
user
-
group
+
group
-
3
-
this
+
3
+
this
-
/some/file
+
/some/file
-
1
+
1
-
user
+
user
-
group
+
group
diff --git a/contrib/libxo/tests/core/saved/test_01.HP.out b/contrib/libxo/tests/core/saved/test_01.HP.out index 9eadb4a1fd2..5a7aed05ac0 100644 --- a/contrib/libxo/tests/core/saved/test_01.HP.out +++ b/contrib/libxo/tests/core/saved/test_01.HP.out @@ -51,10 +51,13 @@
value
+
My Title +
very
42
42
+
gum-1412
Connecting to
my-box
.
diff --git a/contrib/libxo/tests/core/saved/test_01.J.out b/contrib/libxo/tests/core/saved/test_01.J.out index 4a3b05f967b..b8c78267791 100644 --- a/contrib/libxo/tests/core/saved/test_01.J.out +++ b/contrib/libxo/tests/core/saved/test_01.J.out @@ -1 +1 @@ -{"top": {"type":"ethernet","type":"bridge","type":"18u","type":24,"address":"0x0","port":1,"address":"0x0","port":1,"address":"0x0","port":1,"used-percent":12,"kve_start":"0xdeadbeef","kve_end":"0xcabb1e","host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]","host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]}, "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"on-order":10,"in-stock":54}, {"sku":"HRD-000-212","name":"rope","sold":85,"extra":"special","on-order":2,"in-stock":4}, {"sku":"HRD-000-517","name":"ladder","sold":0,"extra":"special","on-order":1,"in-stock":2}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"on-order":42,"in-stock":144}, {"sku":"GRO-000-2331","name":"water","sold":17,"extra":"special","on-order":2,"in-stock":14}]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","pre":"that","links":3,"post":"this","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}} +{"top-level": {"type":"ethernet","type":"bridge","type":"18u","type":24,"address":"0x0","port":1,"address":"0x0","port":1,"address":"0x0","port":1,"used-percent":12,"kve_start":"0xdeadbeef","kve_end":"0xcabb1e","host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]", "sku": ["gum-000-1412"],"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"]}, "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"on-order":10,"in-stock":54}, {"sku":"HRD-000-212","name":"rope","sold":85,"extra":"special","on-order":2,"in-stock":4}, {"sku":"HRD-000-517","name":"ladder","sold":0,"extra":"special","on-order":1,"in-stock":2}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"on-order":42,"in-stock":144}, {"sku":"GRO-000-2331","name":"water","sold":17,"extra":"special","on-order":2,"in-stock":14}]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","pre":"that","links":3,"post":"this","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}} diff --git a/contrib/libxo/tests/core/saved/test_01.JP.out b/contrib/libxo/tests/core/saved/test_01.JP.out index 5c226354c76..71a77cea81d 100644 --- a/contrib/libxo/tests/core/saved/test_01.JP.out +++ b/contrib/libxo/tests/core/saved/test_01.JP.out @@ -1,5 +1,5 @@ { - "top": { + "top-level": { "type": "ethernet", "type": "bridge", "type": "18u", @@ -21,6 +21,9 @@ "max-chaos": "very", "min-chaos": 42, "some-chaos": "[42]", + "sku": [ + "gum-000-1412" + ], "host": "my-box", "domain": "example.com", "data": { diff --git a/contrib/libxo/tests/core/saved/test_01.JPu.err b/contrib/libxo/tests/core/saved/test_01.JPu.err new file mode 100644 index 00000000000..e69de29bb2d diff --git a/contrib/libxo/tests/core/saved/test_01.JPu.out b/contrib/libxo/tests/core/saved/test_01.JPu.out new file mode 100644 index 00000000000..747db16f07a --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.JPu.out @@ -0,0 +1,185 @@ +{ + "top_level": { + "type": "ethernet", + "type": "bridge", + "type": "18u", + "type": 24, + "address": "0x0", + "port": 1, + "address": "0x0", + "port": 1, + "address": "0x0", + "port": 1, + "used_percent": 12, + "kve_start": "0xdeadbeef", + "kve_end": "0xcabb1e", + "host": "my-box", + "domain": "example.com", + "host": "my-box", + "domain": "example.com", + "label": "value", + "max_chaos": "very", + "min_chaos": 42, + "some_chaos": "[42]", + "sku": [ + "gum-000-1412" + ], + "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" + ] + }, + "data": { + "item": [ + { + "sku": "GRO-000-415", + "name": "gum", + "sold": 1412, + "on_order": 10, + "in_stock": 54 + }, + { + "sku": "HRD-000-212", + "name": "rope", + "sold": 85, + "extra": "special", + "on_order": 2, + "in_stock": 4 + }, + { + "sku": "HRD-000-517", + "name": "ladder", + "sold": 0, + "extra": "special", + "on_order": 1, + "in_stock": 2 + }, + { + "sku": "HRD-000-632", + "name": "bolt", + "sold": 4123, + "on_order": 42, + "in_stock": 144 + }, + { + "sku": "GRO-000-2331", + "name": "water", + "sold": 17, + "extra": "special", + "on_order": 2, + "in_stock": 14 + } + ] + }, + "cost": 425, + "cost": 455, + "mode": "mode", + "mode_octal": "octal", + "links": "links", + "user": "user", + "group": "group", + "pre": "that", + "links": 3, + "post": "this", + "mode": "/some/file", + "mode_octal": 640, + "links": 1, + "user": "user", + "group": "group" + } +} diff --git a/contrib/libxo/tests/core/saved/test_01.T.out b/contrib/libxo/tests/core/saved/test_01.T.out index 0b051da25fa..89d3157336e 100644 --- a/contrib/libxo/tests/core/saved/test_01.T.out +++ b/contrib/libxo/tests/core/saved/test_01.T.out @@ -5,8 +5,9 @@ df 12% testing argument modifier my-box.example.com... testing argument modifier with encoding to .example.com... Label text value +My Title very 4242 -Connecting to my-box.example.com... +gum-1412Connecting 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 diff --git a/contrib/libxo/tests/core/saved/test_01.X.out b/contrib/libxo/tests/core/saved/test_01.X.out index 2ba5583fcac..2f1fa826170 100644 --- a/contrib/libxo/tests/core/saved/test_01.X.out +++ b/contrib/libxo/tests/core/saved/test_01.X.out @@ -1 +1 @@ -ethernetbridge18u24
0x0
1
0x0
1
0x0
1120xdeadbeef0xcabb1emy-boxexample.commy-boxexample.comvery42[42]my-boxexample.comGRO-000-415gum14125410HRD-000-212rope8542HRD-000-517ladder021HRD-000-632bolt412314442GRO-000-2331water17142GRO-000-415gum1412.05410HRD-000-212rope85.042HRD-000-517ladder021HRD-000-632bolt4123.014442GRO-000-2331water17.0142GRO-000-533fish1321.0451gumropeladderboltwaterGRO-000-415gum14121054HRD-000-212rope85special24HRD-000-517ladder0special12HRD-000-632bolt412342144GRO-000-2331water17special214425455modeoctallinksusergroup
that
3this/some/file6401usergroup
\ No newline at end of file +ethernetbridge18u24
0x0
1
0x0
1
0x0
1120xdeadbeef0xcabb1emy-boxexample.commy-boxexample.comvery42[42]gum-000-1412my-boxexample.comGRO-000-415gum14125410HRD-000-212rope8542HRD-000-517ladder021HRD-000-632bolt412314442GRO-000-2331water17142GRO-000-415gum1412.05410HRD-000-212rope85.042HRD-000-517ladder021HRD-000-632bolt4123.014442GRO-000-2331water17.0142GRO-000-533fish1321.0451gumropeladderboltwaterGRO-000-415gum14121054HRD-000-212rope85special24HRD-000-517ladder0special12HRD-000-632bolt412342144GRO-000-2331water17special214425455modeoctallinksusergroup
that
3this/some/file6401usergroup
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_01.XP.out b/contrib/libxo/tests/core/saved/test_01.XP.out index e40055a2136..afa79ada5f8 100644 --- a/contrib/libxo/tests/core/saved/test_01.XP.out +++ b/contrib/libxo/tests/core/saved/test_01.XP.out @@ -1,4 +1,4 @@ - + ethernet bridge 18u @@ -20,6 +20,7 @@ very 42 [42] + gum-000-1412 my-box example.com @@ -167,4 +168,4 @@ 1 user group - + diff --git a/contrib/libxo/tests/core/saved/test_02.E.out b/contrib/libxo/tests/core/saved/test_02.E.out index e554b30bab3..7550b680d09 100644 --- a/contrib/libxo/tests/core/saved/test_02.E.out +++ b/contrib/libxo/tests/core/saved/test_02.E.out @@ -23,6 +23,7 @@ op content: [bytes] [2] [0x2004] op content: [bytes] [3] [0x2004] op content: [bytes] [4] [0x2004] op close_leaf_list: [bytes] [] [0] +op content: [granularity-lw] [155] [0] op content: [mbuf-current] [10] [0] op content: [mbuf-cache] [20] [0] op content: [mbuf-total] [30] [0] diff --git a/contrib/libxo/tests/core/saved/test_02.H.out b/contrib/libxo/tests/core/saved/test_02.H.out index a3d88030075..03daf89ff0d 100644 --- a/contrib/libxo/tests/core/saved/test_02.H.out +++ b/contrib/libxo/tests/core/saved/test_02.H.out @@ -2,7 +2,7 @@
abcdef: Bad file descriptor
improper use of profanity; ten yard penalty; first down
length
abcdef
close
-1
returned
Bad file descriptor
good
close
-1
returned
Bad fi
good
improper use of profanity; ten yard penalty; first down -
20
30
40
file
0
bytes
1
byte
2
bytes
3
bytes
4
bytes
10
/
20
/
30
mbufs <&> in use (current/cache/total)
50
from
Boston
64
left out of
640
64
left out of
640
beforeworkingafter:
string
:
10
11
1010
packets here/there/everywhere
1010
packets here/there/everywhere
(
15
/
20
/
125
)
(
15
/
20
/
125
)
(
15
/
20
/
125
)
(
15
/
20
/
125
)
Humanize:
21
,
57 K
,
96M
,
44M
,
1.2G
one
two
three
(null)
1:
1000
2:
test5000
3:
ten-longx
4:
xtest
this is an error
two more errors
this is an warning
two more warnings
V1/V2 packets
:
10
0004
tries
improper use of profanity; ten yard penalty; first down +
20
30
40
file
0
bytes
1
byte
2
bytes
3
bytes
4
bytes
Low/warn granularity
:
155
10
/
20
/
30
mbufs <&> in use (current/cache/total)
50
from
Boston
64
left out of
640
64
left out of
640
beforeworkingafter:
string
:
10
11
1010
packets here/there/everywhere
1010
packets here/there/everywhere
(
15
/
20
/
125
)
(
15
/
20
/
125
)
(
15
/
20
/
125
)
(
15
/
20
/
125
)
Humanize:
21
,
57 K
,
96M
,
44M
,
1.2G
one
two
three
(null)
1:
1000
2:
test5000
3:
ten-longx
4:
xtest
this is an error
two more errors
this is an warning
two more warnings
V1/V2 packets
:
10
0004
tries
improper use of profanity; ten yard penalty; first down
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
err message (1)
err message (2)
err message (1) diff --git a/contrib/libxo/tests/core/saved/test_02.HIPx.out b/contrib/libxo/tests/core/saved/test_02.HIPx.out index 984caa3297f..6859660f2f0 100644 --- a/contrib/libxo/tests/core/saved/test_02.HIPx.out +++ b/contrib/libxo/tests/core/saved/test_02.HIPx.out @@ -78,6 +78,13 @@
bytes
+
+
Low/warn granularity
+
:
+
+
155
+
+
10
/
diff --git a/contrib/libxo/tests/core/saved/test_02.HP.out b/contrib/libxo/tests/core/saved/test_02.HP.out index f2634522dbc..6bf93277a3b 100644 --- a/contrib/libxo/tests/core/saved/test_02.HP.out +++ b/contrib/libxo/tests/core/saved/test_02.HP.out @@ -78,6 +78,13 @@
bytes
+
+
Low/warn granularity
+
:
+
+
155
+
+
10
/
diff --git a/contrib/libxo/tests/core/saved/test_02.J.out b/contrib/libxo/tests/core/saved/test_02.J.out index c34e685b4ac..5e01fa9a8bd 100644 --- a/contrib/libxo/tests/core/saved/test_02.J.out +++ b/contrib/libxo/tests/core/saved/test_02.J.out @@ -1 +1 @@ -{"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}, "error": {"message":"err message (1)"}, "error": {"message":"err message (2)\n"}, "error": {"message":"err message (1)\n"}, "error": {"message":"err message (2)\n"}}}} +{"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","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],"granularity-lw":155,"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}, "error": {"message":"err message (1)"}, "error": {"message":"err message (2)\n"}, "error": {"message":"err message (1)\n"}, "error": {"message":"err message (2)\n"}}}} diff --git a/contrib/libxo/tests/core/saved/test_02.JP.out b/contrib/libxo/tests/core/saved/test_02.JP.out index 1a3b464231b..ef39233d006 100644 --- a/contrib/libxo/tests/core/saved/test_02.JP.out +++ b/contrib/libxo/tests/core/saved/test_02.JP.out @@ -23,6 +23,7 @@ 3, 4 ], + "granularity-lw": 155, "mbuf-current": 10, "mbuf-cache": 20, "mbuf-total": 30, diff --git a/contrib/libxo/tests/core/saved/test_02.JPu.err b/contrib/libxo/tests/core/saved/test_02.JPu.err new file mode 100644 index 00000000000..cedb03e0da3 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.JPu.err @@ -0,0 +1 @@ +test_02: key field emitted after normal value field: 'name' diff --git a/contrib/libxo/tests/core/saved/test_02.JPu.out b/contrib/libxo/tests/core/saved/test_02.JPu.out new file mode 100644 index 00000000000..d0b868a5f8e --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.JPu.out @@ -0,0 +1,99 @@ +{ + "top": { + "data": { + "name": "em0", + "flags": "0x8843", + "name": "em0", + "flags": "0x8843", + "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 + ], + "granularity_lw": 155, + "mbuf_current": 10, + "mbuf_cache": 20, + "mbuf_total": 30, + "distance": 50, + "location": "Boston", + "memory": 64, + "total": 640, + "memory": 64, + "total": 640, + "ten": 10, + "eleven": 11, + "unknown": 1010, + "unknown": 1010, + "min": 15, + "cur": 20, + "max": 125, + "min": 15, + "cur": 20, + "max": 125, + "min": 15, + "cur": 20, + "max": 125, + "min": 15, + "cur": 20, + "max": 125, + "val1": 21, + "val2": 58368, + "val3": 100663296, + "val4": 44470272, + "val5": 1342172800, + "flag": [ + "one", + "two", + "three" + ], + "works": null, + "empty_tag": true, + "t1": "1000", + "t2": "test5000", + "t3": "ten-longx", + "t4": "xtest", + "__error": { + "message": "this is an error" + }, + "__error": { + "message": "two more errors" + }, + "__warning": { + "message": "this is an warning" + }, + "__warning": { + "message": "two more warnings" + }, + "count": 10, + "test": 4, + "error": { + "message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n" + }, + "error": { + "message": "err message (1)" + }, + "error": { + "message": "err message (2)\n" + }, + "error": { + "message": "err message (1)\n" + }, + "error": { + "message": "err message (2)\n" + } + } + } +} diff --git a/contrib/libxo/tests/core/saved/test_02.T.out b/contrib/libxo/tests/core/saved/test_02.T.out index 5b22c1615bb..552e95393ab 100644 --- a/contrib/libxo/tests/core/saved/test_02.T.out +++ b/contrib/libxo/tests/core/saved/test_02.T.out @@ -12,6 +12,7 @@ improper use of profanity; ten yard penalty; first down 2 bytes 3 bytes 4 bytes +Low/warn granularity: 155 mAh 10/20/30 mbufs <&> in use (current/cache/total) 50 miles from Boston 64k left out of 640kb diff --git a/contrib/libxo/tests/core/saved/test_02.X.out b/contrib/libxo/tests/core/saved/test_02.X.out index 598480be994..3c491c3ec81 100644 --- a/contrib/libxo/tests/core/saved/test_02.X.out +++ b/contrib/libxo/tests/core/saved/test_02.X.out @@ -2,7 +2,7 @@ abcdef: Bad file descriptor improper use of profanity; ten yard penalty; first down abcdef-1Bad file descriptorgood-1Bad figoodimproper use of profanity; ten yard penalty; first down -2030400123410203050Boston646406464010111010101015201251520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtest<__error>this is an error<__error>two more errors<__warning>this is an warning<__warning>two more warnings104improper use of profanity; ten yard penalty; first down +2030400123415510203050Boston646406464010111010101015201251520125152012515201252158368100663296444702721342172800onetwothreenull1000test5000ten-longxxtest<__error>this is an error<__error>two more errors<__warning>this is an warning<__warning>two more warnings104improper use of profanity; ten yard penalty; first down Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> err message (1)err message (2) err message (1) diff --git a/contrib/libxo/tests/core/saved/test_02.XP.out b/contrib/libxo/tests/core/saved/test_02.XP.out index 9a0755e0142..c9e85cb46d5 100644 --- a/contrib/libxo/tests/core/saved/test_02.XP.out +++ b/contrib/libxo/tests/core/saved/test_02.XP.out @@ -28,6 +28,7 @@ 2 3 4 + 155 10 20 30 diff --git a/contrib/libxo/tests/core/saved/test_03.JPu.err b/contrib/libxo/tests/core/saved/test_03.JPu.err new file mode 100644 index 00000000000..e69de29bb2d diff --git a/contrib/libxo/tests/core/saved/test_03.JPu.out b/contrib/libxo/tests/core/saved/test_03.JPu.out new file mode 100644 index 00000000000..d0c3ccf45b5 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.JPu.out @@ -0,0 +1,33 @@ +{ + "employees": { + "employee": [ + ], + "extra": "", + "memory": [ + { + "type": "name", + "in_use": 12345, + "memory_use": 54321, + "high_use": "-", + "requests": 32145 + } + ], + "employee": [ + { + "first_name": "Terry", + "last_name": "Jones", + "department": 660 + }, + { + "first_name": "Leslie", + "last_name": "Patterson", + "department": 341 + }, + { + "first_name": "Ashley", + "last_name": "Smith", + "department": 1440 + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_04.JPu.err b/contrib/libxo/tests/core/saved/test_04.JPu.err new file mode 100644 index 00000000000..e69de29bb2d diff --git a/contrib/libxo/tests/core/saved/test_04.JPu.out b/contrib/libxo/tests/core/saved/test_04.JPu.out new file mode 100644 index 00000000000..b0f802dc03f --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.JPu.out @@ -0,0 +1,21 @@ +{ + "employees": { + "employee": [ + { + "first_name": "Terry", + "last_name": "Jones", + "department": 660 + }, + { + "first_name": "Leslie", + "last_name": "Patterson", + "department": 341 + }, + { + "first_name": "Ashley", + "last_name": "Smith", + "department": 1440 + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_05.JPu.err b/contrib/libxo/tests/core/saved/test_05.JPu.err new file mode 100644 index 00000000000..e69de29bb2d diff --git a/contrib/libxo/tests/core/saved/test_05.JPu.out b/contrib/libxo/tests/core/saved/test_05.JPu.out new file mode 100644 index 00000000000..9bcbf69df91 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.JPu.out @@ -0,0 +1,91 @@ +{ + "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": "\"1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 animal-status [animal-status@42 animal="snake" state="loose"] The snake is loose}} +{{test-program: }} +{{The snake is loose}} + +{{<22>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 animal-consumed [animal-consumed@42 animal="snake" pet="hamster"] My snake ate your hamster}} +{{test-program: }} +{{My snake ate your hamster}} + +{{<29>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 animal-talk [animal-talk@42 count="1" animal="owl" quote="\"e=m\\c[2\]\""] 1 owl said "e=m\c[2]"}} +{{test-program: }} +{{1 owl said "e=m\c[2]"}} + +{{<165>1 2015-06-23T13:47:09.123-0500 worker-host test-program 222 ID47 [ID47@32473 iut="3" event-source="application" event-id="1011"] An application 1011 log entry}} +{{test-program: }} +{{An application 1011 log entry}} + +{ + "__version": "3.1.4", + "top": { + + } +} diff --git a/contrib/libxo/tests/core/saved/test_12.JPu.err b/contrib/libxo/tests/core/saved/test_12.JPu.err new file mode 100644 index 00000000000..6e563c3c236 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_12.JPu.err @@ -0,0 +1,4 @@ +test_12: invalid XML tag name: '2by4' +test_12: invalid XML tag name: '4x4' +test_12: invalid XML tag name: '2morrow' +test_12: invalid XML tag name: '2by4' diff --git a/contrib/libxo/tests/core/saved/test_12.JPu.out b/contrib/libxo/tests/core/saved/test_12.JPu.out new file mode 100644 index 00000000000..0095d8dcc59 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_12.JPu.out @@ -0,0 +1,94 @@ +{ + "top": { + "data": { + "animal": "fish", + "animal": "fish", + "thing": [ + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45" + }, + { + "name": "thing", + "color": "green", + "time": "2:15", + "hand": "left", + "color": "blue", + "time": "3:45", + "2by4": { + "4x4": "truck", + "2morrow": "tomorrow" + } + } + ] + } + } +} diff --git a/contrib/libxo/tests/core/test_01.c b/contrib/libxo/tests/core/test_01.c index aeeb0c9ca67..8311efbfc87 100644 --- a/contrib/libxo/tests/core/test_01.c +++ b/contrib/libxo/tests/core/test_01.c @@ -82,7 +82,7 @@ main (int argc, char **argv) xo_set_info(NULL, info, -1); xo_set_flags(NULL, XOF_KEYS); - xo_open_container_h(NULL, "top"); + xo_open_container_h(NULL, "top-level"); xo_emit("static {:type/ethernet} {:type/bridge} {:type/%4du} {:type/%3d}", 18, 24); @@ -104,10 +104,17 @@ main (int argc, char **argv) xo_emit("{La:} {a:}\n", "Label text", "label", "value"); + const char *title = "My Title"; + xo_emit_field("T", title, "%s\n", NULL, NULL); + xo_emit_field("Vt", "max-chaos", NULL, NULL, " very "); xo_emit_field("V", "min-chaos", "%d", NULL, 42); xo_emit_field("V", "some-chaos", "%d\n", "[%d]", 42); + xo_attr("test-attr", "attr-value"); + xo_emit_field_h(NULL, ",leaf-list,quotes", "sku", "%s-%u", "%s-000-%u", + "gum", 1412); + xo_emit("Connecting to {:host}.{:domain}...\n", "my-box", "example.com"); xo_attr("test", "value"); @@ -248,7 +255,7 @@ main (int argc, char **argv) "/some/file", (int) 0640, 8, 1, 10, "user", 12, "group"); - xo_close_container_h(NULL, "top"); + xo_close_container_h(NULL, "top-level"); xo_finish(); diff --git a/contrib/libxo/tests/core/test_02.c b/contrib/libxo/tests/core/test_02.c index 4ea8c459047..7591eb177f7 100644 --- a/contrib/libxo/tests/core/test_02.c +++ b/contrib/libxo/tests/core/test_02.c @@ -85,6 +85,8 @@ main (int argc, char **argv) for (i = 0; i < 5; i++) xo_emit("{lw:bytes/%d}{Np:byte,bytes}\n", i); + xo_emit("{Lc:Low\\/warn granularity}{P:\t}{:granularity-lw/%d}{Uw:/%sh}\n", + 155, "mA"); xo_emit("{:mbuf-current/%u}/{:mbuf-cache/%u}/{:mbuf-total/%u} " "{N:mbufs <&> in use (current\\/cache\\/total)}\n", diff --git a/contrib/libxo/tests/core/test_08.c b/contrib/libxo/tests/core/test_08.c index 80cbff2a4f3..b82a7c1dfcb 100644 --- a/contrib/libxo/tests/core/test_08.c +++ b/contrib/libxo/tests/core/test_08.c @@ -115,11 +115,11 @@ main (int argc, char **argv) ip->i_title, ip->i_count); } - xo_close_container("data3"); /* Should be a noop */ + xo_close_container("data3"); /* warn: fails at marker 'm1' */ xo_emit("{:test}", "one"); xo_close_marker("m1"); - xo_close_container("data3"); /* Should be a noop */ + xo_close_container("data3"); /* this one works, post-marker */ xo_emit("\n\n"); @@ -139,13 +139,13 @@ main (int argc, char **argv) for (i = 0; i < 3; i++) { xo_open_instance("sub"); xo_emit("{Lwc:/Name}{:name/%d} + 1 = {:next/%d}\n", i, i + 1); - xo_close_container("data4"); + xo_close_container("data4"); /* warn: fails at marker 'm2' */ } xo_close_marker("m2"); xo_emit("{Lwc:/Last}{:last/%d}\n", i); } - xo_close_container("data4"); /* Should be a noop */ + xo_close_container("data4"); /* warn: fails at marker 'm1' */ xo_emit("{:test}", "one"); xo_emit("\n\n"); diff --git a/contrib/libxo/tests/xo/xo_01.sh b/contrib/libxo/tests/xo/xo_01.sh old mode 100755 new mode 100644 diff --git a/contrib/libxo/tests/xo/xo_02.sh b/contrib/libxo/tests/xo/xo_02.sh old mode 100755 new mode 100644 diff --git a/contrib/libxo/xo/xo.1 b/contrib/libxo/xo/xo.1 index cd885b3d193..c3d062f750f 100644 --- a/contrib/libxo/xo/xo.1 +++ b/contrib/libxo/xo/xo.1 @@ -179,7 +179,7 @@ prepend data to the XPath values used for HTML output style. .Bd -literal -offset indent #!/bin/sh xo --open top/data - xo --depth 2 '{tag}' value + xo --depth 2 '{:tag}' value xo --close top/data .Pp XML: diff --git a/contrib/libxo/xolint/xolint.pl b/contrib/libxo/xolint/xolint.pl old mode 100755 new mode 100644