source: trunk/libs/newlib/src/newlib/libc/time/tzset_r.c @ 543

Last change on this file since 543 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 3.7 KB
Line 
1#include <_ansi.h>
2#include <reent.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/time.h>
8#include "local.h"
9
10#define sscanf siscanf  /* avoid to pull in FP functions. */
11
12static char __tzname_std[11];
13static char __tzname_dst[11];
14static char *prev_tzenv = NULL;
15
16void
17_tzset_unlocked_r (struct _reent *reent_ptr)
18{
19  char *tzenv;
20  unsigned short hh, mm, ss, m, w, d;
21  int sign, n;
22  int i, ch;
23  __tzinfo_type *tz = __gettzinfo ();
24
25  if ((tzenv = _getenv_r (reent_ptr, "TZ")) == NULL)
26      {
27        _timezone = 0;
28        _daylight = 0;
29        _tzname[0] = "GMT";
30        _tzname[1] = "GMT";
31        free(prev_tzenv);
32        prev_tzenv = NULL;
33        return;
34      }
35
36  if (prev_tzenv != NULL && strcmp(tzenv, prev_tzenv) == 0)
37    return;
38
39  free(prev_tzenv);
40  prev_tzenv = _malloc_r (reent_ptr, strlen(tzenv) + 1);
41  if (prev_tzenv != NULL)
42    strcpy (prev_tzenv, tzenv);
43
44  /* ignore implementation-specific format specifier */
45  if (*tzenv == ':')
46    ++tzenv; 
47
48  if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_std, &n) <= 0)
49    return;
50 
51  tzenv += n;
52
53  sign = 1;
54  if (*tzenv == '-')
55    {
56      sign = -1;
57      ++tzenv;
58    }
59  else if (*tzenv == '+')
60    ++tzenv;
61
62  mm = 0;
63  ss = 0;
64 
65  if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) < 1)
66    return;
67 
68  tz->__tzrule[0].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh);
69  _tzname[0] = __tzname_std;
70  tzenv += n;
71 
72  if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_dst, &n) <= 0)
73    { /* No dst */
74      _tzname[1] = _tzname[0];
75      _timezone = tz->__tzrule[0].offset;
76      _daylight = 0;
77      return;
78    }
79  else
80    _tzname[1] = __tzname_dst;
81
82  tzenv += n;
83
84  /* otherwise we have a dst name, look for the offset */
85  sign = 1;
86  if (*tzenv == '-')
87    {
88      sign = -1;
89      ++tzenv;
90    }
91  else if (*tzenv == '+')
92    ++tzenv;
93
94  hh = 0; 
95  mm = 0;
96  ss = 0;
97 
98  n  = 0;
99  if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) <= 0)
100    tz->__tzrule[1].offset = tz->__tzrule[0].offset - 3600;
101  else
102    tz->__tzrule[1].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh);
103
104  tzenv += n;
105
106  for (i = 0; i < 2; ++i)
107    {
108      if (*tzenv == ',')
109        ++tzenv;
110
111      if (*tzenv == 'M')
112        {
113          if (sscanf (tzenv, "M%hu%n.%hu%n.%hu%n", &m, &n, &w, &n, &d, &n) != 3 ||
114              m < 1 || m > 12 || w < 1 || w > 5 || d > 6)
115            return;
116         
117          tz->__tzrule[i].ch = 'M';
118          tz->__tzrule[i].m = m;
119          tz->__tzrule[i].n = w;
120          tz->__tzrule[i].d = d;
121         
122          tzenv += n;
123        }
124      else 
125        {
126          char *end;
127          if (*tzenv == 'J')
128            {
129              ch = 'J';
130              ++tzenv;
131            }
132          else
133            ch = 'D';
134         
135          d = strtoul (tzenv, &end, 10);
136         
137          /* if unspecified, default to US settings */
138          /* From 1987-2006, US was M4.1.0,M10.5.0, but starting in 2007 is
139           * M3.2.0,M11.1.0 (2nd Sunday March through 1st Sunday November)  */
140          if (end == tzenv)
141            {
142              if (i == 0)
143                {
144                  tz->__tzrule[0].ch = 'M';
145                  tz->__tzrule[0].m = 3;
146                  tz->__tzrule[0].n = 2;
147                  tz->__tzrule[0].d = 0;
148                }
149              else
150                {
151                  tz->__tzrule[1].ch = 'M';
152                  tz->__tzrule[1].m = 11;
153                  tz->__tzrule[1].n = 1;
154                  tz->__tzrule[1].d = 0;
155                }
156            }
157          else
158            {
159              tz->__tzrule[i].ch = ch;
160              tz->__tzrule[i].d = d;
161            }
162         
163          tzenv = end;
164        }
165     
166      /* default time is 02:00:00 am */
167      hh = 2;
168      mm = 0;
169      ss = 0;
170      n = 0;
171     
172      if (*tzenv == '/')
173        sscanf (tzenv, "/%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n);
174
175      tz->__tzrule[i].s = ss + SECSPERMIN * mm + SECSPERHOUR  * hh;
176     
177      tzenv += n;
178    }
179
180  __tzcalc_limits (tz->__tzyear);
181  _timezone = tz->__tzrule[0].offset; 
182  _daylight = tz->__tzrule[0].offset != tz->__tzrule[1].offset;
183}
184
185void
186_tzset_r (struct _reent *reent_ptr)
187{
188  TZ_LOCK;
189  _tzset_unlocked_r (reent_ptr);
190  TZ_UNLOCK;
191}
Note: See TracBrowser for help on using the repository browser.