Re: [PATCH 2/2] emacs: express notmuch-search-line-faces in terms of two new faces...
[notmuch-archives.git] / ef / b71589f945d85f6ed1a8bcba9090aa8622614e
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 EC7EA431FAF\r
6         for <notmuch@notmuchmail.org>; Sat,  8 Dec 2012 11:22:31 -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 YWUD0RgigHOt for <notmuch@notmuchmail.org>;\r
16         Sat,  8 Dec 2012 11:22:30 -0800 (PST)\r
17 Received: from mail-la0-f53.google.com (mail-la0-f53.google.com\r
18         [209.85.215.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 491A5431FAE\r
21         for <notmuch@notmuchmail.org>; Sat,  8 Dec 2012 11:22:30 -0800 (PST)\r
22 Received: by mail-la0-f53.google.com with SMTP id w12so1173543lag.26\r
23         for <notmuch@notmuchmail.org>; Sat, 08 Dec 2012 11:22:27 -0800 (PST)\r
24 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
25         d=google.com; s=20120113;\r
26         h=from:to:cc:subject:in-reply-to:references:user-agent:date\r
27         :message-id:mime-version:content-type:x-gm-message-state;\r
28         bh=DxTPwl2Zc4wWCCgThT7/LWedEjiqXfBeY9KT8ynyPPY=;\r
29         b=nuMrTFt6B5GsbGb8dOBI0mzVG2mznjU9oehyYyWqysTSj6ixl2caqe7cvloytqHSgc\r
30         YW8BX/xl1kZ95FE0iHFvFyN4nE2KGSs2Q+soCd1+NhpGLSY6e8Iec8pG/5KN387tLGzt\r
31         Z1AhENHcdsah7sNCfqFXuCsIXJSC8AUlSGJ7Y1udUaR5dJsf/lQn1IqtZk2DFM+PLK6u\r
32         xTkIG0LY6cNEOX2Q627u7kMnMFjv6GI75d6RkzeZQ+gV2i0lGtrlR2NLSrGawO010ODW\r
33         LIEPSjyHnz2mzBDPBYBshuvn79s2YP1A0jdS8OyVwdPIWyFWRxhSPfWWsxWs5iSSXSdl\r
34         5/TQ==\r
35 Received: by 10.152.148.4 with SMTP id to4mr2543118lab.39.1354994545891;\r
36         Sat, 08 Dec 2012 11:22:25 -0800 (PST)\r
37 Received: from localhost (dsl-hkibrasgw4-fe51df00-27.dhcp.inet.fi.\r
38         [80.223.81.27])\r
39         by mx.google.com with ESMTPS id er8sm5989949lbb.9.2012.12.08.11.22.23\r
40         (version=SSLv3 cipher=OTHER); Sat, 08 Dec 2012 11:22:25 -0800 (PST)\r
41 From: Jani Nikula <jani@nikula.org>\r
42 To: david@tethera.net, notmuch@notmuchmail.org\r
43 Subject: Re: [Patch v4 04/10] tag-util.[ch]: New files for common tagging\r
44         routines\r
45 In-Reply-To: <1354979276-20099-5-git-send-email-david@tethera.net>\r
46 References: <1354979276-20099-1-git-send-email-david@tethera.net>\r
47         <1354979276-20099-5-git-send-email-david@tethera.net>\r
48 User-Agent: Notmuch/0.14+138~g7041c56 (http://notmuchmail.org) Emacs/23.4.1\r
49         (i686-pc-linux-gnu)\r
50 Date: Sat, 08 Dec 2012 21:22:22 +0200\r
51 Message-ID: <871uf0qrgx.fsf@nikula.org>\r
52 MIME-Version: 1.0\r
53 Content-Type: text/plain; charset=us-ascii\r
54 X-Gm-Message-State:\r
55  ALoCoQn3ZhEvGwEoj5YC0MdGOTEM1HSGZuW7K0xwIp2KKgjoh9kXnqtevZCQiGzYyivTL/d4+1dF\r
56 Cc: David Bremner <bremner@debian.org>\r
57 X-BeenThere: notmuch@notmuchmail.org\r
58 X-Mailman-Version: 2.1.13\r
59 Precedence: list\r
60 List-Id: "Use and development of the notmuch mail system."\r
61         <notmuch.notmuchmail.org>\r
62 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
63         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
64 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
65 List-Post: <mailto:notmuch@notmuchmail.org>\r
66 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
67 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
68         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
69 X-List-Received-Date: Sat, 08 Dec 2012 19:22:32 -0000\r
70 \r
71 \r
72 Hi David, some error message bikeshedding below.\r
73 \r
74 BR,\r
75 Jani.\r
76 \r
77 \r
78 On Sat, 08 Dec 2012, david@tethera.net wrote:\r
79 > From: David Bremner <bremner@debian.org>\r
80 >\r
81 > These are meant to be shared between notmuch-tag and notmuch-restore.\r
82 >\r
83 > The bulk of the routines implement a "tag operation list" abstract\r
84 > data type act as a structured representation of a set of tag\r
85 > operations (typically coming from a single tag command or line of\r
86 > input).\r
87 > ---\r
88 >  Makefile.local |    1 +\r
89 >  tag-util.c     |  292 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
90 >  tag-util.h     |  122 +++++++++++++++++++++++\r
91 >  3 files changed, 415 insertions(+)\r
92 >  create mode 100644 tag-util.c\r
93 >  create mode 100644 tag-util.h\r
94 >\r
95 > diff --git a/Makefile.local b/Makefile.local\r
96 > index 0db1713..c274f07 100644\r
97 > --- a/Makefile.local\r
98 > +++ b/Makefile.local\r
99 > @@ -275,6 +275,7 @@ notmuch_client_srcs =             \\r
100 >       query-string.c          \\r
101 >       mime-node.c             \\r
102 >       crypto.c                \\r
103 > +     tag-util.c\r
104 >  \r
105 >  notmuch_client_modules = $(notmuch_client_srcs:.c=.o)\r
106 >  \r
107 > diff --git a/tag-util.c b/tag-util.c\r
108 > new file mode 100644\r
109 > index 0000000..80ebdc2\r
110 > --- /dev/null\r
111 > +++ b/tag-util.c\r
112 > @@ -0,0 +1,292 @@\r
113 > +#include <assert.h>\r
114 > +#include "string-util.h"\r
115 > +#include "tag-util.h"\r
116 > +#include "hex-escape.h"\r
117 > +\r
118 > +#define TAG_OP_LIST_INITIAL_SIZE 10\r
119 > +\r
120 > +struct _tag_operation_t {\r
121 > +    const char *tag;\r
122 > +    notmuch_bool_t remove;\r
123 > +};\r
124 > +\r
125 > +struct _tag_op_list_t {\r
126 > +    tag_operation_t *ops;\r
127 > +    size_t count;\r
128 > +    size_t size;\r
129 > +};\r
130 > +\r
131 > +int\r
132 > +parse_tag_line (void *ctx, char *line,\r
133 > +             tag_op_flag_t flags,\r
134 > +             char **query_string,\r
135 > +             tag_op_list_t *tag_ops)\r
136 > +{\r
137 > +    char *tok = line;\r
138 > +    size_t tok_len = 0;\r
139 > +    char *line_for_error;\r
140 > +    int ret = 0;\r
141 > +\r
142 > +    chomp_newline (line);\r
143 > +\r
144 > +    line_for_error = talloc_strdup (ctx, line);\r
145 > +    if (line_for_error == NULL) {\r
146 > +     fprintf (stderr, "Error: out of memory\n");\r
147 > +     return -1;\r
148 > +    }\r
149 > +\r
150 > +    /* remove leading space */\r
151 > +    while (*tok == ' ' || *tok == '\t')\r
152 > +     tok++;\r
153 > +\r
154 > +    /* Skip empty and comment lines. */\r
155 > +    if (*tok == '\0' || *tok == '#') {\r
156 > +     ret = 2;\r
157 > +     goto DONE;\r
158 > +    }\r
159 > +\r
160 > +    tag_op_list_reset (tag_ops);\r
161 > +\r
162 > +    /* Parse tags. */\r
163 > +    while ((tok = strtok_len (tok + tok_len, " ", &tok_len)) != NULL) {\r
164 > +     notmuch_bool_t remove;\r
165 > +     char *tag;\r
166 > +\r
167 > +     /* Optional explicit end of tags marker. */\r
168 > +     if (tok_len == 2 && strncmp (tok, "--", tok_len) == 0) {\r
169 > +         tok = strtok_len (tok + tok_len, " ", &tok_len);\r
170 > +         if (tok == NULL)\r
171 > +             fprintf (stderr, "Warning: no query string: %s\n", line_for_error);\r
172 \r
173 I think you should move this warning back... (see below)\r
174 \r
175 > +         break;\r
176 > +     }\r
177 > +\r
178 > +     /* Implicit end of tags. */\r
179 > +     if (*tok != '-' && *tok != '+')\r
180 > +         break;\r
181 > +\r
182 > +     /* If tag is terminated by NUL, there's no query string. */\r
183 > +     if (*(tok + tok_len) == '\0') {\r
184 > +         fprintf (stderr, "Warning: no query string: %s\n", line_for_error);\r
185 > +         ret = 1;\r
186 > +         goto DONE;\r
187 > +     }\r
188 > +\r
189 > +     /* Terminate, and start next token after terminator. */\r
190 > +     *(tok + tok_len++) = '\0';\r
191 > +\r
192 > +     remove = (*tok == '-');\r
193 > +     tag = tok + 1;\r
194 > +\r
195 > +     /* Maybe refuse empty tags. */\r
196 > +     if (! (flags & TAG_FLAG_BE_GENEROUS) && *tag == '\0') {\r
197 > +         fprintf (stderr, "Warning: empty tag: %s\n", line_for_error);\r
198 > +         ret = 1;\r
199 > +         goto DONE;\r
200 > +     }\r
201 > +\r
202 > +     /* Decode tag. */\r
203 > +     if (hex_decode_inplace (tag) != HEX_SUCCESS) {\r
204 > +         fprintf (stderr, "Warning: Hex decoding of tag %s failed\n",\r
205 > +                  tag);\r
206 > +         ret = 1;\r
207 > +         goto DONE;\r
208 > +     }\r
209 > +\r
210 > +     if (tag_op_list_append (ctx, tag_ops, tag, remove)) {\r
211 > +         /* diagnostics already printed */\r
212 > +         ret = -1;\r
213 > +         goto DONE;\r
214 > +     }\r
215 > +    }\r
216 > +\r
217 > +    if (tok == NULL) {\r
218 \r
219 ...here where it was. Now you'll only get the warning for lines like:\r
220 \r
221 +foo +bar --\r
222 \r
223 but not for:\r
224 \r
225 +foo +bar\r
226 \r
227 which are only caught here. (Alternatively, you could have both print\r
228 the error message, and set ret and goto DONE also in the first case. But\r
229 I don't know if that gains us anything.)\r
230 \r
231 > +     ret = 1;\r
232 > +     goto DONE;\r
233 > +    }\r
234 > +\r
235 > +    /* tok now points to the query string */\r
236 > +    if (hex_decode_inplace (tok) != HEX_SUCCESS) {\r
237 > +     fprintf (stderr, "Warning: Hex decoding of query %s failed\n",\r
238 > +              tok);\r
239 > +     ret = 1;\r
240 > +     goto DONE;\r
241 > +    }\r
242 > +\r
243 > +    *query_string = tok;\r
244 > +\r
245 > +  DONE:\r
246 > +    if ((ret % 2) != 0)\r
247 > +     fprintf (stderr, "%s invalid input line %s\n",\r
248 > +              ret == 1 ? "Warning: Ignoring" : "Error: Failing at",\r
249 > +              line_for_error);\r
250 \r
251 Can't resist urge to nitpick... I think the (ret % 2) is a bit\r
252 magical. I'd prefer the explicit (ret != 0 && ret != 2). Another one is\r
253 that some of the earlier warnings/errors already print line_for_error,\r
254 resulting in printing the line twice. Maybe only print line_for_error\r
255 here, and remove that bit from the messages earlier?\r
256 \r
257 > +\r
258 > +    talloc_free (line_for_error);\r
259 > +    return ret;\r
260 > +}\r
261 > +\r
262 > +static inline void\r
263 > +message_error (notmuch_message_t *message,\r
264 > +            notmuch_status_t status,\r
265 > +            const char *format, ...)\r
266 > +{\r
267 > +    va_list va_args;\r
268 > +\r
269 > +    va_start (va_args, format);\r
270 > +\r
271 > +    vfprintf (stderr, format, va_args);\r
272 > +    fprintf (stderr, "Message-ID: %s\n", notmuch_message_get_message_id (message));\r
273 > +    fprintf (stderr, "Status: %s\n", notmuch_status_to_string (status));\r
274 > +}\r
275 > +\r
276 > +notmuch_status_t\r
277 > +tag_op_list_apply (notmuch_message_t *message,\r
278 > +                tag_op_list_t *list,\r
279 > +                tag_op_flag_t flags)\r
280 > +{\r
281 > +    size_t i;\r
282 > +    notmuch_status_t status = 0;\r
283 > +    tag_operation_t *tag_ops = list->ops;\r
284 > +\r
285 > +    status = notmuch_message_freeze (message);\r
286 > +    if (status) {\r
287 > +     message_error (message, status, "freezing message");\r
288 > +     return status;\r
289 > +    }\r
290 > +\r
291 > +    if (flags & TAG_FLAG_REMOVE_ALL) {\r
292 > +     status = notmuch_message_remove_all_tags (message);\r
293 > +     if (status) {\r
294 > +         message_error (message, status, "removing all tags");\r
295 > +         return status;\r
296 > +     }\r
297 > +    }\r
298 > +\r
299 > +    for (i = 0; i < list->count; i++) {\r
300 > +     if (tag_ops[i].remove) {\r
301 > +         status = notmuch_message_remove_tag (message, tag_ops[i].tag);\r
302 > +         if (status) {\r
303 > +             message_error (message, status, "removing tag %s", tag_ops[i].tag);\r
304 > +             return status;\r
305 > +         }\r
306 > +     } else {\r
307 > +         status = notmuch_message_add_tag (message, tag_ops[i].tag);\r
308 > +         if (status) {\r
309 > +             message_error (message, status, "adding tag %s", tag_ops[i].tag);\r
310 > +             return status;\r
311 > +         }\r
312 > +\r
313 > +     }\r
314 > +    }\r
315 > +\r
316 > +    status = notmuch_message_thaw (message);\r
317 > +    if (status) {\r
318 > +     message_error (message, status, "thawing message");\r
319 > +     return status;\r
320 > +    }\r
321 > +\r
322 > +\r
323 > +    if (flags & TAG_FLAG_MAILDIR_SYNC) {\r
324 > +     status = notmuch_message_tags_to_maildir_flags (message);\r
325 > +     if (status) {\r
326 > +         message_error (message, status, "synching tags to maildir");\r
327 > +         return status;\r
328 > +     }\r
329 > +    }\r
330 > +\r
331 > +    return NOTMUCH_STATUS_SUCCESS;\r
332 > +\r
333 > +}\r
334 > +\r
335 > +\r
336 > +/* Array of tagging operations (add or remove.  Size will be increased\r
337 > + * as necessary. */\r
338 > +\r
339 > +tag_op_list_t *\r
340 > +tag_op_list_create (void *ctx)\r
341 > +{\r
342 > +    tag_op_list_t *list;\r
343 > +\r
344 > +    list = talloc (ctx, tag_op_list_t);\r
345 > +    if (list == NULL)\r
346 > +     return NULL;\r
347 > +\r
348 > +    list->size = TAG_OP_LIST_INITIAL_SIZE;\r
349 > +    list->count = 0;\r
350 > +\r
351 > +    list->ops = talloc_array (ctx, tag_operation_t, list->size);\r
352 > +    if (list->ops == NULL)\r
353 > +     return NULL;\r
354 > +\r
355 > +    return list;\r
356 > +}\r
357 > +\r
358 > +\r
359 > +int\r
360 > +tag_op_list_append (void *ctx,\r
361 > +                 tag_op_list_t *list,\r
362 > +                 const char *tag,\r
363 > +                 notmuch_bool_t remove)\r
364 > +{\r
365 > +    /* Make room if current array is full.  This should be a fairly\r
366 > +     * rare case, considering the initial array size.\r
367 > +     */\r
368 > +\r
369 > +    if (list->count == list->size) {\r
370 > +     list->size *= 2;\r
371 > +     list->ops = talloc_realloc (ctx, list->ops, tag_operation_t,\r
372 > +                                 list->size);\r
373 > +     if (list->ops == NULL) {\r
374 > +         fprintf (stderr, "Out of memory.\n");\r
375 > +         return 1;\r
376 > +     }\r
377 > +    }\r
378 > +\r
379 > +    /* add the new operation */\r
380 > +\r
381 > +    list->ops[list->count].tag = tag;\r
382 > +    list->ops[list->count].remove = remove;\r
383 > +    list->count++;\r
384 > +    return 0;\r
385 > +}\r
386 > +\r
387 > +/*\r
388 > + *   Is the i'th tag operation a remove?\r
389 > + */\r
390 > +\r
391 > +notmuch_bool_t\r
392 > +tag_op_list_isremove (const tag_op_list_t *list, size_t i)\r
393 > +{\r
394 > +    assert (i < list->count);\r
395 > +    return list->ops[i].remove;\r
396 > +}\r
397 > +\r
398 > +/*\r
399 > + * Reset a list to contain no operations\r
400 > + */\r
401 > +\r
402 > +void\r
403 > +tag_op_list_reset (tag_op_list_t *list)\r
404 > +{\r
405 > +    list->count = 0;\r
406 > +}\r
407 > +\r
408 > +/*\r
409 > + * Return the number of operations in a list\r
410 > + */\r
411 > +\r
412 > +size_t\r
413 > +tag_op_list_size (const tag_op_list_t *list)\r
414 > +{\r
415 > +    return list->count;\r
416 > +}\r
417 > +\r
418 > +/*\r
419 > + *   return the i'th tag in the list\r
420 > + */\r
421 > +\r
422 > +const char *\r
423 > +tag_op_list_tag (const tag_op_list_t *list, size_t i)\r
424 > +{\r
425 > +    assert (i < list->count);\r
426 > +    return list->ops[i].tag;\r
427 > +}\r
428 > diff --git a/tag-util.h b/tag-util.h\r
429 > new file mode 100644\r
430 > index 0000000..581207a\r
431 > --- /dev/null\r
432 > +++ b/tag-util.h\r
433 > @@ -0,0 +1,122 @@\r
434 > +#ifndef _TAG_UTIL_H\r
435 > +#define _TAG_UTIL_H\r
436 > +\r
437 > +#include "notmuch-client.h"\r
438 > +\r
439 > +typedef struct _tag_operation_t tag_operation_t;\r
440 > +typedef struct _tag_op_list_t tag_op_list_t;\r
441 > +\r
442 > +/* Use powers of 2 */\r
443 > +typedef enum {\r
444 > +    TAG_FLAG_NONE = 0,\r
445 > +\r
446 > +    /* Operations are synced to maildir, if possible.\r
447 > +     */\r
448 > +    TAG_FLAG_MAILDIR_SYNC = (1 << 0),\r
449 > +\r
450 > +    /* Remove all tags from message before applying list.\r
451 > +     */\r
452 > +    TAG_FLAG_REMOVE_ALL = (1 << 1),\r
453 > +\r
454 > +    /* Don't try to avoid database operations. Useful when we\r
455 > +     * know that message passed needs these operations.\r
456 > +      */\r
457 > +    TAG_FLAG_PRE_OPTIMIZED = (1 << 2),\r
458 > +\r
459 > +    /* Accept strange tags that might be user error;\r
460 > +     * intended for use by notmuch-restore.\r
461 > +     */\r
462 > +    TAG_FLAG_BE_GENEROUS = (1 << 3)\r
463 > +\r
464 > +} tag_op_flag_t;\r
465 > +\r
466 > +/* Parse a string of the following format:\r
467 > + *\r
468 > + * +<tag>|-<tag> [...] [--] <search-terms>\r
469 > + *\r
470 > + * Each line is interpreted similarly to "notmuch tag" command line\r
471 > + * arguments. The delimiter is one or more spaces ' '. Any characters\r
472 > + * in <tag> and <search-terms> MAY be hex encoded with %NN where NN is\r
473 > + * the hexadecimal value of the character. Any ' ' and '%' characters\r
474 > + * in <tag> and <search-terms> MUST be hex encoded (using %20 and %25,\r
475 > + * respectively). Any characters that are not part of <tag> or\r
476 > + * <search-terms> MUST NOT be hex encoded.\r
477 > + *\r
478 > + * Leading and trailing space ' ' is ignored. Empty lines and lines\r
479 > + * beginning with '#' are ignored.\r
480 > + *\r
481 > + * Returns:  0       OK,\r
482 > + *           1       skipped (invalid) line\r
483 > + *           2       skipped (valid) line\r
484 > + *           -1      fatal(ish) error.\r
485 > + *\r
486 > + * Output Parameters:\r
487 > + *   ops     contains a list of tag operations\r
488 > + *   query_str the search terms.\r
489 > + */\r
490 > +int\r
491 > +parse_tag_line (void *ctx, char *line,\r
492 > +             tag_op_flag_t flags,\r
493 > +             char **query_str, tag_op_list_t *ops);\r
494 > +\r
495 > +/*\r
496 > + * Create an empty list of tag operations\r
497 > + *\r
498 > + * ctx is passed to talloc\r
499 > + */\r
500 > +\r
501 > +tag_op_list_t *\r
502 > +tag_op_list_create (void *ctx);\r
503 > +\r
504 > +/*\r
505 > + * Add a tag operation (delete iff remove == TRUE) to a list.\r
506 > + * The list is expanded as necessary.\r
507 > + */\r
508 > +\r
509 > +int\r
510 > +tag_op_list_append (void *ctx,\r
511 > +                 tag_op_list_t *list,\r
512 > +                 const char *tag,\r
513 > +                 notmuch_bool_t remove);\r
514 > +\r
515 > +/*\r
516 > + * Apply a list of tag operations, in order, to a given message.\r
517 > + *\r
518 > + * Flags can be bitwise ORed; see enum above for possibilies.\r
519 > + */\r
520 > +\r
521 > +notmuch_status_t\r
522 > +tag_op_list_apply (notmuch_message_t *message,\r
523 > +                tag_op_list_t *tag_ops,\r
524 > +                tag_op_flag_t flags);\r
525 > +\r
526 > +/*\r
527 > + * Return the number of operations in a list\r
528 > + */\r
529 > +\r
530 > +size_t\r
531 > +tag_op_list_size (const tag_op_list_t *list);\r
532 > +\r
533 > +/*\r
534 > + * Reset a list to contain no operations\r
535 > + */\r
536 > +\r
537 > +void\r
538 > +tag_op_list_reset (tag_op_list_t *list);\r
539 > +\r
540 > +\r
541 > + /*\r
542 > +  *   return the i'th tag in the list\r
543 > +  */\r
544 > +\r
545 > +const char *\r
546 > +tag_op_list_tag (const tag_op_list_t *list, size_t i);\r
547 > +\r
548 > +/*\r
549 > + *   Is the i'th tag operation a remove?\r
550 > + */\r
551 > +\r
552 > +notmuch_bool_t\r
553 > +tag_op_list_isremove (const tag_op_list_t *list, size_t i);\r
554 > +\r
555 > +#endif\r
556 > -- \r
557 > 1.7.10.4\r
558 >\r
559 > _______________________________________________\r
560 > notmuch mailing list\r
561 > notmuch@notmuchmail.org\r
562 > http://notmuchmail.org/mailman/listinfo/notmuch\r