diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2002-04-17 21:23:31 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2002-04-17 21:23:31 +0000 |
commit | 10d002160949c985e6f99fb8d647d5e3c67ef554 (patch) | |
tree | 6ffe46b0b090120c2a251ffc2ce19574fb5f1dfb /newlib/libc/time/tzset_r.c | |
parent | a26c50352b4db457813ef86fb053bd838d310d30 (diff) | |
download | newlib-10d002160949c985e6f99fb8d647d5e3c67ef554.zip newlib-10d002160949c985e6f99fb8d647d5e3c67ef554.tar.gz newlib-10d002160949c985e6f99fb8d647d5e3c67ef554.tar.bz2 |
2002-04-17 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/time.h (tzset, _tzset_r): Added prototypes.
(strptime): Moved prototype to be within !__STRICT_ANSI__.
(_tzname, _daylight, _timezone): No long __CYGWIN__ only.
(tzname): Defined for all platforms.
(daylight, timezone): Defined only for CYGWIN.
* libc/sys/linux/machine/i386/crt0.c: Add call to tzset() after
environment set up.
* libc/stdlib/setenv_r.c (_setenv_r): Call tzset() if the TZ
environment variable is set.
* libc/time/Makefile.am: Add support for tzset.c, tzlock.c, and
tzset_r.c.
* libc/time/Makefile.in: Regenerated.
* libc/time/gmtime.c (gmtime): Changed to call gmtime_r.
* libc/time/gmtime_r.c (gmtime_r): Changed to call _mktm_r.
* libc/time/lcltime_r.c (lcltime_r): Ditto.
* libc/time/local.h: New local header file.
* libc/time/mktime.c (mktime): Add timezone support.
* libc/time/mktm_r.c: New file which is the common engine
for gmtime_r and lcltime_r. This code has timezone support.
* libc/time/strftime.c (strftime): Add %Z timezone support.
* libc/time/tzlock.c: New file containing timezone lock stubs.
* libc/time/tzset.c: New file containing tzset() routine.
* libc/time/tzset_r.c: New file containing _tzset_r and
internal routine for calculating timezone changes for specified year.
Diffstat (limited to 'newlib/libc/time/tzset_r.c')
-rw-r--r-- | newlib/libc/time/tzset_r.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/newlib/libc/time/tzset_r.c b/newlib/libc/time/tzset_r.c new file mode 100644 index 0000000..a083e5b --- /dev/null +++ b/newlib/libc/time/tzset_r.c @@ -0,0 +1,204 @@ +#include <_ansi.h> +#include <reent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include "local.h" + +static char __tzname_std[11]; +static char __tzname_dst[11]; +static char *prev_tzenv = NULL; + +/* default to GMT */ +char *_tzname[2] = {"GMT" "GMT"}; +int _daylight = 0; +time_t _timezone = (time_t)0; + +int __tzyear = 0; + +int __tznorth = 1; + +__tzrule_type __tzrule[2] = { {'J', 0, 0, 0, 0, (time_t)0, 0 }, + {'J', 0, 0, 0, 0, (time_t)0, 0 } }; + +_VOID +_DEFUN (_tzset_r, (reent_ptr), + struct _reent *reent_ptr) +{ + char *tzenv; + int hh, mm, ss, sign, m, w, d, n; + int i, ch; + + if ((tzenv = _getenv_r (reent_ptr, "TZ")) == NULL) + { + TZ_LOCK; + _timezone = (time_t)0; + _daylight = 0; + _tzname[0] = "GMT"; + _tzname[1] = "GMT"; + TZ_UNLOCK; + return; + } + + TZ_LOCK; + + if (prev_tzenv != NULL && strcmp(tzenv, prev_tzenv) == 0) + { + TZ_UNLOCK; + return; + } + + free(prev_tzenv); + prev_tzenv = _strdup_r (reent_ptr, tzenv); + + /* ignore implementation-specific format specifier */ + if (*tzenv == ':') + ++tzenv; + + if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_std, &n) <= 0) + { + TZ_UNLOCK; + return; + } + + tzenv += n; + + sign = 1; + if (*tzenv == '-') + { + sign = -1; + ++tzenv; + } + else if (*tzenv == '+') + ++tzenv; + + mm = 0; + ss = 0; + + if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) < 1) + { + TZ_UNLOCK; + return; + } + + __tzrule[0].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh); + _tzname[0] = __tzname_std; + tzenv += n; + + if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_dst, &n) <= 0) + { + _tzname[1] = _tzname[0]; + TZ_UNLOCK; + return; + } + else + _tzname[1] = __tzname_dst; + + tzenv += n; + + /* otherwise we have a dst name, look for the offset */ + sign = 1; + if (*tzenv == '-') + { + sign = -1; + ++tzenv; + } + else if (*tzenv == '+') + ++tzenv; + + hh = 0; + mm = 0; + ss = 0; + + if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) <= 0) + __tzrule[1].offset = __tzrule[0].offset - 3600; + else + __tzrule[1].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh); + + tzenv += n; + + if (*tzenv == ',') + ++tzenv; + + for (i = 0; i < 2; ++i) + { + if (*tzenv == 'M') + { + if (sscanf (tzenv, "M%hu%n.%hu%n.%hu%n", &m, &n, &w, &n, &d, &n) != 3 || + m < 1 || m > 12 || w < 1 || w > 5 || d > 6) + { + TZ_UNLOCK; + return; + } + + __tzrule[i].ch = 'M'; + __tzrule[i].m = m; + __tzrule[i].n = w; + __tzrule[i].d = d; + + tzenv += n; + } + else + { + char *end; + if (*tzenv == 'J') + { + ch = 'J'; + ++tzenv; + } + else + ch = 'D'; + + d = strtoul (tzenv, &end, 10); + + /* if unspecified, default to US settings */ + if (end == tzenv) + { + if (i == 0) + { + __tzrule[0].ch = 'M'; + __tzrule[0].m = 4; + __tzrule[0].n = 1; + __tzrule[0].d = 0; + } + else + { + __tzrule[1].ch = 'M'; + __tzrule[1].m = 10; + __tzrule[1].n = 5; + __tzrule[1].d = 0; + } + } + else + { + __tzrule[i].ch = ch; + __tzrule[i].d = d; + } + + tzenv = end; + } + + /* default time is 02:00:00 am */ + hh = 2; + mm = 0; + ss = 0; + + if (*tzenv == '/') + sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n); + + __tzrule[i].s = ss + SECSPERMIN * mm + SECSPERHOUR * hh; + } + + __tzcalc_limits (__tzyear); + _timezone = (time_t)(__tzrule[0].offset); + _daylight = __tzrule[0].offset != __tzrule[1].offset; + + TZ_UNLOCK; +} + + + + + |