[PATCH 2/9] lib: private string map (associative array) API
[notmuch-archives.git] / 1f / 3c9c60a79e996ade7922d50cb58837e26d87bc
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 5F24B431FB6\r
6         for <notmuch@notmuchmail.org>; Sat,  6 Sep 2014 10:48:03 -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.502\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0.502 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_LOW=-0.7] 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 QF1EV+j+LY4j for <notmuch@notmuchmail.org>;\r
17         Sat,  6 Sep 2014 10:47:56 -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 3D215431FAE\r
22         for <notmuch@notmuchmail.org>; Sat,  6 Sep 2014 10:47:56 -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 1XQK5A-0003uj-5p; Sat, 06 Sep 2014 18:47:53 +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 1XQK59-0003BW-Nh; Sat, 06 Sep 2014 18:47:27 +0100\r
31 From: Mark Walters <markwalters1009@gmail.com>\r
32 To: Jani Nikula <jani@nikula.org>, notmuch@notmuchmail.org\r
33 Subject: Re: [PATCH] cli: add --output=address-{from, to,\r
34         all} to notmuch search\r
35 In-Reply-To: <1410021689-15901-1-git-send-email-jani@nikula.org>\r
36 References: <871troub1v.fsf@qmul.ac.uk>\r
37         <1410021689-15901-1-git-send-email-jani@nikula.org>\r
38 User-Agent: Notmuch/0.18.1+86~gef5e66a (http://notmuchmail.org) Emacs/23.4.1\r
39         (x86_64-pc-linux-gnu)\r
40 Date: Sat, 06 Sep 2014 18:47:27 +0100\r
41 Message-ID: <8761h0fxow.fsf@qmul.ac.uk>\r
42 MIME-Version: 1.0\r
43 Content-Type: text/plain; charset=us-ascii\r
44 X-Sender-Host-Address: 87.81.223.162\r
45 X-QM-Geographic: According to ripencc,\r
46         this message was delivered by a machine in Britain (UK) (GB).\r
47 X-QM-SPAM-Info: Sender has good ham record.  :)\r
48 X-QM-Body-MD5: 395bbb73bdb0e55886bace1d71d05c7d (of first 20000 bytes)\r
49 X-SpamAssassin-Score: -0.1\r
50 X-SpamAssassin-SpamBar: /\r
51 X-SpamAssassin-Report: The QM spam filters have analysed this message to\r
52         determine if it is\r
53         spam. We require at least 5.0 points to mark a message as spam.\r
54         This message scored -0.1 points.\r
55         Summary of the scoring: \r
56         * 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail\r
57         provider *      (markwalters1009[at]gmail.com)\r
58         * -0.1 AWL AWL: From: address is in the auto white-list\r
59 X-QM-Scan-Virus: ClamAV says the message is clean\r
60 X-BeenThere: notmuch@notmuchmail.org\r
61 X-Mailman-Version: 2.1.13\r
62 Precedence: list\r
63 List-Id: "Use and development of the notmuch mail system."\r
64         <notmuch.notmuchmail.org>\r
65 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
66         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
67 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
68 List-Post: <mailto:notmuch@notmuchmail.org>\r
69 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
70 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
71         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
72 X-List-Received-Date: Sat, 06 Sep 2014 17:48:03 -0000\r
73 \r
74 \r
75 On Sat, 06 Sep 2014, Jani Nikula <jani@nikula.org> wrote:\r
76 > address-from prints reply-to or from, address-to prints to, cc, and\r
77 > bcc, and address-all prints all of them.\r
78 \r
79 This looks good to me. Obviously needs the new commit\r
80 message. \r
81 \r
82 I think we should think  about the deduplication possibilities but that\r
83 can be added later. My timings suggest that there is a 20 times speed up\r
84 in using this with --output=sender over calling notmuch show\r
85 --body=false --entire-thread=false.\r
86 \r
87 If you want the to,cc then this version is only twice as fast as the\r
88 notmuch show version. \r
89 \r
90 (All the above are with a hot cache: I expect bigger improvements with a\r
91 cold cache).\r
92 \r
93 So this could well speed up dme's address completion patch\r
94 id:1409921969-65129-1-git-send-email-dme@dme.org by a factor of 20.\r
95 \r
96 (The nevermore variants will not get such a big gain as they look at\r
97 to/cc rather than from)\r
98 \r
99 Best wishes\r
100 \r
101 Mark\r
102 \r
103 \r
104 > ---\r
105 >  notmuch-search.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++-----\r
106 >  1 file changed, 100 insertions(+), 9 deletions(-)\r
107 >\r
108 > diff --git a/notmuch-search.c b/notmuch-search.c\r
109 > index bc9be4593ecc..e7cf3d2a0fdf 100644\r
110 > --- a/notmuch-search.c\r
111 > +++ b/notmuch-search.c\r
112 > @@ -23,11 +23,14 @@\r
113 >  #include "string-util.h"\r
114 >  \r
115 >  typedef enum {\r
116 > -    OUTPUT_SUMMARY,\r
117 > -    OUTPUT_THREADS,\r
118 > -    OUTPUT_MESSAGES,\r
119 > -    OUTPUT_FILES,\r
120 > -    OUTPUT_TAGS\r
121 > +    OUTPUT_SUMMARY   = 1 << 0,\r
122 > +    OUTPUT_THREADS   = 1 << 1,\r
123 > +    OUTPUT_MESSAGES  = 1 << 2,\r
124 > +    OUTPUT_FILES     = 1 << 3,\r
125 > +    OUTPUT_TAGS              = 1 << 4,\r
126 > +    OUTPUT_SENDER    = 1 << 5,\r
127 > +    OUTPUT_RECIPIENTS        = 1 << 6,\r
128 > +    OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS,\r
129 >  } output_t;\r
130 >  \r
131 >  /* Return two stable query strings that identify exactly the matched\r
132 > @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format,\r
133 >      return 0;\r
134 >  }\r
135 >  \r
136 > +static void\r
137 > +print_address_list (sprinter_t *format, InternetAddressList *list)\r
138 > +{\r
139 > +    InternetAddress *address;\r
140 > +    int i;\r
141 > +\r
142 > +    for (i = 0; i < internet_address_list_length (list); i++) {\r
143 > +     address = internet_address_list_get_address (list, i);\r
144 > +     if (INTERNET_ADDRESS_IS_GROUP (address)) {\r
145 > +         InternetAddressGroup *group;\r
146 > +         InternetAddressList *group_list;\r
147 > +\r
148 > +         group = INTERNET_ADDRESS_GROUP (address);\r
149 > +         group_list = internet_address_group_get_members (group);\r
150 > +         if (group_list == NULL)\r
151 > +             continue;\r
152 > +\r
153 > +         print_address_list (format, group_list);\r
154 > +     } else {\r
155 > +         InternetAddressMailbox *mailbox;\r
156 > +         const char *name;\r
157 > +         const char *addr;\r
158 > +         char *full_address;\r
159 > +\r
160 > +         mailbox = INTERNET_ADDRESS_MAILBOX (address);\r
161 > +\r
162 > +         name = internet_address_get_name (address);\r
163 > +         addr = internet_address_mailbox_get_addr (mailbox);\r
164 > +\r
165 > +         if (name && *name)\r
166 > +             full_address = talloc_asprintf (NULL, "%s <%s>", name, addr);\r
167 > +         else\r
168 > +             full_address = talloc_asprintf (NULL, "<%s>", addr);\r
169 > +\r
170 > +         if (!full_address)\r
171 > +             break;\r
172 > +\r
173 > +         format->string (format, full_address);\r
174 > +         format->separator (format);\r
175 > +\r
176 > +         talloc_free (full_address);\r
177 > +     }\r
178 > +    }\r
179 > +}\r
180 > +\r
181 > +static void\r
182 > +print_address_string (sprinter_t *format, const char *recipients)\r
183 > +{\r
184 > +    InternetAddressList *list;\r
185 > +\r
186 > +    if (recipients == NULL)\r
187 > +     return;\r
188 > +\r
189 > +    list = internet_address_list_parse_string (recipients);\r
190 > +    if (list == NULL)\r
191 > +     return;\r
192 > +\r
193 > +    print_address_list (format, list);\r
194 > +}\r
195 > +\r
196 >  static int\r
197 >  do_search_messages (sprinter_t *format,\r
198 >                   notmuch_query_t *query,\r
199 > @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format,\r
200 >           \r
201 >           notmuch_filenames_destroy( filenames );\r
202 >  \r
203 > -     } else { /* output == OUTPUT_MESSAGES */\r
204 > +     } else if (output == OUTPUT_MESSAGES) {\r
205 >           format->set_prefix (format, "id");\r
206 >           format->string (format,\r
207 >                           notmuch_message_get_message_id (message));\r
208 >           format->separator (format);\r
209 > +     } else {\r
210 > +         if (output & OUTPUT_SENDER) {\r
211 > +             const char *addrs;\r
212 > +\r
213 > +             addrs = notmuch_message_get_header (message, "from");\r
214 > +             print_address_string (format, addrs);\r
215 > +         }\r
216 > +\r
217 > +         if (output & OUTPUT_RECIPIENTS) {\r
218 > +             const char *hdrs[] = { "to", "cc", "bcc" };\r
219 > +             const char *addrs;\r
220 > +             size_t j;\r
221 > +\r
222 > +             for (j = 0; j < ARRAY_SIZE (hdrs); j++) {\r
223 > +                 addrs = notmuch_message_get_header (message, hdrs[j]);\r
224 > +                 print_address_string (format, addrs);\r
225 > +             }\r
226 > +         }\r
227 >       }\r
228 >  \r
229 >       notmuch_message_destroy (message);\r
230 > @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])\r
231 >      notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;\r
232 >      sprinter_t *format = NULL;\r
233 >      int opt_index, ret;\r
234 > -    output_t output = OUTPUT_SUMMARY;\r
235 > +    output_t output = 0;\r
236 >      int offset = 0;\r
237 >      int limit = -1; /* unlimited */\r
238 >      notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE;\r
239 > @@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])\r
240 >                                 { "text0", NOTMUCH_FORMAT_TEXT0 },\r
241 >                                 { 0, 0 } } },\r
242 >       { NOTMUCH_OPT_INT, &notmuch_format_version, "format-version", 0, 0 },\r
243 > -     { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',\r
244 > +     { NOTMUCH_OPT_KEYWORD_FLAGS, &output, "output", 'o',\r
245 >         (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY },\r
246 >                                 { "threads", OUTPUT_THREADS },\r
247 >                                 { "messages", OUTPUT_MESSAGES },\r
248 > +                               { "sender", OUTPUT_SENDER },\r
249 > +                               { "recipients", OUTPUT_RECIPIENTS },\r
250 >                                 { "files", OUTPUT_FILES },\r
251 >                                 { "tags", OUTPUT_TAGS },\r
252 >                                 { 0, 0 } } },\r
253 > @@ -387,6 +470,9 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])\r
254 >      if (opt_index < 0)\r
255 >       return EXIT_FAILURE;\r
256 >  \r
257 > +    if (! output)\r
258 > +     output = OUTPUT_SUMMARY;\r
259 > +\r
260 >      switch (format_sel) {\r
261 >      case NOTMUCH_FORMAT_TEXT:\r
262 >       format = sprinter_text_create (config, stdout);\r
263 > @@ -453,18 +539,23 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])\r
264 >      }\r
265 >  \r
266 >      switch (output) {\r
267 > -    default:\r
268 >      case OUTPUT_SUMMARY:\r
269 >      case OUTPUT_THREADS:\r
270 >       ret = do_search_threads (format, query, sort, output, offset, limit);\r
271 >       break;\r
272 >      case OUTPUT_MESSAGES:\r
273 > +    case OUTPUT_SENDER:\r
274 > +    case OUTPUT_RECIPIENTS:\r
275 > +    case OUTPUT_ADDRESSES:\r
276 >      case OUTPUT_FILES:\r
277 >       ret = do_search_messages (format, query, output, offset, limit, dupe);\r
278 >       break;\r
279 >      case OUTPUT_TAGS:\r
280 >       ret = do_search_tags (notmuch, format, query);\r
281 >       break;\r
282 > +    default:\r
283 > +     fprintf (stderr, "Error: the combination of outputs is not supported.\n");\r
284 > +     ret = 1;\r
285 >      }\r
286 >  \r
287 >      notmuch_query_destroy (query);\r
288 > -- \r
289 > 2.1.0\r
290 >\r
291 > _______________________________________________\r
292 > notmuch mailing list\r
293 > notmuch@notmuchmail.org\r
294 > http://notmuchmail.org/mailman/listinfo/notmuch\r