Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 80 / 4ab7afcc59a8296a7ddf16a9ab46f15f84746e
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 09F44431FC0\r
6         for <notmuch@notmuchmail.org>; Tue, 25 Sep 2012 05:22:36 -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 xyvE91thvojF for <notmuch@notmuchmail.org>;\r
16         Tue, 25 Sep 2012 05:22:34 -0700 (PDT)\r
17 Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36])\r
18         by olra.theworths.org (Postfix) with ESMTP id 911A4431FAF\r
19         for <notmuch@notmuchmail.org>; Tue, 25 Sep 2012 05:22:34 -0700 (PDT)\r
20 Received: from localhost (unknown [192.168.200.4])\r
21         by max.feld.cvut.cz (Postfix) with ESMTP id 816F03CFF23;\r
22         Tue, 25 Sep 2012 14:21:40 +0200 (CEST)\r
23 X-Virus-Scanned: IMAP AMAVIS\r
24 Received: from max.feld.cvut.cz ([192.168.200.1])\r
25         by localhost (styx.feld.cvut.cz [192.168.200.4]) (amavisd-new,\r
26         port 10044)\r
27         with ESMTP id i3GAJ3IoEsxP; Tue, 25 Sep 2012 14:21:38 +0200 (CEST)\r
28 Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34])\r
29         by max.feld.cvut.cz (Postfix) with ESMTP id 011023CFEE7;\r
30         Tue, 25 Sep 2012 14:05:43 +0200 (CEST)\r
31 Received: from steelpick.2x.cz (unknown [213.29.198.144])\r
32         (Authenticated sender: sojkam1)\r
33         by imap.feld.cvut.cz (Postfix) with ESMTPSA id 1F9F6660969;\r
34         Tue, 25 Sep 2012 14:05:33 +0200 (CEST)\r
35 Received: from wsh by steelpick.2x.cz with local (Exim 4.80)\r
36         (envelope-from <sojkam1@fel.cvut.cz>)\r
37         id 1TGTtH-0001WN-Nb; Tue, 25 Sep 2012 14:05:27 +0200\r
38 From: Michal Sojka <sojkam1@fel.cvut.cz>\r
39 To: Jani Nikula <jani@nikula.org>, notmuch@notmuchmail.org,\r
40         David Bremner <david@tethera.net>\r
41 Subject: [PATCH] test: Improve tests for the date/time parser module\r
42 In-Reply-To:\r
43  <24186aafbdcb967b8f66c2390c928f3788ab6cbf.1347484177.git.jani@nikula.org>\r
44 References: <cover.1347484177.git.jani@nikula.org>\r
45         <24186aafbdcb967b8f66c2390c928f3788ab6cbf.1347484177.git.jani@nikula.org>\r
46 User-Agent: Notmuch/0.14+23~g9d68aca (http://notmuchmail.org) Emacs/24.2.1\r
47         (x86_64-pc-linux-gnu)\r
48 Date: Tue, 25 Sep 2012 14:05:27 +0200\r
49 Message-ID: <87zk4e1f5k.fsf@steelpick.2x.cz>\r
50 MIME-Version: 1.0\r
51 Content-Type: text/plain\r
52 X-BeenThere: notmuch@notmuchmail.org\r
53 X-Mailman-Version: 2.1.13\r
54 Precedence: list\r
55 List-Id: "Use and development of the notmuch mail system."\r
56         <notmuch.notmuchmail.org>\r
57 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
58         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
59 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
60 List-Post: <mailto:notmuch@notmuchmail.org>\r
61 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
62 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
63         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
64 X-List-Received-Date: Tue, 25 Sep 2012 12:22:36 -0000\r
65 \r
66 This patch reworks date/time parser library test program to make it\r
67 easier to to write the actual tests. It also modifies the notmuch test\r
68 script and adds several new tests to it.\r
69 \r
70 The INPUT file for the test contains both the dates to be parsed as well\r
71 as the "expected" results. The test program outputs the results in the\r
72 same format and replaces expected results with real results. Currently,\r
73 the "expected" results in the INPUT file correspond to the real results,\r
74 so the test passes. Some results are, however, different from what I\r
75 would expect - this is mentioned in the comments after '#'.\r
76 \r
77 This patch applies on top of Jani's patchset.\r
78 ---\r
79 It can be seen that there are several errors and unexpected results.\r
80 As I've already written, I'm not sure that the approach taken by this\r
81 library is the right one. I tend to agree with mina86, that using a\r
82 more systematic approach (such as bison) would be beneficial.\r
83 \r
84 This is however not to say to throw this patchset away. Either Jani\r
85 will be able to fix all the corner cases. Or we can work together to\r
86 develop a better solution - add support for ranges to the bison\r
87 parser.\r
88 \r
89 -Michal\r
90 \r
91 diff --git a/test/Makefile.local b/test/Makefile.local\r
92 index 9ae130a..b9105c7 100644\r
93 --- a/test/Makefile.local\r
94 +++ b/test/Makefile.local\r
95 @@ -20,7 +20,7 @@ $(dir)/symbol-test: $(dir)/symbol-test.o\r
96         $(call quiet,CXX) $^ -o $@ -Llib -lnotmuch $(XAPIAN_LDFLAGS)\r
97  \r
98  $(dir)/parse-time: $(dir)/parse-time.o parse-time-string/parse-time-string.o\r
99 -       $(call quiet,CC) $^ -o $@\r
100 +       $(call quiet,CC) $^ -o $@ -lrt\r
101  \r
102  .PHONY: test check\r
103  \r
104 diff --git a/test/parse-time-string b/test/parse-time-string\r
105 index 34b80d7..265437c 100755\r
106 --- a/test/parse-time-string\r
107 +++ b/test/parse-time-string\r
108 @@ -14,13 +14,48 @@ _parse_time ()\r
109      ${TEST_DIRECTORY}/parse-time --format=%s "$*"\r
110  }\r
111  \r
112 -test_begin_subtest "date(1) default format without TZ code"\r
113 -test_expect_equal "$(_parse_time Fri Aug 3 23:06:06 2012)" "$(_date Fri Aug 3 23:06:06 2012)"\r
114 +test_begin_subtest "Date parser tests"\r
115 +cat <<EOF > INPUT\r
116 +now          -> Tue Jan 11 11:11:00 +0000 2011\r
117 +2010-1-1     -> parse_time_string() error: 5\r
118 +Jan 2        -> Sat Jan 02 11:11:00 +0000 2010   # Why 2010?\r
119 +Mon          -> Mon Jan 10 11:11:00 +0000 2011\r
120 +last Friday  -> parse_time_string() error: 4\r
121 +2 hours ago  -> parse_time_string() error: 1\r
122 +last month   -> Sat Dec 11 11:11:00 +0000 2010\r
123 +month ago    -> parse_time_string() error: 1\r
124 +8am          -> Tue Jan 11 08:00:00 +0000 2011\r
125 +9:15         -> Tue Jan 11 09:15:00 +0000 2011\r
126 +12:34        -> Tue Jan 11 12:34:00 +0000 2011\r
127 +monday       -> Mon Jan 10 11:11:00 +0000 2011\r
128 +yesterday    -> Mon Jan 10 11:11:00 +0000 2011\r
129 +tomorrow     -> parse_time_string() error: 1\r
130 +             -> Tue Jan 11 11:11:00 +0000 2011 # Shouldn't empty string return an error???\r
131  \r
132 -test_begin_subtest "date(1) --rfc-2822 format"\r
133 -test_expect_equal "$(_parse_time Fri, 03 Aug 2012 23:07:46 +0100)" "$(_date Fri, 03 Aug 2012 23:07:46 +0100)"\r
134 +Aug 3 23:06:06 2012             -> Fri Aug 03 23:06:06 +0000 2012 # date(1) default format without TZ code\r
135 +Fri, 03 Aug 2012 23:07:46 +0100 -> Fri Aug 03 22:07:46 +0000 2012 # rfc-2822\r
136 +2012-08-03 23:09:37+03:00       -> Fri Aug 03 20:09:37 +0000 2012 # rfc-3339 seconds\r
137  \r
138 -test_begin_subtest "date(1) --rfc=3339=seconds format"\r
139 -test_expect_equal "$(_parse_time 2012-08-03 23:09:37+03:00)" "$(_date 2012-08-03 23:09:37+03:00)"\r
140 +10s           -> Tue Jan 11 11:10:50 +0000 2011\r
141 +19701223s     -> Wed Dec 23 11:10:59 +0000 1970 # Surprising - number is parsed as date and 's' as '1 second'\r
142 +19701223      -> Wed Dec 23 11:11:00 +0000 1970\r
143 +\r
144 +19701223 +0100 -> Wed Dec 23 11:11:00 +0000 1970 # Timezone is ignored without an error\r
145 +\r
146 +today ^-> Wed Jan 12 00:00:00 +0000 2011 # This should be 11 23:59:59\r
147 +today v-> Tue Jan 11 00:00:00 +0000 2011\r
148 +\r
149 +thisweek ^-> Sun Jan 16 00:00:00 +0000 2011  # This should be Sunday 23:59:59\r
150 +thisweek v-> Sun Jan 09 00:00:00 +0000 2011  # This should be Monday 00:00:00\r
151 +\r
152 +two months ago-> parse_time_string() error: 1 # Comments in the code suggest that this is supported\r
153 +two months -> Thu Nov 11 11:11:00 +0000 2010\r
154 +\r
155 +1348569850 -> parse_time_string() error: 4 # Seconds since epoch not yet supported? Backward compatibility in notmuch???\r
156 +10 -> parse_time_string() error: 4 # Seconds since epoch?\r
157 +EOF\r
158 +\r
159 +${TEST_DIRECTORY}/parse-time --now="Tue Jan 11 11:11:00 +0000 2011" < INPUT > OUTPUT\r
160 +test_expect_equal_file INPUT OUTPUT\r
161  \r
162  test_done\r
163 diff --git a/test/parse-time.c b/test/parse-time.c\r
164 index b4de76b..0415f49 100644\r
165 --- a/test/parse-time.c\r
166 +++ b/test/parse-time.c\r
167 @@ -18,59 +18,47 @@\r
168   * Author: Jani Nikula <jani@nikula.org>\r
169   */\r
170  \r
171 +\r
172 +#define _XOPEN_SOURCE 500       /* for strptime() and snprintf() */\r
173  #include <getopt.h>\r
174  #include <stdio.h>\r
175  #include <stdlib.h>\r
176  #include <string.h>\r
177 +#include <time.h>\r
178  \r
179  #include "parse-time-string.h"\r
180  \r
181 -/*\r
182 - * concat argv[start]...argv[end - 1], separating them by a single\r
183 - * space, to a malloced string\r
184 - */\r
185 -static char *\r
186 -concat_args (int start, int end, char *argv[])\r
187 -{\r
188 -    int i;\r
189 -    size_t len = 1;\r
190 -    char *p;\r
191 -\r
192 -    for (i = start; i < end; i++)\r
193 -       len += strlen (argv[i]) + 1;\r
194 -\r
195 -    p = malloc (len);\r
196 -    if (!p)\r
197 -       return NULL;\r
198 -\r
199 -    *p = 0;\r
200 -\r
201 -    for (i = start; i < end; i++) {\r
202 -       if (i != start)\r
203 -           strcat (p, " ");\r
204 -       strcat (p, argv[i]);\r
205 -    }\r
206 -\r
207 -    return p;\r
208 -}\r
209 -\r
210  #define DEFAULT_FORMAT "%a %b %d %T %z %Y"\r
211  \r
212  static void\r
213  usage (const char *name)\r
214  {\r
215 -    printf ("Usage: %s [options ...] <date/time>\n\n", name);\r
216 +    printf ("Usage: %s [options ...]\n\n", name);\r
217      printf (\r
218 -       "Parse <date/time> and display it in given format.\n\n"\r
219 -       "  -f, --format=FMT output format, FMT according to strftime(3)\n"\r
220 -       "                   (default: \"%s\")\n"\r
221 -       "  -n, --now=N      use N seconds since epoch as now (default: now)\n"\r
222 -       "  -u, --up         round result up (default: no rounding)\n"\r
223 -       "  -d, --down       round result down (default: no rounding)\n"\r
224 -       "  -h, --help       print this help\n",\r
225 +       "Parse date/time read from stdin and display it in given format.\n\n"\r
226 +       "  -f, --format=FMT output format for dates and input format for --now,\n"\r
227 +        "                   FMT according to strftime(3) (default: \"%s\")\n"\r
228 +       "  -n, --now=N      reference date in FMT (default: now)\n"\r
229 +       "  -h, --help       print this help\n"\r
230 +       "\n"\r
231 +       "stdin should contain one date/time per line in the following format:\n"\r
232 +       "  <date/time> [ <arrow> [ comment ] ]\n"\r
233 +       "where <arrow> determines the operation performed on the <date/time>.\n"\r
234 +       "It can be one of '->', '^->', 'v->' meaning convert, convert and round\n"\r
235 +       "up, convert and round down, respectively.\n",\r
236         DEFAULT_FORMAT);\r
237  }\r
238  \r
239 +static const char *\r
240 +get_round_str (int round)\r
241 +{\r
242 +    switch (round) {\r
243 +    case PARSE_TIME_ROUND_UP:   return "^";\r
244 +    case PARSE_TIME_ROUND_DOWN: return "v";\r
245 +    default:                   return "";\r
246 +    }\r
247 +}\r
248 +\r
249  int\r
250  main (int argc, char *argv[])\r
251  {\r
252 @@ -79,14 +67,10 @@ main (int argc, char *argv[])\r
253      time_t result;\r
254      time_t now;\r
255      time_t *nowp = NULL;\r
256 -    char *argstr;\r
257      int round = PARSE_TIME_NO_ROUND;\r
258 -    char buf[1024];\r
259      const char *format = DEFAULT_FORMAT;\r
260      struct option options[] = {\r
261         { "help",       no_argument,            NULL,   'h' },\r
262 -       { "up",         no_argument,            NULL,   'u' },\r
263 -       { "down",       no_argument,            NULL,   'd' },\r
264         { "format",     required_argument,      NULL,   'f' },\r
265         { "now",        required_argument,      NULL,   'n' },\r
266         { NULL, 0, NULL, 0 },\r
267 @@ -111,8 +95,13 @@ main (int argc, char *argv[])\r
268             round = PARSE_TIME_ROUND_DOWN;\r
269             break;\r
270         case 'n':\r
271 -           /* specify now in seconds since epoch */\r
272 -           now = (time_t) strtol (optarg, NULL, 10);\r
273 +           memset (&tm, 0, sizeof (tm));\r
274 +           char *parsed = strptime (optarg, format, &tm);\r
275 +           if (!parsed) {\r
276 +               fprintf (stderr, "Cannot parse reference date: %s\n", optarg);\r
277 +               return 1;\r
278 +           }\r
279 +           now = mktime (&tm);\r
280             if (now >= (time_t) 0)\r
281                 nowp = &now;\r
282             break;\r
283 @@ -124,22 +113,47 @@ main (int argc, char *argv[])\r
284         }\r
285      }\r
286  \r
287 -    argstr = concat_args (optind, argc, argv);\r
288 -    if (!argstr)\r
289 -       return 1;\r
290 -\r
291 -    r = parse_time_string (argstr, &result, nowp, round);\r
292 -\r
293 -    free (argstr);\r
294 -\r
295 -    if (r)\r
296 -       return 1;\r
297 -\r
298 -    if (!localtime_r (&result, &tm))\r
299 -       return 1;\r
300 -\r
301 -    strftime (buf, sizeof (buf), format, &tm);\r
302 -    printf ("%s\n", buf);\r
303 +    char input[BUFSIZ];\r
304 +    while (fgets (input, BUFSIZ, stdin) && input[0]) {\r
305 +       if (input[0] == '\n') {\r
306 +           printf ("\n");\r
307 +           continue;\r
308 +       }\r
309 +       char *arrow;\r
310 +       char *comment = strrchr (input, '#');\r
311 +       arrow = strstr (input, "->");\r
312 +       round = PARSE_TIME_NO_ROUND;\r
313 +       if (arrow > input) {\r
314 +           switch (arrow[-1]) {\r
315 +           case '^': round = PARSE_TIME_ROUND_UP; arrow--; break;\r
316 +           case 'v': round = PARSE_TIME_ROUND_DOWN; arrow--; break;\r
317 +           default: break;\r
318 +           }\r
319 +       }\r
320 +       if (arrow)\r
321 +           *arrow = 0;\r
322 +       else\r
323 +           arrow = input + strlen (input); /* XXX: comment is not handled */\r
324 +       while (arrow > input && arrow[-1] == '\n')\r
325 +           arrow--;\r
326 +       *arrow-- = 0;\r
327 +\r
328 +       r = parse_time_string (input, &result, nowp, round);\r
329 +       char resstr[BUFSIZ];\r
330 +       if (r)\r
331 +           snprintf (resstr, sizeof(resstr), "parse_time_string() error: %d", r);\r
332 +       else if (!localtime_r (&result, &tm))\r
333 +           snprintf (resstr, sizeof(resstr), "localtime(result) error");\r
334 +       else\r
335 +           strftime (resstr, sizeof (resstr), format, &tm);\r
336 +\r
337 +       char buf[BUFSIZ];\r
338 +       snprintf (buf, sizeof(buf), "%s%s-> %s", input, get_round_str (round), resstr);\r
339 +       if (!comment)\r
340 +           printf ("%s\n", buf);\r
341 +       else\r
342 +           printf ("%-*s%s", (int)(comment - input), buf, comment);\r
343 +    }\r
344  \r
345      return 0;\r
346  }\r