unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH v3 1/3] Add support for structured output formatters.
@ 2012-07-10 18:56 craven
  0 siblings, 0 replies; 2+ messages in thread
From: craven @ 2012-07-10 18:56 UTC (permalink / raw)
  To: notmuch

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@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

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH v3 1/3] Add support for structured output formatters.
  2012-07-11  8:26 ` [PATCH v3 0/3] Structured Formatters craven
@ 2012-07-11  8:26   ` craven
  0 siblings, 0 replies; 2+ messages in thread
From: craven @ 2012-07-11  8:26 UTC (permalink / raw)
  To: notmuch

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.
- map_key: is called to write the key of a key/value pair.
- 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. State is a user-defined object/data that can contain
arbitrary information. Initial state is constructed by a call to
initial_state.

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"}}
---
 structured-output.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 structured-output.h

diff --git a/structured-output.h b/structured-output.h
new file mode 100644
index 0000000..73029f1
--- /dev/null
+++ b/structured-output.h
@@ -0,0 +1,90 @@
+/* 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@cworth.org>
+ */
+
+#include "notmuch-client.h"
+
+/* structured formatting, useful for JSON, S-Expressions, ...
+ *
+ * All functions should use state to insert delimiters
+ * etc. automatically when appropriate. State is a user-defined
+ * object/data that can contain arbitrary information. Initial state is
+ * constructed by a call to initial_state.
+ *
+ * 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 {
+    /* 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 number that can be used to close all nested structures
+     * (maps and lists), backing out to the returned nesting level.
+     */
+    int (*map) (void *state);
+
+    /* 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 number that can be used to
+     * close all nested structures (maps and lists), backing out to the
+     * returned nesting level.
+     */
+    int (*list) (void *state);
+
+    /* pop: is called to return to a given nesting level. All lists and
+     * maps with a deeper nesting level must be closed.
+     */
+    void (*pop) (void *state, int level);
+
+    /* map_key: is called to write the key of a key/value pair.
+     */
+    void (*map_key) (void *state, const char *key);
+
+    /* number, string, bool: output one element of the specific type. */
+    void (*number) (void *state, int val);
+    void (*string) (void *state, const char *val);
+    void (*bool) (void *state, notmuch_bool_t val);
+
+    /* 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.
+     */
+    void *(*initial_state) (const struct structure_printer *sp,
+			    FILE *output);
+
+} structure_printer_t;
-- 
1.7.11.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-07-11  8:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-10 18:56 [PATCH v3 1/3] Add support for structured output formatters craven
  -- strict thread matches above, loose matches on Subject: below --
2012-07-10 19:13 [PATCH] v2: Added better support for multiple structured output formats Austin Clements
2012-07-11  8:26 ` [PATCH v3 0/3] Structured Formatters craven
2012-07-11  8:26   ` [PATCH v3 1/3] Add support for structured output formatters craven

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).