Getting valid JSON output with xo(1)

Stefan Esser se at freebsd.org
Sun Sep 9 16:13:20 UTC 2018


Am 09.09.18 um 16:10 schrieb Matt Churchyard:
> Hi Stefan,
> 
> I did include the commands used to generate the sample output in my first
> message. I am using the xo(1) utility, not libxo directly. I did mention
> this might not be the right list (you've obviously assumed I'm directly
> using libxo), but it does seem to me this is more an issue with the xo
> utility, rather than just a usage error.

Hi Matt,

I'm sorry - you are of course right and there was everything required to
reproduce the effect in your previous mail ...

> I've since looked further into the libxo documentation, and as you suggest,
> it does seem that I need to be using the xo_open_list/xo_close_list
> functions to generate the right output. However, these are not exposed via
> xo(1). The documentation for xo_open_list describes how it is used to
> create lists of individual entities, whereas the "l" modifier (which is all
> I can access via xo(1)) creates "leaf lists", which are only for single
> values. As such, it seems there's a big hole in the functionality of xo(1),
> meaning it can only really be used to create very simple JSON documents.

The following code fragment in libxo.c does suppress the terminating new-line
character on purpose if depth != 0:

    case XO_STYLE_JSON:
	pre_nl = XOF_ISSET(xop, XOF_PRETTY) ? "\n" : "";
	ppn = (xop->xo_depth <= 1) ? "\n" : "";

	xo_depth_change(xop, name, -1, -1, XSS_CLOSE_CONTAINER, 0);
	rc = xo_printf(xop, "%s%*s}%s", pre_nl, xo_indent(xop), "", ppn);
	xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST;
	break;

The reason appears to be, that closing the outer level construct will print
a new-line before other text. If you omit the second "xo --wrap", everything
will look OK. And if you test with --depth 0, you'll see that the output is
actually terminated with a new-line.

> As I mentioned in my first message, it looks like xo(1) could do with some
> way to open/close lists, similar to the --open/--close options, and a way
> to specify that a single call should be output as a part of a list.

I do not see a better solution than adding an "echo" command between calls
to "xo --wrap", as you already mentioned as a work-around. This is simpler
than adding list_open/close functions and it has the same effect, if you
know that you are emitting JSON.

Best regards, STefan


More information about the freebsd-hackers mailing list