[PATCH] configure: add --without-api-docs option
[notmuch-archives.git] / 76 / 8066aab290337874b43535e7f376043821300a
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 26710429E3C\r
6         for <notmuch@notmuchmail.org>; Wed, 11 Jul 2012 01:25:26 -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 9a9F7MtAQ7EV for <notmuch@notmuchmail.org>;\r
17         Wed, 11 Jul 2012 01:25:23 -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 DDF20429E26\r
20         for <notmuch@notmuchmail.org>; Wed, 11 Jul 2012 01:25:21 -0700 (PDT)\r
21 Received: (qmail invoked by alias); 11 Jul 2012 08:25:14 -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 (mp016) with SMTP; 11 Jul 2012 10:25:14 +0200\r
25 X-Authenticated: #201305\r
26 X-Provags-ID: V01U2FsdGVkX1887tYf0eI8tllIWkVJ6Mvejk7/HvwFk7Ruqa/5x2\r
27         jalLZfI1VUHSon\r
28 Received: by dodekanex.arelion.at (Postfix, from userid 1000)\r
29         id BD7F330313C; Wed, 11 Jul 2012 10:26:36 +0200 (CEST)\r
30 From: <craven@gmx.net>\r
31 To: notmuch@notmuchmail.org\r
32 Subject: [PATCH v3 2/3] Adding a structured formatter for JSON.\r
33 Date: Wed, 11 Jul 2012 10:26:34 +0200\r
34 Message-Id: <1341995195-2497-3-git-send-email-craven@gmx.net>\r
35 X-Mailer: git-send-email 1.7.11.1\r
36 In-Reply-To: <1341995195-2497-1-git-send-email-craven@gmx.net>\r
37 References: <20120710191331.GE7332@mit.edu>\r
38         <1341995195-2497-1-git-send-email-craven@gmx.net>\r
39 MIME-Version: 1.0\r
40 Content-Type: text/plain; charset=UTF-8\r
41 Content-Transfer-Encoding: 8bit\r
42 X-Y-GMX-Trusted: 0\r
43 X-BeenThere: notmuch@notmuchmail.org\r
44 X-Mailman-Version: 2.1.13\r
45 Precedence: list\r
46 List-Id: "Use and development of the notmuch mail system."\r
47         <notmuch.notmuchmail.org>\r
48 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
49         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
50 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
51 List-Post: <mailto:notmuch@notmuchmail.org>\r
52 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
53 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
54         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
55 X-List-Received-Date: Wed, 11 Jul 2012 08:25:26 -0000\r
56 \r
57 This patch adds a structured formatter that prints exactly the same JSON as the built-in JSON printer. All tests pass without change.\r
58 \r
59 Notice that this formatter could be simpler by changing the whitespace\r
60 and line-breaks in the generated JSON.\r
61 ---\r
62  Makefile.local      |   1 +\r
63  structured-output.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++\r
64  structured-output.h |  59 +++++++++++++++++++\r
65  3 files changed, 227 insertions(+)\r
66  create mode 100644 structured-output.c\r
67 \r
68 diff --git a/Makefile.local b/Makefile.local\r
69 index a890df2..9b989dc 100644\r
70 --- a/Makefile.local\r
71 +++ b/Makefile.local\r
72 @@ -291,6 +291,7 @@ notmuch_client_srcs =               \\r
73         notmuch-tag.c           \\r
74         notmuch-time.c          \\r
75         query-string.c          \\r
76 +       structured-output.c     \\r
77         mime-node.c             \\r
78         crypto.c                \\r
79         json.c\r
80 diff --git a/structured-output.c b/structured-output.c\r
81 new file mode 100644\r
82 index 0000000..18a7306\r
83 --- /dev/null\r
84 +++ b/structured-output.c\r
85 @@ -0,0 +1,167 @@\r
86 +/* notmuch - Not much of an email program, (just index and search)\r
87 + *\r
88 + * Copyright © 2009 Carl Worth\r
89 + *\r
90 + * This program is free software: you can redistribute it and/or modify\r
91 + * it under the terms of the GNU General Public License as published by\r
92 + * the Free Software Foundation, either version 3 of the License, or\r
93 + * (at your option) any later version.\r
94 + *\r
95 + * This program is distributed in the hope that it will be useful,\r
96 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
97 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
98 + * GNU General Public License for more details.\r
99 + *\r
100 + * You should have received a copy of the GNU General Public License\r
101 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
102 + *\r
103 + * Author: Carl Worth <cworth@cworth.org>\r
104 + */\r
105 +\r
106 +#include "structured-output.h"\r
107 +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))\r
108 +\r
109 +structure_printer_t *\r
110 +unstructured_text_printer = NULL;\r
111 +\r
112 +structure_printer_t\r
113 +json_structure_printer = {\r
114 +    &json_map,\r
115 +    &json_list,\r
116 +    &json_pop,\r
117 +    &json_map_key,\r
118 +    &json_number,\r
119 +    &json_string,\r
120 +    &json_bool,\r
121 +    &json_initial_state\r
122 +};\r
123 +\r
124 +static int\r
125 +enter_level (void *st, const char *marker, int type) {\r
126 +    json_state_t *state = (json_state_t*)st;\r
127 +    FILE *output = state->output;\r
128 +    json_list_t *el = talloc (st, json_list_t);\r
129 +\r
130 +    json_item_separator (state, (state->level == 1) ? "\n" : " ");\r
131 +    fputs (marker, output);\r
132 +\r
133 +    el->type = type;\r
134 +    el->first_seen = FALSE;\r
135 +    el->rest = state->stack;\r
136 +    state->stack = el;\r
137 +    return state->level++;\r
138 +}\r
139 +\r
140 +void\r
141 +json_print_escaped_string (FILE *output, const char *val)\r
142 +{\r
143 +    static const char * const escapes[] = {\r
144 +        ['\"'] = "\\\"", ['\\'] = "\\\\", ['\b'] = "\\b",\r
145 +        ['\f'] = "\\f",  ['\n'] = "\\n",  ['\t'] = "\\t"\r
146 +    };\r
147 +    fputc ('"', output);\r
148 +    for (; *val; ++val) {\r
149 +        unsigned char ch = *val;\r
150 +        if (ch < ARRAY_SIZE(escapes) && escapes[ch])\r
151 +            fputs (escapes[ch], output);\r
152 +        else if (ch >= 32)\r
153 +            fputc (ch, output);\r
154 +        else\r
155 +            fprintf (output, "\\u%04x", ch);\r
156 +    }\r
157 +    fputc ('"', output);\r
158 +}\r
159 +\r
160 +int\r
161 +json_map (void *st)\r
162 +{\r
163 +    return enter_level (st, "{", TYPE_JSON_MAP);\r
164 +}\r
165 +\r
166 +int\r
167 +json_list (void *st)\r
168 +{\r
169 +    return enter_level (st, "[", TYPE_JSON_ARRAY);\r
170 +}\r
171 +\r
172 +void\r
173 +json_pop (void *st, int level)\r
174 +{\r
175 +    json_state_t *state = (json_state_t*)st;\r
176 +    FILE *output = state->output;\r
177 +    while (state->level > level) {\r
178 +       json_list_t *tos = state->stack;\r
179 +       fputs (tos->type == TYPE_JSON_MAP ? "}" : "]", output);\r
180 +       state->stack = tos->rest;\r
181 +       state->level--;\r
182 +       talloc_free (tos);\r
183 +    }\r
184 +    if (state->level == 0) {\r
185 +       fputs ("\n", output);\r
186 +    }\r
187 +}\r
188 +\r
189 +void\r
190 +json_map_key (void *st, const char *key)\r
191 +{\r
192 +    json_state_t *state = (json_state_t*)st;\r
193 +    FILE *output = state->output;\r
194 +    if (state->stack != NULL && state->stack->first_seen) {\r
195 +       fputs (",\n", output);\r
196 +    }\r
197 +    json_print_escaped_string (output, key);\r
198 +    fputs (": ", output);\r
199 +}\r
200 +\r
201 +void\r
202 +json_item_separator (json_state_t *state, const char *suffix)\r
203 +{\r
204 +    FILE *output = state->output;\r
205 +    if (state->stack != NULL\r
206 +       && state->stack->type == TYPE_JSON_ARRAY\r
207 +       && state->stack->first_seen) {\r
208 +\r
209 +       fputs (",", output);\r
210 +       fputs (suffix, output);\r
211 +    }\r
212 +    if (state->stack != NULL)\r
213 +       state->stack->first_seen = TRUE;\r
214 +}\r
215 +\r
216 +void\r
217 +json_number (void *st, int val)\r
218 +{\r
219 +    json_state_t *state = (json_state_t*)st;\r
220 +    FILE *output = state->output;\r
221 +    json_item_separator (state, state->level == 1 ? "\n" : " ");\r
222 +    fprintf (output, "%d", val);\r
223 +}\r
224 +\r
225 +void\r
226 +json_string (void *st, const char *val)\r
227 +{\r
228 +    json_state_t *state = (json_state_t *)st;\r
229 +    FILE *output = state->output;\r
230 +    json_item_separator (state, state->level == 1 ? "\n" : " ");\r
231 +    json_print_escaped_string (output, val);\r
232 +}\r
233 +\r
234 +void\r
235 +json_bool (void *st, notmuch_bool_t val)\r
236 +{\r
237 +    json_state_t *state = (json_state_t*)st;\r
238 +    FILE *output = state->output;\r
239 +    json_item_separator (state, state->level == 1 ? "\n" : " ");\r
240 +    fputs (val ? "true" : "false", output);\r
241 +}\r
242 +\r
243 +void *\r
244 +json_initial_state (const struct structure_printer *sp, FILE *output)\r
245 +{\r
246 +    (void)sp;\r
247 +    json_state_t *st = talloc (0, json_state_t);\r
248 +    st->level = 0;\r
249 +    st->stack = NULL;\r
250 +    st->output = output;\r
251 +    return st;\r
252 +}\r
253 diff --git a/structured-output.h b/structured-output.h\r
254 index 73029f1..b211ac6 100644\r
255 --- a/structured-output.h\r
256 +++ b/structured-output.h\r
257 @@ -88,3 +88,62 @@ typedef struct structure_printer {\r
258                             FILE *output);\r
259  \r
260  } structure_printer_t;\r
261 +\r
262 +/* dummy object to differentiate plain text from structured output */\r
263 +structure_printer_t *\r
264 +unstructured_text_printer;\r
265 +\r
266 +/* JSON structure printer\r
267 + * An implementation of the JSON structure printer that produces\r
268 + * exactly the same output as the previous JSON printer.\r
269 + */\r
270 +\r
271 +/* single linked list implementation for keeping track of the array/map\r
272 + * nesting state.\r
273 + */\r
274 +typedef enum {TYPE_JSON_MAP, TYPE_JSON_ARRAY} JSON_TYPE;\r
275 +\r
276 +typedef struct json_list {\r
277 +    int type;\r
278 +    notmuch_bool_t first_seen;\r
279 +    struct json_list *rest;\r
280 +} json_list_t;\r
281 +\r
282 +typedef struct json_state {\r
283 +    FILE *output;\r
284 +    json_list_t *stack;\r
285 +    int level;\r
286 +} json_state_t;\r
287 +\r
288 +int\r
289 +json_map(void *state);\r
290 +\r
291 +int\r
292 +json_list(void *state);\r
293 +\r
294 +void\r
295 +json_pop(void *state, int level);\r
296 +\r
297 +void\r
298 +json_map_key(void *state, const char *key);\r
299 +\r
300 +void\r
301 +json_number(void *state, int val);\r
302 +\r
303 +void\r
304 +json_string(void *state, const char *val);\r
305 +\r
306 +void\r
307 +json_bool(void *state, notmuch_bool_t val);\r
308 +\r
309 +void *\r
310 +json_initial_state(const struct structure_printer *sp, FILE *output);\r
311 +\r
312 +void\r
313 +json_print_escaped_string(FILE *output, const char *val);\r
314 +\r
315 +void\r
316 +json_item_separator(json_state_t *state, const char *suffix);\r
317 +\r
318 +structure_printer_t\r
319 +json_structure_printer;\r
320 -- \r
321 1.7.11.1\r
322 \r