Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / bc / fa91fecd4901233b5e9893c5834285d30b3d28
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 1A5F9431FAF\r
6         for <notmuch@notmuchmail.org>; Mon, 10 Dec 2012 13:51:50 -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 LimJP3IJywas for <notmuch@notmuchmail.org>;\r
16         Mon, 10 Dec 2012 13:51:49 -0800 (PST)\r
17 Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com\r
18         [209.85.217.181]) (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 B2D88431FAE\r
21         for <notmuch@notmuchmail.org>; Mon, 10 Dec 2012 13:51:48 -0800 (PST)\r
22 Received: by mail-lb0-f181.google.com with SMTP id ge1so2531934lbb.26\r
23         for <notmuch@notmuchmail.org>; Mon, 10 Dec 2012 13:51:47 -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=f/OUC3lmB+BLaW8GFoWa5HBczTKKvNvwg0gySxJunZI=;\r
29         b=Y4yoZOR8Y+m3E2aWRbRgIZFVj87OzXJMpQB2FMDo0mk0Ak+J+qQgo1Rfand3TzkQ/i\r
30         tN+Jod93/MWHutEKygxnWc/RJyFqqdRwLpzynJy7zSLpGAsGm84fZqAjz3F3P2eknu7z\r
31         8zuj00MBqMRc4cbLeem+AyJJneSOF5uMfyMr02A+r9fX33rowW/+cZziD3FXEaaknqHT\r
32         KgOQ0a2m+sSILbuu05uadEI8nOr2SOSGCo6PeyURfZOHVvLmjObDeSs2H4MHMzTlXOkT\r
33         BfktRPzMFq1VS3XxwpZwR3rUdDmXEFC9WBOiujeA3TlzbP4fz8SqcKfu93P6bajViazu\r
34         3+9w==\r
35 Received: by 10.152.108.42 with SMTP id hh10mr15113564lab.4.1355176307103;\r
36         Mon, 10 Dec 2012 13:51:47 -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 gr12sm8400940lab.3.2012.12.10.13.51.45\r
40         (version=SSLv3 cipher=OTHER); Mon, 10 Dec 2012 13:51:46 -0800 (PST)\r
41 From: Jani Nikula <jani@nikula.org>\r
42 To: david@tethera.net, notmuch@notmuchmail.org\r
43 Subject: Re: [Patch v6 2/6] notmuch-tag.c: convert to use tag-utils\r
44 In-Reply-To: <1355096008-4544-3-git-send-email-david@tethera.net>\r
45 References: <1355096008-4544-1-git-send-email-david@tethera.net>\r
46         <1355096008-4544-3-git-send-email-david@tethera.net>\r
47 User-Agent: Notmuch/0.14+138~g7041c56 (http://notmuchmail.org) Emacs/23.4.1\r
48         (i686-pc-linux-gnu)\r
49 Date: Mon, 10 Dec 2012 23:51:44 +0200\r
50 Message-ID: <876249a83z.fsf@nikula.org>\r
51 MIME-Version: 1.0\r
52 Content-Type: text/plain; charset=us-ascii\r
53 X-Gm-Message-State:\r
54  ALoCoQkM8H3R9FPmyJBWB8sdXMtLKBBwo82Ok0pLR6q91VT5glClMDnvxwwExclWrkRDKqU5A/o6\r
55 Cc: David Bremner <bremner@debian.org>\r
56 X-BeenThere: notmuch@notmuchmail.org\r
57 X-Mailman-Version: 2.1.13\r
58 Precedence: list\r
59 List-Id: "Use and development of the notmuch mail system."\r
60         <notmuch.notmuchmail.org>\r
61 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
62         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
63 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
64 List-Post: <mailto:notmuch@notmuchmail.org>\r
65 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
66 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
67         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
68 X-List-Received-Date: Mon, 10 Dec 2012 21:51:50 -0000\r
69 \r
70 On Mon, 10 Dec 2012, david@tethera.net wrote:\r
71 > From: David Bremner <bremner@debian.org>\r
72 >\r
73 > Command line parsing is factored out into a function\r
74 > parse_tag_command_line in tag-utils.c.\r
75 >\r
76 > There is some duplicated code eliminated in tag_query, and a bunch of\r
77 > translation from using the bare tag_op structs to using that tag-utils\r
78 > API.\r
79 > ---\r
80 >  notmuch-tag.c |  104 +++++++++++++--------------------------------------------\r
81 >  tag-util.c    |   48 ++++++++++++++++++++++++++\r
82 >  tag-util.h    |   16 +++++++++\r
83 >  3 files changed, 87 insertions(+), 81 deletions(-)\r
84 >\r
85 > diff --git a/notmuch-tag.c b/notmuch-tag.c\r
86 > index 88d559b..b5cd578 100644\r
87 > --- a/notmuch-tag.c\r
88 > +++ b/notmuch-tag.c\r
89 > @@ -19,6 +19,7 @@\r
90 >   */\r
91 >  \r
92 >  #include "notmuch-client.h"\r
93 > +#include "tag-util.h"\r
94 >  \r
95 >  static volatile sig_atomic_t interrupted;\r
96 >  \r
97 > @@ -54,14 +55,9 @@ _escape_tag (char *buf, const char *tag)\r
98 >      return buf;\r
99 >  }\r
100 >  \r
101 > -typedef struct {\r
102 > -    const char *tag;\r
103 > -    notmuch_bool_t remove;\r
104 > -} tag_operation_t;\r
105 > -\r
106 >  static char *\r
107 >  _optimize_tag_query (void *ctx, const char *orig_query_string,\r
108 > -                  const tag_operation_t *tag_ops)\r
109 > +                  const tag_op_list_t *list)\r
110 >  {\r
111 >      /* This is subtler than it looks.  Xapian ignores the '-' operator\r
112 >       * at the beginning both queries and parenthesized groups and,\r
113 > @@ -73,19 +69,20 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,\r
114 >  \r
115 >      char *escaped, *query_string;\r
116 >      const char *join = "";\r
117 > -    int i;\r
118 > +    size_t i;\r
119 >      unsigned int max_tag_len = 0;\r
120 >  \r
121 >      /* Don't optimize if there are no tag changes. */\r
122 > -    if (tag_ops[0].tag == NULL)\r
123 > +    if (tag_op_list_size (list) == 0)\r
124 >       return talloc_strdup (ctx, orig_query_string);\r
125 >  \r
126 >      /* Allocate a buffer for escaping tags.  This is large enough to\r
127 >       * hold a fully escaped tag with every character doubled plus\r
128 >       * enclosing quotes and a NUL. */\r
129 > -    for (i = 0; tag_ops[i].tag; i++)\r
130 > -     if (strlen (tag_ops[i].tag) > max_tag_len)\r
131 > -         max_tag_len = strlen (tag_ops[i].tag);\r
132 > +    for (i = 0; i < tag_op_list_size (list); i++)\r
133 > +     if (strlen (tag_op_list_tag (list, i)) > max_tag_len)\r
134 > +         max_tag_len = strlen (tag_op_list_tag (list, i));\r
135 > +\r
136 >      escaped = talloc_array (ctx, char, max_tag_len * 2 + 3);\r
137 >      if (! escaped)\r
138 >       return NULL;\r
139 > @@ -96,11 +93,11 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,\r
140 >      else\r
141 >       query_string = talloc_asprintf (ctx, "( %s ) and (", orig_query_string);\r
142 >  \r
143 > -    for (i = 0; tag_ops[i].tag && query_string; i++) {\r
144 > +    for (i = 0; i < tag_op_list_size (list) && query_string; i++) {\r
145 >       query_string = talloc_asprintf_append_buffer (\r
146 >           query_string, "%s%stag:%s", join,\r
147 > -         tag_ops[i].remove ? "" : "not ",\r
148 > -         _escape_tag (escaped, tag_ops[i].tag));\r
149 > +         tag_op_list_isremove (list, i) ? "" : "not ",\r
150 > +         _escape_tag (escaped, tag_op_list_tag (list, i)));\r
151 >       join = " or ";\r
152 >      }\r
153 >  \r
154 > @@ -116,12 +113,11 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,\r
155 >   * element. */\r
156 \r
157 The comment "array of tagging operations terminated with an empty\r
158 element" needs revision too.\r
159 \r
160 BR,\r
161 Jani.\r
162 \r
163 >  static int\r
164 >  tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,\r
165 > -        tag_operation_t *tag_ops, notmuch_bool_t synchronize_flags)\r
166 > +        tag_op_list_t *tag_ops, tag_op_flag_t flags)\r
167 >  {\r
168 >      notmuch_query_t *query;\r
169 >      notmuch_messages_t *messages;\r
170 >      notmuch_message_t *message;\r
171 > -    int i;\r
172 >  \r
173 >      /* Optimize the query so it excludes messages that already have\r
174 >       * the specified set of tags. */\r
175 > @@ -144,21 +140,7 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,\r
176 >        notmuch_messages_valid (messages) && ! interrupted;\r
177 >        notmuch_messages_move_to_next (messages)) {\r
178 >       message = notmuch_messages_get (messages);\r
179 > -\r
180 > -     notmuch_message_freeze (message);\r
181 > -\r
182 > -     for (i = 0; tag_ops[i].tag; i++) {\r
183 > -         if (tag_ops[i].remove)\r
184 > -             notmuch_message_remove_tag (message, tag_ops[i].tag);\r
185 > -         else\r
186 > -             notmuch_message_add_tag (message, tag_ops[i].tag);\r
187 > -     }\r
188 > -\r
189 > -     notmuch_message_thaw (message);\r
190 > -\r
191 > -     if (synchronize_flags)\r
192 > -         notmuch_message_tags_to_maildir_flags (message);\r
193 > -\r
194 > +     tag_op_list_apply (message, tag_ops, flags | TAG_FLAG_PRE_OPTIMIZED);\r
195 >       notmuch_message_destroy (message);\r
196 >      }\r
197 >  \r
198 > @@ -170,15 +152,13 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,\r
199 >  int\r
200 >  notmuch_tag_command (void *ctx, int argc, char *argv[])\r
201 >  {\r
202 > -    tag_operation_t *tag_ops;\r
203 > -    int tag_ops_count = 0;\r
204 > -    char *query_string;\r
205 > +    tag_op_list_t *tag_ops = NULL;\r
206 > +    char *query_string = NULL;\r
207 >      notmuch_config_t *config;\r
208 >      notmuch_database_t *notmuch;\r
209 >      struct sigaction action;\r
210 > -    notmuch_bool_t synchronize_flags;\r
211 > -    int i;\r
212 > -    int ret;\r
213 > +    tag_op_flag_t tag_flags = TAG_FLAG_NONE;\r
214 > +    int ret = 0;\r
215 >  \r
216 >      /* Setup our handler for SIGINT */\r
217 >      memset (&action, 0, sizeof (struct sigaction));\r
218 > @@ -187,54 +167,15 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])\r
219 >      action.sa_flags = SA_RESTART;\r
220 >      sigaction (SIGINT, &action, NULL);\r
221 >  \r
222 > -    argc--; argv++; /* skip subcommand argument */\r
223 > -\r
224 > -    /* Array of tagging operations (add or remove), terminated with an\r
225 > -     * empty element. */\r
226 > -    tag_ops = talloc_array (ctx, tag_operation_t, argc + 1);\r
227 > +    tag_ops = tag_op_list_create (ctx);\r
228 >      if (tag_ops == NULL) {\r
229 >       fprintf (stderr, "Out of memory.\n");\r
230 >       return 1;\r
231 >      }\r
232 >  \r
233 > -    for (i = 0; i < argc; i++) {\r
234 > -     if (strcmp (argv[i], "--") == 0) {\r
235 > -         i++;\r
236 > -         break;\r
237 > -     }\r
238 > -     if (argv[i][0] == '+' || argv[i][0] == '-') {\r
239 > -         if (argv[i][0] == '+' && argv[i][1] == '\0') {\r
240 > -             fprintf (stderr, "Error: tag names cannot be empty.\n");\r
241 > -             return 1;\r
242 > -         }\r
243 > -         if (argv[i][0] == '+' && argv[i][1] == '-') {\r
244 > -             /* This disallows adding the non-removable tag "-" and\r
245 > -              * enables notmuch tag to take long options in the\r
246 > -              * future. */\r
247 > -             fprintf (stderr, "Error: tag names must not start with '-'.\n");\r
248 > -             return 1;\r
249 > -         }\r
250 > -         tag_ops[tag_ops_count].tag = argv[i] + 1;\r
251 > -         tag_ops[tag_ops_count].remove = (argv[i][0] == '-');\r
252 > -         tag_ops_count++;\r
253 > -     } else {\r
254 > -         break;\r
255 > -     }\r
256 > -    }\r
257 > -\r
258 > -    tag_ops[tag_ops_count].tag = NULL;\r
259 > -\r
260 > -    if (tag_ops_count == 0) {\r
261 > -     fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");\r
262 > -     return 1;\r
263 > -    }\r
264 > -\r
265 > -    query_string = query_string_from_args (ctx, argc - i, &argv[i]);\r
266 > -\r
267 > -    if (*query_string == '\0') {\r
268 > -     fprintf (stderr, "Error: notmuch tag requires at least one search term.\n");\r
269 > +    if (parse_tag_command_line (ctx, argc - 1, argv + 1,\r
270 > +                             0, &query_string, tag_ops))\r
271 >       return 1;\r
272 > -    }\r
273 >  \r
274 >      config = notmuch_config_open (ctx, NULL, NULL);\r
275 >      if (config == NULL)\r
276 > @@ -244,9 +185,10 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])\r
277 >                              NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
278 >       return 1;\r
279 >  \r
280 > -    synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);\r
281 > +    if (notmuch_config_get_maildir_synchronize_flags (config))\r
282 > +     tag_flags |= TAG_FLAG_MAILDIR_SYNC;\r
283 >  \r
284 > -    ret = tag_query (ctx, notmuch, query_string, tag_ops, synchronize_flags);\r
285 > +    ret = tag_query (ctx, notmuch, query_string, tag_ops, tag_flags);\r
286 >  \r
287 >      notmuch_database_destroy (notmuch);\r
288 >  \r
289 > diff --git a/tag-util.c b/tag-util.c\r
290 > index c071ea8..6e3c069 100644\r
291 > --- a/tag-util.c\r
292 > +++ b/tag-util.c\r
293 > @@ -162,6 +162,54 @@ parse_tag_line (void *ctx, char *line,\r
294 >      return ret;\r
295 >  }\r
296 >  \r
297 > +int\r
298 > +parse_tag_command_line (void *ctx, int argc, char **argv,\r
299 > +                     unused(tag_op_flag_t flags),\r
300 > +                     char **query_str, tag_op_list_t *tag_ops){\r
301 > +\r
302 > +    int i;\r
303 > +\r
304 > +    tag_op_list_reset(tag_ops);\r
305 > +\r
306 > +    for (i = 0; i < argc; i++) {\r
307 > +     if (strcmp (argv[i], "--") == 0) {\r
308 > +         i++;\r
309 > +         break;\r
310 > +     }\r
311 > +\r
312 > +     if (argv[i][0] == '+' || argv[i][0] == '-') {\r
313 > +         notmuch_bool_t is_remove = argv[i][0] == '-';\r
314 > +         const char *msg;\r
315 > +\r
316 > +         msg = illegal_tag(argv[i]+1, is_remove);\r
317 > +         if (msg) {\r
318 > +             fprintf (stderr, "Error: %s", msg);\r
319 > +             return 1;\r
320 > +         }\r
321 > +\r
322 > +         tag_op_list_append (ctx, tag_ops,\r
323 > +                             argv[i] + 1, (argv[i][0] == '-'));\r
324 > +     } else {\r
325 > +         break;\r
326 > +     }\r
327 > +    }\r
328 > +\r
329 > +    if (tag_op_list_size (tag_ops) == 0) {\r
330 > +     fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n");\r
331 > +     return 1;\r
332 > +    }\r
333 > +\r
334 > +    *query_str = query_string_from_args (ctx, argc - i, &argv[i]);\r
335 > +\r
336 > +    if (**query_str == '\0') {\r
337 > +     fprintf (stderr, "Error: notmuch tag requires at least one search term.\n");\r
338 > +     return 1;\r
339 > +    }\r
340 > +\r
341 > +    return 0;\r
342 > +}\r
343 > +\r
344 > +\r
345 >  static inline void\r
346 >  message_error (notmuch_message_t *message,\r
347 >              notmuch_status_t status,\r
348 > diff --git a/tag-util.h b/tag-util.h\r
349 > index 99b0fa0..4956725 100644\r
350 > --- a/tag-util.h\r
351 > +++ b/tag-util.h\r
352 > @@ -72,6 +72,22 @@ parse_tag_line (void *ctx, char *line,\r
353 >               tag_op_flag_t flags,\r
354 >               char **query_str, tag_op_list_t *ops);\r
355 >  \r
356 > +\r
357 > +\r
358 > +/* Parse a command line of the following format:\r
359 > + *\r
360 > + * +<tag>|-<tag> [...] [--] <search-terms>\r
361 > + *\r
362 > + * Output Parameters:\r
363 > + *   ops     contains a list of tag operations\r
364 > + *   query_str the search terms.\r
365 > + */\r
366 > +\r
367 > +tag_parse_status_t\r
368 > +parse_tag_command_line (void *ctx, int argc, char **argv,\r
369 > +                     tag_op_flag_t flags,\r
370 > +                     char **query_str, tag_op_list_t *ops);\r
371 > +\r
372 >  /*\r
373 >   * Create an empty list of tag operations\r
374 >   *\r
375 > -- \r
376 > 1.7.10.4\r
377 >\r
378 > _______________________________________________\r
379 > notmuch mailing list\r
380 > notmuch@notmuchmail.org\r
381 > http://notmuchmail.org/mailman/listinfo/notmuch\r