[PATCH v7 1/3] Add support for structured output formatters.

Tomi Ollila tomi.ollila at iki.fi
Fri Jul 20 02:09:07 PDT 2012


On Fri, Jul 20 2012, craven at gmx.net wrote:

> From: <craven at gmx.net>
>
> 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 at 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 *);

The above block duplicated below. Otherwise this LGTM.

I presume the patch 3/3 emails

id:"1342766173-1344-4-git-send-email-craven at gmx.net"
id:"1342772624-23329-1-git-send-email-craven at gmx.net"

have identical content ?

> 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"}}
> ---
>  sprinter.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
>  create mode 100644 sprinter.h
>
> diff --git a/sprinter.h b/sprinter.h
> new file mode 100644
> index 0000000..77dc26f
> --- /dev/null
> +++ b/sprinter.h
> @@ -0,0 +1,58 @@
> +#ifndef NOTMUCH_SPRINTER_H
> +#define NOTMUCH_SPRINTER_H
> +
> +/* Necessary for notmuch_bool_t */
> +#include "notmuch-client.h"
> +
> +/* Structure printer interface. This is used to create output
> + * structured as maps (with key/value pairs), lists and primitives
> + * (strings, integers and booleans).
> + */
> +typedef struct sprinter {
> +    /* 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 *);
> +
> +    /* True if this is the special-cased plain text printer.
> +     */
> +    notmuch_bool_t is_text_printer;
> +} sprinter_t;
> +
> +#endif // NOTMUCH_SPRINTER_H
> -- 
> 1.7.11.2
>
> _______________________________________________
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


More information about the notmuch mailing list