summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-04 12:41:29 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-04 12:41:29 +0300
commit3fc6fc8ae9fe5980abf25e109c96934cb1fdb1eb (patch)
treea8e86fd4842381fe7c470b6ce0d8806bc7c07d85
parent55ce659fd9a9aa49de31d33f7937fb5966fb2e1d (diff)
downloadmailutils-3fc6fc8ae9fe5980abf25e109c96934cb1fdb1eb.tar.gz
mailutils-3fc6fc8ae9fe5980abf25e109c96934cb1fdb1eb.tar.bz2
Improve parsedate & related MH formats
* libmailutils/datetime/parsedate.y (spec production): If a non-signed number is given, treat it as a (positive) timezone, unless tz is already set, or as a year number, unless a year is already set, or throw an error otherwise. (mu_parse_date_dtl): Revert sign of the returned utc_offset * mh/mh_format.c (builtin_tzone): Compatibility fix * mh/tests/fmtfunc.at: Test more functions.
-rw-r--r--libmailutils/datetime/parsedate.y45
-rw-r--r--mh/mh_format.c35
-rw-r--r--mh/tests/fmtfunc.at49
3 files changed, 93 insertions, 36 deletions
diff --git a/libmailutils/datetime/parsedate.y b/libmailutils/datetime/parsedate.y
index 8ea9b2c43..a422d59d2 100644
--- a/libmailutils/datetime/parsedate.y
+++ b/libmailutils/datetime/parsedate.y
@@ -116,7 +116,25 @@ struct pd_date
#define SET_DAY(d,v) __SET_DAY(d,v,YYERROR)
#define SET_MONTH(d,v) __SET_MONTH(d,v,YYERROR)
#define SET_YEAR(d,v) __SET_YEAR(d,v,YYERROR)
-#define SET_TZ(d,v) __SET_TZ(d,v,YYERROR)
+#define SET_TZ(d,v) __SET_TZ(d,v,YYERROR)
+/* Set timezone from a packed representation (HHMM)
+
+ The proper way of doing so would be:
+
+#define SET_TZ_PACK(d,v) \
+ SET_TZ (d, ((v) < 0 ? -(-(v) % 100 + (-(v) / 100) * 60) \
+ : ((v) % 100 + ((v) / 100) * 60)))
+
+ However, we need to invert the sign in order for mktime
+ to work properly (see mu_parse_date_dtl below). The proper
+ sign is then restored upon return from the function.
+
+ Once mu_mktime is in place, this can be changed.
+*/
+#define SET_TZ_PACK(d,v) \
+ SET_TZ (d, ((v) < 0 ? (-(v) % 100 + (-(v) / 100) * 60) \
+ : -((v) % 100 + ((v) / 100) * 60)))
+
#define SET_MERIDIAN(d,v) __SET_MERIDIAN(d,v,YYERROR)
#define SET_ORDINAL(d,v) __SET_ORDINAL(d,v,YYERROR)
#define SET_NUMBER(d,v) __SET_NUMBER(d,v,YYERROR)
@@ -225,7 +243,19 @@ spec : /* NULL */
{
if (MASK_IS_SET ($1.date.mask, (MU_PD_MASK_TIME|MU_PD_MASK_DATE))
&& !$1.rel.mask)
- SET_YEAR ($1.date, $2);
+ {
+ if (MASK_IS_SET ($1.date.mask, MU_PD_MASK_YEAR))
+ {
+ if (!MASK_IS_SET ($1.date.mask, MU_PD_MASK_TZ))
+ SET_TZ_PACK ($1.date, $2);
+ else
+ YYERROR;
+ }
+ else
+ {
+ SET_YEAR ($1.date, $2);
+ }
+ }
else
{
if ($2 > 10000)
@@ -277,10 +307,7 @@ time : T_UNUMBER T_MERIDIAN
SET_HOUR ($$, $1);
SET_MINUTE ($$, $3);
SET_MERIDIAN ($$, MER24);
- SET_TZ ($$, ($4 < 0
- ? -$4 % 100 + (-$4 / 100) * 60
- : - ($4 % 100 + ($4 / 100) * 60)));
-
+ SET_TZ_PACK ($$, $4);
}
| T_UNUMBER ':' T_UNUMBER ':' T_UNUMBER o_merid
{
@@ -297,9 +324,7 @@ time : T_UNUMBER T_MERIDIAN
SET_MINUTE ($$, $3);
SET_SECOND ($$, $5);
SET_MERIDIAN ($$, MER24);
- SET_TZ ($$, ($6 < 0
- ? -$6 % 100 + (-$6 / 100) * 60
- : - ($6 % 100 + ($6 / 100) * 60)));
+ SET_TZ_PACK ($$, $6);
}
;
@@ -1153,7 +1178,7 @@ mu_parse_date_dtl (const char *p, const time_t *now,
{
if (MASK_TEST (pd.date.mask, MU_PD_MASK_TZ))
{
- rettz->utc_offset = pd.date.tz * 60L;
+ rettz->utc_offset = - pd.date.tz * 60L;
rettz->tz_name = pd.date.tzname
? pd.date.tzname
: (tm.tm_isdst != -1 ? tzname[tm.tm_isdst] : NULL);
diff --git a/mh/mh_format.c b/mh/mh_format.c
index 3948be49f..1278bfa28 100644
--- a/mh/mh_format.c
+++ b/mh/mh_format.c
@@ -1104,29 +1104,32 @@ static void
builtin_tzone (struct mh_fvm *mach)
{
struct mu_timezone tz;
+ char buf[6];
+ int s;
+ unsigned hrs;
_parse_date (mach, NULL, &tz, NULL);
-
+
+#if 0
+ /* FIXME: If symbolic tz representation is needed, we'd do: */
if (tz.tz_name)
mh_string_load (&mach->str[R_REG], tz.tz_name);
else
- {
- char buf[6];
- int s;
- unsigned hrs;
+ /* .... */
+ /* However, MH's tzone function simply formats the timezone */
+#endif
- if (tz.utc_offset < 0)
- {
- s = '-';
- tz.utc_offset = - tz.utc_offset;
- }
- else
- s = '+';
- hrs = tz.utc_offset / 3600;
- snprintf (buf, sizeof buf, "%c%02u%02u", s,
- hrs, (tz.utc_offset - hrs * 3600) / 60);
- mh_string_load (&mach->str[R_REG], buf);
+ if (tz.utc_offset < 0)
+ {
+ s = '-';
+ tz.utc_offset = - tz.utc_offset;
}
+ else
+ s = '+';
+ hrs = tz.utc_offset / 3600;
+ snprintf (buf, sizeof buf, "%c%02u%02u", s,
+ hrs, (tz.utc_offset - hrs * 3600) / 60);
+ mh_string_load (&mach->str[R_REG], buf);
}
/* szone date integer timezone explicit?
diff --git a/mh/tests/fmtfunc.at b/mh/tests/fmtfunc.at
index 8f8b81c27..07be0e07d 100644
--- a/mh/tests/fmtfunc.at
+++ b/mh/tests/fmtfunc.at
@@ -464,7 +464,17 @@ FMTFUNC([weekday],
[Monday
])
-# FIXME: sday
+FMTFUNC([sday],
+[%(sday{Date})
+%(sday{X-Date})
+],
+[Date: Mon, 3 Jul 2017 13:17:58 +0300
+X-Date: 3 Jul 2017 13:17:58 +0300
+
+],
+[1
+0
+])
FMTFUNC([mday],
[%(mday{Date})
@@ -522,17 +532,36 @@ FMTFUNC([year],
# FIXME: zone
-# FIXME: This returns EEST if tz files are properly set
-# FMTFUNC([tzone],
-# [%(tzone{Date})
-# ],
-# [Date: Mon, 3 Jul 2017 13:17:58 +0300
+FMTFUNC([tzone],
+[%(tzone{Date})
+%(tzone{X-Date-1})
+%(tzone{X-Date-2})
+%(tzone{X-Date-3})
+],
+[Date: Mon, 3 Jul 2017 13:17:58 +0300
+X-Date-1: Mon, 3 Jul 2017 13:17:58 -0500
+X-Date-2: Mon, 3 Jul 2017 13:17:58 +0000
+X-Date-3: Mon, 3 Jul 2017 13:17:58 0000
-# ],
-# [+0300
-# ])
-# FIXME: szone
+],
+[+0300
+-0500
++0000
++0000
+])
+
+FMTFUNC([szone],
+[%(szone{Date})
+%(szone{X-Date})
+],
+[Date: Mon, 3 Jul 2017 13:17:58 +0300
+X-Date: Mon, 3 Jul 2017 13:17:58
+
+],
+[1
+0
+])
# FIXME: date2local

Return to:

Send suggestions and report system problems to the System administrator.