[PATCH 0/2] lib: Allow read-only messages to be synchronized to a writable database
[notmuch-archives.git] / 02 / 1d460ed2a2f34b2e9ff08e52b836162c43c1de
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 7C286431FC3\r
6         for <notmuch@notmuchmail.org>; Mon, 16 Jul 2012 23:04:43 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0.001\r
10 X-Spam-Level: \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
13         autolearn=disabled\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 40t7iUMC0gG7 for <notmuch@notmuchmail.org>;\r
17         Mon, 16 Jul 2012 23:04:41 -0700 (PDT)\r
18 Received: from mailout-de.gmx.net (mailout-de.gmx.net [213.165.64.22])\r
19         by olra.theworths.org (Postfix) with SMTP id 9690E431FDA\r
20         for <notmuch@notmuchmail.org>; Mon, 16 Jul 2012 23:04:38 -0700 (PDT)\r
21 Received: (qmail invoked by alias); 17 Jul 2012 06:04:36 -0000\r
22 Received: from gw.arelion.cust.net.lagis.at (EHLO dodekanex.arelion.at)\r
23         [83.164.197.182]\r
24         by mail.gmx.net (mp032) with SMTP; 17 Jul 2012 08:04:36 +0200\r
25 X-Authenticated: #201305\r
26 X-Provags-ID: V01U2FsdGVkX1+GX8Zf46mGH4YAZBhReaiFebarWJ1/Yk5o3h7s5/\r
27         i5mbwX5C2lkeB0\r
28 Received: by dodekanex.arelion.at (Postfix, from userid 1000)\r
29         id EB349303543; Mon, 16 Jul 2012 10:35:05 +0200 (CEST)\r
30 From: <craven@gmx.net>\r
31 To: notmuch@notmuchmail.org\r
32 Subject: [PATCH v6 1/3] Add support for structured output formatters.\r
33 Date: Mon, 16 Jul 2012 10:35:00 +0200\r
34 Message-Id: <1342427702-23316-2-git-send-email-craven@gmx.net>\r
35 X-Mailer: git-send-email 1.7.11.1\r
36 In-Reply-To: <1342427702-23316-1-git-send-email-craven@gmx.net>\r
37 References: <20120714020954.GD31670@mit.edu>\r
38         <1342427702-23316-1-git-send-email-craven@gmx.net>\r
39 X-Y-GMX-Trusted: 0\r
40 X-BeenThere: notmuch@notmuchmail.org\r
41 X-Mailman-Version: 2.1.13\r
42 Precedence: list\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: Tue, 17 Jul 2012 06:04:44 -0000\r
53 \r
54 This patch adds a new struct type sprinter_t, which is used for\r
55 structured formatting, e.g. JSON or S-Expressions. The structure printer\r
56 is heavily based on code from Austin Clements\r
57 (id:87d34hsdx8.fsf@awakening.csail.mit.edu).\r
58 \r
59 It includes the following functions:\r
60 \r
61     /* Start a new map/dictionary structure. This should be followed by\r
62      * a sequence of alternating calls to map_key and one of the\r
63      * value-printing functions until the map is ended by end.\r
64      */\r
65     void (*begin_map) (struct sprinter *);\r
66 \r
67     /* Start a new list/array structure.\r
68      */\r
69     void (*begin_list) (struct sprinter *);\r
70 \r
71     /* End the last opened list or map structure.\r
72      */\r
73     void (*end) (struct sprinter *);\r
74 \r
75     /* Print one string/integer/boolean/null element (possibly inside a\r
76      * list or map, followed or preceded by separators).\r
77      * For string, the char * must be UTF-8 encoded.\r
78      */\r
79     void (*string) (struct sprinter *, const char *);\r
80     void (*integer) (struct sprinter *, int);\r
81     void (*boolean) (struct sprinter *, notmuch_bool_t);\r
82     void (*null) (struct sprinter *);\r
83 \r
84     /* Print the key of a map's key/value pair. The char * must be UTF-8\r
85      * encoded.\r
86      */\r
87     void (*map_key) (struct sprinter *, const char *);\r
88 \r
89     /* Insert a separator (usually extra whitespace) for improved\r
90      * readability without affecting the abstract syntax of the\r
91      * structure being printed.\r
92      * For JSON, this could simply be a line break.\r
93      */\r
94     void (*separator) (struct sprinter *);\r
95 \r
96 To support the plain text format properly, the following two additional\r
97 functions must also be implemented:\r
98 \r
99     /* Set the current string prefix. This only affects the text\r
100      * printer, which will print this string, followed by a colon,\r
101      * before any string. For other printers, this does nothing.\r
102      */\r
103     void (*set_prefix) (struct sprinter *, const char *);\r
104 \r
105     /* Return TRUE if this is a text printer. Some special casing\r
106      * applies to the pure plain text printer. This should always\r
107      * return FALSE in custom structured output printers.\r
108      */\r
109     notmuch_bool_t (*is_text_printer) (struct sprinter *);\r
110 \r
111 The printer can (and should) use internal state to insert delimiters\r
112 and syntax at the correct places.\r
113 \r
114 Example:\r
115 \r
116 format->begin_map(format);\r
117 format->map_key(format, "foo");\r
118 format->begin_list(format);\r
119 format->integer(format, 1);\r
120 format->integer(format, 2);\r
121 format->integer(format, 3);\r
122 format->end(format);\r
123 format->map_key(format, "bar");\r
124 format->begin_map(format);\r
125 format->map_key(format, "baaz");\r
126 format->string(format, "hello world");\r
127 format->end(format);\r
128 format->end(format);\r
129 \r
130 would output JSON as follows:\r
131 \r
132 {"foo": [1, 2, 3], "bar": { "baaz": "hello world"}}\r
133 ---\r
134  sprinter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
135  1 file changed, 60 insertions(+)\r
136  create mode 100644 sprinter.h\r
137 \r
138 diff --git a/sprinter.h b/sprinter.h\r
139 new file mode 100644\r
140 index 0000000..dc09a15\r
141 --- /dev/null\r
142 +++ b/sprinter.h\r
143 @@ -0,0 +1,60 @@\r
144 +#ifndef NOTMUCH_SPRINTER_H\r
145 +#define NOTMUCH_SPRINTER_H\r
146 +\r
147 +/* Necessary for notmuch_bool_t */\r
148 +#include "notmuch-client.h"\r
149 +\r
150 +/* Structure printer interface. This is used to create output\r
151 + * structured as maps (with key/value pairs), lists and primitives\r
152 + * (strings, integers and booleans).\r
153 + */\r
154 +typedef struct sprinter {\r
155 +    /* Start a new map/dictionary structure. This should be followed by\r
156 +     * a sequence of alternating calls to map_key and one of the\r
157 +     * value-printing functions until the map is ended by end.\r
158 +     */\r
159 +    void (*begin_map) (struct sprinter *);\r
160 +\r
161 +    /* Start a new list/array structure.\r
162 +     */\r
163 +    void (*begin_list) (struct sprinter *);\r
164 +\r
165 +    /* End the last opened list or map structure.\r
166 +     */\r
167 +    void (*end) (struct sprinter *);\r
168 +\r
169 +    /* Print one string/integer/boolean/null element (possibly inside a\r
170 +     * list or map, followed or preceded by separators).\r
171 +     * For string, the char * must be UTF-8 encoded.\r
172 +     */\r
173 +    void (*string) (struct sprinter *, const char *);\r
174 +    void (*integer) (struct sprinter *, int);\r
175 +    void (*boolean) (struct sprinter *, notmuch_bool_t);\r
176 +    void (*null) (struct sprinter *);\r
177 +\r
178 +    /* Print the key of a map's key/value pair. The char * must be UTF-8\r
179 +     * encoded.\r
180 +     */\r
181 +    void (*map_key) (struct sprinter *, const char *);\r
182 +\r
183 +    /* Insert a separator (usually extra whitespace) for improved\r
184 +     * readability without affecting the abstract syntax of the\r
185 +     * structure being printed.\r
186 +     * For JSON, this could simply be a line break.\r
187 +     */\r
188 +    void (*separator) (struct sprinter *);\r
189 +\r
190 +    /* Set the current string prefix. This only affects the text\r
191 +     * printer, which will print this string, followed by a colon,\r
192 +     * before any string. For other printers, this does nothing.\r
193 +     */\r
194 +    void (*set_prefix) (struct sprinter *, const char *);\r
195 +\r
196 +    /* Return TRUE if this is a text printer. Some special casing\r
197 +     * applies to the pure plain text printer. This should always\r
198 +     * return FALSE in custom structured output printers.\r
199 +     */ \r
200 +    notmuch_bool_t (*is_text_printer) (struct sprinter *);\r
201 +} sprinter_t;\r
202 +\r
203 +#endif // NOTMUCH_SPRINTER_H\r
204 -- \r
205 1.7.11.1\r
206 \r