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

craven at gmx.net craven at gmx.net
Tue Jul 10 11:56:09 PDT 2012


This patch adds a new type structure_printer, which is used for structured formatting, e.g. JSON or S-Expressions.

The structure contains the following function pointers:

- initial_state: is called to create a state object, that is passed to all invocations. This should be used to keep track of the output file and everything else necessary to correctly format output.
- map: is called when a new map (associative array, dictionary) is started. map_key and the primitives (string, number, bool) are used alternatingly to add key/value pairs. pop is used to close the map (see there). This function must return a nesting level identifier that can be used to close all nested structures (maps and lists), backing out to the returned nesting level.
- list: is called when a new list (array, vector) is started. the primitives (string, number, bool) are used consecutively to add values to the list. pop is used to close the list. This function must return a nesting level identifier that can be used to close all nested structures (maps and lists), backing out to the returned nesting level.
- pop: is called to return to a given nesting level. All lists and maps with a deeper nesting level must be closed.
- number, string, bool: output one element of the specific type.

All functions should use state to insert delimiters etc. automatically when appropriate.

Example:
int top, one;
top = map(state);
map_key(state, "foo");
one = list(state);
number(state, 1);
number(state, 2);
number(state, 3);
pop(state, one);
map_key(state, "bar");
map(state);
map_key(state, "baaz");
string(state, "hello world");
pop(state, top);

would output JSON as follows:

{"foo": [1, 2, 3], "bar": { "baaz": "hello world"}}
---
 Makefile.local      |    1 +
 structured-output.h |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 structured-output.h

diff --git a/Makefile.local b/Makefile.local
index a890df2..9b3db5e 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -286,6 +286,7 @@ notmuch_client_srcs =		\
 	notmuch-reply.c		\
 	notmuch-restore.c	\
 	notmuch-search.c	\
+	structured-output.c     \
 	notmuch-setup.c		\
 	notmuch-show.c		\
 	notmuch-tag.c		\
diff --git a/structured-output.h b/structured-output.h
new file mode 100644
index 0000000..b43afe0
--- /dev/null
+++ b/structured-output.h
@@ -0,0 +1,64 @@
+/* notmuch - Not much of an email program, (just index and search)
+ *
+ * Copyright © 2009 Carl Worth
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ *
+ * Author: Carl Worth <cworth at cworth.org>
+ */
+
+#include "notmuch-client.h"
+
+/* structured formatting, useful for JSON, S-Expressions, ...
+
+- initial_state: is called to create a state object, that is passed to all invocations. This should be used to keep track of the output file and everything else necessary to correctly format output.
+- map: is called when a new map (associative array, dictionary) is started. map_key and the primitives (string, number, bool) are used alternatingly to add key/value pairs. pop is used to close the map (see there). This function must return a nesting level identifier that can be used to close all nested structures (maps and lists), backing out to the returned nesting level.
+- list: is called when a new list (array, vector) is started. the primitives (string, number, bool) are used consecutively to add values to the list. pop is used to close the list. This function must return a nesting level identifier that can be used to close all nested structures (maps and lists), backing out to the returned nesting level.
+- pop: is called to return to a given nesting level. All lists and maps with a deeper nesting level must be closed.
+- number, string, bool: output one element of the specific type.
+
+All functions should use state to insert delimiters etc. automatically when appropriate.
+
+Example:
+int top, one;
+top = map(state);
+map_key(state, "foo");
+one = list(state);
+number(state, 1);
+number(state, 2);
+number(state, 3);
+pop(state, one);
+map_key(state, "bar");
+map(state);
+map_key(state, "baaz");
+string(state, "hello world");
+pop(state, top);
+
+would output JSON as follows:
+
+{"foo": [1, 2, 3], "bar": { "baaz": "hello world"}}
+
+ */
+typedef struct structure_printer {
+    int (*map)(void *state);
+    int (*list)(void *state);
+    void (*pop)(void *state, int level);
+    void (*map_key)(void *state, const char *key);
+    void (*number)(void *state, int val);
+    void (*string)(void *state, const char *val);
+    void (*bool)(void *state, notmuch_bool_t val);
+    void *(*initial_state)(const struct structure_printer *sp, FILE *output);
+} structure_printer_t;
+
+
-- 
1.7.10.4


More information about the notmuch mailing list