Re: [PATCH v4 01/16] add util/search-path.{c, h} to test for executables in $PATH
[notmuch-archives.git] / 54 / f19cdcc8af7b87c5a3033d3d5e7d6c773481e5
1 Return-Path: <m.walters@qmul.ac.uk>\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 1C1D5431FB6\r
6         for <notmuch@notmuchmail.org>; Wed, 22 Oct 2014 03:51:36 -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: -1.098\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-1.098 tagged_above=-999 required=5\r
12         tests=[DKIM_ADSP_CUSTOM_MED=0.001, FREEMAIL_FROM=0.001,\r
13         NML_ADSP_CUSTOM_MED=1.2, RCVD_IN_DNSWL_MED=-2.3] 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 YNyxmMzX1S8I for <notmuch@notmuchmail.org>;\r
17         Wed, 22 Oct 2014 03:51:27 -0700 (PDT)\r
18 Received: from mail2.qmul.ac.uk (mail2.qmul.ac.uk [138.37.6.6])\r
19         (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
20         (No client certificate requested)\r
21         by olra.theworths.org (Postfix) with ESMTPS id 2EB02431FAE\r
22         for <notmuch@notmuchmail.org>; Wed, 22 Oct 2014 03:51:27 -0700 (PDT)\r
23 Received: from smtp.qmul.ac.uk ([138.37.6.40])\r
24         by mail2.qmul.ac.uk with esmtp (Exim 4.71)\r
25         (envelope-from <m.walters@qmul.ac.uk>)\r
26         id 1XgtVO-0006jw-MK; Wed, 22 Oct 2014 11:51:23 +0100\r
27 Received: from 5751dfa2.skybroadband.com ([87.81.223.162] helo=localhost)\r
28         by smtp.qmul.ac.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.71)\r
29         (envelope-from <m.walters@qmul.ac.uk>)\r
30         id 1XgtVN-0001HV-KJ; Wed, 22 Oct 2014 11:51:01 +0100\r
31 From: Mark Walters <markwalters1009@gmail.com>\r
32 To: Michal Sojka <sojkam1@fel.cvut.cz>, notmuch@notmuchmail.org\r
33 Subject: Re: [PATCH v3 3/4] cli: Extend the search command for\r
34         --output={sender, recipients}\r
35 In-Reply-To: <1413150093-8383-4-git-send-email-sojkam1@fel.cvut.cz>\r
36 References: <87zjd51phx.fsf@steelpick.2x.cz>\r
37         <1413150093-8383-1-git-send-email-sojkam1@fel.cvut.cz>\r
38         <1413150093-8383-4-git-send-email-sojkam1@fel.cvut.cz>\r
39 User-Agent: Notmuch/0.18.1+86~gef5e66a (http://notmuchmail.org) Emacs/23.4.1\r
40         (x86_64-pc-linux-gnu)\r
41 Date: Wed, 22 Oct 2014 11:51:00 +0100\r
42 Message-ID: <87mw8obcob.fsf@qmul.ac.uk>\r
43 MIME-Version: 1.0\r
44 Content-Type: text/plain; charset=utf-8\r
45 Content-Transfer-Encoding: quoted-printable\r
46 X-Sender-Host-Address: 87.81.223.162\r
47 X-QM-Geographic: According to ripencc,\r
48         this message was delivered by a machine in Britain (UK) (GB).\r
49 X-QM-SPAM-Info: Sender has good ham record.  :)\r
50 X-QM-Body-MD5: f9682e64e38253fc92b27f9bf576528e (of first 20000 bytes)\r
51 X-SpamAssassin-Score: -0.1\r
52 X-SpamAssassin-SpamBar: /\r
53 X-SpamAssassin-Report: The QM spam filters have analysed this message to\r
54         determine if it is\r
55         spam. We require at least 5.0 points to mark a message as spam.\r
56         This message scored -0.1 points.\r
57         Summary of the scoring: \r
58         * 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail\r
59         provider *      (markwalters1009[at]gmail.com)\r
60         * -0.1 AWL AWL: From: address is in the auto white-list\r
61 X-QM-Scan-Virus: ClamAV says the message is clean\r
62 X-BeenThere: notmuch@notmuchmail.org\r
63 X-Mailman-Version: 2.1.13\r
64 Precedence: list\r
65 List-Id: "Use and development of the notmuch mail system."\r
66         <notmuch.notmuchmail.org>\r
67 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
68         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
69 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
70 List-Post: <mailto:notmuch@notmuchmail.org>\r
71 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
72 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
73         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
74 X-List-Received-Date: Wed, 22 Oct 2014 10:51:36 -0000\r
75 \r
76 On Sun, 12 Oct 2014, Michal Sojka <sojkam1@fel.cvut.cz> wrote:\r
77 > The new outputs allow printing senders, recipients or both of matching\r
78 > messages. The --output option is converted from "keyword" argument to\r
79 > "flags" argument, which means that the user can use --output=3Dsender and\r
80 > --output=3Drecipients simultaneously, to print both. Other combinations\r
81 > produce an error.\r
82 >\r
83 > This code based on a patch from Jani Nikula.\r
84 > ---\r
85 >  completion/notmuch-completion.bash |   2 +-\r
86 >  completion/notmuch-completion.zsh  |   3 +-\r
87 >  doc/man1/notmuch-search.rst        |  22 +++++++-\r
88 >  notmuch-search.c                   | 110 +++++++++++++++++++++++++++++++=\r
89 +++---\r
90 >  test/T090-search-output.sh         |  64 +++++++++++++++++++++\r
91 >  5 files changed, 189 insertions(+), 12 deletions(-)\r
92 >\r
93 > diff --git a/completion/notmuch-completion.bash b/completion/notmuch-comp=\r
94 letion.bash\r
95 > index 0571dc9..cfbd389 100644\r
96 > --- a/completion/notmuch-completion.bash\r
97 > +++ b/completion/notmuch-completion.bash\r
98 > @@ -294,7 +294,7 @@ _notmuch_search()\r
99 >           return\r
100 >           ;;\r
101 >       --output)\r
102 > -         COMPREPLY=3D( $( compgen -W "summary threads messages files tags" -=\r
103 - "${cur}" ) )\r
104 > +         COMPREPLY=3D( $( compgen -W "summary threads messages files tags se=\r
105 nder recipients" -- "${cur}" ) )\r
106 >           return\r
107 >           ;;\r
108 >       --sort)\r
109 > diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-compl=\r
110 etion.zsh\r
111 > index 67a9aba..3e52a00 100644\r
112 > --- a/completion/notmuch-completion.zsh\r
113 > +++ b/completion/notmuch-completion.zsh\r
114 > @@ -52,7 +52,8 @@ _notmuch_search()\r
115 >    _arguments -s : \\r
116 >      '--max-threads=3D[display only the first x threads from the search r=\r
117 esults]:number of threads to show: ' \\r
118 >      '--first=3D[omit the first x threads from the search results]:number=\r
119  of threads to omit: ' \\r
120 > -    '--sort=3D[sort results]:sorting:((newest-first\:"reverse chronologi=\r
121 cal order" oldest-first\:"chronological order"))'\r
122 > +    '--sort=3D[sort results]:sorting:((newest-first\:"reverse chronologi=\r
123 cal order" oldest-first\:"chronological order"))' \\r
124 > +    '--output=3D[select what to output]:output:((summary threads message=\r
125 s files tags sender recipients))'\r
126 >  }\r
127 >=20=20\r
128 >  _notmuch()\r
129 > diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst\r
130 > index 90160f2..c9d38b1 100644\r
131 > --- a/doc/man1/notmuch-search.rst\r
132 > +++ b/doc/man1/notmuch-search.rst\r
133 > @@ -35,7 +35,7 @@ Supported options for **search** include\r
134 >          intended for programs that invoke **notmuch(1)** internally. If\r
135 >          omitted, the latest supported version will be used.\r
136 >=20=20\r
137 > -    ``--output=3D(summary|threads|messages|files|tags)``\r
138 > +    ``--output=3D(summary|threads|messages|files|tags|sender|recipients)=\r
139 ``\r
140 >=20=20\r
141 >          **summary**\r
142 >              Output a summary of each thread with any message matching\r
143 > @@ -78,6 +78,26 @@ Supported options for **search** include\r
144 >              by null characters (--format=3Dtext0), as a JSON array\r
145 >              (--format=3Djson), or as an S-Expression list (--format=3Dse=\r
146 xp).\r
147 >=20=20\r
148 > +     **sender**\r
149 > +            Output all addresses from the *From* header that appear on\r
150 > +            any message matching the search terms, either one per line\r
151 > +            (--format=3Dtext), separated by null characters\r
152 > +            (--format=3Dtext0), as a JSON array (--format=3Djson), or as\r
153 > +            an S-Expression list (--format=3Dsexp).\r
154 > +\r
155 > +         Note: Searching for **sender** should be much faster than\r
156 > +         searching for **recipients**, because sender addresses are\r
157 > +         cached directly in the database whereas other addresses\r
158 > +         need to be fetched from message files.\r
159 > +\r
160 > +     **recipients**\r
161 > +            Like **sender** but for addresses from *To*, *Cc* and\r
162 > +         *Bcc* headers.\r
163 > +\r
164 > +     This option can be given multiple times to combine different\r
165 > +     outputs. Curently, this is only supported for **sender** and\r
166 > +     **recipients** outputs.\r
167 > +\r
168 >      ``--sort=3D``\ (**newest-first**\ \|\ **oldest-first**)\r
169 >          This option can be used to present results in either\r
170 >          chronological order (**oldest-first**) or reverse chronological\r
171 > diff --git a/notmuch-search.c b/notmuch-search.c\r
172 > index 5ac2a26..74588f8 100644\r
173 > --- a/notmuch-search.c\r
174 > +++ b/notmuch-search.c\r
175 > @@ -23,11 +23,14 @@\r
176 >  #include "string-util.h"\r
177 >=20=20\r
178 >  typedef enum {\r
179 > -    OUTPUT_SUMMARY,\r
180 > -    OUTPUT_THREADS,\r
181 > -    OUTPUT_MESSAGES,\r
182 > -    OUTPUT_FILES,\r
183 > -    OUTPUT_TAGS\r
184 > +    OUTPUT_SUMMARY   =3D 1 << 0,\r
185 > +    OUTPUT_THREADS   =3D 1 << 1,\r
186 > +    OUTPUT_MESSAGES  =3D 1 << 2,\r
187 > +    OUTPUT_FILES     =3D 1 << 3,\r
188 > +    OUTPUT_TAGS              =3D 1 << 4,\r
189 > +    OUTPUT_SENDER    =3D 1 << 5,\r
190 > +    OUTPUT_RECIPIENTS        =3D 1 << 6,\r
191 > +    OUTPUT_ADDRESSES =3D OUTPUT_SENDER | OUTPUT_RECIPIENTS,\r
192 \r
193 I think I would drop the OUTPUT_ADDRESSES enum as the parser no longer\r
194 uses it (and replace the one use by OUTPUT_SENDER | OUTPUT_RECIPIENTS below=\r
195 ).\r
196 \r
197 >  } output_t;\r
198 >=20=20\r
199 >  typedef struct {\r
200 > @@ -220,6 +223,67 @@ do_search_threads (search_options_t *o)\r
201 >      return 0;\r
202 >  }\r
203 >=20=20\r
204 > +static void\r
205 > +print_address_list (const search_options_t *o, InternetAddressList *list)\r
206 > +{\r
207 > +    InternetAddress *address;\r
208 > +    int i;\r
209 > +\r
210 > +    for (i =3D 0; i < internet_address_list_length (list); i++) {\r
211 > +     address =3D internet_address_list_get_address (list, i);\r
212 > +     if (INTERNET_ADDRESS_IS_GROUP (address)) {\r
213 > +         InternetAddressGroup *group;\r
214 > +         InternetAddressList *group_list;\r
215 > +\r
216 > +         group =3D INTERNET_ADDRESS_GROUP (address);\r
217 > +         group_list =3D internet_address_group_get_members (group);\r
218 > +         if (group_list =3D=3D NULL)\r
219 > +             continue;\r
220 > +\r
221 > +         print_address_list (o, group_list);\r
222 > +     } else {\r
223 > +         InternetAddressMailbox *mailbox;\r
224 > +         const char *name;\r
225 > +         const char *addr;\r
226 > +         char *full_address;\r
227 > +\r
228 > +         mailbox =3D INTERNET_ADDRESS_MAILBOX (address);\r
229 > +\r
230 > +         name =3D internet_address_get_name (address);\r
231 > +         addr =3D internet_address_mailbox_get_addr (mailbox);\r
232 > +\r
233 > +         if (name && *name)\r
234 > +             full_address =3D talloc_asprintf (o->format, "%s <%s>", name, addr);\r
235 > +         else\r
236 > +             full_address =3D talloc_strdup (o->format, addr);\r
237 > +\r
238 > +         if (!full_address) {\r
239 > +             fprintf (stderr, "Error: out of memory\n");\r
240 > +             break;\r
241 > +         }\r
242 > +         o->format->string (o->format, full_address);\r
243 > +         o->format->separator (o->format);\r
244 > +\r
245 > +         talloc_free (full_address);\r
246 > +     }\r
247 > +    }\r
248 > +}\r
249 > +\r
250 > +static void\r
251 > +print_address_string (const search_options_t *o, const char *recipients)\r
252 > +{\r
253 > +    InternetAddressList *list;\r
254 > +\r
255 > +    if (recipients =3D=3D NULL)\r
256 > +     return;\r
257 > +\r
258 > +    list =3D internet_address_list_parse_string (recipients);\r
259 > +    if (list =3D=3D NULL)\r
260 > +     return;\r
261 > +\r
262 > +    print_address_list (o, list);\r
263 > +}\r
264 > +\r
265 >  static int\r
266 >  do_search_messages (search_options_t *o)\r
267 >  {\r
268 > @@ -266,11 +330,29 @@ do_search_messages (search_options_t *o)\r
269 >=20=20=09=20=20=20=20\r
270 >           notmuch_filenames_destroy( filenames );\r
271 >=20=20\r
272 > -     } else { /* output =3D=3D OUTPUT_MESSAGES */\r
273 > +     } else if (o->output =3D=3D OUTPUT_MESSAGES) {\r
274 >           format->set_prefix (format, "id");\r
275 >           format->string (format,\r
276 >                           notmuch_message_get_message_id (message));\r
277 >           format->separator (format);\r
278 > +     } else {\r
279 > +         if (o->output & OUTPUT_SENDER) {\r
280 > +             const char *addrs;\r
281 > +\r
282 > +             addrs =3D notmuch_message_get_header (message, "from");\r
283 > +             print_address_string (o, addrs);\r
284 > +         }\r
285 > +\r
286 > +         if (o->output & OUTPUT_RECIPIENTS) {\r
287 > +             const char *hdrs[] =3D { "to", "cc", "bcc" };\r
288 > +             const char *addrs;\r
289 > +             size_t j;\r
290 > +\r
291 > +             for (j =3D 0; j < ARRAY_SIZE (hdrs); j++) {\r
292 > +                 addrs =3D notmuch_message_get_header (message, hdrs[j]);\r
293 > +                 print_address_string (o, addrs);\r
294 > +             }\r
295 > +         }\r
296 >       }\r
297 >=20=20\r
298 >       notmuch_message_destroy (message);\r
299 > @@ -337,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int=\r
300  argc, char *argv[])\r
301 >      notmuch_database_t *notmuch;\r
302 >      search_options_t o =3D {\r
303 >       .sort =3D NOTMUCH_SORT_NEWEST_FIRST,\r
304 > -     .output =3D OUTPUT_SUMMARY,\r
305 > +     .output =3D 0,\r
306 >       .offset =3D 0,\r
307 >       .limit =3D -1, /* unlimited */\r
308 >       .dupe =3D -1,\r
309 \r
310 It is slightly unfortunate that all the other defaults are defined here\r
311 but the default output is after the option parsing but I can't see a\r
312 nice way round that. I only mention it in case you (or anyone else) can\r
313 see a nice way round this.\r
314 \r
315 \r
316 > @@ -366,10 +448,12 @@ notmuch_search_command (notmuch_config_t *config, i=\r
317 nt argc, char *argv[])\r
318 >                                 { "text0", NOTMUCH_FORMAT_TEXT0 },\r
319 >                                 { 0, 0 } } },\r
320 >       { NOTMUCH_OPT_INT, &notmuch_format_version, "format-version", 0, 0 },\r
321 > -     { NOTMUCH_OPT_KEYWORD, &o.output, "output", 'o',\r
322 > +     { NOTMUCH_OPT_KEYWORD_FLAGS, &o.output, "output", 'o',\r
323 >         (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },\r
324 >                                 { "threads", OUTPUT_THREADS },\r
325 >                                 { "messages", OUTPUT_MESSAGES },\r
326 > +                               { "sender", OUTPUT_SENDER },\r
327 > +                               { "recipients", OUTPUT_RECIPIENTS },\r
328 >                                 { "files", OUTPUT_FILES },\r
329 >                                 { "tags", OUTPUT_TAGS },\r
330 >                                 { 0, 0 } } },\r
331 > @@ -389,6 +473,9 @@ notmuch_search_command (notmuch_config_t *config, int=\r
332  argc, char *argv[])\r
333 >      if (opt_index < 0)\r
334 >       return EXIT_FAILURE;\r
335 >=20=20\r
336 > +    if (! o.output)\r
337 > +     o.output =3D OUTPUT_SUMMARY;\r
338 > +\r
339 >      switch (format_sel) {\r
340 >      case NOTMUCH_FORMAT_TEXT:\r
341 >       o.format =3D sprinter_text_create (config, stdout);\r
342 > @@ -455,18 +542,23 @@ notmuch_search_command (notmuch_config_t *config, i=\r
343 nt argc, char *argv[])\r
344 >      }\r
345 >=20=20\r
346 >      switch (o.output) {\r
347 > -    default:\r
348 >      case OUTPUT_SUMMARY:\r
349 >      case OUTPUT_THREADS:\r
350 >       ret =3D do_search_threads (&o);\r
351 >       break;\r
352 >      case OUTPUT_MESSAGES:\r
353 > +    case OUTPUT_SENDER:\r
354 > +    case OUTPUT_RECIPIENTS:\r
355 > +    case OUTPUT_ADDRESSES:\r
356 \r
357 This is the one use of OUTPUT_ADDRESSES that I would replace with\r
358 OUTPUT_SENDER | OUTPUT_RECIPIENTS\r
359 \r
360 Otherwise this looks good to me. (I have not tested it yet.)\r
361 \r
362 Best wishes\r
363 \r
364 Mark\r
365 \r
366 >      case OUTPUT_FILES:\r
367 >       ret =3D do_search_messages (&o);\r
368 >       break;\r
369 >      case OUTPUT_TAGS:\r
370 >       ret =3D do_search_tags (notmuch, o.format, o.query);\r
371 >       break;\r
372 > +    default:\r
373 > +     fprintf (stderr, "Error: the combination of outputs is not supported.\n=\r
374 ");\r
375 > +     ret =3D 1;\r
376 >      }\r
377 >=20=20\r
378 >      notmuch_query_destroy (o.query);\r
379 > diff --git a/test/T090-search-output.sh b/test/T090-search-output.sh\r
380 > index 947d572..e696c01 100755\r
381 > --- a/test/T090-search-output.sh\r
382 > +++ b/test/T090-search-output.sh\r
383 > @@ -387,6 +387,70 @@ cat <<EOF >EXPECTED\r
384 >  EOF\r
385 >  test_expect_equal_file OUTPUT EXPECTED\r
386 >=20=20\r
387 > +test_begin_subtest "--output=3Dsender"\r
388 > +notmuch search --output=3Dsender '*' | sort | uniq --count >OUTPUT\r
389 > +cat <<EOF >EXPECTED\r
390 > +      1 Adrian Perez de Castro <aperez@igalia.com>\r
391 > +      2 Alex Botero-Lowry <alex.boterolowry@gmail.com>\r
392 > +      4 Alexander Botero-Lowry <alex.boterolowry@gmail.com>\r
393 > +      1 Aron Griffis <agriffis@n01se.net>\r
394 > +     12 Carl Worth <cworth@cworth.org>\r
395 > +      1 Chris Wilson <chris@chris-wilson.co.uk>\r
396 > +      1 Fran=C3=A7ois Boulogne <boulogne.f@gmail.com>\r
397 > +      1 Ingmar Vanhassel <ingmar@exherbo.org>\r
398 > +      1 Israel Herraiz <isra@herraiz.org>\r
399 > +      4 Jan Janak <jan@ryngle.com>\r
400 > +      2 Jjgod Jiang <gzjjgod@gmail.com>\r
401 > +      7 Keith Packard <keithp@keithp.com>\r
402 > +      5 Lars Kellogg-Stedman <lars@seas.harvard.edu>\r
403 > +      5 Mikhail Gusarov <dottedmag@dottedmag.net>\r
404 > +      1 Olivier Berger <olivier.berger@it-sudparis.eu>\r
405 > +      1 Rolland Santimano <rollandsantimano@yahoo.com>\r
406 > +      3 Stewart Smith <stewart@flamingspork.com>\r
407 > +EOF\r
408 > +test_expect_equal_file OUTPUT EXPECTED\r
409 > +\r
410 > +test_begin_subtest "--output=3Drecipients"\r
411 > +notmuch search --output=3Drecipients '*' | sort | uniq --count >OUTPUT\r
412 > +cat <<EOF >EXPECTED\r
413 > +      1 Allan McRae <allan@archlinux.org>\r
414 > +      1 Discussion about the Arch User Repository (AUR) <aur-general@arc=\r
415 hlinux.org>\r
416 > +      1 Keith Packard <keithp@keithp.com>\r
417 > +      1 Mikhail Gusarov <dottedmag@dottedmag.net>\r
418 > +      2 notmuch <notmuch@notmuchmail.org>\r
419 > +     48 notmuch@notmuchmail.org\r
420 > +      1 olivier.berger@it-sudparis.eu\r
421 > +EOF\r
422 > +test_expect_equal_file OUTPUT EXPECTED\r
423 > +\r
424 > +test_begin_subtest "--output=3Dsender --output=3Drecipients"\r
425 > +notmuch search --output=3Dsender --output=3Drecipients '*' | sort | uniq=\r
426  --count >OUTPUT\r
427 > +cat <<EOF >EXPECTED\r
428 > +      1 Adrian Perez de Castro <aperez@igalia.com>\r
429 > +      2 Alex Botero-Lowry <alex.boterolowry@gmail.com>\r
430 > +      4 Alexander Botero-Lowry <alex.boterolowry@gmail.com>\r
431 > +      1 Allan McRae <allan@archlinux.org>\r
432 > +      1 Aron Griffis <agriffis@n01se.net>\r
433 > +     12 Carl Worth <cworth@cworth.org>\r
434 > +      1 Chris Wilson <chris@chris-wilson.co.uk>\r
435 > +      1 Discussion about the Arch User Repository (AUR) <aur-general@arc=\r
436 hlinux.org>\r
437 > +      1 Fran=C3=A7ois Boulogne <boulogne.f@gmail.com>\r
438 > +      1 Ingmar Vanhassel <ingmar@exherbo.org>\r
439 > +      1 Israel Herraiz <isra@herraiz.org>\r
440 > +      4 Jan Janak <jan@ryngle.com>\r
441 > +      2 Jjgod Jiang <gzjjgod@gmail.com>\r
442 > +      8 Keith Packard <keithp@keithp.com>\r
443 > +      5 Lars Kellogg-Stedman <lars@seas.harvard.edu>\r
444 > +      6 Mikhail Gusarov <dottedmag@dottedmag.net>\r
445 > +      1 Olivier Berger <olivier.berger@it-sudparis.eu>\r
446 > +      1 Rolland Santimano <rollandsantimano@yahoo.com>\r
447 > +      3 Stewart Smith <stewart@flamingspork.com>\r
448 > +      2 notmuch <notmuch@notmuchmail.org>\r
449 > +     48 notmuch@notmuchmail.org\r
450 > +      1 olivier.berger@it-sudparis.eu\r
451 > +EOF\r
452 > +test_expect_equal_file OUTPUT EXPECTED\r
453 > +\r
454 >  test_begin_subtest "sanitize output for quoted-printable line-breaks in =\r
455 author and subject"\r
456 >  add_message "[subject]=3D'two =3D?ISO-8859-1?Q?line=3D0A_subject?=3D\r
457 >       headers'"\r
458 > --=20\r
459 > 2.1.1\r
460 >\r
461 > _______________________________________________\r
462 > notmuch mailing list\r
463 > notmuch@notmuchmail.org\r
464 > http://notmuchmail.org/mailman/listinfo/notmuch\r