Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 2c / d345935c23ed97a1354a875751f6d5600ae620
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 arlo.cworth.org (Postfix) with ESMTP id 7EF766DE18A0\r
6  for <notmuch@notmuchmail.org>; Sat, 12 Mar 2016 04:31:56 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.032\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.032 tagged_above=-999 required=5\r
12  tests=[AWL=-0.021, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01]\r
13  autolearn=disabled\r
14 Received: from arlo.cworth.org ([127.0.0.1])\r
15  by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
16  with ESMTP id Z0OW6nmf7om1 for <notmuch@notmuchmail.org>;\r
17  Sat, 12 Mar 2016 04:31:53 -0800 (PST)\r
18 Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197])\r
19  by arlo.cworth.org (Postfix) with ESMTPS id 5D5736DE18A2\r
20  for <notmuch@notmuchmail.org>; Sat, 12 Mar 2016 04:31:41 -0800 (PST)\r
21 Received: from remotemail by fethera.tethera.net with local (Exim 4.84)\r
22  (envelope-from <bremner@tethera.net>)\r
23  id 1aeiiQ-0004zY-3H; Sat, 12 Mar 2016 07:32:18 -0500\r
24 Received: (nullmailer pid 17173 invoked by uid 1000);\r
25  Sat, 12 Mar 2016 12:31:33 -0000\r
26 From: David Bremner <david@tethera.net>\r
27 To: David Bremner <david@tethera.net>, notmuch@notmuchmail.org\r
28 Subject: [PATCH 1/6] lib: provide config API\r
29 Date: Sat, 12 Mar 2016 08:31:25 -0400\r
30 Message-Id: <1457785890-17058-2-git-send-email-david@tethera.net>\r
31 X-Mailer: git-send-email 2.7.0\r
32 In-Reply-To: <1457785890-17058-1-git-send-email-david@tethera.net>\r
33 References: <1453561198-2893-1-git-send-email-david@tethera.net>\r
34  <1457785890-17058-1-git-send-email-david@tethera.net>\r
35 MIME-Version: 1.0\r
36 Content-Type: text/plain; charset=UTF-8\r
37 Content-Transfer-Encoding: 8bit\r
38 X-BeenThere: notmuch@notmuchmail.org\r
39 X-Mailman-Version: 2.1.20\r
40 Precedence: list\r
41 List-Id: "Use and development of the notmuch mail system."\r
42  <notmuch.notmuchmail.org>\r
43 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
44  <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
45 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
46 List-Post: <mailto:notmuch@notmuchmail.org>\r
47 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
48 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
49  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
50 X-List-Received-Date: Sat, 12 Mar 2016 12:31:56 -0000\r
51 \r
52 This is a thin wrapper around the Xapian metadata API. The job of this\r
53 layer is to keep the config key value pairs from colliding with other\r
54 metadata by transparently prefixing the keys, along with the usual glue\r
55 to provide a C interface.\r
56 \r
57 The split of _get_config into two functions is to allow returning of the\r
58 return value with different memory ownership semantics.\r
59 ---\r
60  lib/Makefile.local     |  1 +\r
61  lib/config.cc          | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++\r
62  lib/notmuch.h          | 20 +++++++++++\r
63  test/T590-libconfig.sh | 58 ++++++++++++++++++++++++++++++++\r
64  4 files changed, 169 insertions(+)\r
65  create mode 100644 lib/config.cc\r
66  create mode 100755 test/T590-libconfig.sh\r
67 \r
68 diff --git a/lib/Makefile.local b/lib/Makefile.local\r
69 index 3a07090..eb442d1 100644\r
70 --- a/lib/Makefile.local\r
71 +++ b/lib/Makefile.local\r
72 @@ -48,6 +48,7 @@ libnotmuch_cxx_srcs =         \\r
73         $(dir)/index.cc         \\r
74         $(dir)/message.cc       \\r
75         $(dir)/query.cc         \\r
76 +       $(dir)/config.cc        \\r
77         $(dir)/thread.cc\r
78  \r
79  libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)\r
80 diff --git a/lib/config.cc b/lib/config.cc\r
81 new file mode 100644\r
82 index 0000000..af00d6f\r
83 --- /dev/null\r
84 +++ b/lib/config.cc\r
85 @@ -0,0 +1,90 @@\r
86 +/* metadata.cc - API for database metadata\r
87 + *\r
88 + * Copyright © 2015 David Bremner\r
89 + *\r
90 + * This program is free software: you can redistribute it and/or modify\r
91 + * it under the terms of the GNU General Public License as published by\r
92 + * the Free Software Foundation, either version 3 of the License, or\r
93 + * (at your option) any later version.\r
94 + *\r
95 + * This program is distributed in the hope that it will be useful,\r
96 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
97 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
98 + * GNU General Public License for more details.\r
99 + *\r
100 + * You should have received a copy of the GNU General Public License\r
101 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
102 + *\r
103 + * Author: David Bremner <david@tethera.net>\r
104 + */\r
105 +\r
106 +#include "notmuch.h"\r
107 +#include "notmuch-private.h"\r
108 +#include "database-private.h"\r
109 +\r
110 +static const std::string CONFIG_PREFIX="C";\r
111 +\r
112 +notmuch_status_t\r
113 +notmuch_database_set_config (notmuch_database_t *notmuch,\r
114 +                            const char *key,\r
115 +                            const char *value)\r
116 +{\r
117 +    notmuch_status_t status;\r
118 +    Xapian::WritableDatabase *db;\r
119 +\r
120 +    status = _notmuch_database_ensure_writable (notmuch);\r
121 +    if (status)\r
122 +       return status;\r
123 +\r
124 +    try {\r
125 +       db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);\r
126 +       db->set_metadata (CONFIG_PREFIX+key, value);\r
127 +    } catch (const Xapian::Error &error) {\r
128 +       status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;\r
129 +       notmuch->exception_reported = TRUE;\r
130 +       if (! notmuch->exception_reported) {\r
131 +           _notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n",\r
132 +                                  error.get_msg().c_str());\r
133 +       }\r
134 +    }\r
135 +    return NOTMUCH_STATUS_SUCCESS;\r
136 +}\r
137 +\r
138 +static notmuch_status_t\r
139 +_metadata_value (notmuch_database_t *notmuch,\r
140 +                const char *key,\r
141 +                std::string &value)\r
142 +{\r
143 +    notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;\r
144 +\r
145 +    try {\r
146 +       value = notmuch->xapian_db->get_metadata (CONFIG_PREFIX+key);\r
147 +    } catch (const Xapian::Error &error) {\r
148 +       status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;\r
149 +       notmuch->exception_reported = TRUE;\r
150 +       if (! notmuch->exception_reported) {\r
151 +           _notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n",\r
152 +                                  error.get_msg().c_str());\r
153 +       }\r
154 +    }\r
155 +    return status;\r
156 +}\r
157 +\r
158 +notmuch_status_t\r
159 +notmuch_database_get_config (notmuch_database_t *notmuch,\r
160 +                            const char *key,\r
161 +                            char **value) {\r
162 +    std::string strval;\r
163 +    notmuch_status_t status;\r
164 +\r
165 +    if (!value)\r
166 +       return NOTMUCH_STATUS_NULL_POINTER;\r
167 +\r
168 +    status = _metadata_value (notmuch, key, strval);\r
169 +    if (status)\r
170 +       return status;\r
171 +\r
172 +    *value = strdup (strval.c_str ());\r
173 +\r
174 +    return NOTMUCH_STATUS_SUCCESS;\r
175 +}\r
176 diff --git a/lib/notmuch.h b/lib/notmuch.h\r
177 index 310a8b8..c62223b 100644\r
178 --- a/lib/notmuch.h\r
179 +++ b/lib/notmuch.h\r
180 @@ -1829,6 +1829,26 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames);\r
181  void\r
182  notmuch_filenames_destroy (notmuch_filenames_t *filenames);\r
183  \r
184 +\r
185 +/**\r
186 + * set config 'key' to 'value'\r
187 + *\r
188 + */\r
189 +notmuch_status_t\r
190 +notmuch_database_set_config (notmuch_database_t *db, const char *key, const char *value);\r
191 +\r
192 +/**\r
193 + * retrieve config item 'key', assign to  'value'\r
194 + *\r
195 + * keys which have not been previously set with n_d_set_config will\r
196 + * return an empty string.\r
197 + *\r
198 + * return value is allocated by malloc and should be freed by the\r
199 + * caller.\r
200 + */\r
201 +notmuch_status_t\r
202 +notmuch_database_get_config (notmuch_database_t *db, const char *key, char **value);\r
203 +\r
204  /* @} */\r
205  \r
206  NOTMUCH_END_DECLS\r
207 diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh\r
208 new file mode 100755\r
209 index 0000000..85e4497\r
210 --- /dev/null\r
211 +++ b/test/T590-libconfig.sh\r
212 @@ -0,0 +1,58 @@\r
213 +#!/usr/bin/env bash\r
214 +test_description="library config API"\r
215 +\r
216 +. ./test-lib.sh || exit 1\r
217 +\r
218 +add_email_corpus\r
219 +\r
220 +cat <<EOF > c_head\r
221 +#include <stdio.h>\r
222 +#include <string.h>\r
223 +#include <stdlib.h>\r
224 +#include <notmuch.h>\r
225 +\r
226 +void run(int line, notmuch_status_t ret)\r
227 +{\r
228 +   if (ret) {\r
229 +       fprintf (stderr, "line %d: %s\n", line, ret);\r
230 +       exit (1);\r
231 +   }\r
232 +}\r
233 +\r
234 +#define RUN(v)  run(__LINE__, v);\r
235 +\r
236 +int main (int argc, char** argv)\r
237 +{\r
238 +   notmuch_database_t *db;\r
239 +   char *val;\r
240 +   notmuch_status_t stat;\r
241 +\r
242 +   RUN(notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db));\r
243 +\r
244 +EOF\r
245 +\r
246 +cat <<EOF > c_tail\r
247 +   RUN(notmuch_database_destroy(db));\r
248 +}\r
249 +EOF\r
250 +\r
251 +test_begin_subtest "notmuch_database_{set,get}_config"\r
252 +cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}\r
253 +{\r
254 +   RUN(notmuch_database_set_config (db, "testkey1", "testvalue1"));\r
255 +   RUN(notmuch_database_set_config (db, "testkey2", "testvalue2"));\r
256 +   RUN(notmuch_database_get_config (db, "testkey1", &val));\r
257 +   printf("testkey1 = %s\n", val);\r
258 +   RUN(notmuch_database_get_config (db, "testkey2", &val));\r
259 +   printf("testkey2 = %s\n", val);\r
260 +}\r
261 +EOF\r
262 +cat <<'EOF' >EXPECTED\r
263 +== stdout ==\r
264 +testkey1 = testvalue1\r
265 +testkey2 = testvalue2\r
266 +== stderr ==\r
267 +EOF\r
268 +test_expect_equal_file EXPECTED OUTPUT\r
269 +\r
270 +test_done\r
271 -- \r
272 2.7.0\r
273 \r