Re: [PATCH] doc: Allow rst2man.py as an alternative to rst2man
[notmuch-archives.git] / 83 / e313ad532cbaf31f1b69599a4782d0f68c3759
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 E2414431FAF\r
6         for <notmuch@notmuchmail.org>; Fri,  7 Dec 2012 14:50:38 -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 ZgnonjmAGWuM for <notmuch@notmuchmail.org>;\r
16         Fri,  7 Dec 2012 14:50:35 -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 2BAC1431FAE\r
21         for <notmuch@notmuchmail.org>; Fri,  7 Dec 2012 14:50:35 -0800 (PST)\r
22 Received: by mail-lb0-f181.google.com with SMTP id ge1so818909lbb.26\r
23         for <notmuch@notmuchmail.org>; Fri, 07 Dec 2012 14:50:33 -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=P3TukPoWkkUB29JL9yU0auODosCrhMIt02bnP4TjfTM=;\r
29         b=jCF8sdzwdwovoWg99edEJsezWCez4kxjtdLOAir5gFPQkYDQGdMyNfEMP4imFiMcLh\r
30         jDGs3D/FiAhI814bcdzr9LxRR6lUjRsMBX4esLjkv5MPWdJihJ0Cm5m84cjLqa66XIlj\r
31         rIwXpZJBGgtOVun6uerKFalDgNUgbti6z5WfjXWoBdmCzwl/e+1mLRin8CCz1ReAHxOF\r
32         9jBu13OnyId7kJUzG4YP0IYSAWIJA2Cbwpw+vLQMMWTHJGc7Zaa893C5LChuxbSz6tiW\r
33         RIuCowNLp5lgg10G0fr3az9T7B+sObTs0a6e5cHC7tgBzwqSmAU81uGgQmS2JmOZlHmU\r
34         jJgg==\r
35 Received: by 10.152.111.166 with SMTP id ij6mr6881771lab.38.1354920633638;\r
36         Fri, 07 Dec 2012 14:50:33 -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 k7sm5169390lbf.4.2012.12.07.14.50.31\r
40         (version=SSLv3 cipher=OTHER); Fri, 07 Dec 2012 14:50:32 -0800 (PST)\r
41 From: Jani Nikula <jani@nikula.org>\r
42 To: david@tethera.net, notmuch@notmuchmail.org\r
43 Subject: Re: [Patch v3b 5/9] notmuch-restore: add support for input format\r
44         'batch-tag'\r
45 In-Reply-To: <1354843607-17980-6-git-send-email-david@tethera.net>\r
46 References: <1354843607-17980-1-git-send-email-david@tethera.net>\r
47         <1354843607-17980-6-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 00:50:30 +0200\r
51 Message-ID: <87r4n1xyrt.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  ALoCoQmXhQ8xCv3wzjRKWVpqETFqwkaf92pBPcKOq56wLOqHhphpbo1OFT1FWIspp5bt6CEnIJxW\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: Fri, 07 Dec 2012 22:50:39 -0000\r
70 \r
71 \r
72 LGTM.\r
73 \r
74 On Fri, 07 Dec 2012, david@tethera.net wrote:\r
75 > From: David Bremner <bremner@debian.org>\r
76 >\r
77 > This can be enabled with the new --format=batch-tag command line\r
78 > option to "notmuch restore". The input must consist of lines of the\r
79 > format:\r
80 >\r
81 >     +<tag>|-<tag> [...] [--] id:<msg-id>\r
82 >\r
83 > Each line is interpreted similarly to "notmuch tag" command line\r
84 > arguments. The delimiter is one or more spaces ' '. Any characters in\r
85 > <tag> and <search-terms> MAY be hex encoded with %NN where NN is the\r
86 > hexadecimal value of the character. Any ' ' and '%' characters in\r
87 > <tag> and <msg-id> MUST be hex encoded (using %20 and %25,\r
88 > respectively). Any characters that are not part of <tag> or\r
89 > <search-terms> MUST NOT be hex encoded.\r
90 >\r
91 > Leading and trailing space ' ' is ignored. Empty lines and lines\r
92 > beginning with '#' are ignored.\r
93 >\r
94 > Commit message mainly stolen from Jani's batch tagging commit, to\r
95 > follow.\r
96 > ---\r
97 >  notmuch-restore.c |  206 ++++++++++++++++++++++++++++++++++-------------------\r
98 >  1 file changed, 131 insertions(+), 75 deletions(-)\r
99 >\r
100 > diff --git a/notmuch-restore.c b/notmuch-restore.c\r
101 > index f03dcac..ceec2d3 100644\r
102 > --- a/notmuch-restore.c\r
103 > +++ b/notmuch-restore.c\r
104 > @@ -19,18 +19,22 @@\r
105 >   */\r
106 >  \r
107 >  #include "notmuch-client.h"\r
108 > +#include "dump-restore-private.h"\r
109 > +#include "tag-util.h"\r
110 > +#include "string-util.h"\r
111 > +\r
112 > +static volatile sig_atomic_t interrupted;\r
113 > +static regex_t regex;\r
114 >  \r
115 >  static int\r
116 > -tag_message (notmuch_database_t *notmuch, const char *message_id,\r
117 > -          char *file_tags, notmuch_bool_t remove_all,\r
118 > -          notmuch_bool_t synchronize_flags)\r
119 > +tag_message (unused (void *ctx),\r
120 > +          notmuch_database_t *notmuch,\r
121 > +          const char *message_id,\r
122 > +          tag_op_list_t *tag_ops,\r
123 > +          tag_op_flag_t flags)\r
124 >  {\r
125 >      notmuch_status_t status;\r
126 > -    notmuch_tags_t *db_tags;\r
127 > -    char *db_tags_str;\r
128 >      notmuch_message_t *message = NULL;\r
129 > -    const char *tag;\r
130 > -    char *next;\r
131 >      int ret = 0;\r
132 >  \r
133 >      status = notmuch_database_find_message (notmuch, message_id, &message);\r
134 > @@ -44,55 +48,62 @@ tag_message (notmuch_database_t *notmuch, const char *message_id,\r
135 >  \r
136 >      /* In order to detect missing messages, this check/optimization is\r
137 >       * intentionally done *after* first finding the message. */\r
138 > -    if (! remove_all && (file_tags == NULL || *file_tags == '\0'))\r
139 > -     goto DONE;\r
140 > -\r
141 > -    db_tags_str = NULL;\r
142 > -    for (db_tags = notmuch_message_get_tags (message);\r
143 > -      notmuch_tags_valid (db_tags);\r
144 > -      notmuch_tags_move_to_next (db_tags)) {\r
145 > -     tag = notmuch_tags_get (db_tags);\r
146 > -\r
147 > -     if (db_tags_str)\r
148 > -         db_tags_str = talloc_asprintf_append (db_tags_str, " %s", tag);\r
149 > -     else\r
150 > -         db_tags_str = talloc_strdup (message, tag);\r
151 > -    }\r
152 > +    if ((flags & TAG_FLAG_REMOVE_ALL) || tag_op_list_size (tag_ops))\r
153 > +     tag_op_list_apply (message, tag_ops, flags);\r
154 >  \r
155 > -    if (((file_tags == NULL || *file_tags == '\0') &&\r
156 > -      (db_tags_str == NULL || *db_tags_str == '\0')) ||\r
157 > -     (file_tags && db_tags_str && strcmp (file_tags, db_tags_str) == 0))\r
158 > -     goto DONE;\r
159 > +    notmuch_message_destroy (message);\r
160 >  \r
161 > -    notmuch_message_freeze (message);\r
162 > +    return ret;\r
163 > +}\r
164 >  \r
165 > -    if (remove_all)\r
166 > -     notmuch_message_remove_all_tags (message);\r
167 > +static int\r
168 > +parse_sup_line (void *ctx, char *line,\r
169 > +             char **query_str, tag_op_list_t *tag_ops)\r
170 > +{\r
171 >  \r
172 > -    next = file_tags;\r
173 > -    while (next) {\r
174 > -     tag = strsep (&next, " ");\r
175 > -     if (*tag == '\0')\r
176 > -         continue;\r
177 > -     status = notmuch_message_add_tag (message, tag);\r
178 > -     if (status) {\r
179 > -         fprintf (stderr, "Error applying tag %s to message %s:\n",\r
180 > -                  tag, message_id);\r
181 > -         fprintf (stderr, "%s\n", notmuch_status_to_string (status));\r
182 > -         ret = 1;\r
183 > -     }\r
184 > +    regmatch_t match[3];\r
185 > +    char *file_tags;\r
186 > +    int rerr;\r
187 > +\r
188 > +    tag_op_list_reset (tag_ops);\r
189 > +\r
190 > +    chomp_newline (line);\r
191 > +\r
192 > +    /* Silently ignore blank lines */\r
193 > +    if (line[0] == '\0') {\r
194 > +     return 1;\r
195 > +    }\r
196 > +\r
197 > +    rerr = xregexec (&regex, line, 3, match, 0);\r
198 > +    if (rerr == REG_NOMATCH) {\r
199 > +     fprintf (stderr, "Warning: Ignoring invalid sup format line: %s\n",\r
200 > +              line);\r
201 > +     return 1;\r
202 >      }\r
203 >  \r
204 > -    notmuch_message_thaw (message);\r
205 > +    *query_str = talloc_strndup (ctx, line + match[1].rm_so,\r
206 > +                              match[1].rm_eo - match[1].rm_so);\r
207 > +    file_tags = talloc_strndup (ctx, line + match[2].rm_so,\r
208 > +                             match[2].rm_eo - match[2].rm_so);\r
209 >  \r
210 > -    if (synchronize_flags)\r
211 > -     notmuch_message_tags_to_maildir_flags (message);\r
212 > +    char *tok = file_tags;\r
213 > +    size_t tok_len = 0;\r
214 >  \r
215 > -  DONE:\r
216 > -    if (message)\r
217 > -     notmuch_message_destroy (message);\r
218 > +    tag_op_list_reset (tag_ops);\r
219 > +\r
220 > +    while ((tok = strtok_len (tok + tok_len, " ", &tok_len)) != NULL) {\r
221 > +\r
222 > +     if (*(tok + tok_len) != '\0') {\r
223 > +         *(tok + tok_len) = '\0';\r
224 > +         tok_len++;\r
225 > +     }\r
226 > +\r
227 > +     if (tag_op_list_append (ctx, tag_ops, tok, FALSE))\r
228 > +         return -1;\r
229 > +    }\r
230 > +\r
231 > +    return 0;\r
232 >  \r
233 > -    return ret;\r
234 >  }\r
235 >  \r
236 >  int\r
237 > @@ -100,16 +111,19 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
238 >  {\r
239 >      notmuch_config_t *config;\r
240 >      notmuch_database_t *notmuch;\r
241 > -    notmuch_bool_t synchronize_flags;\r
242 >      notmuch_bool_t accumulate = FALSE;\r
243 > +    tag_op_flag_t flags = 0;\r
244 > +    tag_op_list_t *tag_ops;\r
245 > +\r
246 >      char *input_file_name = NULL;\r
247 >      FILE *input = stdin;\r
248 >      char *line = NULL;\r
249 >      size_t line_size;\r
250 >      ssize_t line_len;\r
251 > -    regex_t regex;\r
252 > -    int rerr;\r
253 > +\r
254 > +    int ret = 0;\r
255 >      int opt_index;\r
256 > +    int input_format = DUMP_FORMAT_AUTO;\r
257 >  \r
258 >      config = notmuch_config_open (ctx, NULL, NULL);\r
259 >      if (config == NULL)\r
260 > @@ -119,9 +133,15 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
261 >                              NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
262 >       return 1;\r
263 >  \r
264 > -    synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);\r
265 > +    if (notmuch_config_get_maildir_synchronize_flags (config))\r
266 > +     flags |= TAG_FLAG_MAILDIR_SYNC;\r
267 >  \r
268 >      notmuch_opt_desc_t options[] = {\r
269 > +     { NOTMUCH_OPT_KEYWORD, &input_format, "format", 'f',\r
270 > +       (notmuch_keyword_t []){ { "auto", DUMP_FORMAT_AUTO },\r
271 > +                               { "batch-tag", DUMP_FORMAT_BATCH_TAG },\r
272 > +                               { "sup", DUMP_FORMAT_SUP },\r
273 > +                               { 0, 0 } } },\r
274 >       { NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },\r
275 >       { NOTMUCH_OPT_BOOLEAN,  &accumulate, "accumulate", 'a', 0 },\r
276 >       { 0, 0, 0, 0, 0 }\r
277 > @@ -134,6 +154,9 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
278 >       return 1;\r
279 >      }\r
280 >  \r
281 > +    if (! accumulate)\r
282 > +     flags |= TAG_FLAG_REMOVE_ALL;\r
283 > +\r
284 >      if (input_file_name) {\r
285 >       input = fopen (input_file_name, "r");\r
286 >       if (input == NULL) {\r
287 > @@ -154,44 +177,77 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
288 >       * non-space characters for the message-id, then one or more\r
289 >       * spaces, then a list of space-separated tags as a sequence of\r
290 >       * characters within literal '(' and ')'. */\r
291 > -    if ( xregcomp (&regex,\r
292 > -                "^([^ ]+) \\(([^)]*)\\)$",\r
293 > -                REG_EXTENDED) )\r
294 > -     INTERNAL_ERROR ("compile time constant regex failed.");\r
295 > +    char *p;\r
296 >  \r
297 > -    while ((line_len = getline (&line, &line_size, input)) != -1) {\r
298 > -     regmatch_t match[3];\r
299 > -     char *message_id, *file_tags;\r
300 > +    line_len = getline (&line, &line_size, input);\r
301 > +    if (line_len == 0)\r
302 > +     return 0;\r
303 >  \r
304 > -     chomp_newline (line);\r
305 > +    tag_ops = tag_op_list_create (ctx);\r
306 > +    if (tag_ops == NULL) {\r
307 > +     fprintf (stderr, "Out of memory.\n");\r
308 > +     return 1;\r
309 > +    }\r
310 >  \r
311 > -     rerr = xregexec (&regex, line, 3, match, 0);\r
312 > -     if (rerr == REG_NOMATCH) {\r
313 > -         fprintf (stderr, "Warning: Ignoring invalid input line: %s\n",\r
314 > -                  line);\r
315 > -         continue;\r
316 > +    for (p = line; (input_format == DUMP_FORMAT_AUTO) && *p; p++) {\r
317 > +     if (*p == '(')\r
318 > +         input_format = DUMP_FORMAT_SUP;\r
319 > +    }\r
320 > +\r
321 > +    if (input_format == DUMP_FORMAT_AUTO)\r
322 > +     input_format = DUMP_FORMAT_BATCH_TAG;\r
323 > +\r
324 > +    if (input_format == DUMP_FORMAT_SUP)\r
325 > +     if ( xregcomp (&regex,\r
326 > +                    "^([^ ]+) \\(([^)]*)\\)$",\r
327 > +                    REG_EXTENDED) )\r
328 > +         INTERNAL_ERROR ("compile time constant regex failed.");\r
329 > +\r
330 > +    do {\r
331 > +     char *query_string;\r
332 > +\r
333 > +     if (input_format == DUMP_FORMAT_SUP) {\r
334 > +         ret = parse_sup_line (ctx, line, &query_string, tag_ops);\r
335 > +     } else {\r
336 > +         ret = parse_tag_line (ctx, line, TAG_FLAG_BE_GENEROUS,\r
337 > +                               &query_string, tag_ops);\r
338 > +\r
339 > +         if (ret == 0) {\r
340 > +             if (strncmp ("id:", query_string, 3) != 0) {\r
341 > +                 fprintf (stderr, "Unsupported query: %s\n", query_string);\r
342 > +                 continue;\r
343 > +             }\r
344 > +             /* delete id: from front of string; tag_message\r
345 > +              * expects a raw message-id.\r
346 > +              *\r
347 > +              * XXX: Note that query string id:foo and bar will be\r
348 > +              * interpreted as a message id "foo and bar". This\r
349 > +              * should eventually be fixed to give a better error\r
350 > +              * message.\r
351 > +              */\r
352 > +             query_string = query_string + 3;\r
353 > +         }\r
354 >       }\r
355 >  \r
356 > -     message_id = xstrndup (line + match[1].rm_so,\r
357 > -                            match[1].rm_eo - match[1].rm_so);\r
358 > -     file_tags = xstrndup (line + match[2].rm_so,\r
359 > -                           match[2].rm_eo - match[2].rm_so);\r
360 > +     if (ret > 0)\r
361 > +         continue;\r
362 >  \r
363 > -     tag_message (notmuch, message_id, file_tags, ! accumulate,\r
364 > -                  synchronize_flags);\r
365 > +     if (ret < 0 || tag_message (ctx, notmuch, query_string,\r
366 > +                                 tag_ops, flags))\r
367 > +         break;\r
368 >  \r
369 > -     free (message_id);\r
370 > -     free (file_tags);\r
371 > -    }\r
372 > +    }  while ((line_len = getline (&line, &line_size, input)) != -1);\r
373 >  \r
374 > -    regfree (&regex);\r
375 > +    if (input_format == DUMP_FORMAT_SUP)\r
376 > +     regfree (&regex);\r
377 >  \r
378 >      if (line)\r
379 >       free (line);\r
380 >  \r
381 >      notmuch_database_destroy (notmuch);\r
382 > +\r
383 >      if (input != stdin)\r
384 >       fclose (input);\r
385 >  \r
386 > -    return 0;\r
387 > +    return ret;\r
388 >  }\r
389 > -- \r
390 > 1.7.10.4\r
391 >\r
392 > _______________________________________________\r
393 > notmuch mailing list\r
394 > notmuch@notmuchmail.org\r
395 > http://notmuchmail.org/mailman/listinfo/notmuch\r