diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2017-07-05 22:04:37 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2017-07-05 22:17:00 +0300 |
commit | 3e11bc9b24db031640772f20b303bc2430e6d3f2 (patch) | |
tree | 4e9777332f6318a333f2973d805c68f4959d04e5 | |
parent | 9da939ebc7cde925ee45f405786a6b0d451b7180 (diff) | |
parent | 9e78589f35c4610a896609368a8ea187e54dac87 (diff) | |
download | mailutils-3e11bc9b24db031640772f20b303bc2430e6d3f2.tar.gz mailutils-3e11bc9b24db031640772f20b303bc2430e6d3f2.tar.bz2 |
Merge branch 'mhfmt'
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 (<m) - TMSEC (>m); - 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 |