Re: [PATCH] Fix typo in Message.maildir_flags_to_tags
[notmuch-archives.git] / 6a / 31fa4147c51e8452a11e7d6f47d4e217d507c1
1 Return-Path: <bremner@tethera.net>\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 86787431FDC\r
6         for <notmuch@notmuchmail.org>; Fri, 14 Dec 2012 05:34:54 -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\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12         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 nKbxWROMvIpo for <notmuch@notmuchmail.org>;\r
16         Fri, 14 Dec 2012 05:34:52 -0800 (PST)\r
17 Received: from tesseract.cs.unb.ca (tesseract.cs.unb.ca [131.202.240.238])\r
18         (using TLSv1 with cipher AES256-SHA (256/256 bits))\r
19         (No client certificate requested)\r
20         by olra.theworths.org (Postfix) with ESMTPS id 51B36431FC9\r
21         for <notmuch@notmuchmail.org>; Fri, 14 Dec 2012 05:34:52 -0800 (PST)\r
22 Received: from fctnnbsc30w-142167090129.dhcp-dynamic.fibreop.nb.bellaliant.net\r
23         ([142.167.90.129] helo=zancas.localnet)\r
24         by tesseract.cs.unb.ca with esmtpsa\r
25         (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72)\r
26         (envelope-from <bremner@tethera.net>)\r
27         id 1TjVPf-0004yj-EU; Fri, 14 Dec 2012 09:34:51 -0400\r
28 Received: from bremner by zancas.localnet with local (Exim 4.80)\r
29         (envelope-from <bremner@tethera.net>)\r
30         id 1TjVPZ-000226-Sw; Fri, 14 Dec 2012 09:34:45 -0400\r
31 From: david@tethera.net\r
32 To: notmuch@notmuchmail.org\r
33 Subject: [Patch v7 04/14] notmuch-tag: factor out double quoting routine\r
34 Date: Fri, 14 Dec 2012 09:34:12 -0400\r
35 Message-Id: <1355492062-7546-5-git-send-email-david@tethera.net>\r
36 X-Mailer: git-send-email 1.7.10.4\r
37 In-Reply-To: <1355492062-7546-1-git-send-email-david@tethera.net>\r
38 References: <1355492062-7546-1-git-send-email-david@tethera.net>\r
39 X-Spam_bar: -\r
40 Cc: David Bremner <bremner@debian.org>\r
41 X-BeenThere: notmuch@notmuchmail.org\r
42 X-Mailman-Version: 2.1.13\r
43 Precedence: list\r
44 List-Id: "Use and development of the notmuch mail system."\r
45         <notmuch.notmuchmail.org>\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
47         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
49 List-Post: <mailto:notmuch@notmuchmail.org>\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
53 X-List-Received-Date: Fri, 14 Dec 2012 13:34:54 -0000\r
54 \r
55 From: David Bremner <bremner@debian.org>\r
56 \r
57 This could live in tag-util as well, but it is really nothing specific\r
58 to tags (although the conventions are arguable specific to Xapian).\r
59 \r
60 The API is changed from "caller-allocates" to "readline-like". The scan for\r
61 max tag length is pushed down into the double quoting routine.\r
62 ---\r
63  notmuch-tag.c      |   50 ++++++++++++++++----------------------------------\r
64  util/string-util.c |   34 ++++++++++++++++++++++++++++++++++\r
65  util/string-util.h |    8 ++++++++\r
66  3 files changed, 58 insertions(+), 34 deletions(-)\r
67 \r
68 diff --git a/notmuch-tag.c b/notmuch-tag.c\r
69 index 0965ee7..13f2268 100644\r
70 --- a/notmuch-tag.c\r
71 +++ b/notmuch-tag.c\r
72 @@ -20,6 +20,7 @@\r
73  \r
74  #include "notmuch-client.h"\r
75  #include "tag-util.h"\r
76 +#include "string-util.h"\r
77  \r
78  static volatile sig_atomic_t interrupted;\r
79  \r
80 @@ -37,25 +38,6 @@ handle_sigint (unused (int sig))\r
81  }\r
82  \r
83  static char *\r
84 -_escape_tag (char *buf, const char *tag)\r
85 -{\r
86 -    const char *in = tag;\r
87 -    char *out = buf;\r
88 -\r
89 -    /* Boolean terms surrounded by double quotes can contain any\r
90 -     * character.  Double quotes are quoted by doubling them. */\r
91 -    *out++ = '"';\r
92 -    while (*in) {\r
93 -       if (*in == '"')\r
94 -           *out++ = '"';\r
95 -       *out++ = *in++;\r
96 -    }\r
97 -    *out++ = '"';\r
98 -    *out = 0;\r
99 -    return buf;\r
100 -}\r
101 -\r
102 -static char *\r
103  _optimize_tag_query (void *ctx, const char *orig_query_string,\r
104                      const tag_op_list_t *list)\r
105  {\r
106 @@ -67,44 +49,44 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,\r
107       * parenthesize and the exclusion part of the query must not use\r
108       * the '-' operator (though the NOT operator is fine). */\r
109  \r
110 -    char *escaped, *query_string;\r
111 +    char *escaped = NULL;\r
112 +    size_t escaped_len = 0;\r
113 +    char *query_string;\r
114      const char *join = "";\r
115      size_t i;\r
116 -    unsigned int max_tag_len = 0;\r
117  \r
118      /* Don't optimize if there are no tag changes. */\r
119      if (tag_op_list_size (list) == 0)\r
120         return talloc_strdup (ctx, orig_query_string);\r
121  \r
122 -    /* Allocate a buffer for escaping tags.  This is large enough to\r
123 -     * hold a fully escaped tag with every character doubled plus\r
124 -     * enclosing quotes and a NUL. */\r
125 -    for (i = 0; i < tag_op_list_size (list); i++)\r
126 -       if (strlen (tag_op_list_tag (list, i)) > max_tag_len)\r
127 -           max_tag_len = strlen (tag_op_list_tag (list, i));\r
128 -\r
129 -    escaped = talloc_array (ctx, char, max_tag_len * 2 + 3);\r
130 -    if (! escaped)\r
131 -       return NULL;\r
132 -\r
133      /* Build the new query string */\r
134      if (strcmp (orig_query_string, "*") == 0)\r
135         query_string = talloc_strdup (ctx, "(");\r
136      else\r
137         query_string = talloc_asprintf (ctx, "( %s ) and (", orig_query_string);\r
138  \r
139 +\r
140 +    /* Boolean terms surrounded by double quotes can contain any\r
141 +     * character.  Double quotes are quoted by doubling them. */\r
142 +\r
143      for (i = 0; i < tag_op_list_size (list) && query_string; i++) {\r
144 +       double_quote_str (ctx,\r
145 +                         tag_op_list_tag (list, i),\r
146 +                         &escaped, &escaped_len);\r
147 +\r
148         query_string = talloc_asprintf_append_buffer (\r
149             query_string, "%s%stag:%s", join,\r
150             tag_op_list_isremove (list, i) ? "" : "not ",\r
151 -           _escape_tag (escaped, tag_op_list_tag (list, i)));\r
152 +           escaped);\r
153         join = " or ";\r
154      }\r
155  \r
156      if (query_string)\r
157         query_string = talloc_strdup_append_buffer (query_string, ")");\r
158  \r
159 -    talloc_free (escaped);\r
160 +    if (escaped)\r
161 +       talloc_free (escaped);\r
162 +\r
163      return query_string;\r
164  }\r
165  \r
166 diff --git a/util/string-util.c b/util/string-util.c\r
167 index 44f8cd3..ea7c25b 100644\r
168 --- a/util/string-util.c\r
169 +++ b/util/string-util.c\r
170 @@ -20,6 +20,7 @@\r
171  \r
172  \r
173  #include "string-util.h"\r
174 +#include "talloc.h"\r
175  \r
176  char *\r
177  strtok_len (char *s, const char *delim, size_t *len)\r
178 @@ -32,3 +33,36 @@ strtok_len (char *s, const char *delim, size_t *len)\r
179  \r
180      return *len ? s : NULL;\r
181  }\r
182 +\r
183 +\r
184 +int\r
185 +double_quote_str (void *ctx, const char *str,\r
186 +                 char **buf, size_t *len)\r
187 +{\r
188 +    const char *in;\r
189 +    char *out;\r
190 +    size_t needed = 3;\r
191 +\r
192 +    for (in = str; *in; in++)\r
193 +       needed += (*in == '"') ? 2 : 1;\r
194 +\r
195 +    if (needed > *len)\r
196 +       *buf = talloc_realloc (ctx, *buf, char, 2*needed);\r
197 +\r
198 +    if (! *buf)\r
199 +       return 1;\r
200 +\r
201 +    out = *buf;\r
202 +\r
203 +    *out++ = '"';\r
204 +    in = str;\r
205 +    while (*in) {\r
206 +       if (*in == '"')\r
207 +           *out++ = '"';\r
208 +       *out++ = *in++;\r
209 +    }\r
210 +    *out++ = '"';\r
211 +    *out = 0;\r
212 +\r
213 +    return 0;\r
214 +}\r
215 diff --git a/util/string-util.h b/util/string-util.h\r
216 index ac7676c..b593bc7 100644\r
217 --- a/util/string-util.h\r
218 +++ b/util/string-util.h\r
219 @@ -19,4 +19,12 @@\r
220  \r
221  char *strtok_len (char *s, const char *delim, size_t *len);\r
222  \r
223 +/* Copy str to dest, surrounding with double quotes.\r
224 + * Any internal double-quotes are doubled, i.e. a"b -> "a""b"\r
225 + *\r
226 + * Output is into buf; it may be talloc_realloced\r
227 + * return 0 on success, non-zero on failure.\r
228 + */\r
229 +int double_quote_str (void *talloc_ctx, const char *str,\r
230 +                     char **buf, size_t *len);\r
231  #endif\r
232 -- \r
233 1.7.10.4\r
234 \r