Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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