[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-10-03 Thread Jani Nikula
On Tue, 25 Sep 2012, Michal Sojka  wrote:
> Hello Jani,
>
> On Wed, Sep 12 2012, Jani Nikula wrote:
>> Add a date/time parser to notmuch, to be used for adding date range
>> query support for notmuch lib later on. Add the parser to a directory
>> of its own to make it independent of the rest of the notmuch code
>> base.
>
> First of all, thank you very much for pushing this towards mainline.
> This is definitely one of the features I miss in notmuch most.
>
> Some comments below.

Thanks for the comments; sorry about the delay in responding.

>>
>> Signed-off-by: Jani Nikula 
>> ---
>>  Makefile  |2 +-
>>  parse-time-string/Makefile|5 +
>>  parse-time-string/Makefile.local  |   12 +
>>  parse-time-string/README  |9 +
>>  parse-time-string/parse-time-string.c | 1484 
>> +
>>  parse-time-string/parse-time-string.h |   95 +++
>>  6 files changed, 1606 insertions(+), 1 deletion(-)
>>  create mode 100644 parse-time-string/Makefile
>>  create mode 100644 parse-time-string/Makefile.local
>>  create mode 100644 parse-time-string/README
>>  create mode 100644 parse-time-string/parse-time-string.c
>>  create mode 100644 parse-time-string/parse-time-string.h
>>
>> diff --git a/Makefile b/Makefile
>> index e5e2e3a..bb9c316 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -3,7 +3,7 @@
>>  all:
>>
>>  # List all subdirectories here. Each contains its own Makefile.local
>> -subdirs = compat completion emacs lib man util test
>> +subdirs = compat completion emacs lib man parse-time-string util test
>>
>>  # We make all targets depend on the Makefiles themselves.
>>  global_deps = Makefile Makefile.config Makefile.local \
>> diff --git a/parse-time-string/Makefile b/parse-time-string/Makefile
>> new file mode 100644
>> index 000..fa25832
>> --- /dev/null
>> +++ b/parse-time-string/Makefile
>> @@ -0,0 +1,5 @@
>> +all:
>> +$(MAKE) -C .. all
>> +
>> +.DEFAULT:
>> +$(MAKE) -C .. $@
>> diff --git a/parse-time-string/Makefile.local 
>> b/parse-time-string/Makefile.local
>> new file mode 100644
>> index 000..53534f3
>> --- /dev/null
>> +++ b/parse-time-string/Makefile.local
>> @@ -0,0 +1,12 @@
>> +dir := parse-time-string
>> +extra_cflags += -I$(srcdir)/$(dir)
>> +
>> +libparse-time-string_c_srcs := $(dir)/parse-time-string.c
>> +
>> +libparse-time-string_modules := $(libparse-time-string_c_srcs:.c=.o)
>> +
>> +$(dir)/libparse-time-string.a: $(libparse-time-string_modules)
>> +$(call quiet,AR) rcs $@ $^
>> +
>> +SRCS := $(SRCS) $(libparse-time-string_c_srcs)
>> +CLEAN := $(CLEAN) $(libparse-time-string_modules) 
>> $(dir)/libparse-time-string.a
>> diff --git a/parse-time-string/README b/parse-time-string/README
>> new file mode 100644
>> index 000..300ff1f
>> --- /dev/null
>> +++ b/parse-time-string/README
>> @@ -0,0 +1,9 @@
>> +PARSE TIME STRING
>> +=
>> +
>> +parse_time_string() is a date/time parser originally written for
>> +notmuch by Jani Nikula . However, there is nothing
>> +notmuch specific in it, and it should be kept reusable for other
>> +projects, and ready to be packaged on its own as needed. Please do not
>> +add dependencies on or references to anything notmuch specific. The
>> +parser should only depend on the C library.
>> diff --git a/parse-time-string/parse-time-string.c 
>> b/parse-time-string/parse-time-string.c
>> new file mode 100644
>> index 000..15cf686
>> --- /dev/null
>> +++ b/parse-time-string/parse-time-string.c
>> @@ -0,0 +1,1484 @@
>> +/*
>> + * parse time string - user friendly date and time parser
>> + * Copyright ? 2012 Jani Nikula
>> + *
>> + * This program is free software: you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation, either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see .
>> + *
>> + * Author: Jani Nikula 
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include "parse-time-string.h"
>> +
>> +/*
>> + * IMPLEMENTATION DETAILS
>> + *
>> + * At a high level, the parsing is done in two phases: 1) actual
>> + * parsing of the input string and storing the parsed data into
>> + * 'struct state', and 2) processing of the data in 'struct state'
>> + * according to current time (or provided reference time) and
>> + * rounding. This is evident in the main entry 

[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-10-03 Thread Michal Sojka
On Wed, Oct 03 2012, Jani Nikula wrote:
> On Tue, 25 Sep 2012, Michal Sojka  wrote:
>> Hello Jani,
>>
>> On Wed, Sep 12 2012, Jani Nikula wrote:
>>> Add a date/time parser to notmuch, to be used for adding date range
>>> query support for notmuch lib later on. Add the parser to a directory
>>> of its own to make it independent of the rest of the notmuch code
>>> base.
>>
>> First of all, thank you very much for pushing this towards mainline.
>> This is definitely one of the features I miss in notmuch most.
>>
>> Some comments below.
>
> Thanks for the comments; sorry about the delay in responding.

No problem :)

[...]

>>> +/**
>>> + * parse_time_string() - user friendly date and time parser
>>> + * @s: string to parse
>>> + * @t: pointer to time_t to store parsed time in
>>> + * @now:   pointer to time_t containing reference date/time, or NULL
>>> + * @round: PARSE_TIME_NO_ROUND, PARSE_TIME_ROUND_DOWN, or
>>> + * PARSE_TIME_ROUND_UP
>>> + *
>>> + * Parse a date/time string 's' and store the parsed date/time result
>>> + * in 't'.
>>> + *
>>> + * A reference date/time is used for determining the "date/time units"
>>> + * (roughly equivalent to struct tm members) not specified by 's'. If
>>> + * 'now' is non-NULL, it must contain a pointer to a time_t to be used
>>> + * as reference date/time. Otherwise, the current time is used.
>>> + *
>>> + * If 's' does not specify a full date/time, the 'round' parameter
>>> + * specifies if and how the result should be rounded as follows:
>>> + *
>>> + *   PARSE_TIME_NO_ROUND: All date/time units that are not specified
>>> + *   by 's' are set to the corresponding unit derived from the
>>> + *   reference date/time.
>>> + *
>>> + *   PARSE_TIME_ROUND_DOWN: All date/time units that are more accurate
>>> + *   than the most accurate unit specified by 's' are set to the
>>> + *   smallest valid value for that unit. Rest of the unspecified units
>>> + *   are set as in PARSE_TIME_NO_ROUND.
>>> + *
>>> + *   PARSE_TIME_ROUND_UP: All date/time units that are more accurate
>>> + *   than the most accurate unit specified by 's' are set to the
>>> + *   smallest valid value for that unit. The most accurate unit
>>> + *   specified by 's' is incremented by one (and this is rolled over
>>> + *   to the less accurate units as necessary). Rest of the unspecified
>>> + *   units are set as in PARSE_TIME_NO_ROUND.
>>
>> Why you round down and increase the most accurate unit? If I want to see
>> emails that were send yesterday, I do not want to see any email that was
>> sent the first second of today. (OK, I know that this is slightly easier
>> to implement)
>
> It's easy to agree that yesterday's messages should not include messages
> from the first second of today. It's not even too difficult to implement
> that. But doing that in this API would feel like rounding 0.6 up and
> getting 0.... as a result.
>
> I'll look at adding a separate rounding mode to keep the API generic
> while better support the sole user of the API.

I agree that the operation I want here should not be called rounding.
Maybe, you can use a term from set theory: supremum or prehaps maximum
(seconds are countable).

Cheers,
-Michal


Re: [PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-10-03 Thread Michal Sojka
On Wed, Oct 03 2012, Jani Nikula wrote:
 On Tue, 25 Sep 2012, Michal Sojka sojk...@fel.cvut.cz wrote:
 Hello Jani,

 On Wed, Sep 12 2012, Jani Nikula wrote:
 Add a date/time parser to notmuch, to be used for adding date range
 query support for notmuch lib later on. Add the parser to a directory
 of its own to make it independent of the rest of the notmuch code
 base.

 First of all, thank you very much for pushing this towards mainline.
 This is definitely one of the features I miss in notmuch most.

 Some comments below.

 Thanks for the comments; sorry about the delay in responding.

No problem :)

[...]

 +/**
 + * parse_time_string() - user friendly date and time parser
 + * @s: string to parse
 + * @t: pointer to time_t to store parsed time in
 + * @now:   pointer to time_t containing reference date/time, or NULL
 + * @round: PARSE_TIME_NO_ROUND, PARSE_TIME_ROUND_DOWN, or
 + * PARSE_TIME_ROUND_UP
 + *
 + * Parse a date/time string 's' and store the parsed date/time result
 + * in 't'.
 + *
 + * A reference date/time is used for determining the date/time units
 + * (roughly equivalent to struct tm members) not specified by 's'. If
 + * 'now' is non-NULL, it must contain a pointer to a time_t to be used
 + * as reference date/time. Otherwise, the current time is used.
 + *
 + * If 's' does not specify a full date/time, the 'round' parameter
 + * specifies if and how the result should be rounded as follows:
 + *
 + *   PARSE_TIME_NO_ROUND: All date/time units that are not specified
 + *   by 's' are set to the corresponding unit derived from the
 + *   reference date/time.
 + *
 + *   PARSE_TIME_ROUND_DOWN: All date/time units that are more accurate
 + *   than the most accurate unit specified by 's' are set to the
 + *   smallest valid value for that unit. Rest of the unspecified units
 + *   are set as in PARSE_TIME_NO_ROUND.
 + *
 + *   PARSE_TIME_ROUND_UP: All date/time units that are more accurate
 + *   than the most accurate unit specified by 's' are set to the
 + *   smallest valid value for that unit. The most accurate unit
 + *   specified by 's' is incremented by one (and this is rolled over
 + *   to the less accurate units as necessary). Rest of the unspecified
 + *   units are set as in PARSE_TIME_NO_ROUND.

 Why you round down and increase the most accurate unit? If I want to see
 emails that were send yesterday, I do not want to see any email that was
 sent the first second of today. (OK, I know that this is slightly easier
 to implement)

 It's easy to agree that yesterday's messages should not include messages
 from the first second of today. It's not even too difficult to implement
 that. But doing that in this API would feel like rounding 0.6 up and
 getting 0.... as a result.

 I'll look at adding a separate rounding mode to keep the API generic
 while better support the sole user of the API.

I agree that the operation I want here should not be called rounding.
Maybe, you can use a term from set theory: supremum or prehaps maximum
(seconds are countable).

Cheers,
-Michal
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-25 Thread Michal Sojka
Hello Jani,

On Wed, Sep 12 2012, Jani Nikula wrote:
> Add a date/time parser to notmuch, to be used for adding date range
> query support for notmuch lib later on. Add the parser to a directory
> of its own to make it independent of the rest of the notmuch code
> base.

First of all, thank you very much for pushing this towards mainline.
This is definitely one of the features I miss in notmuch most.

Some comments below.

>
> Signed-off-by: Jani Nikula 
> ---
>  Makefile  |2 +-
>  parse-time-string/Makefile|5 +
>  parse-time-string/Makefile.local  |   12 +
>  parse-time-string/README  |9 +
>  parse-time-string/parse-time-string.c | 1484 
> +
>  parse-time-string/parse-time-string.h |   95 +++
>  6 files changed, 1606 insertions(+), 1 deletion(-)
>  create mode 100644 parse-time-string/Makefile
>  create mode 100644 parse-time-string/Makefile.local
>  create mode 100644 parse-time-string/README
>  create mode 100644 parse-time-string/parse-time-string.c
>  create mode 100644 parse-time-string/parse-time-string.h
>
> diff --git a/Makefile b/Makefile
> index e5e2e3a..bb9c316 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -3,7 +3,7 @@
>  all:
>
>  # List all subdirectories here. Each contains its own Makefile.local
> -subdirs = compat completion emacs lib man util test
> +subdirs = compat completion emacs lib man parse-time-string util test
>
>  # We make all targets depend on the Makefiles themselves.
>  global_deps = Makefile Makefile.config Makefile.local \
> diff --git a/parse-time-string/Makefile b/parse-time-string/Makefile
> new file mode 100644
> index 000..fa25832
> --- /dev/null
> +++ b/parse-time-string/Makefile
> @@ -0,0 +1,5 @@
> +all:
> + $(MAKE) -C .. all
> +
> +.DEFAULT:
> + $(MAKE) -C .. $@
> diff --git a/parse-time-string/Makefile.local 
> b/parse-time-string/Makefile.local
> new file mode 100644
> index 000..53534f3
> --- /dev/null
> +++ b/parse-time-string/Makefile.local
> @@ -0,0 +1,12 @@
> +dir := parse-time-string
> +extra_cflags += -I$(srcdir)/$(dir)
> +
> +libparse-time-string_c_srcs := $(dir)/parse-time-string.c
> +
> +libparse-time-string_modules := $(libparse-time-string_c_srcs:.c=.o)
> +
> +$(dir)/libparse-time-string.a: $(libparse-time-string_modules)
> + $(call quiet,AR) rcs $@ $^
> +
> +SRCS := $(SRCS) $(libparse-time-string_c_srcs)
> +CLEAN := $(CLEAN) $(libparse-time-string_modules) 
> $(dir)/libparse-time-string.a
> diff --git a/parse-time-string/README b/parse-time-string/README
> new file mode 100644
> index 000..300ff1f
> --- /dev/null
> +++ b/parse-time-string/README
> @@ -0,0 +1,9 @@
> +PARSE TIME STRING
> +=
> +
> +parse_time_string() is a date/time parser originally written for
> +notmuch by Jani Nikula . However, there is nothing
> +notmuch specific in it, and it should be kept reusable for other
> +projects, and ready to be packaged on its own as needed. Please do not
> +add dependencies on or references to anything notmuch specific. The
> +parser should only depend on the C library.
> diff --git a/parse-time-string/parse-time-string.c 
> b/parse-time-string/parse-time-string.c
> new file mode 100644
> index 000..15cf686
> --- /dev/null
> +++ b/parse-time-string/parse-time-string.c
> @@ -0,0 +1,1484 @@
> +/*
> + * parse time string - user friendly date and time parser
> + * Copyright ? 2012 Jani Nikula
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + *
> + * Author: Jani Nikula 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "parse-time-string.h"
> +
> +/*
> + * IMPLEMENTATION DETAILS
> + *
> + * At a high level, the parsing is done in two phases: 1) actual
> + * parsing of the input string and storing the parsed data into
> + * 'struct state', and 2) processing of the data in 'struct state'
> + * according to current time (or provided reference time) and
> + * rounding. This is evident in the main entry point function
> + * parse_time_string().
> + *
> + * 1) The parsing phase - parse_input()
> + *
> + * Parsing is greedy and happens from left to right. The parsing is as
> + * unambiguous as possible; only unambiguous date/time formats are
> + * 

[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-17 Thread Jani Nikula
On Mon, 17 Sep 2012, Michal Nazarewicz  wrote:
> Bison can do a lot of weird stuff including modifying how lexer
> interpretes tokens even while parsing given grammar rule.

I'll just have to take your word for it.

> I'm sorry.  I sometime tend to go into extremes with my statements, so
> yes, the ?totally unreadable? was a over statement on my part.

Okay.

> My point was however that parsing is a solved problem, and for
> non-trivial parsers one needs to ask herself whether it's worth trying
> to implement the logic, or maybe using a parser generator is just
> simpler.

If there's something non-trivial about parsing dates and times, it's not
the actual parsing. It's not a well defined grammar. And judging by the
number of date parsers available that would be suitable for notmuch, as
a library, parsing dates is not a solved problem.

> And in this particular case, my feeling is that bison is easier to read
> and modify.
>
> To add some merit to my statement, I attach a bison parser.

And there are people out there writing compilers without a parser
generator... [1] But using a parser generator or not is really not the
issue here, whichever has more merit. The issue is adding suitable date
range queries to notmuch.

I have submitted patches to do just that. I don't intend to rework them
much anymore. It's always interesting in the beginning, but adding the
last bits of polish and fixing the corner cases can get a bit
tedious. You know how it is. At this point, I'd just like to have the
feature in notmuch.

So I don't know. I guess I want to say, please submit patches to add the
feature, with polish, and not to prove a point, damnit. I have no issues
with promoting whichever approach is the best in the end.


BR,
Jani.


[1] http://git.kernel.org/?p=devel/sparse/sparse.git


[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-17 Thread Michal Nazarewicz
> On Thu, 13 Sep 2012, Michal Nazarewicz  wrote:
>> Have you consider doing the same in bison?  I consider the code totally
>> unreadable and unmaintainable.

On Thu, Sep 13 2012, Jani Nikula wrote:
> I do not think you could easily do everything that this parser does in
> bison. But then I'm not an expert in bison, and I have zero ambition to
> become one. So I'm biased, and I'm open about it.

Bison can do a lot of weird stuff including modifying how lexer
interpretes tokens even while parsing given grammar rule.

> Even so, if you're suggesting doing this in bison would make this
> totally readable and maintainable, I urge you to have a good look at
> [1]. Note that it also does less in more lines of code. (And using it
> as-is in notmuch has pretty much been turned down in the past.)
>
> Finally, I also suggest you actually read and review the code, pointing
> out concrete issues in readability or maintainability that you
> see. Especially since an earlier version has received comment "[I]t
> looks very nice to me. It is pleasantly nice to read." [2]. What you're
> doing is worthless bikeshedding otherwise.

I'm sorry.  I sometime tend to go into extremes with my statements, so
yes, the ?totally unreadable? was a over statement on my part.

My point was however that parsing is a solved problem, and for
non-trivial parsers one needs to ask herself whether it's worth trying
to implement the logic, or maybe using a parser generator is just
simpler.

And in this particular case, my feeling is that bison is easier to read
and modify.

To add some merit to my statement, I attach a bison parser.

It supports ranges as so:
  the specific moment with duration dependent
on specification.  How duration is figured out
is described in the next paragraph.
..dates >=  and < , so for instance
?yesterday..0? days yields results from yesterday.
..  dates < 
..dates >= 
++   a shorthand of ?.. + ?.
This is useful for things like: ?2012q1++2
quarters? which is equivalent to
?2012/01/01..2012/07/01?, ie. the first two
quarters of 2012.

It supports specifications as:
'@' 
Raw timestamp.  It's duration is one second.

 (seconds | minutes | hours | days | weeks | fortnights) [ago]
moves the date by given number of units in the future or
in the past (if ?ago? is given).   can be preceded
by sign.

This specification's duration is whatever unit was used,
ie. one second, one minute, one hour, one day, one week
or one fortnight.  So ?7 days ago? and ?1 week ago?
specify the same moment, but they hay different
durations.

 (months | quarters | years) [ago]
Like above, but calendar months are used which do not
always have the same length.  If applying the offset
ends up with a day of the month out of range, the day
is capped to the last day of the month.

yesterday
Moves one day back. [*]  Note that because of [*] this
is not quivalent to ?-1day?.
/MM/DD
-MM-DD
MM-DD-
DD Month 
Month DD 
Sets date accordingly. [*] ?Month? is a human readable
month name.
Month [DD] []
If either day or year is missing, given component of the
date is not changed. [*]  Also, if day is missing, the
duration is set to one month rather than one day (but
see caveats described in [*]).
 q Q
Sets date to the beginning of quarter Q, ie. ?2012q2? is
roughly the same as ?2012/04/01?. [*] Sets duration to
three moths but see caveats described in [*].

midnight | noon
Sets time to 0:00:00 and 12:00:00 respectively.   Has
duration of 1 hour.
HH:MM:SS [am | pm]
HH:MM[am | pm]
HH   (am | pm)
Sets time accordingly with the part that is not
specified set to zero.  Duration depends on how many
components are missing, ie. ?HH (am|pm)? has a duration of
on hour, ?HH:MM? has a duration of one minute and
?HH:MM:SS? has a duration of one second.

[*] Formats specifying the date will zero the time to midnight unless
the time has already been specified (ie. ?yesterday? is roughly the
same as ?yesterday midnight?, but ?noon yesterday? still keeps time
as noon.

Also, if the time has not been specified, those formats will set
duration to one day (with two exception), so ?yesterday? has

Re: [PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-17 Thread Michal Nazarewicz
 On Thu, 13 Sep 2012, Michal Nazarewicz min...@mina86.com wrote:
 Have you consider doing the same in bison?  I consider the code totally
 unreadable and unmaintainable.

On Thu, Sep 13 2012, Jani Nikula wrote:
 I do not think you could easily do everything that this parser does in
 bison. But then I'm not an expert in bison, and I have zero ambition to
 become one. So I'm biased, and I'm open about it.

Bison can do a lot of weird stuff including modifying how lexer
interpretes tokens even while parsing given grammar rule.

 Even so, if you're suggesting doing this in bison would make this
 totally readable and maintainable, I urge you to have a good look at
 [1]. Note that it also does less in more lines of code. (And using it
 as-is in notmuch has pretty much been turned down in the past.)

 Finally, I also suggest you actually read and review the code, pointing
 out concrete issues in readability or maintainability that you
 see. Especially since an earlier version has received comment [I]t
 looks very nice to me. It is pleasantly nice to read. [2]. What you're
 doing is worthless bikeshedding otherwise.

I'm sorry.  I sometime tend to go into extremes with my statements, so
yes, the “totally unreadable” was a over statement on my part.

My point was however that parsing is a solved problem, and for
non-trivial parsers one needs to ask herself whether it's worth trying
to implement the logic, or maybe using a parser generator is just
simpler.

And in this particular case, my feeling is that bison is easier to read
and modify.

To add some merit to my statement, I attach a bison parser.

It supports ranges as so:
date  the specific moment with duration dependent
on specification.  How duration is figured out
is described in the next paragraph.
from..todates = from and  to, so for instance
“yesterday..0” days yields results from yesterday.
..to  dates  to
from..dates = from
from++dur   a shorthand of “from..from + dur”.
This is useful for things like: “2012q1++2
quarters” which is equivalent to
“2012/01/01..2012/07/01”, ie. the first two
quarters of 2012.

It supports specifications as:
'@' num
Raw timestamp.  It's duration is one second.

num (seconds | minutes | hours | days | weeks | fortnights) [ago]
moves the date by given number of units in the future or
in the past (if “ago” is given).  num can be preceded
by sign.

This specification's duration is whatever unit was used,
ie. one second, one minute, one hour, one day, one week
or one fortnight.  So “7 days ago” and “1 week ago”
specify the same moment, but they hay different
durations.

num (months | quarters | years) [ago]
Like above, but calendar months are used which do not
always have the same length.  If applying the offset
ends up with a day of the month out of range, the day
is capped to the last day of the month.

yesterday
Moves one day back. [*]  Note that because of [*] this
is not quivalent to “-1day”.
/MM/DD
-MM-DD
MM-DD-
DD Month 
Month DD 
Sets date accordingly. [*] “Month” is a human readable
month name.
Month [DD] []
If either day or year is missing, given component of the
date is not changed. [*]  Also, if day is missing, the
duration is set to one month rather than one day (but
see caveats described in [*]).
 q Q
Sets date to the beginning of quarter Q, ie. “2012q2” is
roughly the same as “2012/04/01”. [*] Sets duration to
three moths but see caveats described in [*].

midnight | noon
Sets time to 0:00:00 and 12:00:00 respectively.   Has
duration of 1 hour.
HH:MM:SS [am | pm]
HH:MM[am | pm]
HH   (am | pm)
Sets time accordingly with the part that is not
specified set to zero.  Duration depends on how many
components are missing, ie. “HH (am|pm)” has a duration of
on hour, “HH:MM” has a duration of one minute and
“HH:MM:SS” has a duration of one second.

[*] Formats specifying the date will zero the time to midnight unless
the time has already been specified (ie. “yesterday” is roughly the
same as “yesterday midnight”, but “noon yesterday” still keeps time
as noon.

Also, if the time has not been specified, those formats will set
duration 

[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-13 Thread Tomi Ollila
On Thu, Sep 13 2012, Michal Nazarewicz  wrote:

> On Wed, Sep 12 2012, Jani Nikula  wrote:
>> Add a date/time parser to notmuch, to be used for adding date range
>> query support for notmuch lib later on. Add the parser to a directory
>> of its own to make it independent of the rest of the notmuch code
>> base.
>>
>> Signed-off-by: Jani Nikula 
>
> Have you consider doing the same in bison?  I consider the code totally
> unreadable and unmaintainable.

Well, I don't find this code 'unreadable', perhaps it depends how you
define it ;)

This functionality has been in 'work-in-progress' for a long time. I think
the interface how this (separate library) is hooked to notmuch is sane.
Also, my 'hunch' is that this is maintainable enough (and Jani will do
all expected 'zero' maintenaince issues that will appear). If, in the
future, there is enough desire for internationalization then Someone(TM)
may see the way to do it.

But, for the time being I applause the hard work Jani has put into 
this library and as it is much better what we have now (i.e. nothing)
I am going to start testing this (and drop my current wrapper which
I've been using to search using relative times)...

It might be interesting to see this implemented in Bison but just for
the sake of it I don't think it is worth of it. Maybe, someday...,
Someone Else(tm) does that. The interface should allow to make drop-in
replacement for this parser...

Tomi


>
> -- 
> Best regards, _ _
> .o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
> ..o | Computer Science,  Micha? ?mina86? Nazarewicz(o o)
> ooo + google.com>--ooO--(_)--Ooo--___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-13 Thread Jani Nikula
On Thu, 13 Sep 2012, Michal Nazarewicz  wrote:
> On Wed, Sep 12 2012, Jani Nikula  wrote:
>> Add a date/time parser to notmuch, to be used for adding date range
>> query support for notmuch lib later on. Add the parser to a directory
>> of its own to make it independent of the rest of the notmuch code
>> base.
>>
>> Signed-off-by: Jani Nikula 
>
> Have you consider doing the same in bison?  I consider the code totally
> unreadable and unmaintainable.

I do not think you could easily do everything that this parser does in
bison. But then I'm not an expert in bison, and I have zero ambition to
become one. So I'm biased, and I'm open about it.

Even so, if you're suggesting doing this in bison would make this
totally readable and maintainable, I urge you to have a good look at
[1]. Note that it also does less in more lines of code. (And using it
as-is in notmuch has pretty much been turned down in the past.)

Finally, I also suggest you actually read and review the code, pointing
out concrete issues in readability or maintainability that you
see. Especially since an earlier version has received comment "[I]t
looks very nice to me. It is pleasantly nice to read." [2]. What you're
doing is worthless bikeshedding otherwise.

BR,
Jani.

[1] 
http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob_plain;f=lib/parse-datetime.y
[2] id:"87mx86dlul.fsf at qmul.ac.uk"


[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-13 Thread Michal Nazarewicz
On Wed, Sep 12 2012, Jani Nikula  wrote:
> Add a date/time parser to notmuch, to be used for adding date range
> query support for notmuch lib later on. Add the parser to a directory
> of its own to make it independent of the rest of the notmuch code
> base.
>
> Signed-off-by: Jani Nikula 

Have you consider doing the same in bison?  I consider the code totally
unreadable and unmaintainable.

-- 
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Micha? ?mina86? Nazarewicz(o o)
ooo +--ooO--(_)--Ooo--
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: 



[PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-13 Thread Jani Nikula
Add a date/time parser to notmuch, to be used for adding date range
query support for notmuch lib later on. Add the parser to a directory
of its own to make it independent of the rest of the notmuch code
base.

Signed-off-by: Jani Nikula 
---
 Makefile  |2 +-
 parse-time-string/Makefile|5 +
 parse-time-string/Makefile.local  |   12 +
 parse-time-string/README  |9 +
 parse-time-string/parse-time-string.c | 1484 +
 parse-time-string/parse-time-string.h |   95 +++
 6 files changed, 1606 insertions(+), 1 deletion(-)
 create mode 100644 parse-time-string/Makefile
 create mode 100644 parse-time-string/Makefile.local
 create mode 100644 parse-time-string/README
 create mode 100644 parse-time-string/parse-time-string.c
 create mode 100644 parse-time-string/parse-time-string.h

diff --git a/Makefile b/Makefile
index e5e2e3a..bb9c316 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 all:

 # List all subdirectories here. Each contains its own Makefile.local
-subdirs = compat completion emacs lib man util test
+subdirs = compat completion emacs lib man parse-time-string util test

 # We make all targets depend on the Makefiles themselves.
 global_deps = Makefile Makefile.config Makefile.local \
diff --git a/parse-time-string/Makefile b/parse-time-string/Makefile
new file mode 100644
index 000..fa25832
--- /dev/null
+++ b/parse-time-string/Makefile
@@ -0,0 +1,5 @@
+all:
+   $(MAKE) -C .. all
+
+.DEFAULT:
+   $(MAKE) -C .. $@
diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local
new file mode 100644
index 000..53534f3
--- /dev/null
+++ b/parse-time-string/Makefile.local
@@ -0,0 +1,12 @@
+dir := parse-time-string
+extra_cflags += -I$(srcdir)/$(dir)
+
+libparse-time-string_c_srcs := $(dir)/parse-time-string.c
+
+libparse-time-string_modules := $(libparse-time-string_c_srcs:.c=.o)
+
+$(dir)/libparse-time-string.a: $(libparse-time-string_modules)
+   $(call quiet,AR) rcs $@ $^
+
+SRCS := $(SRCS) $(libparse-time-string_c_srcs)
+CLEAN := $(CLEAN) $(libparse-time-string_modules) $(dir)/libparse-time-string.a
diff --git a/parse-time-string/README b/parse-time-string/README
new file mode 100644
index 000..300ff1f
--- /dev/null
+++ b/parse-time-string/README
@@ -0,0 +1,9 @@
+PARSE TIME STRING
+=
+
+parse_time_string() is a date/time parser originally written for
+notmuch by Jani Nikula . However, there is nothing
+notmuch specific in it, and it should be kept reusable for other
+projects, and ready to be packaged on its own as needed. Please do not
+add dependencies on or references to anything notmuch specific. The
+parser should only depend on the C library.
diff --git a/parse-time-string/parse-time-string.c 
b/parse-time-string/parse-time-string.c
new file mode 100644
index 000..15cf686
--- /dev/null
+++ b/parse-time-string/parse-time-string.c
@@ -0,0 +1,1484 @@
+/*
+ * parse time string - user friendly date and time parser
+ * Copyright ? 2012 Jani Nikula
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ *
+ * Author: Jani Nikula 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "parse-time-string.h"
+
+/*
+ * IMPLEMENTATION DETAILS
+ *
+ * At a high level, the parsing is done in two phases: 1) actual
+ * parsing of the input string and storing the parsed data into
+ * 'struct state', and 2) processing of the data in 'struct state'
+ * according to current time (or provided reference time) and
+ * rounding. This is evident in the main entry point function
+ * parse_time_string().
+ *
+ * 1) The parsing phase - parse_input()
+ *
+ * Parsing is greedy and happens from left to right. The parsing is as
+ * unambiguous as possible; only unambiguous date/time formats are
+ * accepted. Redundant or contradictory absolute date/time in the
+ * input (e.g. date specified multiple times/ways) is not
+ * accepted. Relative date/time on the other hand just accumulates if
+ * present multiple times (e.g. "5 days 5 days" just turns into 10
+ * days).
+ *
+ * Parsing decisions are made on the input format, not value. For
+ * example, "20/5/2005" fails because the recognized format here is
+ * MM/D/, even though the values would suggest DD/M/.
+ *

Re: [PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-13 Thread Michal Nazarewicz
On Wed, Sep 12 2012, Jani Nikula j...@nikula.org wrote:
 Add a date/time parser to notmuch, to be used for adding date range
 query support for notmuch lib later on. Add the parser to a directory
 of its own to make it independent of the rest of the notmuch code
 base.

 Signed-off-by: Jani Nikula j...@nikula.org

Have you consider doing the same in bison?  I consider the code totally
unreadable and unmaintainable.

-- 
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo--

pgpmpHXEOhpX7.pgp
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v3 2/9] parse-time-string: add a date/time parser to notmuch

2012-09-13 Thread Tomi Ollila
On Thu, Sep 13 2012, Michal Nazarewicz min...@mina86.com wrote:

 On Wed, Sep 12 2012, Jani Nikula j...@nikula.org wrote:
 Add a date/time parser to notmuch, to be used for adding date range
 query support for notmuch lib later on. Add the parser to a directory
 of its own to make it independent of the rest of the notmuch code
 base.

 Signed-off-by: Jani Nikula j...@nikula.org

 Have you consider doing the same in bison?  I consider the code totally
 unreadable and unmaintainable.

Well, I don't find this code 'unreadable', perhaps it depends how you
define it ;)

This functionality has been in 'work-in-progress' for a long time. I think
the interface how this (separate library) is hooked to notmuch is sane.
Also, my 'hunch' is that this is maintainable enough (and Jani will do
all expected 'zero' maintenaince issues that will appear). If, in the
future, there is enough desire for internationalization then Someone(TM)
may see the way to do it.

But, for the time being I applause the hard work Jani has put into 
this library and as it is much better what we have now (i.e. nothing)
I am going to start testing this (and drop my current wrapper which
I've been using to search using relative times)...

It might be interesting to see this implemented in Bison but just for
the sake of it I don't think it is worth of it. Maybe, someday...,
Someone Else(tm) does that. The interface should allow to make drop-in
replacement for this parser...

Tomi



 -- 
 Best regards, _ _
 .o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
 ..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
 ooo +email/xmpp: 
 m...@google.com--ooO--(_)--Ooo--___
 notmuch mailing list
 notmuch@notmuchmail.org
 http://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch