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

Subject: [PATCH v4 1/3] Add support for structured output formatters.

Date: Thu, 12 Jul 2012 09:43:22 +0200

To: notmuch@notmuchmail.org

Cc:

From: craven@gmx.net


This patch adds a new type sprinter_t, which is used for structured
formatting, e.g. JSON or S-Expressions. The structure printer is the
code from Austin Clements (id:87d34hsdx8.fsf@awakening.csail.mit.edu).

The structure printer contains the following function pointers:

/* start a new map/dictionary structure.
 */
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
 */
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.
 */
void (*map_key) (struct sprinter *, const char *);

/* print a frame delimiter (such as a newline or extra whitespace)
 */
void (*frame) (struct sprinter *);

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 | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 sprinter.h

diff --git a/sprinter.h b/sprinter.h
new file mode 100644
index 0000000..1dad9a0
--- /dev/null
+++ b/sprinter.h
@@ -0,0 +1,49 @@
+#ifndef NOTMUCH_SPRINTER_H
+#define NOTMUCH_SPRINTER_H
+
+/* for notmuch_bool_t */
+#include "notmuch-client.h"
+
+/* Structure printer interface */
+typedef struct sprinter
+{
+    /* start a new map/dictionary structure.
+     */
+    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
+     */
+    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.
+     */
+    void (*map_key) (struct sprinter *, const char *);
+
+    /* print a frame delimiter (such as a newline or extra whitespace)
+     */
+    void (*frame) (struct sprinter *);
+} sprinter_t;
+
+/* Create a new structure printer that emits JSON */
+struct sprinter *
+sprinter_json_new(const void *ctx, FILE *stream);
+
+/* A dummy structure printer that signifies that standard text output is
+ * to be used instead of any structured format.
+ */
+struct sprinter *
+sprinter_text;
+
+#endif // NOTMUCH_SPRINTER_H
-- 
1.7.11.1


Thread: