1 Return-Path: <craven@gmx.net>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 72F09431FCB
\r
6 for <notmuch@notmuchmail.org>; Thu, 19 Jul 2012 23:34:57 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0.001 tagged_above=-999 required=5
\r
12 tests=[FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001]
\r
14 Received: from olra.theworths.org ([127.0.0.1])
\r
15 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id JYFH5N8Gd2CA for <notmuch@notmuchmail.org>;
\r
17 Thu, 19 Jul 2012 23:34:53 -0700 (PDT)
\r
18 Received: from mailout-de.gmx.net (mailout-de.gmx.net [213.165.64.23])
\r
19 by olra.theworths.org (Postfix) with SMTP id 11165431FBC
\r
20 for <notmuch@notmuchmail.org>; Thu, 19 Jul 2012 23:34:50 -0700 (PDT)
\r
21 Received: (qmail invoked by alias); 20 Jul 2012 06:34:44 -0000
\r
22 Received: from gw.arelion.cust.net.lagis.at (EHLO dodekanex.arelion.at)
\r
24 by mail.gmx.net (mp069) with SMTP; 20 Jul 2012 08:34:44 +0200
\r
25 X-Authenticated: #201305
\r
26 X-Provags-ID: V01U2FsdGVkX19ltEZ7s0Zl5D69fpoGnawGa8JNoDGxjLUKbKc4Wl
\r
28 Received: by dodekanex.arelion.at (Postfix, from userid 1000)
\r
29 id B9FAF301BF6; Fri, 20 Jul 2012 08:36:18 +0200 (CEST)
\r
30 From: craven@gmx.net
\r
31 To: notmuch@notmuchmail.org
\r
32 Subject: [PATCH v7 1/3] Add support for structured output formatters.
\r
33 Date: Fri, 20 Jul 2012 08:36:11 +0200
\r
34 Message-Id: <1342766173-1344-2-git-send-email-craven@gmx.net>
\r
35 X-Mailer: git-send-email 1.7.11.2
\r
36 In-Reply-To: <1342766173-1344-1-git-send-email-craven@gmx.net>
\r
37 References: <20120718194819.GP31670@mit.edu>
\r
38 <1342766173-1344-1-git-send-email-craven@gmx.net>
\r
40 X-BeenThere: notmuch@notmuchmail.org
\r
41 X-Mailman-Version: 2.1.13
\r
43 List-Id: "Use and development of the notmuch mail system."
\r
44 <notmuch.notmuchmail.org>
\r
45 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
46 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
47 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
48 List-Post: <mailto:notmuch@notmuchmail.org>
\r
49 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
50 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
51 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
52 X-List-Received-Date: Fri, 20 Jul 2012 06:34:57 -0000
\r
54 From: <craven@gmx.net>
\r
56 This patch adds a new struct type sprinter_t, which is used for
\r
57 structured formatting, e.g. JSON or S-Expressions. The structure printer
\r
58 is heavily based on code from Austin Clements
\r
59 (id:87d34hsdx8.fsf@awakening.csail.mit.edu).
\r
61 It includes the following functions:
\r
63 /* Start a new map/dictionary structure. This should be followed by
\r
64 * a sequence of alternating calls to map_key and one of the
\r
65 * value-printing functions until the map is ended by end.
\r
67 void (*begin_map) (struct sprinter *);
\r
69 /* Start a new list/array structure.
\r
71 void (*begin_list) (struct sprinter *);
\r
73 /* End the last opened list or map structure.
\r
75 void (*end) (struct sprinter *);
\r
77 /* Print one string/integer/boolean/null element (possibly inside a
\r
78 * list or map, followed or preceded by separators).
\r
79 * For string, the char * must be UTF-8 encoded.
\r
81 void (*string) (struct sprinter *, const char *);
\r
82 void (*integer) (struct sprinter *, int);
\r
83 void (*boolean) (struct sprinter *, notmuch_bool_t);
\r
84 void (*null) (struct sprinter *);
\r
86 /* Print the key of a map's key/value pair. The char * must be UTF-8
\r
89 void (*map_key) (struct sprinter *, const char *);
\r
91 /* Insert a separator (usually extra whitespace) for improved
\r
92 * readability without affecting the abstract syntax of the
\r
93 * structure being printed.
\r
94 * For JSON, this could simply be a line break.
\r
96 void (*separator) (struct sprinter *);
\r
98 /* Set the current string prefix. This only affects the text
\r
99 * printer, which will print this string, followed by a colon,
\r
100 * before any string. For other printers, this does nothing.
\r
102 void (*set_prefix) (struct sprinter *, const char *);
\r
104 To support the plain text format properly, the following additional
\r
105 function must also be implemented:
\r
107 /* Set the current string prefix. This only affects the text
\r
108 * printer, which will print this string, followed by a colon,
\r
109 * before any string. For other printers, this does nothing.
\r
111 void (*set_prefix) (struct sprinter *, const char *);
\r
113 The structure also contains a flag that should be set to FALSE in all
\r
114 custom printers and to TRUE in the plain text formatter.
\r
116 /* True if this is the special-cased plain text printer.
\r
118 notmuch_bool_t is_text_printer;
\r
120 The printer can (and should) use internal state to insert delimiters
\r
121 and syntax at the correct places.
\r
125 format->begin_map(format);
\r
126 format->map_key(format, "foo");
\r
127 format->begin_list(format);
\r
128 format->integer(format, 1);
\r
129 format->integer(format, 2);
\r
130 format->integer(format, 3);
\r
131 format->end(format);
\r
132 format->map_key(format, "bar");
\r
133 format->begin_map(format);
\r
134 format->map_key(format, "baaz");
\r
135 format->string(format, "hello world");
\r
136 format->end(format);
\r
137 format->end(format);
\r
139 would output JSON as follows:
\r
141 {"foo": [1, 2, 3], "bar": { "baaz": "hello world"}}
\r
143 sprinter.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
\r
144 1 file changed, 58 insertions(+)
\r
145 create mode 100644 sprinter.h
\r
147 diff --git a/sprinter.h b/sprinter.h
\r
148 new file mode 100644
\r
149 index 0000000..77dc26f
\r
153 +#ifndef NOTMUCH_SPRINTER_H
\r
154 +#define NOTMUCH_SPRINTER_H
\r
156 +/* Necessary for notmuch_bool_t */
\r
157 +#include "notmuch-client.h"
\r
159 +/* Structure printer interface. This is used to create output
\r
160 + * structured as maps (with key/value pairs), lists and primitives
\r
161 + * (strings, integers and booleans).
\r
163 +typedef struct sprinter {
\r
164 + /* Start a new map/dictionary structure. This should be followed by
\r
165 + * a sequence of alternating calls to map_key and one of the
\r
166 + * value-printing functions until the map is ended by end.
\r
168 + void (*begin_map) (struct sprinter *);
\r
170 + /* Start a new list/array structure.
\r
172 + void (*begin_list) (struct sprinter *);
\r
174 + /* End the last opened list or map structure.
\r
176 + void (*end) (struct sprinter *);
\r
178 + /* Print one string/integer/boolean/null element (possibly inside a
\r
179 + * list or map, followed or preceded by separators).
\r
180 + * For string, the char * must be UTF-8 encoded.
\r
182 + void (*string) (struct sprinter *, const char *);
\r
183 + void (*integer) (struct sprinter *, int);
\r
184 + void (*boolean) (struct sprinter *, notmuch_bool_t);
\r
185 + void (*null) (struct sprinter *);
\r
187 + /* Print the key of a map's key/value pair. The char * must be UTF-8
\r
190 + void (*map_key) (struct sprinter *, const char *);
\r
192 + /* Insert a separator (usually extra whitespace) for improved
\r
193 + * readability without affecting the abstract syntax of the
\r
194 + * structure being printed.
\r
195 + * For JSON, this could simply be a line break.
\r
197 + void (*separator) (struct sprinter *);
\r
199 + /* Set the current string prefix. This only affects the text
\r
200 + * printer, which will print this string, followed by a colon,
\r
201 + * before any string. For other printers, this does nothing.
\r
203 + void (*set_prefix) (struct sprinter *, const char *);
\r
205 + /* True if this is the special-cased plain text printer.
\r
207 + notmuch_bool_t is_text_printer;
\r
210 +#endif // NOTMUCH_SPRINTER_H
\r