summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2017-07-05 22:04:37 +0300
committerSergey Poznyakoff <gray@gnu.org>2017-07-05 22:17:00 +0300
commit3e11bc9b24db031640772f20b303bc2430e6d3f2 (patch)
tree4e9777332f6318a333f2973d805c68f4959d04e5
parent9da939ebc7cde925ee45f405786a6b0d451b7180 (diff)
parent9e78589f35c4610a896609368a8ea187e54dac87 (diff)
downloadmailutils-3e11bc9b24db031640772f20b303bc2430e6d3f2.tar.gz
mailutils-3e11bc9b24db031640772f20b303bc2430e6d3f2.tar.bz2
Merge branch 'mhfmt'
-rw-r--r--include/mailutils/cctype.h7
-rw-r--r--include/mailutils/datetime.h19
-rw-r--r--libmailutils/address/parse822.c5
-rw-r--r--libmailutils/base/Makefile.am5
-rw-r--r--libmailutils/datetime/Makefile.am3
-rw-r--r--libmailutils/datetime/gylwrap.conf (renamed from libmailutils/base/gylwrap.conf)0
-rw-r--r--libmailutils/datetime/parsedate.y (renamed from libmailutils/base/parsedate.y)259
-rw-r--r--libmailutils/datetime/utcoff.c4
-rw-r--r--libmailutils/diag/diag.c24
-rw-r--r--libmailutils/string/muctype.c130
-rw-r--r--libmailutils/string/wordsplit.c1
-rw-r--r--libmailutils/tests/wordsplit.at9
-rw-r--r--mh/Makefile.am1
-rw-r--r--mh/etc/replcomps7
-rw-r--r--mh/etc/replgroupcomps7
-rw-r--r--mh/fmtcheck.c64
-rw-r--r--mh/inc.c53
-rw-r--r--mh/mh.h163
-rw-r--r--mh/mh_fmtgram.y1783
-rw-r--r--mh/mh_format.c1911
-rw-r--r--mh/mh_format.h174
-rw-r--r--mh/mh_getopt.c29
-rw-r--r--mh/mh_getopt.h6
-rw-r--r--mh/mh_init.c346
-rw-r--r--mh/mh_list.c385
-rw-r--r--mh/repl.c68
-rw-r--r--mh/scan.c65
-rw-r--r--mh/scanfmt.c43
-rw-r--r--mh/sortm.c23
-rw-r--r--mh/tests/Makefile.am2
-rw-r--r--mh/tests/atlocal.in1
-rw-r--r--mh/tests/fmtcomp.at344
-rw-r--r--mh/tests/fmtfunc.at708
-rw-r--r--mh/tests/scan.at60
-rw-r--r--mh/tests/testsuite.at2
-rw-r--r--po/POTFILES.in3
36 files changed, 4666 insertions, 2048 deletions
diff --git a/include/mailutils/cctype.h b/include/mailutils/cctype.h
index bed749b96..fba82a104 100644
--- a/include/mailutils/cctype.h
+++ b/include/mailutils/cctype.h
@@ -37,6 +37,9 @@ extern "C" {
#define MU_CTYPE_XLETR 0x0400
#define MU_CTYPE_ENDLN 0x0800
#define MU_CTYPE_TSPEC 0x1000 /* tspecials: RFC 2045, section 5.1. */
+#define MU_CTYPE_IDENT 0x2000 /* Valid identifier consituent: alnum or _ */
+#define MU_CTYPE_HEADR 0x4000 /* Valid header name consituent: alnum, _,
+ or - */
#define MU_C_TAB_MAX 128
@@ -60,7 +63,9 @@ extern int mu_c_tab[MU_C_TAB_MAX];
#define mu_isblank(c) mu_c_is_class (c, MU_CTYPE_BLANK)
#define mu_isendln(c) mu_c_is_class (c, MU_CTYPE_ENDLN)
#define mu_istspec(c) mu_c_is_class (c, MU_CTYPE_TSPEC)
-
+#define mu_isident(c) mu_c_is_class (c, MU_CTYPE_IDENT)
+#define mu_isheadr(c) mu_c_is_class (c, MU_CTYPE_HEADR)
+
#define mu_tolower(c) \
({ int __c = (c); \
(__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \
diff --git a/include/mailutils/datetime.h b/include/mailutils/datetime.h
index 7ea0e8c2b..ad8ba0793 100644
--- a/include/mailutils/datetime.h
+++ b/include/mailutils/datetime.h
@@ -60,6 +60,25 @@ struct mu_timezone
to be a pointer to static string, so will never be freed. */
};
+#define MU_PD_MASK_SECOND 00001
+#define MU_PD_MASK_MINUTE 00002
+#define MU_PD_MASK_HOUR 00004
+#define MU_PD_MASK_DAY 00010
+#define MU_PD_MASK_MONTH 00020
+#define MU_PD_MASK_YEAR 00040
+#define MU_PD_MASK_TZ 00100
+#define MU_PD_MASK_MERIDIAN 00200
+#define MU_PD_MASK_ORDINAL 00400
+#define MU_PD_MASK_NUMBER 01000
+
+#define MU_PD_MASK_TIME MU_PD_MASK_SECOND|MU_PD_MASK_MINUTE|MU_PD_MASK_HOUR
+#define MU_PD_MASK_DATE MU_PD_MASK_DAY|MU_PD_MASK_MONTH|MU_PD_MASK_YEAR
+#define MU_PD_MASK_DOW MU_PD_MASK_NUMBER
+
+int mu_parse_date_dtl (const char *p, const time_t *now,
+ time_t *rettime, struct tm *rettm,
+ struct mu_timezone *rettz,
+ int *retflags);
int mu_parse_date (const char *p, time_t *rettime, const time_t *now);
int mu_utc_offset (void);
diff --git a/libmailutils/address/parse822.c b/libmailutils/address/parse822.c
index 732028930..9a4ef48de 100644
--- a/libmailutils/address/parse822.c
+++ b/libmailutils/address/parse822.c
@@ -1760,7 +1760,7 @@ mu_parse822_time (const char **p, const char *e,
}
#if 0
-For reference, especially the for the required range and values of the
+For reference, especially for the required range and values of the
integer fields.
struct tm
@@ -1844,6 +1844,9 @@ mu_parse822_date_time (const char **p, const char *e, struct tm *tm,
tm->tm_min = min;
tm->tm_sec = sec;
+ tm->tm_yday = mu_datetime_dayofyear (tm->tm_year + 1900,
+ tm->tm_mon + 1, tm->tm_mday) - 1;
+
#ifdef HAVE_STRUCT_TM_TM_ISDST
tm->tm_isdst = -1; /* unknown whether it's dst or not */
#endif
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am
index 0936a2d19..8214e483e 100644
--- a/libmailutils/base/Makefile.am
+++ b/libmailutils/base/Makefile.am
@@ -54,7 +54,6 @@ libbase_la_SOURCES = \
observer.c\
onexit.c\
opool.c\
- parsedate.y\
permstr.c\
registrar.c\
refcount.c\
@@ -82,10 +81,6 @@ AM_CPPFLAGS = \
-DLOCALEDIR=\"$(localedir)\"
-YLWRAP = @MU_YLWRAP@
-EXTRA_DIST = gylwrap.conf
-AM_YFLAGS=
-AM_LFLAGS=
diff --git a/libmailutils/datetime/Makefile.am b/libmailutils/datetime/Makefile.am
index bb7e873c7..66e51cf68 100644
--- a/libmailutils/datetime/Makefile.am
+++ b/libmailutils/datetime/Makefile.am
@@ -21,6 +21,7 @@ libdatetime_la_SOURCES = \
dow.c\
doy.c\
jd.c\
+ parsedate.y\
scantime.c\
streamftime.c\
strftime.c\
@@ -31,3 +32,5 @@ libdatetime_la_SOURCES = \
yd.c
AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
+YLWRAP = @MU_YLWRAP@
+EXTRA_DIST = gylwrap.conf
diff --git a/libmailutils/base/gylwrap.conf b/libmailutils/datetime/gylwrap.conf
index 33b8c123f..33b8c123f 100644
--- a/libmailutils/base/gylwrap.conf
+++ b/libmailutils/datetime/gylwrap.conf
diff --git a/libmailutils/base/parsedate.y b/libmailutils/datetime/parsedate.y
index 3e176c018..e8eddd6b8 100644
--- a/libmailutils/base/parsedate.y
+++ b/libmailutils/datetime/parsedate.y
@@ -28,46 +28,24 @@
#endif
#include <stdio.h>
-#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/cctype.h>
+#include <mailutils/cstr.h>
+#include <mailutils/datetime.h>
-#if HAVE_STDLIB_H
-# include <stdlib.h> /* for `free'; used by Bison 1.27 */
-#endif
-
-#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii(c)
-#endif
-
-#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
-#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
-#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
-#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
-
-/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
- - Its arg may be any int or unsigned int; it need not be an unsigned char.
- - It's guaranteed to evaluate its argument exactly once.
- - It's typically faster.
- Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
- only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
- it's important to use the locale's definition of `digit' even when the
- host does not conform to Posix. */
-#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
-
-#if defined (STDC_HEADERS) || defined (USG)
-# include <string.h>
-#endif
+#define ISSPACE(c) mu_isspace (c)
+#define ISALPHA(c) mu_isalpha (c)
+#define ISUPPER(c) mu_isupper (c)
-/* Some old versions of bison generate parsers that use bcopy.
- That loses on systems that don't provide the function, so we have
- to redefine it here. */
-#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
-# define bcopy(from, to, len) memcpy ((to), (from), (len))
-#endif
+static inline int ISDIGIT (unsigned c)
+{
+ return mu_isdigit (c);
+}
-static int yylex ();
-static int yyerror ();
+static int yyparse (void);
+static int yylex (void);
+static int yyerror (char *s);
#define EPOCH 1970
#define HOUR(x) ((x) * 60)
@@ -92,21 +70,6 @@ typedef enum meridian {
MERpm,
MER24
} MERIDIAN;
-
-#define PD_MASK_SECOND 00001
-#define PD_MASK_MINUTE 00002
-#define PD_MASK_HOUR 00004
-#define PD_MASK_DAY 00010
-#define PD_MASK_MONTH 00020
-#define PD_MASK_YEAR 00040
-#define PD_MASK_TZ 00100
-#define PD_MASK_MERIDIAN 00200
-#define PD_MASK_ORDINAL 00400
-#define PD_MASK_NUMBER 01000
-
-#define PD_MASK_TIME PD_MASK_SECOND|PD_MASK_MINUTE|PD_MASK_HOUR
-#define PD_MASK_DATE PD_MASK_DAY|PD_MASK_MONTH|PD_MASK_YEAR
-#define PD_MASK_DOW PD_MASK_NUMBER
#define MASK_IS_SET(f,m) (((f)&(m))==(m))
#define MASK_TEST(f,m) ((f)&(m))
@@ -120,6 +83,7 @@ struct pd_date
int second;
int year;
int tz;
+ char const *tzname;
enum meridian meridian;
int number;
int ordinal;
@@ -130,21 +94,21 @@ struct pd_date
do \
{ \
int __x = val; \
- if (((m) != PD_MASK_TZ && __x < 0) || (lim && __x > lim)) onerror; \
+ if (((m) != MU_PD_MASK_TZ && __x < 0) || (lim && __x > lim)) onerror;\
date . memb = __x; date.mask |= m; \
} \
while (0)
-#define __SET_SECOND(d,v,a) DATE_SET(d,second,PD_MASK_SECOND,v,59,a)
-#define __SET_MINUTE(d,v,a) DATE_SET(d,minute,PD_MASK_MINUTE,v,59,a)
-#define __SET_HOUR(d,v,a) DATE_SET(d,hour,PD_MASK_HOUR,v,23,a)
-#define __SET_DAY(d,v,a) DATE_SET(d,day,PD_MASK_DAY,v,31,a)
-#define __SET_MONTH(d,v,a) DATE_SET(d,month,PD_MASK_MONTH,v,12,a)
-#define __SET_YEAR(d,v,a) DATE_SET(d,year,PD_MASK_YEAR,v,0,a)
-#define __SET_TZ(d,v,a) DATE_SET(d,tz,PD_MASK_TZ,v,0,a)
-#define __SET_MERIDIAN(d,v,a) DATE_SET(d,meridian,PD_MASK_MERIDIAN,v,MER24,a)
-#define __SET_ORDINAL(d,v,a) DATE_SET(d,ordinal,PD_MASK_ORDINAL,v,0,a)
-#define __SET_NUMBER(d,v,a) DATE_SET(d,number,PD_MASK_NUMBER,v,0,a)
+#define __SET_SECOND(d,v,a) DATE_SET(d,second,MU_PD_MASK_SECOND,v,59,a)
+#define __SET_MINUTE(d,v,a) DATE_SET(d,minute,MU_PD_MASK_MINUTE,v,59,a)
+#define __SET_HOUR(d,v,a) DATE_SET(d,hour,MU_PD_MASK_HOUR,v,23,a)
+#define __SET_DAY(d,v,a) DATE_SET(d,day,MU_PD_MASK_DAY,v,31,a)
+#define __SET_MONTH(d,v,a) DATE_SET(d,month,MU_PD_MASK_MONTH,v,12,a)
+#define __SET_YEAR(d,v,a) DATE_SET(d,year,MU_PD_MASK_YEAR,v,0,a)
+#define __SET_TZ(d,v,a) DATE_SET(d,tz,MU_PD_MASK_TZ,v,0,a)
+#define __SET_MERIDIAN(d,v,a) DATE_SET(d,meridian,MU_PD_MASK_MERIDIAN,v,MER24,a)
+#define __SET_ORDINAL(d,v,a) DATE_SET(d,ordinal,MU_PD_MASK_ORDINAL,v,0,a)
+#define __SET_NUMBER(d,v,a) DATE_SET(d,number,MU_PD_MASK_NUMBER,v,0,a)
#define SET_SECOND(d,v) __SET_SECOND(d,v,YYERROR)
#define SET_MINUTE(d,v) __SET_MINUTE(d,v,YYERROR)
@@ -152,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)
@@ -166,34 +148,34 @@ pd_date_union (struct pd_date *a, struct pd_date *b)
a->mask |= diff;
- if (diff & PD_MASK_SECOND)
+ if (diff & MU_PD_MASK_SECOND)
a->second = b->second;
- if (diff & PD_MASK_MINUTE)
+ if (diff & MU_PD_MASK_MINUTE)
a->minute = b->minute;
- if (diff & PD_MASK_HOUR)
+ if (diff & MU_PD_MASK_HOUR)
a->hour = b->hour;
- if (diff & PD_MASK_DAY)
+ if (diff & MU_PD_MASK_DAY)
a->day = b->day;
- if (diff & PD_MASK_MONTH)
+ if (diff & MU_PD_MASK_MONTH)
a->month = b->month;
- if (diff & PD_MASK_YEAR)
+ if (diff & MU_PD_MASK_YEAR)
a->year = b->year;
- if (diff & PD_MASK_TZ)
+ if (diff & MU_PD_MASK_TZ)
a->tz = b->tz;
- if (diff & PD_MASK_MERIDIAN)
+ if (diff & MU_PD_MASK_MERIDIAN)
a->meridian = b->meridian;
- if (diff & PD_MASK_ORDINAL)
+ if (diff & MU_PD_MASK_ORDINAL)
a->ordinal = b->ordinal;
- if (diff & PD_MASK_NUMBER)
+ if (diff & MU_PD_MASK_NUMBER)
a->number = b->number;
return 0;
@@ -216,14 +198,16 @@ static const char *yyinput;
enum meridian meridian;
struct pd_date date;
struct pd_datespec datespec;
+ struct { char const *name; int delta; } tz;
}
/*FIXME: do we need T_ID? */
%token T_AGO T_DST T_ID
-%token <number> T_DAY T_DAY_UNIT T_DAYZONE T_HOUR_UNIT T_MINUTE_UNIT
+%token <number> T_DAY T_DAY_UNIT T_HOUR_UNIT T_MINUTE_UNIT
%token <number> T_MONTH T_MONTH_UNIT
-%token <number> T_SEC_UNIT T_SNUMBER T_UNUMBER T_YEAR_UNIT T_ZONE
+%token <number> T_SEC_UNIT T_SNUMBER T_UNUMBER T_YEAR_UNIT
+%token <tz> T_ZONE T_DAYZONE
%token <meridian> T_MERIDIAN
%type <meridian> o_merid
@@ -257,9 +241,21 @@ spec : /* NULL */
}
| spec T_UNUMBER
{
- if (MASK_IS_SET ($1.date.mask, (PD_MASK_TIME|PD_MASK_DATE))
+ 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)
@@ -311,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
{
@@ -331,26 +324,27 @@ 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);
}
;
zone : T_ZONE
{
DATE_INIT ($$);
- SET_TZ ($$, $1);
+ SET_TZ ($$, $1.delta);
+ $$.tzname = $1.name;
}
| T_DAYZONE
{
DATE_INIT ($$);
- SET_TZ ($$, $1 - 60);
+ SET_TZ ($$, $1.delta - 60);
+ $$.tzname = $1.name;
}
| T_ZONE T_DST
{
DATE_INIT ($$);
- SET_TZ ($$, $1 - 60);
+ SET_TZ ($$, $1.delta - 60);
+ $$.tzname = $1.name;
}
;
@@ -864,9 +858,7 @@ sym_lookup (char *buff)
int abbrev;
/* Make it lowercase. */
- for (p = buff; *p; p++)
- if (ISUPPER ((unsigned char) *p))
- *p = tolower (*p);
+ mu_strlower (buff);
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
{
@@ -910,7 +902,8 @@ sym_lookup (char *buff)
for (tp = tz_tab; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
{
- yylval.number = tp->value;
+ yylval.tz.name = tp->name;
+ yylval.tz.delta = tp->value;
return tp->type;
}
@@ -951,7 +944,8 @@ sym_lookup (char *buff)
for (tp = mil_tz_tab; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
{
- yylval.number = tp->value;
+ yylval.tz.name = tp->name;
+ yylval.tz.delta = tp->value;
return tp->type;
}
}
@@ -975,7 +969,7 @@ sym_lookup (char *buff)
}
static int
-yylex ()
+yylex (void)
{
register unsigned char c;
register char *p;
@@ -1056,7 +1050,11 @@ difftm (struct tm *a, struct tm *b)
}
int
-mu_parse_date (const char *p, time_t *rettime, const time_t *now)
+mu_parse_date_dtl (const char *p, const time_t *now,
+ time_t *rettime,
+ struct tm *rettm,
+ struct mu_timezone *rettz,
+ int *retflags)
{
struct tm tm, tm0, *tmp;
time_t start;
@@ -1073,27 +1071,27 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
if (yyparse ())
return -1;
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_YEAR))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_YEAR))
__SET_YEAR (pd.date, tmp->tm_year + TM_YEAR_ORIGIN, return -1);
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_MONTH))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_MONTH))
__SET_MONTH (pd.date, tmp->tm_mon + 1, return -1);
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_DAY))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_DAY))
__SET_DAY (pd.date, tmp->tm_mday, return -1);
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_HOUR))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_HOUR))
__SET_HOUR (pd.date, tmp->tm_hour, return -1);
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_MERIDIAN))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_MERIDIAN))
__SET_MERIDIAN (pd.date, MER24, return -1);
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_MINUTE))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_MINUTE))
__SET_MINUTE (pd.date, tmp->tm_min, return -1);
- if (!MASK_IS_SET (pd.date.mask, PD_MASK_SECOND))
+ if (!MASK_IS_SET (pd.date.mask, MU_PD_MASK_SECOND))
__SET_SECOND (pd.date, tmp->tm_sec, return -1);
tm.tm_year = norm_year (pd.date.year) - TM_YEAR_ORIGIN + pd.rel.year;
tm.tm_mon = pd.date.month - 1 + pd.rel.month;
tm.tm_mday = pd.date.day + pd.rel.day;
- if (MASK_TEST (pd.date.mask, PD_MASK_TIME)
- || (pd.rel.mask && !MASK_TEST (pd.date.mask, PD_MASK_DATE)
- && !MASK_TEST (pd.date.mask, PD_MASK_DOW)))
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_TIME)
+ || (pd.rel.mask && !MASK_TEST (pd.date.mask, MU_PD_MASK_DATE)
+ && !MASK_TEST (pd.date.mask, MU_PD_MASK_DOW)))
{
tm.tm_hour = norm_hour (pd.date.hour, pd.date.meridian);
if (tm.tm_hour < 0)
@@ -1111,8 +1109,8 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
/* Let mktime deduce tm_isdst if we have an absolute timestamp,
or if the relative timestamp mentions days, months, or years. */
- if (MASK_TEST (pd.date.mask, PD_MASK_DATE | PD_MASK_DOW | PD_MASK_TIME)
- || MASK_TEST (pd.rel.mask, PD_MASK_DOW | PD_MASK_MONTH | PD_MASK_YEAR))
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_DATE | MU_PD_MASK_DOW | MU_PD_MASK_TIME)
+ || MASK_TEST (pd.rel.mask, MU_PD_MASK_DOW | MU_PD_MASK_MONTH | MU_PD_MASK_YEAR))
tm.tm_isdst = -1;
tm0 = tm;
@@ -1130,7 +1128,7 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
zone by 24 hours to compensate. This algorithm assumes that
there is no DST transition within a day of the time_t boundaries. */
- if (MASK_TEST (pd.date.mask, PD_MASK_TZ))
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_TZ))
{
tm = tm0;
if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
@@ -1150,8 +1148,8 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
return -1;
}
- if (MASK_TEST (pd.date.mask, PD_MASK_DOW)
- && !MASK_TEST (pd.date.mask, PD_MASK_DATE))
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_DOW)
+ && !MASK_TEST (pd.date.mask, MU_PD_MASK_DATE))
{
tm.tm_mday += ((pd.date.number - tm.tm_wday + 7) % 7
+ 7 * (pd.date.ordinal - (0 < pd.date.ordinal)));
@@ -1160,7 +1158,7 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
return -1;
}
- if (MASK_TEST (pd.date.mask, PD_MASK_TZ))
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_TZ))
{
long delta;
struct tm *gmt = gmtime (&start);
@@ -1172,11 +1170,46 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
start += delta;
}
}
-
- *rettime = start;
+
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_TZ))
+ {
+ pd.date.tz = - pd.date.tz * 60L;
+ if (!pd.date.tzname)
+ pd.date.tzname = tm.tm_isdst != -1 ? tzname[tm.tm_isdst] : NULL;
+#if HAVE_STRUCT_TM_TM_GMTOFF
+ tm.tm_gmtoff = pd.date.tz;
+#endif
+#if HAVE_STRUCT_TM_TM_ZONE
+ tm.tm_zone = pd.date.tzname;
+#endif
+ }
+ if (rettime)
+ *rettime = start;
+ if (rettm)
+ *rettm = tm;
+ if (rettz)
+ {
+ if (MASK_TEST (pd.date.mask, MU_PD_MASK_TZ))
+ {
+ rettz->utc_offset = pd.date.tz;
+ rettz->tz_name = pd.date.tzname;
+ }
+ else
+ {
+ mu_datetime_tz_local (rettz);
+ }
+ }
+ if (retflags)
+ *retflags = pd.date.mask;
return 0;
}
+int
+mu_parse_date (const char *p, time_t *rettime, const time_t *now)
+{
+ return mu_parse_date_dtl (p, now, rettime, NULL, NULL, NULL);
+}
+
#ifdef STANDALONE
int
main (int argc, char *argv[])
diff --git a/libmailutils/datetime/utcoff.c b/libmailutils/datetime/utcoff.c
index 0caa6706b..3b8bc21f7 100644
--- a/libmailutils/datetime/utcoff.c
+++ b/libmailutils/datetime/utcoff.c
@@ -30,7 +30,9 @@ mu_utc_offset (void)
struct tm ltm = *localtime (&t);
struct tm gtm = *gmtime (&t);
int d = TMSEC (&ltm) - TMSEC (&gtm);
- if (!(ltm.tm_year = gtm.tm_year && ltm.tm_mon == gtm.tm_mon))
+ if (!(ltm.tm_year = gtm.tm_year
+ && ltm.tm_mon == gtm.tm_mon
+ && ltm.tm_mday == gtm.tm_mday))
d += 86400;
return d;
}
diff --git a/libmailutils/diag/diag.c b/libmailutils/diag/diag.c
index b5a7482a6..e9d2f84fe 100644
--- a/libmailutils/diag/diag.c
+++ b/libmailutils/diag/diag.c
@@ -60,17 +60,25 @@ void
mu_vdiag_at_locus_range (int level, struct mu_locus_range const *loc,
const char *fmt, va_list ap)
{
- struct mu_locus_range old = MU_LOCUS_RANGE_INITIALIZER;
+ struct mu_locus_range old_loc = MU_LOCUS_RANGE_INITIALIZER;
+ int old_mode;
int restore = 0;
if (loc)
{
if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
- MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE, &old) == 0)
+ MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE, &old_loc) == 0)
{
- mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
- MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, (void*) loc);
- restore = 1;
+ if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_GET_MODE, &old_mode) == 0)
+ {
+ int mode = old_mode | MU_LOGMODE_LOCUS;
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, (void*) loc);
+ restore = 1;
+ }
}
}
@@ -79,8 +87,10 @@ mu_vdiag_at_locus_range (int level, struct mu_locus_range const *loc,
if (restore)
{
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
- MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &old);
- mu_locus_range_deinit (&old);
+ MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &old_loc);
+ mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &old_mode);
+ mu_locus_range_deinit (&old_loc);
}
}
diff --git a/libmailutils/string/muctype.c b/libmailutils/string/muctype.c
index ffa050d6e..bd24a2aa8 100644
--- a/libmailutils/string/muctype.c
+++ b/libmailutils/string/muctype.c
@@ -66,19 +66,19 @@ int mu_c_tab[MU_C_TAB_MAX] = {
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
- MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT,
+ MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_HEADR,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
- MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
+ MU_CTYPE_DIGIT|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_IDENT|MU_CTYPE_HEADR,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
@@ -86,64 +86,64 @@ int mu_c_tab[MU_C_TAB_MAX] = {
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_PUNCT|MU_CTYPE_TSPEC,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER|MU_CTYPE_XLETR,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER|MU_CTYPE_XLETR,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER|MU_CTYPE_XLETR,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER|MU_CTYPE_XLETR,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER|MU_CTYPE_XLETR,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER|MU_CTYPE_XLETR,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT|MU_CTYPE_UPPER,
- MU_CTYPE_ALPHA|MU_CTYPE_GRAPH|MU_CTYPE_PRINT