[notmuch] [PATCH 4/4] integrate keithp's date.c into the notmuch date parser and delete my previous own attempt
Sebastian Spaeth
Sebastian at SSpaeth.de
Tue Jan 26 03:43:41 PST 2010
Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
lib/database.cc | 84 ++++++++++--------------------------------------------
lib/date.c | 59 ++++++--------------------------------
lib/notmuch.h | 20 +++++++++++++
notmuch-new.c | 1 +
notmuch.1 | 33 +++++++++++----------
notmuch.c | 20 +++++++------
6 files changed, 74 insertions(+), 143 deletions(-)
diff --git a/lib/database.cc b/lib/database.cc
index b386e1a..78cd898 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -219,6 +219,8 @@ notmuch_status_to_string (notmuch_status_t status)
return "Erroneous NULL pointer";
case NOTMUCH_STATUS_TAG_TOO_LONG:
return "Tag value is too long (exceeds NOTMUCH_TAG_MAX)";
+ case NOTMUCH_STATUS_INVALID_DATE:
+ return "Date value did not parse to a valid date";
case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
return "Unbalanced number of calls to notmuch_message_freeze/thaw";
default:
@@ -497,83 +499,29 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
struct MaildateValueRangeProcessor : public Xapian::ValueRangeProcessor {
MaildateValueRangeProcessor() {}
- time_t
- parsedate(std::string &str, bool early) {
- /* Parse the date to a 'time_t', return NULL on error */
- /* possible time formats: YYYY-MM-DD, YYYY-MM, YYYY, */
- /* MM-DD (current month), DD (day in current month). */
- /* Uses start of time unit when 'early', end otherwise, e.g. */
- /* 2001:=2001-01-01:00:00:00 when 'early' or 2001-12-31:23:59:59 */
- bool now = false;
- struct tm *timeinfo;
- time_t timet;
- int year = 0, month = 0, day = 0;
-
- now = (str == "now");
-
- if (str.size() == 2) {
- /* We got just current day in month, parse & remove it */
- day = atoi(str.c_str());
- str.erase(0,2);
- }
-
- if (str.size() == 4 or str.size() > 5) {
- /* expect a year, parse & remove it */
- year = atoi(str.c_str());
- str.erase(0,5);
- }
-
- /* parse & remove month if there is sth left in the string */
- month = atoi(str.c_str());
- str.erase(0,3);
-
- /* Parse day if we have one left */
- if (str.size())
- day = atoi(str.c_str());
-
- if (!now && year == 0 && month == 0 && day == 0)
- // no expected time format
- return -1 ;
-
- timet = time(NULL); /* init timeinfo with current time */
- timeinfo = gmtime(&timet);
-
- if (!now) {
- /* add timeunit if !early (1 second too much, which we deduct later */
- if (!early) {
- if (year && !month) ++year; /* only year given */
- if (year && month && !day) ++month; /* year & month given */
- }
- if (year) timeinfo -> tm_year = year - 1900;
- if (month) timeinfo -> tm_mon = month - 1;
- if (day) timeinfo -> tm_mday = (early ? day : ++day);
- else timeinfo -> tm_mday = 1;
-
- timeinfo -> tm_hour = 0;
- timeinfo -> tm_min = 0;
- timeinfo -> tm_sec = (early ? 0 : -1); /* -1 sec if !early */
- }
- timet = mktime(timeinfo);
-
- return timet;
- }
-
Xapian::valueno operator()(std::string &begin, std::string &end) {
- time_t begintime, endtime;
+ time_t begin_first,begin_last, end_first, end_last;
+ int retval;
if (begin.substr(0, 5) != "date:")
return Xapian::BAD_VALUENO;
begin.erase(0, 5);
- begintime = parsedate(begin, true);
- endtime = parsedate(end, false);
+ retval = notmuch_parse_date(begin.c_str(), &begin_first, &begin_last, 0);
- if ((begintime == -1) || (endtime == -1))
- // parsedate failed, no valid time format
+ if (retval == NOTMUCH_STATUS_INVALID_DATE) {
+ fprintf(stderr,"Begin date failed to parse: %s",begin.c_str());
return Xapian::BAD_VALUENO;
+ }
+
+ retval = notmuch_parse_date(end.c_str(),&end_first,&end_last,begin_first);
+ if (retval == NOTMUCH_STATUS_INVALID_DATE) {
+ fprintf(stderr,"End date failed to parse: %s",end.c_str());
+ return Xapian::BAD_VALUENO;
+ }
- begin.assign(Xapian::sortable_serialise(begintime));
- end.assign(Xapian::sortable_serialise(endtime));
+ begin.assign(Xapian::sortable_serialise(begin_first));
+ end.assign(Xapian::sortable_serialise(end_last));
return NOTMUCH_VALUE_TIMESTAMP;
}
diff --git a/lib/date.c b/lib/date.c
index 09c5ef9..805a1d9 100644
--- a/lib/date.c
+++ b/lib/date.c
@@ -37,6 +37,7 @@ today(struct tm *result, time_t after) {
}
static int parse_today(const char *text, time_t *first, time_t *last, time_t after) {
+ (void)after; /*disable unused paramter warning*/
if (strcasecmp(text, "today") == 0) {
struct tm n;
today(&n, 0);
@@ -56,6 +57,7 @@ static int parse_yesterday(const char *text, time_t *first, time_t *last, time_t
return 0;
}
return 1;
+ (void)after; /*disable unused paramter warning*/
}
static int parse_thisweek(const char *text, time_t *first, time_t *last, time_t after) {
@@ -67,6 +69,7 @@ static int parse_thisweek(const char *text, time_t *first, time_t *last, time_t
return 0;
}
return 1;
+ (void)after; /*disable unused paramter warning*/
}
static int parse_lastweek(const char *text, time_t *first, time_t *last, time_t after) {
@@ -78,6 +81,7 @@ static int parse_lastweek(const char *text, time_t *first, time_t *last, time_t
return 0;
}
return 1;
+ (void)after; /*disable unused paramter warning*/
}
static int parse_thismonth(const char *text, time_t *first, time_t *last, time_t after) {
@@ -94,6 +98,7 @@ static int parse_thismonth(const char *text, time_t *first, time_t *last, time_t
return 0;
}
return 1;
+ (void)after; /*disable unused paramter warning*/
}
static int parse_lastmonth(const char *text, time_t *first, time_t *last, time_t after) {
@@ -115,6 +120,7 @@ static int parse_lastmonth(const char *text, time_t *first, time_t *last, time_t
return 0;
}
return 1;
+ (void)after; /*disable unused paramter warning*/
}
static const char *months[12][2] = {
@@ -308,6 +314,7 @@ static int parse_iso(const char *text, time_t *first, time_t *last, time_t after
return 0;
}
return 1;
+ (void)after; /*disable unused paramter warning*/
}
/* month[/day[/year]] */
@@ -396,8 +403,8 @@ static int (*parsers[])(const char *text, time_t *first, time_t *last, time_t af
0,
};
-static notmuch_status_t
-notmuch_one_date(const char *text, time_t *first, time_t *last, time_t after)
+notmuch_status_t
+notmuch_parse_date(const char *text, time_t *first, time_t *last, time_t after)
{
int i;
for (i = 0; parsers[i]; i++)
@@ -405,51 +412,3 @@ notmuch_one_date(const char *text, time_t *first, time_t *last, time_t after)
return NOTMUCH_STATUS_SUCCESS;
return NOTMUCH_STATUS_INVALID_DATE;
}
-
-notmuch_status_t
-notmuch_date(const char *text, time_t *first, time_t *last)
-{
- char *dots;
- char first_text[80], last_text[80];
- notmuch_status_t status;
- time_t first_first, first_last, last_first, last_last;
-
- if (strlen(text) > sizeof (first_text))
- return NOTMUCH_STATUS_INVALID_DATE;
- dots = strstr(text, "..");
- if (dots) {
- strncpy(first_text, text, dots - text);
- first_text[dots-text] = '\0';
- status = notmuch_one_date(first_text, &first_first, &first_last, 0);
- if (status)
- return status;
- status = notmuch_one_date(dots + 2, &last_first, &last_last, first_first);
- if (status)
- return status;
- *first = first_first;
- *last = last_last;
- return 0;
- }
- return notmuch_one_date(text, first, last, 0);
-}
-
-#if 1
-int
-main (int argc, char **argv)
-{
- int i;
- for (i = 1; i < argc; i++) {
- time_t first, last;
-
- if (notmuch_date(argv[i], &first, &last) == 0) {
- char first_string[80], last_string[80];
-
- ctime_r(&first, first_string);
- first_string[strlen(first_string)-1] = '\0';
- ctime_r(&last, last_string);
- last_string[strlen(last_string)-1] = '\0';
- printf ("%s: %s - %s\n", argv[i], first_string, last_string);
- }
- }
-}
-#endif
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 15c9db4..be474bf 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -78,6 +78,8 @@ typedef int notmuch_bool_t;
* NOTMUCH_STATUS_TAG_TOO_LONG: A tag value is too long (exceeds
* NOTMUCH_TAG_MAX)
*
+ * NOTMUCH_STATUS_INVALID_DATE: Date parsing failed
+ *
* NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: The notmuch_message_thaw
* function has been called more times than notmuch_message_freeze.
*
@@ -96,6 +98,7 @@ typedef enum _notmuch_status {
NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID,
NOTMUCH_STATUS_NULL_POINTER,
NOTMUCH_STATUS_TAG_TOO_LONG,
+ NOTMUCH_STATUS_INVALID_DATE,
NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
NOTMUCH_STATUS_LAST_STATUS
@@ -1086,6 +1089,23 @@ notmuch_filenames_advance (notmuch_filenames_t *filenames);
void
notmuch_filenames_destroy (notmuch_filenames_t *filenames);
+notmuch_status_t
+notmuch_parse_date(const char *text, time_t *first, time_t *last, time_t after);
+/* Parse a string into the first and last possible timestamps.
+ * It parses the possible formats and stops if one pattern matches.
+ * Keywords: 'today','yesterday','thisweek','lastweek','thismonth',
+ * 'lastmonth'
+ * Month-day : month[-day]] (month: January, Jan, or 1)\n"
+ * ISO format: year[-month[-day]]
+ * US format : month[/day[/year]]
+ *
+ * 'after' is used to fill in bits from context if left out, e.g. a
+ * 'date:2004..01' will find from 2004-01-01 through 2004-01-31
+ *
+ * Return values:
+ * NOTMUCH_STATUS_SUCCESS
+ * NOTMUCH_STATUS_INVALID_DATE: Error parsing the date string
+ */
NOTMUCH_END_DECLS
#endif
diff --git a/notmuch-new.c b/notmuch-new.c
index f25c71f..5da31c1 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -431,6 +431,7 @@ add_files_recursive (notmuch_database_t *notmuch,
ret = status;
goto DONE;
default:
+ case NOTMUCH_STATUS_INVALID_DATE:
case NOTMUCH_STATUS_FILE_ERROR:
case NOTMUCH_STATUS_NULL_POINTER:
case NOTMUCH_STATUS_TAG_TOO_LONG:
diff --git a/notmuch.1 b/notmuch.1
index 38379b1..175fe86 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -417,22 +417,23 @@ particular time range, (based on the Date: header) with a syntax of:
A
.B date
-can be specified in the following formats:
-.BR
-.B YYYY
-(e.g 2001 meaning since 2001, or through 2001, depending on whether it is the start or end). 2)
-.B YYYY-MM
-meaning from/to month MM in year YYYY, 3)
-.B YYYY-MM-DD
-(from/to that exact day) 4)
-.B MM-DD
-(from/to month/day in the current year) 5)
-.B DD
-(from/to day DD in current month). 6) the keyword
-.B now
-can be used to denote NOW (so a "05-01..now" finds all mails from May until now).
-.BR
-Formats can be mixed, so "date:2001..22" means from 2001-01-01 until the 22nd this months.
+can be specified in various formats. It parses the formats in this order and stops if one pattern matches:
+
+ Keywords:
+.B today,
+.B yesterday,
+.B thisweek,
+.B lastweek,
+.B thismonth,
+.B lastmonth.
+
+ Month-day: month[-day]] (month: "January", "Jan", 1)
+
+ ISO format: year[-month[-day]]
+
+ US format : month[/day[/year]]
+
+The date parser will try to fill in bits in the enddate from context if left out, e.g. a 'date:2004..01' will find from 2004-01-01 through 2004-01-31.
.SH SEE ALSO
The emacs-based interface to notmuch (available as
diff --git a/notmuch.c b/notmuch.c
index 808a370..b8fe01a 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -94,16 +94,18 @@ static const char search_terms_help[] =
"\t\tFinally, results can be restricted to only messages within a\n"
"\t\tparticular time range, (based on the Date: header) with a\n"
"\t\tsyntax of: date:<startdate>..<enddate>\n"
- "\t\tIt can be specified in the following formats:\n"
- "\t\tYYYY (e.g 2001 meaning since 2001, or through 2001, depending\n"
- "\t\ton whether it is the start or end). 2) YYYY-MM meaning from/to\n"
- "\t\tmonth MM in year YYYY, 3) YYYY-MM-DD (that exact day) 4)\n"
- "\t\tMM-DD (month/day in the current year) 5) DD (day DD in \n"
- "\t\tcurrent month). 6) the keyword 'now' can be used to denote\n"
- "\t\tNOW (so a 'date:05-01..now' finds all mails from May until now).\n"
"\n"
- "\t\tFormats can be mixed, so 'date:2001..22' means from 2001-01-01\n"
- "\t\tuntil the 22nd this months.\n"
+ "\t\tIt can be specified in the following formats, parsing will \n"
+ "\t\tstop if the first pattern matches:\n"
+ "\t\tKeywords: 'today','yesterday','thisweek','lastweek',\n"
+ "\t\t'thismonth', 'lastmonth'. \n"
+ "\t\tmonth-day : month[-day]] (month: January, Jan, or 1)\n"
+ "\t\tISO format: year[-month[-day]] (month: January, Jan, or 1)\n"
+ "\t\tUS format : month[/day[/year]]\n"
+ "\n"
+ "\t\tThe parser will fill in bits in the enddate from context if\n"
+ "\t\tleft out, e.g. a 'date:2004..01' will find from 2004-01-01\n"
+ "\t\tthrough 2004-01-31\n"
"\n\n";
command_t commands[] = {
--
1.6.3.3
More information about the notmuch
mailing list