1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
/*
********************************************************************************
**
** \file ./boot/startup/src/localtime.c
**
** \version $Id: localtime.c 6304 2016-03-18 03:39:06Z chenke $
**
** \brief ARM1176 RealView libc function retargeting.
**
** This files retargets the time-specific function localtime().
**
** \attention THIS SAMPLE CODE IS PROVIDED AS IS. FUJITSU MICROELECTRONICS
** ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
** OMMISSIONS.
**
** (C) Copyright 2006-2010 by Fujitsu Microelectronics Europe GmbH
** (C) Copyright 2010 by Fujitsu Semiconductor Europe GmbH
**
********************************************************************************
**
** \note The following LINT statements have been suppressed:
**
** - Warning 438: Last value assigned to variable not used.
** - Warning 586: function 'mktime' is deprecated. [MISRA 2004 Rule 20.12]
** - Note 961: Violates MISRA 2004 Advisory Rule 19.7, Function-like macro
** defined
*****************************************************************************
*/
//**************************************************************************
//**************************************************************************
//** Standard includes
//**************************************************************************
//**************************************************************************
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "internal.h"
#include "errno.h"
//**************************************************************************
//**************************************************************************
//** FAPI includes
//**************************************************************************
//**************************************************************************
//**************************************************************************
//**************************************************************************
//** Defines and Macros
//**************************************************************************
//**************************************************************************
/*lint -save -e(961) */
#define IS_HIGH_BIT_SET(val) (((1LL << ((sizeof(val) * 8) - 1)) & val) != 0)
/*lint -restore */
//**************************************************************************
//**************************************************************************
//** Global Data
//**************************************************************************
//**************************************************************************
static struct tm _localtime_tm;
//******************************************************************************
//******************************************************************************
//** Local Functions Declaration
//******************************************************************************
//******************************************************************************
int _is_dst(time_t t);
//******************************************************************************
//******************************************************************************
//** API Functions
//******************************************************************************
//******************************************************************************
/*
********************************************************************************
** \brief Retarget implementation of the stdc library function.
**
** This is the standard C library gmtime() function from time.h.
**
** The localtime() function shall convert the time in seconds since the epoch
** pointed to by timer into a broken-down time, expressed as a local time.
** The function corrects for the timezone and any seasonal time adjustments.
** Local timezone information is used as though localtime() calls tzset().
**
** The relationship between a time in seconds since the Epoch used as an
** argument to localtime() and the tm structure (defined in the <time.h> header) is
** that the result shall be as specified in the expression given in the
** definition of seconds since the Epoch (see the Base Definitions volume of
** IEEE Std 1003.1-2001, Section 4.14, Seconds Since the Epoch), where the names
** in the structure and in the expression correspond.
**
** The asctime(), ctime(), gmtime(), and localtime() functions shall return
** values in one of two static objects: a broken-down time structure and an
** array of type char. Execution of any of the functions may overwrite the
** information returned in either of these objects by any of the other
** functions.
**
** \param timer Pointer to time in seconds since the epoch (00:00:00 UTC on
** 1 January 1970)
**
** \return Upon successful completion, the localtime() function shall return a
** pointer to the broken-down time structure. If an error is detected,
** localtime() shall return a null pointer and set errno to indicate the error.
** ERRORS:
** - EOVERFLOW The result cannot be represented.
********************************************************************************
*/
struct tm * localtime_r(const time_t *timer,struct tm * tmp)
{
struct tm *tm = tmp;
uint32_t cpu_flags;
/* check parameter validity */
if (timer == NULL) {
return (NULL);
}
/* check parameter validity */
if (tm == NULL) {
return (NULL);
}
/* irrespective of values sign representation, high bit set in time_t leads
to an invalid (overflow) result */
if (IS_HIGH_BIT_SET(*timer)) {
/*lint -e{48,63} */
errno = EOVERFLOW;
return (NULL);
}
/* update time zone values based on environment variable TZ */
tzset();
//////////////////////////////////
cpu_flags = st_enter_crit_func();
//////////////////////////////////
/* reset local time structure */
memset(tm, 0x0, sizeof(struct tm));
/* fill up time based on epoch using given seconds */
tm->tm_year = 70;
tm->tm_mday = 1;
tm->tm_sec = (int) *timer - (int) _timezone; /* ignore DST offset first */
tm->tm_isdst = _is_dst((time_t) tm->tm_sec);
if (tm->tm_isdst) { /* do DST correction */
tm->tm_sec -= (int) _daylight;
}
/* check if overflow has happened */
/* irrespective of values sign representation, high bit set leads to an
invalid (overflow) result */
if (IS_HIGH_BIT_SET(tm->tm_sec)) {
/*lint -e{48,63} */
errno = EOVERFLOW;
return (NULL);
}
/* normalize data */
/*lint -e(586) */
mktime(tm);
//////////////////////////////
st_exit_crit_func(cpu_flags);
//////////////////////////////
return (tm);
}
//******************************************************************************
//******************************************************************************
//** Local Functions
//******************************************************************************
//******************************************************************************
/*
********************************************************************************
** \brief Determines if the daylight savings time should be applied.
**
** This function should normally implement the various DST rules applied to
** different timezones, which would imply extensive calculation.
**
** \attention The current implementation is very limited, simply informing if
** the DST is activated in the TZ variable.
** This means this implementation only works correct if the current time zone
** value is updated accordingly.
**
** \param now defines the current timestamp, where DST is checked to be applied.
**
** \return
** - 1, if actual time stamp is in DST range
** - 0, otherwise
********************************************************************************
*/
/*lint -e{438} */
int _is_dst(time_t now)
{
now = now;
if (!_daylight) {
return (0);
}
return (1);
}
struct tm * localtime(const time_t *timer)
{
return localtime_r(timer,&_localtime_tm);
}
|