1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 11:42:21 +00:00

Backport changes to AST time library from ksh 93v- beta

This incorporates the last changes in the tm library before AT&T
laid off the AST developers. It contains mostly time zone and
locale related changes/fixes.

I was hoping these would fix #52 (locale-based 'printf %T' output
is broken), but no such luck. This is probably good to have anyway.
This commit is contained in:
Martijn Dekker 2021-01-21 13:45:05 +00:00
parent 0a10e76ccc
commit 9f43f8d10b
6 changed files with 151 additions and 44 deletions

View file

@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 1985-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
@ -14,9 +14,9 @@
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* Glenn Fowler <glenn.s.fowler@gmail.com> *
* David Korn <dgkorn@gmail.com> *
* Phong Vo <phongvo@gmail.com> *
* *
***********************************************************************/
#pragma prototyped
@ -247,6 +247,10 @@ tmlocal(void)
else if (e)
environ[0] = e;
}
#endif
#if _dat_tzname
local.standard = strdup(tzname[0]);
local.daylight = strdup(tzname[1]);
#endif
tmlocale();
@ -292,8 +296,10 @@ tmlocal(void)
* POSIX
*/
local.standard = strdup(tzname[0]);
local.daylight = strdup(tzname[1]);
if (!local.standard)
local.standard = strdup(tzname[0]);
if (!local.daylight)
local.daylight = strdup(tzname[1]);
}
else
#endif
@ -375,6 +381,23 @@ tmlocal(void)
}
}
}
if (!*local.standard && !local.west && !local.dst && (s = getenv("TZ")))
{
if ((zp = tmzone(s, &t, NiL, NiL)) && !*t)
{
local.standard = strdup(zp->standard);
if (zp->daylight)
local.daylight = strdup(zp->daylight);
local.west = zp->west;
local.dst = zp->dst;
}
else
local.standard = strdup(s);
if (!local.standard)
local.standard = "";
if (!local.daylight)
local.daylight = "";
}
/*
* set the options

View file

@ -14,9 +14,9 @@
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* Glenn Fowler <glenn.s.fowler@gmail.com> *
* David Korn <dgkorn@gmail.com> *
* Phong Vo <phongvo@gmail.com> *
* *
***********************************************************************/
#pragma prototyped
@ -135,7 +135,7 @@ powerize(Tm_t* tm, unsigned long p, unsigned long q, unsigned long u)
q *= 10;
t *= 10;
}
tm->tm_nsec += (int)(t % TMX_RESOLUTION);
tm->tm_nsec += (int)((unsigned long)t % TMX_RESOLUTION);
tm->tm_sec += (int)(t / TMX_RESOLUTION);
}
@ -228,12 +228,14 @@ tmxdate(register const char* s, char** e, Time_t now)
state &= (state & HOLD) ? ~(HOLD) : ~(EXACT|LAST|NEXT|THIS);
if ((set|state) & (YEAR|MONTH|DAY))
skip['/'] = 1;
message((-1, "AHA#%d state=" FFMT " set=" FFMT, __LINE__, FLAGS(state), FLAGS(set)));
while (isspace(*s))
s++;
message((-1, "AHA#%d state=" FFMT " set=" FFMT " '%s'", __LINE__, FLAGS(state), FLAGS(set), s));
for (;;)
{
if (*s == '.' || *s == '-' || *s == '+')
{
if (((set|state) & (YEAR|MONTH|HOUR|MINUTE|ZONE)) == (YEAR|MONTH|HOUR|MINUTE) && (i = tmgoff(s, &t, TM_LOCALZONE)) != TM_LOCALZONE)
if (((set|state) & (MONTH|HOUR|MINUTE|ZONE)) == (MONTH|HOUR|MINUTE) && (i = tmgoff(s, &t, TM_LOCALZONE)) != TM_LOCALZONE)
{
zone = i;
state |= ZONE;
@ -518,13 +520,15 @@ tmxdate(register const char* s, char** e, Time_t now)
if (!(state & CRON))
{
/*
* check for cron date
* check for cron/iso date
*
* min hour day-of-month month day-of-week
*
* if it's cron then determine the next time
* that satisfies the specification
*
* if it's iso then its a point in time
*
* NOTE: the only spacing is ' '||'_'||';'
*/
@ -765,7 +769,8 @@ tmxdate(register const char* s, char** e, Time_t now)
if (dig2(t, k) < 1 || k > 31)
break;
flags |= DAY;
goto save_yymmdd;
if (*t != 'T' && *t != 't' || !isdigit(*++t))
goto save_yymmdd;
}
n = strtol(s = t, &t, 0);
if ((t - s) < 2)
@ -965,6 +970,12 @@ tmxdate(register const char* s, char** e, Time_t now)
tm->tm_year = m;
s = t;
set |= flags;
if ((*s == '-' || *s == '+') && (i = tmgoff(s, &t, TM_LOCALZONE)) != TM_LOCALZONE)
{
zone = i;
set |= ZONE;
s = t;
}
continue;
}
for (s = t; skip[*s]; s++);

View file

@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 1985-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
@ -14,9 +14,9 @@
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* Glenn Fowler <glenn.s.fowler@gmail.com> *
* David Korn <dgkorn@gmail.com> *
* Phong Vo <phongvo@gmail.com> *
* *
***********************************************************************/
#pragma prototyped
@ -111,6 +111,7 @@ tmxfmt(char* buf, size_t len, const char* format, Time_t t)
int prec;
int parts;
char* arg;
char* e;
char* f;
const char* oformat;
Tm_t* tm;
@ -471,12 +472,26 @@ tmxfmt(char* buf, size_t len, const char* format, Time_t t)
p = tm_info.format[TM_RECENT];
goto push;
case 'z': /* time zone nation code */
if (!(flags & TM_UTC))
if (arg)
{
if ((zp = tmzone(arg, &e, NiL, NiL)) && !*e)
{
tm->tm_zone = zp;
flags &= ~TM_UTC;
}
}
else if (!(flags & TM_UTC))
{
if ((zp = tm->tm_zone) != tm_info.local)
{
for (; zp >= tm_data.zone; zp--)
{
if (p = zp->type)
goto string;
if (zp->standard == zp->daylight)
break;
}
}
else if (p = zp->type)
goto string;
}
@ -597,10 +612,14 @@ tmxfmt(char* buf, size_t len, const char* format, Time_t t)
if (arg)
{
if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
{
tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
if (zp->west || zp->dst)
flags &= ~TM_UTC;
}
continue;
}
p = (flags & TM_UTC) ? tm_info.format[TM_UT] : tm->tm_isdst && tm->tm_zone->daylight ? tm->tm_zone->daylight : tm->tm_zone->standard;
p = (flags & TM_UTC) ? tm_info.local->standard : tm->tm_isdst && tm->tm_zone->daylight ? tm->tm_zone->daylight : tm->tm_zone->standard;
goto string;
case '=': /* (AST) OBSOLETE use %([+-]flag...)Qo (old %=[=][+-]flag) */
for (arg = argbuf; *format == '=' || *format == '-' || *format == '+' || *format == '!'; format++)

View file

@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 1985-2014 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
@ -14,9 +14,9 @@
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* Glenn Fowler <glenn.s.fowler@gmail.com> *
* David Korn <dgkorn@gmail.com> *
* Phong Vo <phongvo@gmail.com> *
* *
***********************************************************************/
#pragma prototyped
@ -296,11 +296,15 @@ scan(register const char* s, char** e, const char* format, char** f, Time_t t, l
continue;
case 'n':
if (pedantic)
{
while (*s == '\n')
s++;
else
while (isspace(*s))
s++;
continue;
}
/*FALLTHROUGH*/
case 't':
while (isspace(*s))
s++;
continue;
case 'N':
NUMBER(9, 0, 999999999L);

View file

@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 1985-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
@ -14,9 +14,9 @@
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* Glenn Fowler <glenn.s.fowler@gmail.com> *
* David Korn <dgkorn@gmail.com> *
* Phong Vo <phongvo@gmail.com> *
* *
***********************************************************************/
#pragma prototyped
@ -29,6 +29,7 @@
#include <ast.h>
#include <tm.h>
#include <ctype.h>
/*
* return timezone pointer given name and type
@ -49,16 +50,63 @@ Tm_zone_t*
tmzone(register const char* name, char** end, const char* type, int* dst)
{
register Tm_zone_t* zp;
register char* prev;
register char* p;
char* e;
int d;
static Tm_zone_t fixed;
static char off[16];
tmset(tm_info.zone);
if ((*name == '+' || *name == '-') && (fixed.west = tmgoff(name, &e, TM_LOCALZONE)) != TM_LOCALZONE && !*e)
if ((name[0] == '+' || name[0] == '-') && (fixed.west = tmgoff(name, &e, TM_LOCALZONE)) != TM_LOCALZONE && (!*e || isspace(*e)))
{
strlcpy(fixed.standard = fixed.daylight = off, name, sizeof(off));
p = fixed.standard = fixed.daylight = off;
*p++ = 'Z';
if ((d = fixed.west) <= 0)
{
d = -d;
*p++ = 'E';
}
else
*p++ = 'W';
p += sfsprintf(p, sizeof(off) - 2, "%u", d / 60);
if (d = (d % 60) / 15)
*p++ = 'A' + d - 1;
*p = 0;
fixed.dst = 0;
if (end)
*end = e;
if (dst)
*dst = 0;
return &fixed;
}
else if ((name[0] == 'Z' || name[0] == 'Y') && (name[1] == 'E' || name[1] == 'W') && name[2] >= '0' && name[2] <= '9')
{
e = (char*)name + 2;
fixed.west = 0;
while (*e >= '0' && *e <= '9')
fixed.west = fixed.west * 10 + (*e++ - '0');
fixed.west *= 60;
d = 0;
switch (*e)
{
case 'C':
d += 15;
/*FALLTHROUGH*/
case 'B':
d += 15;
/*FALLTHROUGH*/
case 'A':
d += 15;
e++;
break;
}
fixed.west += d;
if (name[1] == 'E')
fixed.west = -fixed.west;
fixed.dst = name[0] == 'Z' ? 0 : d ? -d : TM_DST;
memcpy(fixed.standard = fixed.daylight = off, name, d);
off[d] = 0;
if (end)
*end = e;
if (dst)
@ -66,12 +114,12 @@ tmzone(register const char* name, char** end, const char* type, int* dst)
return &fixed;
}
zp = tm_info.local;
prev = 0;
p = 0;
do
{
if (zp->type)
prev = zp->type;
if (!type || type == prev || !prev)
p = zp->type;
if (!type || type == p || !p)
{
if (tmword(name, end, zp->standard, NiL, 0))
{

View file

@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2012 AT&T Intellectual Property *
* Copyright (c) 1985-2013 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
@ -14,9 +14,9 @@
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* Glenn Fowler <glenn.s.fowler@gmail.com> *
* David Korn <dgkorn@gmail.com> *
* Phong Vo <phongvo@gmail.com> *
* *
***********************************************************************/
#pragma prototyped
@ -95,6 +95,7 @@ tvtouch(const char* path, register const Tv_t* av, register const Tv_t* mv, cons
#if _lib_utimets || _lib_utimensat
struct timespec ts[2];
#endif
#if !_lib_utimets
#if _lib_utimes
struct timeval am[2];
#else
@ -103,6 +104,7 @@ tvtouch(const char* path, register const Tv_t* av, register const Tv_t* mv, cons
#else
time_t am[2];
#endif
#endif
#endif
oerrno = errno;
@ -147,7 +149,7 @@ tvtouch(const char* path, register const Tv_t* av, register const Tv_t* mv, cons
return -1;
umask(mode = umask(0));
mode = (~mode) & (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, mode)) < 0)
if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode)) < 0)
return -1;
close(fd);
errno = oerrno;
@ -251,7 +253,7 @@ tvtouch(const char* path, register const Tv_t* av, register const Tv_t* mv, cons
errno = EINVAL;
return -1;
}
if ((fd = open(path, O_RDWR|O_cloexec)) >= 0)
if ((fd = open(path, O_RDWR|O_CLOEXEC)) >= 0)
{
char c;
@ -271,7 +273,7 @@ tvtouch(const char* path, register const Tv_t* av, register const Tv_t* mv, cons
return -1;
umask(mode = umask(0));
mode = (~mode) & (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, mode)) < 0)
if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode)) < 0)
return -1;
close(fd);
errno = oerrno;