Re: Avoiding the "huge INBOX of death"
[notmuch-archives.git] / dc / 0b1fcf8b8bee88e1fa152d6d162de5039df4d5
1 Return-Path: <sojkam1@fel.cvut.cz>\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 7FA1542D283\r
6         for <notmuch@notmuchmail.org>; Sun, 23 Jan 2011 03:47:57 -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 Thofc9oz6WoK for <notmuch@notmuchmail.org>;\r
16         Sun, 23 Jan 2011 03:47:55 -0800 (PST)\r
17 Received: from mail.loccal.net (gw.loccal.net [94.142.235.206])\r
18         by olra.theworths.org (Postfix) with ESMTP id 1D32D42D280\r
19         for <notmuch@notmuchmail.org>; Sun, 23 Jan 2011 03:47:55 -0800 (PST)\r
20 Received: from localhost (localhost [127.0.0.1])\r
21         by mail.loccal.net (Postfix) with ESMTP id 7C0211043A;\r
22         Sun, 23 Jan 2011 13:01:10 +0100 (CET)\r
23 X-Virus-Scanned: amavisd-new at loccal.net\r
24 Received: from mail.loccal.net ([127.0.0.1])\r
25         by localhost (mail.loccal.net [127.0.0.1]) (amavisd-new, port 10024)\r
26         with LMTP id 8QpSTAB1Y4-8; Sun, 23 Jan 2011 13:00:55 +0100 (CET)\r
27 Received: from steelpick.2x.cz (unknown [10.21.129.4])\r
28         by mail.loccal.net (Postfix) with ESMTPS id 7DE3F1BDAD;\r
29         Sun, 23 Jan 2011 13:00:51 +0100 (CET)\r
30 Received: from wsh by steelpick.2x.cz with local (Exim 4.72)\r
31         (envelope-from <sojkam1@fel.cvut.cz>)\r
32         id 1PgyPu-0005i1-Gw; Sun, 23 Jan 2011 12:47:34 +0100\r
33 From: Michal Sojka <sojkam1@fel.cvut.cz>\r
34 To: notmuch@notmuchmail.org\r
35 Subject: [PATCH 2/4] Compile the date/time parser into notmuch library\r
36 Date: Sun, 23 Jan 2011 12:47:25 +0100\r
37 Message-Id: <1295783247-21900-3-git-send-email-sojkam1@fel.cvut.cz>\r
38 X-Mailer: git-send-email 1.7.2.3\r
39 In-Reply-To: <1295783247-21900-1-git-send-email-sojkam1@fel.cvut.cz>\r
40 References: <1295783247-21900-1-git-send-email-sojkam1@fel.cvut.cz>\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: Sun, 23 Jan 2011 11:47:57 -0000\r
54 \r
55 ---\r
56  Makefile.local     |    3 +\r
57  configure          |    8 ++\r
58  lib/Makefile.local |    5 +-\r
59  lib/config.h       |   45 +++++++++++++\r
60  lib/getdate.c      |  185 +++++++++++++++++++++++++++-------------------------\r
61  lib/getdate.h      |    9 +++\r
62  lib/getdate.y      |   15 ++++-\r
63  7 files changed, 178 insertions(+), 92 deletions(-)\r
64  create mode 100644 lib/config.h\r
65 \r
66 diff --git a/Makefile.local b/Makefile.local\r
67 index f9b5a9b..ce35c59 100644\r
68 --- a/Makefile.local\r
69 +++ b/Makefile.local\r
70 @@ -205,6 +205,9 @@ quiet ?= $($(shell echo $1 | sed -e s'/ .*//'))\r
71  %.o: %.c $(global_deps)\r
72         $(call quiet,CC $(CFLAGS)) -c $(FINAL_CFLAGS) $< -o $@\r
73  \r
74 +%.c: %.y\r
75 +       $(call quiet,YACC $(YFLAGS)) $(YFLAGS) $< -o $@\r
76 +\r
77  .deps/%.d: %.c $(global_deps)\r
78         @set -e; rm -f $@; mkdir -p $$(dirname $@) ; \\r
79         $(CC) -M $(CPPFLAGS) $(FINAL_CFLAGS) $< > $@.$$$$ 2>/dev/null ; \\r
80 diff --git a/configure b/configure\r
81 index c58dd0f..6d9fda4 100755\r
82 --- a/configure\r
83 +++ b/configure\r
84 @@ -12,9 +12,11 @@ tab="$(printf '\t')"\r
85  # environemnt variables)\r
86  CC=${CC:-gcc}\r
87  CXX=${CXX:-g++}\r
88 +YACC=${YACC:-yacc}\r
89  CFLAGS=${CFLAGS:--O2}\r
90  CXXFLAGS=${CXXFLAGS:-\$(CFLAGS)}\r
91  LDFLAGS=${LDFLAGS:-}\r
92 +YFLAGS=${YFLAGS}\r
93  XAPIAN_CONFIG=${XAPIAN_CONFIG:-xapian-config}\r
94  \r
95  # We don't allow the EMACS or GZIP Makefile variables inherit values\r
96 @@ -477,6 +479,9 @@ CC = ${CC}\r
97  # The C++ compiler to use\r
98  CXX = ${CXX}\r
99  \r
100 +# The parser generator to use\r
101 +YACC = ${YACC}\r
102 +\r
103  # Command to execute emacs from Makefiles\r
104  EMACS = emacs --quick\r
105  \r
106 @@ -495,6 +500,9 @@ WARN_CXXFLAGS=${WARN_CXXFLAGS}\r
107  # Flags to enable warnings when using the C compiler\r
108  WARN_CFLAGS=${WARN_CFLAGS}\r
109  \r
110 +# Default FLAGS for parser generator (can be overridden by user such as "make YFLAGS=-y")\r
111 +YFLAGS = ${YFLAGS}\r
112 +\r
113  # The prefix to which notmuch should be installed\r
114  # Note: If you change this value here, be sure to ensure that the\r
115  # LIBDIR_IN_LDCONFIG value below is still set correctly.\r
116 diff --git a/lib/Makefile.local b/lib/Makefile.local\r
117 index 37d3735..89b5bb7 100644\r
118 --- a/lib/Makefile.local\r
119 +++ b/lib/Makefile.local\r
120 @@ -56,7 +56,10 @@ libnotmuch_c_srcs =          \\r
121         $(dir)/messages.c       \\r
122         $(dir)/sha1.c           \\r
123         $(dir)/tags.c           \\r
124 -       $(dir)/xutil.c\r
125 +       $(dir)/xutil.c          \\r
126 +       $(dir)/getdate.c        \\r
127 +       $(dir)/c-ctype.c        \\r
128 +       $(dir)/gettime.c\r
129  \r
130  libnotmuch_cxx_srcs =          \\r
131         $(dir)/database.cc      \\r
132 diff --git a/lib/config.h b/lib/config.h\r
133 new file mode 100644\r
134 index 0000000..e8bc5b7\r
135 --- /dev/null\r
136 +++ b/lib/config.h\r
137 @@ -0,0 +1,45 @@\r
138 +/* lib/config.h.  Generated from config.hin by configure.  */\r
139 +/* lib/config.hin.  Generated from configure.ac by autoheader.  */\r
140 +\r
141 +/* Define to 1 if you have the `clock_gettime' function. */\r
142 +#define HAVE_CLOCK_GETTIME 1\r
143 +\r
144 +/* Define if you have compound literals. */\r
145 +#define HAVE_COMPOUND_LITERALS 1\r
146 +\r
147 +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.\r
148 +   */\r
149 +/* #undef HAVE_DECL_TZNAME */\r
150 +\r
151 +/* Define to 1 if you have the `nanotime' function. */\r
152 +/* #undef HAVE_NANOTIME */\r
153 +\r
154 +/* Define to 1 if `tm_zone' is a member of `struct tm'. */\r
155 +#define HAVE_STRUCT_TM_TM_ZONE 1\r
156 +\r
157 +/* Define if struct tm has the tm_gmtoff member. */\r
158 +#define HAVE_TM_GMTOFF 1\r
159 +\r
160 +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use\r
161 +   `HAVE_STRUCT_TM_TM_ZONE' instead. */\r
162 +#define HAVE_TM_ZONE 1\r
163 +\r
164 +/* Define to 1 if you don't have `tm_zone' but do have the external array\r
165 +   `tzname'. */\r
166 +/* #undef HAVE_TZNAME */\r
167 +\r
168 +/* Define to 1 if you have the `tzset' function. */\r
169 +#define HAVE_TZSET 1\r
170 +\r
171 +\r
172 +/* Define as a marker that can be attached to declarations that might not\r
173 +    be used.  This helps to reduce warnings, such as from\r
174 +    GCC -Wunused-parameter.  */\r
175 +#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)\r
176 +# define _GL_UNUSED __attribute__ ((__unused__))\r
177 +#else\r
178 +# define _GL_UNUSED\r
179 +#endif\r
180 +/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name\r
181 +   is a misnomer outside of parameter lists.  */\r
182 +#define _UNUSED_PARAMETER_ _GL_UNUSED\r
183 diff --git a/lib/getdate.c b/lib/getdate.c\r
184 index 5b20eeb..57f33e9 100644\r
185 --- a/lib/getdate.c\r
186 +++ b/lib/getdate.c\r
187 @@ -68,7 +68,7 @@\r
188  /* Copy the first part of user declarations.  */\r
189  \r
190  /* Line 189 of yacc.c  */\r
191 -#line 1 "getdate.y"\r
192 +#line 1 "lib/getdate.y"\r
193  \r
194  /* Parse a string into an internal time stamp.\r
195  \r
196 @@ -102,6 +102,8 @@\r
197  /* FIXME: Check for arithmetic overflow in all cases, not just\r
198     some of them.  */\r
199  \r
200 +#include "notmuch-private.h"   /* For xmalloc() */\r
201 +\r
202  #include <config.h>\r
203  \r
204  #include "getdate.h"\r
205 @@ -137,9 +139,6 @@\r
206  #include <stdlib.h>\r
207  #include <string.h>\r
208  \r
209 -#include "xalloc.h"\r
210 -\r
211 -\r
212  /* ISDIGIT differs from isdigit, as follows:\r
213     - Its arg may be any int or unsigned int; it need not be an unsigned char\r
214       or EOF.\r
215 @@ -344,7 +343,7 @@ set_hhmmss (parser_control *pc, long int hour, long int minutes,\r
216  \r
217  \r
218  /* Line 189 of yacc.c  */\r
219 -#line 348 "getdate.c"\r
220 +#line 347 "lib/getdate.c"\r
221  \r
222  /* Enabling traces.  */\r
223  #ifndef YYDEBUG\r
224 @@ -423,7 +422,7 @@ typedef union YYSTYPE\r
225  {\r
226  \r
227  /* Line 214 of yacc.c  */\r
228 -#line 285 "getdate.y"\r
229 +#line 284 "lib/getdate.y"\r
230  \r
231    long int intval;\r
232    textint textintval;\r
233 @@ -433,7 +432,7 @@ typedef union YYSTYPE\r
234  \r
235  \r
236  /* Line 214 of yacc.c  */\r
237 -#line 437 "getdate.c"\r
238 +#line 436 "lib/getdate.c"\r
239  } YYSTYPE;\r
240  # define YYSTYPE_IS_TRIVIAL 1\r
241  # define yystype YYSTYPE /* obsolescent; will be withdrawn */\r
242 @@ -445,7 +444,7 @@ typedef union YYSTYPE\r
243  \r
244  \r
245  /* Line 264 of yacc.c  */\r
246 -#line 449 "getdate.c"\r
247 +#line 448 "lib/getdate.c"\r
248  \r
249  #ifdef short\r
250  # undef short\r
251 @@ -759,15 +758,15 @@ static const yytype_int8 yyrhs[] =\r
252  /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */\r
253  static const yytype_uint16 yyrline[] =\r
254  {\r
255 -       0,   311,   311,   312,   316,   323,   325,   329,   331,   333,\r
256 -     335,   337,   339,   340,   341,   345,   350,   355,   362,   367,\r
257 -     377,   382,   390,   392,   395,   397,   399,   404,   409,   414,\r
258 -     419,   427,   432,   452,   459,   467,   475,   480,   486,   491,\r
259 -     500,   502,   504,   509,   511,   513,   515,   517,   519,   521,\r
260 -     523,   525,   527,   529,   531,   533,   535,   537,   539,   541,\r
261 -     543,   545,   547,   549,   553,   555,   557,   559,   561,   563,\r
262 -     568,   572,   572,   575,   576,   581,   582,   587,   592,   603,\r
263 -     604,   610,   611\r
264 +       0,   310,   310,   311,   315,   322,   324,   328,   330,   332,\r
265 +     334,   336,   338,   339,   340,   344,   349,   354,   361,   366,\r
266 +     376,   381,   389,   391,   394,   396,   398,   403,   408,   413,\r
267 +     418,   426,   431,   451,   458,   466,   474,   479,   485,   490,\r
268 +     499,   501,   503,   508,   510,   512,   514,   516,   518,   520,\r
269 +     522,   524,   526,   528,   530,   532,   534,   536,   538,   540,\r
270 +     542,   544,   546,   548,   552,   554,   556,   558,   560,   562,\r
271 +     567,   571,   571,   574,   575,   580,   581,   586,   591,   602,\r
272 +     603,   609,   610\r
273  };\r
274  #endif\r
275  \r
276 @@ -1742,7 +1741,7 @@ yyreduce:\r
277          case 4:\r
278  \r
279  /* Line 1455 of yacc.c  */\r
280 -#line 317 "getdate.y"\r
281 +#line 316 "lib/getdate.y"\r
282      {\r
283          pc->seconds = (yyvsp[(2) - (2)].timespec);\r
284          pc->timespec_seen = true;\r
285 @@ -1752,42 +1751,42 @@ yyreduce:\r
286    case 7:\r
287  \r
288  /* Line 1455 of yacc.c  */\r
289 -#line 330 "getdate.y"\r
290 +#line 329 "lib/getdate.y"\r
291      { pc->times_seen++; }\r
292      break;\r
293  \r
294    case 8:\r
295  \r
296  /* Line 1455 of yacc.c  */\r
297 -#line 332 "getdate.y"\r
298 +#line 331 "lib/getdate.y"\r
299      { pc->local_zones_seen++; }\r
300      break;\r
301  \r
302    case 9:\r
303  \r
304  /* Line 1455 of yacc.c  */\r
305 -#line 334 "getdate.y"\r
306 +#line 333 "lib/getdate.y"\r
307      { pc->zones_seen++; }\r
308      break;\r
309  \r
310    case 10:\r
311  \r
312  /* Line 1455 of yacc.c  */\r
313 -#line 336 "getdate.y"\r
314 +#line 335 "lib/getdate.y"\r
315      { pc->dates_seen++; }\r
316      break;\r
317  \r
318    case 11:\r
319  \r
320  /* Line 1455 of yacc.c  */\r
321 -#line 338 "getdate.y"\r
322 +#line 337 "lib/getdate.y"\r
323      { pc->days_seen++; }\r
324      break;\r
325  \r
326    case 15:\r
327  \r
328  /* Line 1455 of yacc.c  */\r
329 -#line 346 "getdate.y"\r
330 +#line 345 "lib/getdate.y"\r
331      {\r
332          set_hhmmss (pc, (yyvsp[(1) - (2)].textintval).value, 0, 0, 0);\r
333          pc->meridian = (yyvsp[(2) - (2)].intval);\r
334 @@ -1797,7 +1796,7 @@ yyreduce:\r
335    case 16:\r
336  \r
337  /* Line 1455 of yacc.c  */\r
338 -#line 351 "getdate.y"\r
339 +#line 350 "lib/getdate.y"\r
340      {\r
341          set_hhmmss (pc, (yyvsp[(1) - (4)].textintval).value, (yyvsp[(3) - (4)].textintval).value, 0, 0);\r
342          pc->meridian = (yyvsp[(4) - (4)].intval);\r
343 @@ -1807,7 +1806,7 @@ yyreduce:\r
344    case 17:\r
345  \r
346  /* Line 1455 of yacc.c  */\r
347 -#line 356 "getdate.y"\r
348 +#line 355 "lib/getdate.y"\r
349      {\r
350          set_hhmmss (pc, (yyvsp[(1) - (5)].textintval).value, (yyvsp[(3) - (5)].textintval).value, 0, 0);\r
351          pc->meridian = MER24;\r
352 @@ -1819,7 +1818,7 @@ yyreduce:\r
353    case 18:\r
354  \r
355  /* Line 1455 of yacc.c  */\r
356 -#line 363 "getdate.y"\r
357 +#line 362 "lib/getdate.y"\r
358      {\r
359          set_hhmmss (pc, (yyvsp[(1) - (6)].textintval).value, (yyvsp[(3) - (6)].textintval).value, (yyvsp[(5) - (6)].timespec).tv_sec, (yyvsp[(5) - (6)].timespec).tv_nsec);\r
360          pc->meridian = (yyvsp[(6) - (6)].intval);\r
361 @@ -1829,7 +1828,7 @@ yyreduce:\r
362    case 19:\r
363  \r
364  /* Line 1455 of yacc.c  */\r
365 -#line 368 "getdate.y"\r
366 +#line 367 "lib/getdate.y"\r
367      {\r
368          set_hhmmss (pc, (yyvsp[(1) - (7)].textintval).value, (yyvsp[(3) - (7)].textintval).value, (yyvsp[(5) - (7)].timespec).tv_sec, (yyvsp[(5) - (7)].timespec).tv_nsec);\r
369          pc->meridian = MER24;\r
370 @@ -1841,7 +1840,7 @@ yyreduce:\r
371    case 20:\r
372  \r
373  /* Line 1455 of yacc.c  */\r
374 -#line 378 "getdate.y"\r
375 +#line 377 "lib/getdate.y"\r
376      {\r
377          pc->local_isdst = (yyvsp[(1) - (1)].intval);\r
378          pc->dsts_seen += (0 < (yyvsp[(1) - (1)].intval));\r
379 @@ -1851,7 +1850,7 @@ yyreduce:\r
380    case 21:\r
381  \r
382  /* Line 1455 of yacc.c  */\r
383 -#line 383 "getdate.y"\r
384 +#line 382 "lib/getdate.y"\r
385      {\r
386          pc->local_isdst = 1;\r
387          pc->dsts_seen += (0 < (yyvsp[(1) - (2)].intval)) + 1;\r
388 @@ -1861,14 +1860,14 @@ yyreduce:\r
389    case 22:\r
390  \r
391  /* Line 1455 of yacc.c  */\r
392 -#line 391 "getdate.y"\r
393 +#line 390 "lib/getdate.y"\r
394      { pc->time_zone = (yyvsp[(1) - (1)].intval); }\r
395      break;\r
396  \r
397    case 23:\r
398  \r
399  /* Line 1455 of yacc.c  */\r
400 -#line 393 "getdate.y"\r
401 +#line 392 "lib/getdate.y"\r
402      { pc->time_zone = (yyvsp[(1) - (2)].intval);\r
403          apply_relative_time (pc, (yyvsp[(2) - (2)].rel), 1); }\r
404      break;\r
405 @@ -1876,28 +1875,28 @@ yyreduce:\r
406    case 24:\r
407  \r
408  /* Line 1455 of yacc.c  */\r
409 -#line 396 "getdate.y"\r
410 +#line 395 "lib/getdate.y"\r
411      { pc->time_zone = (yyvsp[(1) - (3)].intval) + time_zone_hhmm (pc, (yyvsp[(2) - (3)].textintval), (yyvsp[(3) - (3)].intval)); }\r
412      break;\r
413  \r
414    case 25:\r
415  \r
416  /* Line 1455 of yacc.c  */\r
417 -#line 398 "getdate.y"\r
418 +#line 397 "lib/getdate.y"\r
419      { pc->time_zone = (yyvsp[(1) - (1)].intval) + 60; }\r
420      break;\r
421  \r
422    case 26:\r
423  \r
424  /* Line 1455 of yacc.c  */\r
425 -#line 400 "getdate.y"\r
426 +#line 399 "lib/getdate.y"\r
427      { pc->time_zone = (yyvsp[(1) - (2)].intval) + 60; }\r
428      break;\r
429  \r
430    case 27:\r
431  \r
432  /* Line 1455 of yacc.c  */\r
433 -#line 405 "getdate.y"\r
434 +#line 404 "lib/getdate.y"\r
435      {\r
436          pc->day_ordinal = 0;\r
437          pc->day_number = (yyvsp[(1) - (1)].intval);\r
438 @@ -1907,7 +1906,7 @@ yyreduce:\r
439    case 28:\r
440  \r
441  /* Line 1455 of yacc.c  */\r
442 -#line 410 "getdate.y"\r
443 +#line 409 "lib/getdate.y"\r
444      {\r
445          pc->day_ordinal = 0;\r
446          pc->day_number = (yyvsp[(1) - (2)].intval);\r
447 @@ -1917,7 +1916,7 @@ yyreduce:\r
448    case 29:\r
449  \r
450  /* Line 1455 of yacc.c  */\r
451 -#line 415 "getdate.y"\r
452 +#line 414 "lib/getdate.y"\r
453      {\r
454          pc->day_ordinal = (yyvsp[(1) - (2)].intval);\r
455          pc->day_number = (yyvsp[(2) - (2)].intval);\r
456 @@ -1927,7 +1926,7 @@ yyreduce:\r
457    case 30:\r
458  \r
459  /* Line 1455 of yacc.c  */\r
460 -#line 420 "getdate.y"\r
461 +#line 419 "lib/getdate.y"\r
462      {\r
463          pc->day_ordinal = (yyvsp[(1) - (2)].textintval).value;\r
464          pc->day_number = (yyvsp[(2) - (2)].intval);\r
465 @@ -1937,7 +1936,7 @@ yyreduce:\r
466    case 31:\r
467  \r
468  /* Line 1455 of yacc.c  */\r
469 -#line 428 "getdate.y"\r
470 +#line 427 "lib/getdate.y"\r
471      {\r
472          pc->month = (yyvsp[(1) - (3)].textintval).value;\r
473          pc->day = (yyvsp[(3) - (3)].textintval).value;\r
474 @@ -1947,7 +1946,7 @@ yyreduce:\r
475    case 32:\r
476  \r
477  /* Line 1455 of yacc.c  */\r
478 -#line 433 "getdate.y"\r
479 +#line 432 "lib/getdate.y"\r
480      {\r
481          /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,\r
482             otherwise as MM/DD/YY.\r
483 @@ -1972,7 +1971,7 @@ yyreduce:\r
484    case 33:\r
485  \r
486  /* Line 1455 of yacc.c  */\r
487 -#line 453 "getdate.y"\r
488 +#line 452 "lib/getdate.y"\r
489      {\r
490          /* ISO 8601 format.  YYYY-MM-DD.  */\r
491          pc->year = (yyvsp[(1) - (3)].textintval);\r
492 @@ -1984,7 +1983,7 @@ yyreduce:\r
493    case 34:\r
494  \r
495  /* Line 1455 of yacc.c  */\r
496 -#line 460 "getdate.y"\r
497 +#line 459 "lib/getdate.y"\r
498      {\r
499          /* e.g. 17-JUN-1992.  */\r
500          pc->day = (yyvsp[(1) - (3)].textintval).value;\r
501 @@ -1997,7 +1996,7 @@ yyreduce:\r
502    case 35:\r
503  \r
504  /* Line 1455 of yacc.c  */\r
505 -#line 468 "getdate.y"\r
506 +#line 467 "lib/getdate.y"\r
507      {\r
508          /* e.g. JUN-17-1992.  */\r
509          pc->month = (yyvsp[(1) - (3)].intval);\r
510 @@ -2010,7 +2009,7 @@ yyreduce:\r
511    case 36:\r
512  \r
513  /* Line 1455 of yacc.c  */\r
514 -#line 476 "getdate.y"\r
515 +#line 475 "lib/getdate.y"\r
516      {\r
517          pc->month = (yyvsp[(1) - (2)].intval);\r
518          pc->day = (yyvsp[(2) - (2)].textintval).value;\r
519 @@ -2020,7 +2019,7 @@ yyreduce:\r
520    case 37:\r
521  \r
522  /* Line 1455 of yacc.c  */\r
523 -#line 481 "getdate.y"\r
524 +#line 480 "lib/getdate.y"\r
525      {\r
526          pc->month = (yyvsp[(1) - (4)].intval);\r
527          pc->day = (yyvsp[(2) - (4)].textintval).value;\r
528 @@ -2031,7 +2030,7 @@ yyreduce:\r
529    case 38:\r
530  \r
531  /* Line 1455 of yacc.c  */\r
532 -#line 487 "getdate.y"\r
533 +#line 486 "lib/getdate.y"\r
534      {\r
535          pc->day = (yyvsp[(1) - (2)].textintval).value;\r
536          pc->month = (yyvsp[(2) - (2)].intval);\r
537 @@ -2041,7 +2040,7 @@ yyreduce:\r
538    case 39:\r
539  \r
540  /* Line 1455 of yacc.c  */\r
541 -#line 492 "getdate.y"\r
542 +#line 491 "lib/getdate.y"\r
543      {\r
544          pc->day = (yyvsp[(1) - (3)].textintval).value;\r
545          pc->month = (yyvsp[(2) - (3)].intval);\r
546 @@ -2052,238 +2051,238 @@ yyreduce:\r
547    case 40:\r
548  \r
549  /* Line 1455 of yacc.c  */\r
550 -#line 501 "getdate.y"\r
551 +#line 500 "lib/getdate.y"\r
552      { apply_relative_time (pc, (yyvsp[(1) - (2)].rel), -1); }\r
553      break;\r
554  \r
555    case 41:\r
556  \r
557  /* Line 1455 of yacc.c  */\r
558 -#line 503 "getdate.y"\r
559 +#line 502 "lib/getdate.y"\r
560      { apply_relative_time (pc, (yyvsp[(1) - (1)].rel), 1); }\r
561      break;\r
562  \r
563    case 42:\r
564  \r
565  /* Line 1455 of yacc.c  */\r
566 -#line 505 "getdate.y"\r
567 +#line 504 "lib/getdate.y"\r
568      { apply_relative_time (pc, (yyvsp[(1) - (1)].rel), 1); }\r
569      break;\r
570  \r
571    case 43:\r
572  \r
573  /* Line 1455 of yacc.c  */\r
574 -#line 510 "getdate.y"\r
575 +#line 509 "lib/getdate.y"\r
576      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].intval); }\r
577      break;\r
578  \r
579    case 44:\r
580  \r
581  /* Line 1455 of yacc.c  */\r
582 -#line 512 "getdate.y"\r
583 +#line 511 "lib/getdate.y"\r
584      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].textintval).value; }\r
585      break;\r
586  \r
587    case 45:\r
588  \r
589  /* Line 1455 of yacc.c  */\r
590 -#line 514 "getdate.y"\r
591 +#line 513 "lib/getdate.y"\r
592      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = 1; }\r
593      break;\r
594  \r
595    case 46:\r
596  \r
597  /* Line 1455 of yacc.c  */\r
598 -#line 516 "getdate.y"\r
599 +#line 515 "lib/getdate.y"\r
600      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].intval); }\r
601      break;\r
602  \r
603    case 47:\r
604  \r
605  /* Line 1455 of yacc.c  */\r
606 -#line 518 "getdate.y"\r
607 +#line 517 "lib/getdate.y"\r
608      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].textintval).value; }\r
609      break;\r
610  \r
611    case 48:\r
612  \r
613  /* Line 1455 of yacc.c  */\r
614 -#line 520 "getdate.y"\r
615 +#line 519 "lib/getdate.y"\r
616      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = 1; }\r
617      break;\r
618  \r
619    case 49:\r
620  \r
621  /* Line 1455 of yacc.c  */\r
622 -#line 522 "getdate.y"\r
623 +#line 521 "lib/getdate.y"\r
624      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); }\r
625      break;\r
626  \r
627    case 50:\r
628  \r
629  /* Line 1455 of yacc.c  */\r
630 -#line 524 "getdate.y"\r
631 +#line 523 "lib/getdate.y"\r
632      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); }\r
633      break;\r
634  \r
635    case 51:\r
636  \r
637  /* Line 1455 of yacc.c  */\r
638 -#line 526 "getdate.y"\r
639 +#line 525 "lib/getdate.y"\r
640      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (1)].intval); }\r
641      break;\r
642  \r
643    case 52:\r
644  \r
645  /* Line 1455 of yacc.c  */\r
646 -#line 528 "getdate.y"\r
647 +#line 527 "lib/getdate.y"\r
648      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].intval); }\r
649      break;\r
650  \r
651    case 53:\r
652  \r
653  /* Line 1455 of yacc.c  */\r
654 -#line 530 "getdate.y"\r
655 +#line 529 "lib/getdate.y"\r
656      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].textintval).value; }\r
657      break;\r
658  \r
659    case 54:\r
660  \r
661  /* Line 1455 of yacc.c  */\r
662 -#line 532 "getdate.y"\r
663 +#line 531 "lib/getdate.y"\r
664      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = 1; }\r
665      break;\r
666  \r
667    case 55:\r
668  \r
669  /* Line 1455 of yacc.c  */\r
670 -#line 534 "getdate.y"\r
671 +#line 533 "lib/getdate.y"\r
672      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].intval); }\r
673      break;\r
674  \r
675    case 56:\r
676  \r
677  /* Line 1455 of yacc.c  */\r
678 -#line 536 "getdate.y"\r
679 +#line 535 "lib/getdate.y"\r
680      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].textintval).value; }\r
681      break;\r
682  \r
683    case 57:\r
684  \r
685  /* Line 1455 of yacc.c  */\r
686 -#line 538 "getdate.y"\r
687 +#line 537 "lib/getdate.y"\r
688      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = 1; }\r
689      break;\r
690  \r
691    case 58:\r
692  \r
693  /* Line 1455 of yacc.c  */\r
694 -#line 540 "getdate.y"\r
695 +#line 539 "lib/getdate.y"\r
696      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].intval); }\r
697      break;\r
698  \r
699    case 59:\r
700  \r
701  /* Line 1455 of yacc.c  */\r
702 -#line 542 "getdate.y"\r
703 +#line 541 "lib/getdate.y"\r
704      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].textintval).value; }\r
705      break;\r
706  \r
707    case 60:\r
708  \r
709  /* Line 1455 of yacc.c  */\r
710 -#line 544 "getdate.y"\r
711 +#line 543 "lib/getdate.y"\r
712      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; }\r
713      break;\r
714  \r
715    case 61:\r
716  \r
717  /* Line 1455 of yacc.c  */\r
718 -#line 546 "getdate.y"\r
719 +#line 545 "lib/getdate.y"\r
720      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; }\r
721      break;\r
722  \r
723    case 62:\r
724  \r
725  /* Line 1455 of yacc.c  */\r
726 -#line 548 "getdate.y"\r
727 +#line 547 "lib/getdate.y"\r
728      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = 1; }\r
729      break;\r
730  \r
731    case 64:\r
732  \r
733  /* Line 1455 of yacc.c  */\r
734 -#line 554 "getdate.y"\r
735 +#line 553 "lib/getdate.y"\r
736      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].textintval).value; }\r
737      break;\r
738  \r
739    case 65:\r
740  \r
741  /* Line 1455 of yacc.c  */\r
742 -#line 556 "getdate.y"\r
743 +#line 555 "lib/getdate.y"\r
744      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].textintval).value; }\r
745      break;\r
746  \r
747    case 66:\r
748  \r
749  /* Line 1455 of yacc.c  */\r
750 -#line 558 "getdate.y"\r
751 +#line 557 "lib/getdate.y"\r
752      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); }\r
753      break;\r
754  \r
755    case 67:\r
756  \r
757  /* Line 1455 of yacc.c  */\r
758 -#line 560 "getdate.y"\r
759 +#line 559 "lib/getdate.y"\r
760      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].textintval).value; }\r
761      break;\r
762  \r
763    case 68:\r
764  \r
765  /* Line 1455 of yacc.c  */\r
766 -#line 562 "getdate.y"\r
767 +#line 561 "lib/getdate.y"\r
768      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].textintval).value; }\r
769      break;\r
770  \r
771    case 69:\r
772  \r
773  /* Line 1455 of yacc.c  */\r
774 -#line 564 "getdate.y"\r
775 +#line 563 "lib/getdate.y"\r
776      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].textintval).value; }\r
777      break;\r
778  \r
779    case 70:\r
780  \r
781  /* Line 1455 of yacc.c  */\r
782 -#line 569 "getdate.y"\r
783 +#line 568 "lib/getdate.y"\r
784      { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (1)].intval); }\r
785      break;\r
786  \r
787    case 74:\r
788  \r
789  /* Line 1455 of yacc.c  */\r
790 -#line 577 "getdate.y"\r
791 +#line 576 "lib/getdate.y"\r
792      { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; }\r
793      break;\r
794  \r
795    case 76:\r
796  \r
797  /* Line 1455 of yacc.c  */\r
798 -#line 583 "getdate.y"\r
799 +#line 582 "lib/getdate.y"\r
800      { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; }\r
801      break;\r
802  \r
803    case 77:\r
804  \r
805  /* Line 1455 of yacc.c  */\r
806 -#line 588 "getdate.y"\r
807 +#line 587 "lib/getdate.y"\r
808      { digits_to_date_time (pc, (yyvsp[(1) - (1)].textintval)); }\r
809      break;\r
810  \r
811    case 78:\r
812  \r
813  /* Line 1455 of yacc.c  */\r
814 -#line 593 "getdate.y"\r
815 +#line 592 "lib/getdate.y"\r
816      {\r
817          /* Hybrid all-digit and relative offset, so that we accept e.g.,\r
818             "YYYYMMDD +N days" as well as "YYYYMMDD N days".  */\r
819 @@ -2295,35 +2294,35 @@ yyreduce:\r
820    case 79:\r
821  \r
822  /* Line 1455 of yacc.c  */\r
823 -#line 603 "getdate.y"\r
824 +#line 602 "lib/getdate.y"\r
825      { (yyval.intval) = -1; }\r
826      break;\r
827  \r
828    case 80:\r
829  \r
830  /* Line 1455 of yacc.c  */\r
831 -#line 605 "getdate.y"\r
832 +#line 604 "lib/getdate.y"\r
833      { (yyval.intval) = (yyvsp[(2) - (2)].textintval).value; }\r
834      break;\r
835  \r
836    case 81:\r
837  \r
838  /* Line 1455 of yacc.c  */\r
839 -#line 610 "getdate.y"\r
840 +#line 609 "lib/getdate.y"\r
841      { (yyval.intval) = MER24; }\r
842      break;\r
843  \r
844    case 82:\r
845  \r
846  /* Line 1455 of yacc.c  */\r
847 -#line 612 "getdate.y"\r
848 +#line 611 "lib/getdate.y"\r
849      { (yyval.intval) = (yyvsp[(1) - (1)].intval); }\r
850      break;\r
851  \r
852  \r
853  \r
854  /* Line 1455 of yacc.c  */\r
855 -#line 2327 "getdate.c"\r
856 +#line 2326 "lib/getdate.c"\r
857        default: break;\r
858      }\r
859    YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);\r
860 @@ -2535,7 +2534,7 @@ yyreturn:\r
861  \r
862  \r
863  /* Line 1675 of yacc.c  */\r
864 -#line 615 "getdate.y"\r
865 +#line 614 "lib/getdate.y"\r
866  \r
867  \r
868  static table const meridian_table[] =\r
869 @@ -3104,6 +3103,16 @@ mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)\r
870     Use heap allocation if TZ's length exceeds this.  */\r
871  enum { TZBUFSIZE = 100 };\r
872  \r
873 +/* Clone an object P of size S, with error checking.  There's no need\r
874 +   for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any\r
875 +   need for an arithmetic overflow check.  */\r
876 +\r
877 +static void *\r
878 +xmemdup (void const *p, size_t s)\r
879 +{\r
880 +  return memcpy (xmalloc (s), p, s);\r
881 +}\r
882 +\r
883  /* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated\r
884     otherwise.  */\r
885  static char *\r
886 diff --git a/lib/getdate.h b/lib/getdate.h\r
887 index 22cc2c0..ad1283c 100644\r
888 --- a/lib/getdate.h\r
889 +++ b/lib/getdate.h\r
890 @@ -19,4 +19,13 @@\r
891  #include <stdbool.h>\r
892  #include <time.h>\r
893  \r
894 +#ifdef __cplusplus\r
895 +extern "C" {\r
896 +#endif\r
897 +\r
898  bool get_date (struct timespec *, char const *, struct timespec const *);\r
899 +\r
900 +#ifdef __cplusplus\r
901 +}\r
902 +#endif\r
903 +\r
904 diff --git a/lib/getdate.y b/lib/getdate.y\r
905 index 445865b..d423f5b 100644\r
906 --- a/lib/getdate.y\r
907 +++ b/lib/getdate.y\r
908 @@ -31,6 +31,8 @@\r
909  /* FIXME: Check for arithmetic overflow in all cases, not just\r
910     some of them.  */\r
911  \r
912 +#include "notmuch-private.h"   /* For xmalloc() */\r
913 +\r
914  #include <config.h>\r
915  \r
916  #include "getdate.h"\r
917 @@ -66,9 +68,6 @@\r
918  #include <stdlib.h>\r
919  #include <string.h>\r
920  \r
921 -#include "xalloc.h"\r
922 -\r
923 -\r
924  /* ISDIGIT differs from isdigit, as follows:\r
925     - Its arg may be any int or unsigned int; it need not be an unsigned char\r
926       or EOF.\r
927 @@ -1180,6 +1179,16 @@ mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)\r
928     Use heap allocation if TZ's length exceeds this.  */\r
929  enum { TZBUFSIZE = 100 };\r
930  \r
931 +/* Clone an object P of size S, with error checking.  There's no need\r
932 +   for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any\r
933 +   need for an arithmetic overflow check.  */\r
934 +\r
935 +static void *\r
936 +xmemdup (void const *p, size_t s)\r
937 +{\r
938 +  return memcpy (xmalloc (s), p, s);\r
939 +}\r
940 +\r
941  /* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated\r
942     otherwise.  */\r
943  static char *\r
944 -- \r
945 1.7.2.3\r
946 \r