Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 4e / fee23b9c1983cc7d225c28d8225bb21d689180
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 C33E9431FBF\r
6         for <notmuch@notmuchmail.org>; Sun, 23 Dec 2012 17:40:12 -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 snZj-fxVhemM for <notmuch@notmuchmail.org>;\r
16         Sun, 23 Dec 2012 17:40:11 -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 8E63D431FC9\r
21         for <notmuch@notmuchmail.org>; Sun, 23 Dec 2012 17:40:02 -0800 (PST)\r
22 Received: from fctnnbsc30w-156034082078.dhcp-dynamic.fibreop.nb.bellaliant.net\r
23         ([156.34.82.78] 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 1Tmx1L-0008Kn-Km; Sun, 23 Dec 2012 21:40:00 -0400\r
28 Received: from bremner by zancas.localnet with local (Exim 4.80)\r
29         (envelope-from <bremner@tethera.net>)\r
30         id 1Tmx1G-0002nV-4h; Sun, 23 Dec 2012 21:39:54 -0400\r
31 From: david@tethera.net\r
32 To: notmuch@notmuchmail.org\r
33 Subject: [Patch v9 04/17] notmuch-tag: factor out double quoting routine\r
34 Date: Sun, 23 Dec 2012 21:39:30 -0400\r
35 Message-Id: <1356313183-9266-5-git-send-email-david@tethera.net>\r
36 X-Mailer: git-send-email 1.7.10.4\r
37 In-Reply-To: <1356313183-9266-1-git-send-email-david@tethera.net>\r
38 References: <1356313183-9266-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: Mon, 24 Dec 2012 01:40:13 -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      |   52 ++++++++++++++++++----------------------------------\r
64  util/string-util.c |   37 +++++++++++++++++++++++++++++++++++++\r
65  util/string-util.h |    8 ++++++++\r
66  3 files changed, 63 insertions(+), 34 deletions(-)\r
67 \r
68 diff --git a/notmuch-tag.c b/notmuch-tag.c\r
69 index 0965ee7..a480215 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,46 @@ _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 +    /* Boolean terms surrounded by double quotes can contain any\r
140 +     * character.  Double quotes are quoted by doubling them. */\r
141 +\r
142      for (i = 0; i < tag_op_list_size (list) && query_string; i++) {\r
143 +       /* XXX in case of OOM, query_string will be deallocated when\r
144 +        * ctx is, which might be at shutdown */\r
145 +       if (double_quote_str (ctx,\r
146 +                             tag_op_list_tag (list, i),\r
147 +                             &escaped, &escaped_len))\r
148 +           return NULL;\r
149 +\r
150         query_string = talloc_asprintf_append_buffer (\r
151             query_string, "%s%stag:%s", join,\r
152             tag_op_list_isremove (list, i) ? "" : "not ",\r
153 -           _escape_tag (escaped, tag_op_list_tag (list, i)));\r
154 +           escaped);\r
155         join = " or ";\r
156      }\r
157  \r
158      if (query_string)\r
159         query_string = talloc_strdup_append_buffer (query_string, ")");\r
160  \r
161 -    talloc_free (escaped);\r
162 +    if (escaped)\r
163 +       talloc_free (escaped);\r
164 +\r
165      return query_string;\r
166  }\r
167  \r
168 diff --git a/util/string-util.c b/util/string-util.c\r
169 index 44f8cd3..b9039f4 100644\r
170 --- a/util/string-util.c\r
171 +++ b/util/string-util.c\r
172 @@ -20,6 +20,7 @@\r
173  \r
174  \r
175  #include "string-util.h"\r
176 +#include "talloc.h"\r
177  \r
178  char *\r
179  strtok_len (char *s, const char *delim, size_t *len)\r
180 @@ -32,3 +33,39 @@ strtok_len (char *s, const char *delim, size_t *len)\r
181  \r
182      return *len ? s : NULL;\r
183  }\r
184 +\r
185 +\r
186 +int\r
187 +double_quote_str (void *ctx, const char *str,\r
188 +                 char **buf, size_t *len)\r
189 +{\r
190 +    const char *in;\r
191 +    char *out;\r
192 +    size_t needed = 3;\r
193 +\r
194 +    for (in = str; *in; in++)\r
195 +       needed += (*in == '"') ? 2 : 1;\r
196 +\r
197 +    if ((*buf == NULL) || (needed > *len)) {\r
198 +       *len = 2 * needed;\r
199 +       *buf = talloc_realloc (ctx, *buf, char, *len);\r
200 +    }\r
201 +\r
202 +\r
203 +    if (! *buf)\r
204 +       return 1;\r
205 +\r
206 +    out = *buf;\r
207 +\r
208 +    *out++ = '"';\r
209 +    in = str;\r
210 +    while (*in) {\r
211 +       if (*in == '"')\r
212 +           *out++ = '"';\r
213 +       *out++ = *in++;\r
214 +    }\r
215 +    *out++ = '"';\r
216 +    *out = '\0';\r
217 +\r
218 +    return 0;\r
219 +}\r
220 diff --git a/util/string-util.h b/util/string-util.h\r
221 index ac7676c..4fc7942 100644\r
222 --- a/util/string-util.h\r
223 +++ b/util/string-util.h\r
224 @@ -19,4 +19,12 @@\r
225  \r
226  char *strtok_len (char *s, const char *delim, size_t *len);\r
227  \r
228 +/* Copy str to dest, surrounding with double quotes.\r
229 + * Any internal double-quotes are doubled, i.e. a"b -> "a""b"\r
230 + *\r
231 + * Output is into buf; it may be talloc_realloced\r
232 + * Return: 0 on success, non-zero on memory allocation failure.\r
233 + */\r
234 +int double_quote_str (void *talloc_ctx, const char *str,\r
235 +                     char **buf, size_t *len);\r
236  #endif\r
237 -- \r
238 1.7.10.4\r
239 \r