Re: [PATCH 9/9] add has: query prefix to search for specific properties
[notmuch-archives.git] / 42 / 89f0e6ee370b666546b82cfa82b00e5aeb3d81
1 Return-Path: <jani@nikula.org>\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 6EDAE429E21\r
6         for <notmuch@notmuchmail.org>; Mon, 28 Nov 2011 11:44:44 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.7\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id 55VsFv4rg1SF for <notmuch@notmuchmail.org>;\r
16         Mon, 28 Nov 2011 11:44:42 -0800 (PST)\r
17 Received: from mail-bw0-f53.google.com (mail-bw0-f53.google.com\r
18         [209.85.214.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
19         (No client certificate requested)\r
20         by olra.theworths.org (Postfix) with ESMTPS id 83FBA431FB6\r
21         for <notmuch@notmuchmail.org>; Mon, 28 Nov 2011 11:44:41 -0800 (PST)\r
22 Received: by bkaq10 with SMTP id q10so9775204bka.26\r
23         for <notmuch@notmuchmail.org>; Mon, 28 Nov 2011 11:44:38 -0800 (PST)\r
24 Received: by 10.205.118.14 with SMTP id fo14mr47516695bkc.63.1322509478032;\r
25         Mon, 28 Nov 2011 11:44:38 -0800 (PST)\r
26 Received: from localhost (dsl-hkibrasgw4-fe5cdc00-23.dhcp.inet.fi.\r
27         [80.220.92.23])\r
28         by mx.google.com with ESMTPS id hy13sm31813751bkc.0.2011.11.28.11.44.33\r
29         (version=SSLv3 cipher=OTHER); Mon, 28 Nov 2011 11:44:35 -0800 (PST)\r
30 From: Jani Nikula <jani@nikula.org>\r
31 To: Austin Clements <amdragon@MIT.EDU>, notmuch@notmuchmail.org\r
32 Subject: Re: [PATCH 4/4] show: Rewrite show_message_body to use the MIME tree\r
33         interface.\r
34 In-Reply-To: <1322446871-14986-5-git-send-email-amdragon@mit.edu>\r
35 References: <1322446871-14986-1-git-send-email-amdragon@mit.edu>\r
36         <1322446871-14986-5-git-send-email-amdragon@mit.edu>\r
37 User-Agent: Notmuch/0.10+51~gef3ae74 (http://notmuchmail.org) Emacs/23.3.1\r
38         (i686-pc-linux-gnu)\r
39 Date: Mon, 28 Nov 2011 21:44:31 +0200\r
40 Message-ID: <87pqgcuj4w.fsf@nikula.org>\r
41 MIME-Version: 1.0\r
42 Content-Type: text/plain; charset=utf-8\r
43 Content-Transfer-Encoding: quoted-printable\r
44 Cc: dkg@fifthhorseman.net\r
45 X-BeenThere: notmuch@notmuchmail.org\r
46 X-Mailman-Version: 2.1.13\r
47 Precedence: list\r
48 List-Id: "Use and development of the notmuch mail system."\r
49         <notmuch.notmuchmail.org>\r
50 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
51         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
52 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
53 List-Post: <mailto:notmuch@notmuchmail.org>\r
54 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
55 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
56         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
57 X-List-Received-Date: Mon, 28 Nov 2011 19:44:44 -0000\r
58 \r
59 On Sun, 27 Nov 2011 21:21:11 -0500, Austin Clements <amdragon@MIT.EDU> wrot=\r
60 e:\r
61 > Since this is a rewrite, the diff is not very enlightening.  It's\r
62 > easier to look at the old code and the new code side-by-side.\r
63 \r
64 Hi Austin, try the git format-patch --break-rewrites option. It works\r
65 nicely on patches like this. See below.\r
66 \r
67 BR,\r
68 Jani.\r
69 \r
70 \r
71 >From 4df3de0d35b7fb5b142b3413d56cda2811406fd9 Mon Sep 17 00:00:00 2001\r
72 From: Austin Clements <amdragon@MIT.EDU>\r
73 Date: Sun, 27 Nov 2011 21:21:11 -0500\r
74 Subject: [PATCH] show: Rewrite show_message_body to use the MIME tree\r
75  interface.\r
76 \r
77 This removes all of the MIME traversal logic from show_message_body\r
78 and leaves only its interaction with the format callbacks.\r
79 \r
80 Besides isolating concerns, since traversal happens behind a trivial\r
81 interface, there is now much less code duplication in\r
82 show_message_part.  Also, this uses mime_node_seek_dfs to start at the\r
83 requested part, eliminating all of the logic about parts being\r
84 selected or being in_zone (and reducing the "show state" to only a\r
85 part counter).  notmuch_show_params_t no longer needs to be passed\r
86 through the recursion because the only two fields that mattered\r
87 (related to crypto) are now handled by the MIME tree.\r
88 \r
89 The few remaining complexities in show_message_part highlight\r
90 irregularities in the format callbacks with respect to top-level\r
91 messages and embedded message parts.\r
92 \r
93 Since this is a rewrite, the diff is not very enlightening.  It's\r
94 easier to look at the old code and the new code side-by-side.\r
95 ---\r
96  show-message.c |  329 +++++++++++++++++-----------------------------------=\r
97 ---\r
98  1 files changed, 102 insertions(+), 227 deletions(-)\r
99  rewrite show-message.c (81%)\r
100 \r
101 diff --git a/show-message.c b/show-message.c\r
102 dissimilarity index 81%\r
103 index 09fa607..4560aea 100644\r
104 --- a/show-message.c\r
105 +++ b/show-message.c\r
106 @@ -1,227 +1,102 @@\r
107 -/* notmuch - Not much of an email program, (just index and search)\r
108 - *\r
109 - * Copyright =C2=A9 2009 Carl Worth\r
110 - * Copyright =C2=A9 2009 Keith Packard\r
111 - *\r
112 - * This program is free software: you can redistribute it and/or modify\r
113 - * it under the terms of the GNU General Public License as published by\r
114 - * the Free Software Foundation, either version 3 of the License, or\r
115 - * (at your option) any later version.\r
116 - *\r
117 - * This program is distributed in the hope that it will be useful,\r
118 - * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
119 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
120 - * GNU General Public License for more details.\r
121 - *\r
122 - * You should have received a copy of the GNU General Public License\r
123 - * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
124 - *\r
125 - * Authors: Carl Worth <cworth@cworth.org>\r
126 - *         Keith Packard <keithp@keithp.com>\r
127 - */\r
128 -\r
129 -#include "notmuch-client.h"\r
130 -\r
131 -typedef struct show_message_state {\r
132 -    int part_count;\r
133 -    int in_zone;\r
134 -} show_message_state_t;\r
135 -\r
136 -static void\r
137 -show_message_part (GMimeObject *part,\r
138 -                  show_message_state_t *state,\r
139 -                  const notmuch_show_format_t *format,\r
140 -                  notmuch_show_params_t *params,\r
141 -                  int first)\r
142 -{\r
143 -    GMimeObject *decryptedpart =3D NULL;\r
144 -    int selected;\r
145 -    state->part_count +=3D 1;\r
146 -\r
147 -    if (! (GMIME_IS_PART (part) || GMIME_IS_MULTIPART (part) || GMIME_IS_M=\r
148 ESSAGE_PART (part))) {\r
149 -       fprintf (stderr, "Warning: Not displaying unknown mime part: %s.\n",\r
150 -                g_type_name (G_OBJECT_TYPE (part)));\r
151 -       return;\r
152 -    }\r
153 -\r
154 -    selected =3D (params->part <=3D 0 || state->part_count =3D=3D params->=\r
155 part);\r
156 -\r
157 -    if (selected || state->in_zone) {\r
158 -       if (!first && (params->part <=3D 0 || state->in_zone))\r
159 -           fputs (format->part_sep, stdout);\r
160 -\r
161 -       if (format->part_start)\r
162 -           format->part_start (part, &(state->part_count));\r
163 -    }\r
164 -\r
165 -    /* handle PGP/MIME parts */\r
166 -    if (GMIME_IS_MULTIPART (part) && params->cryptoctx) {\r
167 -       GMimeMultipart *multipart =3D GMIME_MULTIPART (part);\r
168 -       GError* err =3D NULL;\r
169 -\r
170 -       if (GMIME_IS_MULTIPART_ENCRYPTED (part) && params->decrypt)\r
171 -       {\r
172 -           if ( g_mime_multipart_get_count (multipart) !=3D 2 ) {\r
173 -               /* this violates RFC 3156 section 4, so we won't bother with it. */\r
174 -               fprintf (stderr,\r
175 -                        "Error: %d part(s) for a multipart/encrypted message (should be exactl=\r
176 y 2)\n",\r
177 -                        g_mime_multipart_get_count (multipart));\r
178 -           } else {\r
179 -               GMimeMultipartEncrypted *encrypteddata =3D GMIME_MULTIPART_ENCRYPTED (pa=\r
180 rt);\r
181 -               decryptedpart =3D g_mime_multipart_encrypted_decrypt (encrypteddata, par=\r
182 ams->cryptoctx, &err);\r
183 -               if (decryptedpart) {\r
184 -                   if ((selected || state->in_zone) && format->part_encstatus)\r
185 -                       format->part_encstatus (1);\r
186 -                   const GMimeSignatureValidity *sigvalidity =3D g_mime_multipart_encry=\r
187 pted_get_signature_validity (encrypteddata);\r
188 -                   if (!sigvalidity)\r
189 -                       fprintf (stderr, "Failed to verify signed part: %s\n", (err ? err->mess=\r
190 age : "no error explanation given"));\r
191 -                   if ((selected || state->in_zone) && format->part_sigstatus)\r
192 -                       format->part_sigstatus (sigvalidity);\r
193 -               } else {\r
194 -                   fprintf (stderr, "Failed to decrypt part: %s\n", (err ? err->message=\r
195  : "no error explanation given"));\r
196 -                   if ((selected || state->in_zone) && format->part_encstatus)\r
197 -                       format->part_encstatus (0);\r
198 -               }\r
199 -           }\r
200 -       }\r
201 -       else if (GMIME_IS_MULTIPART_SIGNED (part))\r
202 -       {\r
203 -           if ( g_mime_multipart_get_count (multipart) !=3D 2 ) {\r
204 -               /* this violates RFC 3156 section 5, so we won't bother with it. */\r
205 -               fprintf (stderr,\r
206 -                        "Error: %d part(s) for a multipart/signed message (should be exactly 2=\r
207 )\n",\r
208 -                        g_mime_multipart_get_count (multipart));\r
209 -           } else {\r
210 -               /* For some reason the GMimeSignatureValidity returned\r
211 -                * here is not a const (inconsistent with that\r
212 -                * returned by\r
213 -                * g_mime_multipart_encrypted_get_signature_validity,\r
214 -                * and therefore needs to be properly disposed of.\r
215 -                * Hopefully the API will become more consistent. */\r
216 -               GMimeSignatureValidity *sigvalidity =3D g_mime_multipart_signed_verify (=\r
217 GMIME_MULTIPART_SIGNED (part), params->cryptoctx, &err);\r
218 -               if (!sigvalidity) {\r
219 -                   fprintf (stderr, "Failed to verify signed part: %s\n", (err ? err->m=\r
220 essage : "no error explanation given"));\r
221 -               }\r
222 -               if ((selected || state->in_zone) && format->part_sigstatus)\r
223 -                   format->part_sigstatus (sigvalidity);\r
224 -               if (sigvalidity)\r
225 -                   g_mime_signature_validity_free (sigvalidity);\r
226 -           }\r
227 -       }\r
228 -\r
229 -       if (err)\r
230 -           g_error_free (err);\r
231 -    }\r
232 -    /* end handle PGP/MIME parts */\r
233 -\r
234 -    if (selected || state->in_zone)\r
235 -       format->part_content (part);\r
236 -\r
237 -    if (GMIME_IS_MULTIPART (part)) {\r
238 -       GMimeMultipart *multipart =3D GMIME_MULTIPART (part);\r
239 -       int i;\r
240 -\r
241 -       if (selected)\r
242 -           state->in_zone =3D 1;\r
243 -\r
244 -       if (decryptedpart) {\r
245 -           /* We emit the useless application/pgp-encrypted version\r
246 -            * part here only to keep the emitted output as consistent\r
247 -            * as possible between decrypted output and the\r
248 -            * unprocessed multipart/mime. For some strange reason,\r
249 -            * the actual encrypted data is the second part of the\r
250 -            * multipart. */\r
251 -           show_message_part (g_mime_multipart_get_part (multipart, 0), state, f=\r
252 ormat, params, TRUE);\r
253 -           show_message_part (decryptedpart, state, format, params, FALSE);\r
254 -       } else {\r
255 -           for (i =3D 0; i < g_mime_multipart_get_count (multipart); i++) {\r
256 -               show_message_part (g_mime_multipart_get_part (multipart, i),\r
257 -                                  state, format, params, i =3D=3D 0);\r
258 -           }\r
259 -       }\r
260 -\r
261 -       if (selected)\r
262 -           state->in_zone =3D 0;\r
263 -\r
264 -    } else if (GMIME_IS_MESSAGE_PART (part)) {\r
265 -       GMimeMessage *mime_message =3D g_mime_message_part_get_message (GMIME_MES=\r
266 SAGE_PART (part));\r
267 -\r
268 -       if (selected)\r
269 -           state->in_zone =3D 1;\r
270 -\r
271 -       if (selected || (!selected && state->in_zone)) {\r
272 -           fputs (format->header_start, stdout);\r
273 -           if (format->header_message_part)\r
274 -               format->header_message_part (mime_message);\r
275 -           fputs (format->header_end, stdout);\r
276 -\r
277 -           fputs (format->body_start, stdout);\r
278 -       }\r
279 -\r
280 -       show_message_part (g_mime_message_get_mime_part (mime_message),\r
281 -                          state, format, params, TRUE);\r
282 -\r
283 -       if (selected || (!selected && state->in_zone))\r
284 -           fputs (format->body_end, stdout);\r
285 -\r
286 -       if (selected)\r
287 -           state->in_zone =3D 0;\r
288 -    }\r
289 -\r
290 -    if (selected || state->in_zone) {\r
291 -       if (format->part_end)\r
292 -           format->part_end (part);\r
293 -    }\r
294 -}\r
295 -\r
296 -notmuch_status_t\r
297 -show_message_body (notmuch_message_t *message,\r
298 -                  const notmuch_show_format_t *format,\r
299 -                  notmuch_show_params_t *params)\r
300 -{\r
301 -    GMimeStream *stream =3D NULL;\r
302 -    GMimeParser *parser =3D NULL;\r
303 -    GMimeMessage *mime_message =3D NULL;\r
304 -    notmuch_status_t ret =3D NOTMUCH_STATUS_SUCCESS;\r
305 -    const char *filename =3D notmuch_message_get_filename (message);\r
306 -    FILE *file =3D NULL;\r
307 -    show_message_state_t state;\r
308 -\r
309 -    state.part_count =3D 0;\r
310 -    state.in_zone =3D 0;\r
311 -\r
312 -    file =3D fopen (filename, "r");\r
313 -    if (! file) {\r
314 -       fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno));\r
315 -       ret =3D NOTMUCH_STATUS_FILE_ERROR;\r
316 -       goto DONE;\r
317 -    }\r
318 -\r
319 -    stream =3D g_mime_stream_file_new (file);\r
320 -    g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream), FALSE);\r
321 -\r
322 -    parser =3D g_mime_parser_new_with_stream (stream);\r
323 -\r
324 -    mime_message =3D g_mime_parser_construct_message (parser);\r
325 -\r
326 -    show_message_part (g_mime_message_get_mime_part (mime_message),\r
327 -                      &state,\r
328 -                      format,\r
329 -                      params,\r
330 -                      TRUE);\r
331 -\r
332 -  DONE:\r
333 -    if (mime_message)\r
334 -       g_object_unref (mime_message);\r
335 -\r
336 -    if (parser)\r
337 -       g_object_unref (parser);\r
338 -\r
339 -    if (stream)\r
340 -       g_object_unref (stream);\r
341 -\r
342 -    if (file)\r
343 -       fclose (file);\r
344 -\r
345 -    return ret;\r
346 -}\r
347 +/* notmuch - Not much of an email program, (just index and search)\r
348 + *\r
349 + * Copyright =C2=A9 2009 Carl Worth\r
350 + * Copyright =C2=A9 2009 Keith Packard\r
351 + *\r
352 + * This program is free software: you can redistribute it and/or modify\r
353 + * it under the terms of the GNU General Public License as published by\r
354 + * the Free Software Foundation, either version 3 of the License, or\r
355 + * (at your option) any later version.\r
356 + *\r
357 + * This program is distributed in the hope that it will be useful,\r
358 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
359 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
360 + * GNU General Public License for more details.\r
361 + *\r
362 + * You should have received a copy of the GNU General Public License\r
363 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
364 + *\r
365 + * Authors: Carl Worth <cworth@cworth.org>\r
366 + *         Keith Packard <keithp@keithp.com>\r
367 + */\r
368 +\r
369 +#include "notmuch-client.h"\r
370 +\r
371 +typedef struct show_message_state {\r
372 +    int part_count;\r
373 +} show_message_state_t;\r
374 +\r
375 +static void\r
376 +show_message_part (mime_node_t *node,\r
377 +                  show_message_state_t *state,\r
378 +                  const notmuch_show_format_t *format,\r
379 +                  int first)\r
380 +{\r
381 +    /* Formatters expect the envelope for embedded message parts */\r
382 +    GMimeObject *part =3D node->envelope_part ?\r
383 +       GMIME_OBJECT (node->envelope_part) : node->part;\r
384 +    int i;\r
385 +\r
386 +    if (!first)\r
387 +       fputs (format->part_sep, stdout);\r
388 +\r
389 +    /* Format this part */\r
390 +    if (format->part_start)\r
391 +       format->part_start (part, &(state->part_count));\r
392 +\r
393 +    if (node->is_encrypted && format->part_encstatus)\r
394 +       format->part_encstatus (node->decrypt_success);\r
395 +\r
396 +    if (node->is_signed && format->part_sigstatus)\r
397 +       format->part_sigstatus (node->sig_validity);\r
398 +\r
399 +    format->part_content (part);\r
400 +\r
401 +    if (node->envelope_part) {\r
402 +       fputs (format->header_start, stdout);\r
403 +       if (format->header_message_part)\r
404 +           format->header_message_part (GMIME_MESSAGE (node->part));\r
405 +       fputs (format->header_end, stdout);\r
406 +\r
407 +       fputs (format->body_start, stdout);\r
408 +    }\r
409 +\r
410 +    /* Recurse over the children */\r
411 +    state->part_count +=3D 1;\r
412 +    for (i =3D 0; i < node->children; i++)\r
413 +       show_message_part (mime_node_child (node, i), state, format, i =3D=3D 0);\r
414 +\r
415 +    /* Finish this part */\r
416 +    if (node->envelope_part)\r
417 +       fputs (format->body_end, stdout);\r
418 +\r
419 +    if (format->part_end)\r
420 +       format->part_end (part);\r
421 +}\r
422 +\r
423 +notmuch_status_t\r
424 +show_message_body (notmuch_message_t *message,\r
425 +                  const notmuch_show_format_t *format,\r
426 +                  notmuch_show_params_t *params)\r
427 +{\r
428 +    notmuch_status_t ret;\r
429 +    show_message_state_t state;\r
430 +    mime_node_t *root, *part;\r
431 +\r
432 +    ret =3D mime_node_open (NULL, message, params->cryptoctx, params->decr=\r
433 ypt,\r
434 +                         &root);\r
435 +    if (ret)\r
436 +       return ret;\r
437 +\r
438 +    /* The caller of show_message_body has already handled the\r
439 +     * outermost envelope, so skip it. */\r
440 +    state.part_count =3D MAX (params->part, 1);\r
441 +\r
442 +    part =3D mime_node_seek_dfs (root, state.part_count);\r
443 +    if (part)\r
444 +       show_message_part (part, &state, format, TRUE);\r
445 +\r
446 +    talloc_free (root);\r
447 +\r
448 +    return NOTMUCH_STATUS_SUCCESS;\r
449 +}\r
450 --=20\r
451 1.7.5.4\r
452 \r
453 \r
454 \r
455 \r