Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / df / 2c71fbaaaccc0cf587a989289ca804379cd7a4
1 Return-Path: <amdragon@mit.edu>\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 1219F431FC2\r
6         for <notmuch@notmuchmail.org>; Mon, 25 Aug 2014 10:26:23 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -2.3\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_MED=-2.3] 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 mjCZ7ZBNKWTt for <notmuch@notmuchmail.org>;\r
16         Mon, 25 Aug 2014 10:26:15 -0700 (PDT)\r
17 Received: from dmz-mailsec-scanner-8.mit.edu (dmz-mailsec-scanner-8.mit.edu\r
18         [18.7.68.37])\r
19         (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
20         (No client certificate requested)\r
21         by olra.theworths.org (Postfix) with ESMTPS id 77029431FAE\r
22         for <notmuch@notmuchmail.org>; Mon, 25 Aug 2014 10:26:15 -0700 (PDT)\r
23 X-AuditID: 12074425-f79e46d000002583-15-53fb71b67eaa\r
24 Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])\r
25         (using TLS with cipher AES256-SHA (256/256 bits))\r
26         (Client did not present a certificate)\r
27         by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP\r
28         id 1B.7E.09603.6B17BF35; Mon, 25 Aug 2014 13:26:14 -0400 (EDT)\r
29 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])\r
30         by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id s7PHQDsW007792; \r
31         Mon, 25 Aug 2014 13:26:14 -0400\r
32 Received: from drake.dyndns.org (31-35-14.wireless.csail.mit.edu\r
33         [128.31.35.14]) (authenticated bits=0)\r
34         (User authenticated as amdragon@ATHENA.MIT.EDU)\r
35         by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id s7PHQBp7029601\r
36         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
37         Mon, 25 Aug 2014 13:26:13 -0400\r
38 Received: from amthrax by drake.dyndns.org with local (Exim 4.77)\r
39         (envelope-from <amdragon@mit.edu>)\r
40         id 1XLy1z-0003jH-RC; Mon, 25 Aug 2014 13:26:11 -0400\r
41 From: Austin Clements <amdragon@mit.edu>\r
42 To: notmuch@notmuchmail.org\r
43 Subject: [PATCH v4 00/11] Implement and use database "features"\r
44 Date: Mon, 25 Aug 2014 13:25:58 -0400\r
45 Message-Id: <1408987569-14146-1-git-send-email-amdragon@mit.edu>\r
46 X-Mailer: git-send-email 2.0.0\r
47 X-Brightmail-Tracker:\r
48  H4sIAAAAAAAAA+NgFlrPIsWRmVeSWpSXmKPExsUixCmqrLut8HewwbVGQ4sbrd2MFk3TnS2u\r
49         35zJ7MDscev+a3aPZ6tuMXtsOfSeOYA5issmJTUnsyy1SN8ugStj/dKlbAWTgireLV3K0sD4\r
50         yaGLkZNDQsBEYuK7b+wQtpjEhXvr2boYuTiEBGYzSbw8c4gRwtnIKHFoxSUmCOcYk8SvWf1Q\r
51         ZXMZJda/7WQD6WcT0JD4fWsxE4gtIiAtsfPubFYQm1lATWL9n1dgO4QF7CVeP9gCVsMioCpx\r
52         /9RMsDivgIPEq7/zWSHukJNouPGJbQIj7wJGhlWMsim5Vbq5iZk5xanJusXJiXl5qUW6Fnq5\r
53         mSV6qSmlmxhB4cLuorqDccIhpUOMAhyMSjy8N+J/BwuxJpYVV+YeYpTkYFIS5Z2WDxTiS8pP\r
54         qcxILM6ILyrNSS0+xCjBwawkwtsMkuNNSaysSi3Kh0lJc7AoifO+tbYKFhJITyxJzU5NLUgt\r
55         gsnKcHAoSfDmFgA1ChalpqdWpGXmlCCkmTg4QYbzAA2PB6nhLS5IzC3OTIfIn2JUlBLn/Q+S\r
56         EABJZJTmwfXC4vkVozjQK8K8R0GqeICpAK77FdBgJqDBpj0/QQaXJCKkpBoYo10yz+1bWy+r\r
57         sOPZjIdb+puLdJqzZ7ctf3v9Sei8afs/qYdVfjn8692utP65y0oiipbnnxcNnLb+coLHq6r/\r
58         b7aLPP6kUlGw13qNGsvutT+iCozL9+isCnSbdtRV/GX7xW2Jh1ZNr/xpfEGiIVp8DeO3RPW2\r
59         3M5zqQtiPjO6nCnp+xDuOjGBQYmlOCPRUIu5qDgRADK9FEHCAgAA\r
60 X-BeenThere: notmuch@notmuchmail.org\r
61 X-Mailman-Version: 2.1.13\r
62 Precedence: list\r
63 List-Id: "Use and development of the notmuch mail system."\r
64         <notmuch.notmuchmail.org>\r
65 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
66         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
67 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
68 List-Post: <mailto:notmuch@notmuchmail.org>\r
69 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
70 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
71         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
72 X-List-Received-Date: Mon, 25 Aug 2014 17:26:23 -0000\r
73 \r
74 This is v4 of id:1406859003-11561-1-git-send-email-amdragon@mit.edu.\r
75 In addition to rebasing to current master, this makes several tidying\r
76 changes: it gives the features enum a name for better\r
77 self-documentation and type-safety; improves the robustness of\r
78 _parse_features to NULL pointers; requests upgrades if the database\r
79 version is old, even if it supports all current features; improves\r
80 various comments; and fixes some style errors.\r
81 \r
82 The diff from v3 is below.  Most of this diff relates to giving the\r
83 enum a name, since it has to move above struct _notmuch_database and\r
84 we need to define bitwise operators for C++.\r
85 \r
86 diff --git a/lib/database-private.h b/lib/database-private.h\r
87 index 2ffab33..ca0751c 100644\r
88 --- a/lib/database-private.h\r
89 +++ b/lib/database-private.h\r
90 @@ -36,36 +36,30 @@\r
91  \r
92  #pragma GCC visibility push(hidden)\r
93  \r
94 -struct _notmuch_database {\r
95 -    notmuch_bool_t exception_reported;\r
96 -\r
97 -    char *path;\r
98 -\r
99 -    notmuch_database_mode_t mode;\r
100 -    int atomic_nesting;\r
101 -    Xapian::Database *xapian_db;\r
102 -\r
103 -    /* Bit mask of features used by this database.  Features are\r
104 -     * named, independent aspects of the database schema.  This is a\r
105 -     * bitwise-OR of NOTMUCH_FEATURE_* values (below). */\r
106 -    unsigned int features;\r
107 -\r
108 -    unsigned int last_doc_id;\r
109 -    uint64_t last_thread_id;\r
110 -\r
111 -    Xapian::QueryParser *query_parser;\r
112 -    Xapian::TermGenerator *term_gen;\r
113 -    Xapian::ValueRangeProcessor *value_range_processor;\r
114 -    Xapian::ValueRangeProcessor *date_range_processor;\r
115 -};\r
116 -\r
117 -/* Bit masks for _notmuch_database::features. */\r
118 -enum {\r
119 +/* Bit masks for _notmuch_database::features.  Features are named,\r
120 + * independent aspects of the database schema.\r
121 + *\r
122 + * A database stores the set of features that it "uses" (implicitly\r
123 + * before database version 3 and explicitly as of version 3).\r
124 + *\r
125 + * A given library version will "recognize" a particular set of\r
126 + * features; if a database uses a feature that the library does not\r
127 + * recognize, the library will refuse to open it.  It is assumed the\r
128 + * set of recognized features grows monotonically over time.  A\r
129 + * library version will "implement" some subset of the recognized\r
130 + * features: some operations may require that the database use (or not\r
131 + * use) some feature, while other operations may support both\r
132 + * databases that use and that don't use some feature.\r
133 + *\r
134 + * On disk, the database stores string names for these features (see\r
135 + * the feature_names array).  These enum bit values are never\r
136 + * persisted to disk and may change freely.\r
137 + */\r
138 +enum _notmuch_features {\r
139      /* If set, file names are stored in "file-direntry" terms.  If\r
140       * unset, file names are stored in document data.\r
141       *\r
142 -     * Introduced: version 1.  Implementation support: both for read;\r
143 -     * required for write. */\r
144 +     * Introduced: version 1. */\r
145      NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,\r
146  \r
147      /* If set, directory timestamps are stored in documents with\r
148 @@ -73,7 +67,7 @@ enum {\r
149       * timestamps are stored in documents with XTIMESTAMP terms and\r
150       * absolute paths.\r
151       *\r
152 -     * Introduced: version 1.  Implementation support: required. */\r
153 +     * Introduced: version 1. */\r
154      NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,\r
155  \r
156      /* If set, the from, subject, and message-id headers are stored in\r
157 @@ -82,7 +76,6 @@ enum {\r
158       * retrieved from the message file.\r
159       *\r
160       * Introduced: optional in version 1, required as of version 3.\r
161 -     * Implementation support: both.\r
162       */\r
163      NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,\r
164  \r
165 @@ -90,13 +83,71 @@ enum {\r
166       * unset, folder terms are probabilistic and stemmed and path\r
167       * terms do not exist.\r
168       *\r
169 -     * Introduced: version 2.  Implementation support: required. */\r
170 +     * Introduced: version 2. */\r
171      NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,\r
172  };\r
173  \r
174 +/* In C++, a named enum is its own type, so define bitwise operators\r
175 + * on _notmuch_features. */\r
176 +inline _notmuch_features\r
177 +operator|(_notmuch_features a, _notmuch_features b)\r
178 +{\r
179 +    return static_cast<_notmuch_features>(\r
180 +       static_cast<unsigned>(a) | static_cast<unsigned>(b));\r
181 +}\r
182 +\r
183 +inline _notmuch_features\r
184 +operator&(_notmuch_features a, _notmuch_features b)\r
185 +{\r
186 +    return static_cast<_notmuch_features>(\r
187 +       static_cast<unsigned>(a) & static_cast<unsigned>(b));\r
188 +}\r
189 +\r
190 +inline _notmuch_features\r
191 +operator~(_notmuch_features a)\r
192 +{\r
193 +    return static_cast<_notmuch_features>(~static_cast<unsigned>(a));\r
194 +}\r
195 +\r
196 +inline _notmuch_features&\r
197 +operator|=(_notmuch_features &a, _notmuch_features b)\r
198 +{\r
199 +    a = a | b;\r
200 +    return a;\r
201 +}\r
202 +\r
203 +inline _notmuch_features&\r
204 +operator&=(_notmuch_features &a, _notmuch_features b)\r
205 +{\r
206 +    a = a & b;\r
207 +    return a;\r
208 +}\r
209 +\r
210 +struct _notmuch_database {\r
211 +    notmuch_bool_t exception_reported;\r
212 +\r
213 +    char *path;\r
214 +\r
215 +    notmuch_database_mode_t mode;\r
216 +    int atomic_nesting;\r
217 +    Xapian::Database *xapian_db;\r
218 +\r
219 +    /* Bit mask of features used by this database.  This is a\r
220 +     * bitwise-OR of NOTMUCH_FEATURE_* values (above). */\r
221 +    enum _notmuch_features features;\r
222 +\r
223 +    unsigned int last_doc_id;\r
224 +    uint64_t last_thread_id;\r
225 +\r
226 +    Xapian::QueryParser *query_parser;\r
227 +    Xapian::TermGenerator *term_gen;\r
228 +    Xapian::ValueRangeProcessor *value_range_processor;\r
229 +    Xapian::ValueRangeProcessor *date_range_processor;\r
230 +};\r
231 +\r
232  /* Prior to database version 3, features were implied by the database\r
233   * version number, so hard-code them for earlier versions. */\r
234 -#define NOTMUCH_FEATURES_V0 (0)\r
235 +#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features)0)\r
236  #define NOTMUCH_FEATURES_V1 (NOTMUCH_FEATURES_V0 | NOTMUCH_FEATURE_FILE_TERMS | \\r
237                              NOTMUCH_FEATURE_DIRECTORY_DOCS)\r
238  #define NOTMUCH_FEATURES_V2 (NOTMUCH_FEATURES_V1 | NOTMUCH_FEATURE_BOOL_FOLDER)\r
239 diff --git a/lib/database.cc b/lib/database.cc\r
240 index 63257c2..5116188 100644\r
241 --- a/lib/database.cc\r
242 +++ b/lib/database.cc\r
243 @@ -266,10 +266,9 @@ _find_prefix (const char *name)\r
244      return "";\r
245  }\r
246  \r
247 -static const struct\r
248 -{\r
249 +static const struct {\r
250      /* NOTMUCH_FEATURE_* value. */\r
251 -    unsigned int value;\r
252 +    _notmuch_features value;\r
253      /* Feature name as it appears in the database.  This name should\r
254       * be appropriate for displaying to the user if an older version\r
255       * of notmuch doesn't support this feature. */\r
256 @@ -277,12 +276,16 @@ static const struct\r
257      /* Compatibility flags when this feature is declared. */\r
258      const char *flags;\r
259  } feature_names[] = {\r
260 -    {NOTMUCH_FEATURE_FILE_TERMS,             "multiple paths per message", "rw"},\r
261 -    {NOTMUCH_FEATURE_DIRECTORY_DOCS,         "relative directory paths", "rw"},\r
262 +    { NOTMUCH_FEATURE_FILE_TERMS,\r
263 +      "multiple paths per message", "rw" },\r
264 +    { NOTMUCH_FEATURE_DIRECTORY_DOCS,\r
265 +      "relative directory paths", "rw" },\r
266      /* Header values are not required for reading a database because a\r
267       * reader can just refer to the message file. */\r
268 -    {NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES, "from/subject/message-ID in database", "w"},\r
269 -    {NOTMUCH_FEATURE_BOOL_FOLDER,            "exact folder:/path: search", "rw"},\r
270 +    { NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES,\r
271 +      "from/subject/message-ID in database", "w" },\r
272 +    { NOTMUCH_FEATURE_BOOL_FOLDER,\r
273 +      "exact folder:/path: search", "rw" },\r
274  };\r
275  \r
276  const char *\r
277 @@ -658,6 +661,7 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)\r
278  }\r
279  \r
280  /* Parse a database features string from the given database version.\r
281 + * Returns the feature bit set.\r
282   *\r
283   * For version < 3, this ignores the features string and returns a\r
284   * hard-coded set of features.\r
285 @@ -665,13 +669,15 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)\r
286   * If there are unrecognized features that are required to open the\r
287   * database in mode (which should be 'r' or 'w'), return a\r
288   * comma-separated list of unrecognized but required features in\r
289 - * *incompat_out, which will be allocated from ctx.\r
290 + * *incompat_out suitable for presenting to the user.  *incompat_out\r
291 + * will be allocated from ctx.\r
292   */\r
293 -static unsigned int\r
294 +static _notmuch_features\r
295  _parse_features (const void *ctx, const char *features, unsigned int version,\r
296                  char mode, char **incompat_out)\r
297  {\r
298 -    unsigned int res = 0, namelen, i;\r
299 +    _notmuch_features res = static_cast<_notmuch_features>(0);\r
300 +    unsigned int namelen, i;\r
301      size_t llen = 0;\r
302      const char *flags;\r
303  \r
304 @@ -699,7 +705,7 @@ _parse_features (const void *ctx, const char *features, unsigned int version,\r
305             }\r
306         }\r
307  \r
308 -       if (i == ARRAY_SIZE (feature_names)) {\r
309 +       if (i == ARRAY_SIZE (feature_names) && incompat_out) {\r
310             /* Unrecognized feature */\r
311             const char *have = strchr (flags, mode);\r
312             if (have && have < features + llen) {\r
313 @@ -1167,7 +1173,8 @@ notmuch_bool_t\r
314  notmuch_database_needs_upgrade (notmuch_database_t *notmuch)\r
315  {\r
316      return notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&\r
317 -       (NOTMUCH_FEATURES_CURRENT & ~notmuch->features);\r
318 +       ((NOTMUCH_FEATURES_CURRENT & ~notmuch->features) ||\r
319 +        (notmuch_database_get_version (notmuch) < NOTMUCH_DATABASE_VERSION));\r
320  }\r
321  \r
322  static volatile sig_atomic_t do_progress_notify = 0;\r
323 @@ -1202,7 +1209,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,\r
324      struct sigaction action;\r
325      struct itimerval timerval;\r
326      notmuch_bool_t timer_is_active = FALSE;\r
327 -    unsigned int target_features, new_features;\r
328 +    enum _notmuch_features target_features, new_features;\r
329      notmuch_status_t status;\r
330      unsigned int count = 0, total = 0;\r
331  \r
332 diff --git a/lib/notmuch.h b/lib/notmuch.h\r
333 index d771eb2..21a5225 100644\r
334 --- a/lib/notmuch.h\r
335 +++ b/lib/notmuch.h\r
336 @@ -352,12 +352,14 @@ unsigned int\r
337  notmuch_database_get_version (notmuch_database_t *database);\r
338  \r
339  /**\r
340 - * Is the database behind the latest supported database version?\r
341 + * Can the database be upgraded to a newer database version?\r
342   *\r
343   * If this function returns TRUE, then the caller may call\r
344   * notmuch_database_upgrade to upgrade the database.  If the caller\r
345   * does not upgrade an out-of-date database, then some functions may\r
346 - * fail with NOTMUCH_STATUS_UPGRADE_REQUIRED.\r
347 + * fail with NOTMUCH_STATUS_UPGRADE_REQUIRED.  This always returns\r
348 + * FALSE for a read-only database because there's no way to upgrade a\r
349 + * read-only database.\r
350   */\r
351  notmuch_bool_t\r
352  notmuch_database_needs_upgrade (notmuch_database_t *database);\r
353 \r
354 \r
355 \r