Commit graph

5 commits

Author SHA1 Message Date
Peter Feigl
fd3ffe35a2 Adding an S-expression structured output printer.
This commit adds a structured output printer for Lisp
S-Expressions. Later commits will use this printer in notmuch search,
show and reply.

The structure is the same as json, but:
- arrays are written as lists: ("foo" "bar" "baaz" 1 2 3)
- maps are written as p-lists: (:key "value" :other-key "other-value")
- true is written as t
- false is written as nil
- null is written as nil

[ whitespace changes by db ]
2012-12-08 09:26:29 -04:00
Mark Walters
94c3b40d41 sprinters: bugfix when NULL passed for a string.
The string function in a sprinter may be called with a NULL string
pointer (eg if a header is absent). This causes a segfault. We fix
this by checking for a null pointer in the string functions and update
the sprinter documentation.

At the moment some output when format=text is done directly rather than
via an sprinter: in that case a null pointer is passed to printf or
similar and a "(null)" appears in the output. That behaviour is not
changed in this patch.
2012-08-12 21:25:01 +02:00
Austin Clements
14883b0700 sprinter: Add a string_len method
This method allows callers to output strings with specific lengths.
It's useful both for strings with embedded NULs (which JSON can
represent, though parser support is apparently spotty), and
non-terminated strings.
2012-08-03 20:21:29 -03:00
craven@gmx.net
36522fca1c Add structured output formatter for JSON and plain text (but don't use them yet).
Using the new structured printer support in sprinter.h, implement
sprinter_json_create, which returns a new JSON structured output
formatter. The formatter prints output similar to the existing JSON, but
with differences in whitespace (mostly newlines, --output=summary prints
the entire message summary on one line, not split across multiple lines).

Also implement a "structured" formatter for plain text that prints
prefixed strings, to be used with notmuch-search.c plain text output.
2012-07-24 09:26:59 -03:00
craven@gmx.net
41becc0c9d Add support for structured output formatters.
This patch adds a new struct type sprinter_t, which is used for
structured formatting, e.g. JSON or S-Expressions. The structure printer
is heavily based on code from Austin Clements
(id:87d34hsdx8.fsf@awakening.csail.mit.edu).

It includes the following functions:

    /* Start a new map/dictionary structure. This should be followed by
     * a sequence of alternating calls to map_key and one of the
     * value-printing functions until the map is ended by end.
     */
    void (*begin_map) (struct sprinter *);

    /* Start a new list/array structure.
     */
    void (*begin_list) (struct sprinter *);

    /* End the last opened list or map structure.
     */
    void (*end) (struct sprinter *);

    /* Print one string/integer/boolean/null element (possibly inside a
     * list or map, followed or preceded by separators).
     * For string, the char * must be UTF-8 encoded.
     */
    void (*string) (struct sprinter *, const char *);
    void (*integer) (struct sprinter *, int);
    void (*boolean) (struct sprinter *, notmuch_bool_t);
    void (*null) (struct sprinter *);

    /* Print the key of a map's key/value pair. The char * must be UTF-8
     * encoded.
     */
    void (*map_key) (struct sprinter *, const char *);

    /* Insert a separator (usually extra whitespace) for improved
     * readability without affecting the abstract syntax of the
     * structure being printed.
     * For JSON, this could simply be a line break.
     */
    void (*separator) (struct sprinter *);

    /* Set the current string prefix. This only affects the text
     * printer, which will print this string, followed by a colon,
     * before any string. For other printers, this does nothing.
     */
    void (*set_prefix) (struct sprinter *, const char *);

To support the plain text format properly, the following additional
function must also be implemented:

    /* Set the current string prefix. This only affects the text
     * printer, which will print this string, followed by a colon,
     * before any string. For other printers, this does nothing.
     */
    void (*set_prefix) (struct sprinter *, const char *);

The structure also contains a flag that should be set to FALSE in all
custom printers and to TRUE in the plain text formatter.

    /* True if this is the special-cased plain text printer.
     */
    notmuch_bool_t is_text_printer;

The printer can (and should) use internal state to insert delimiters
and syntax at the correct places.

Example:

format->begin_map(format);
format->map_key(format, "foo");
format->begin_list(format);
format->integer(format, 1);
format->integer(format, 2);
format->integer(format, 3);
format->end(format);
format->map_key(format, "bar");
format->begin_map(format);
format->map_key(format, "baaz");
format->string(format, "hello world");
format->end(format);
format->end(format);

would output JSON as follows:

{"foo": [1, 2, 3], "bar": { "baaz": "hello world"}}
2012-07-24 09:26:49 -03:00