1
0

tzset.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. ********************************************************************************
  3. **
  4. ** \file ./boot/startup/src/tzset.c
  5. **
  6. ** \version $Id: tzset.c 6304 2016-03-18 03:39:06Z chenke $
  7. **
  8. ** \brief ARM1176 RealView libc function retargeting.
  9. **
  10. ** This files retargets the time zone specific function tzset().
  11. **
  12. ** \attention THIS SAMPLE CODE IS PROVIDED AS IS. FUJITSU MICROELECTRONICS
  13. ** ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
  14. ** OMMISSIONS.
  15. **
  16. ** (C) Copyright 2006-2010 by Fujitsu Microelectronics Europe GmbH
  17. ** (C) Copyright 2010 by Fujitsu Semiconductor Europe GmbH
  18. **
  19. ********************************************************************************
  20. **
  21. ** \note The following LINT statements have been suppressed:
  22. **
  23. **
  24. *****************************************************************************
  25. */
  26. //**************************************************************************
  27. //**************************************************************************
  28. //** Standard includes
  29. //**************************************************************************
  30. //**************************************************************************
  31. //#include <stdchar.h>
  32. #include <stdint.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. //#include <time_ext.h>
  36. #include <time.h>
  37. #include "internal.h"
  38. //**************************************************************************
  39. //**************************************************************************
  40. //** FAPI includes
  41. //**************************************************************************
  42. //**************************************************************************
  43. //**************************************************************************
  44. //**************************************************************************
  45. //** Defines and Macros
  46. //**************************************************************************
  47. //**************************************************************************
  48. #ifndef TZNAME_MAX
  49. #define TZNAME_MAX 16
  50. #endif
  51. #define TZ_DEFAULT "GMT0"
  52. #define TZ_INIT_STD_OFFSET 0L // in seconds
  53. #define TZ_INIT_STD_NAME "GMT"
  54. #define TZ_INIT_DST_OFFSET 0 // in seconds
  55. #define TZ_INIT_DST_NAME ""
  56. #define TZ_DEFAULT_DST_OFFSET -3600 // in seconds
  57. //**************************************************************************
  58. //**************************************************************************
  59. //** Global Data
  60. //**************************************************************************
  61. //**************************************************************************
  62. static char _stdname[TZNAME_MAX] = TZ_INIT_STD_NAME;
  63. static char _dstname[TZNAME_MAX] = TZ_INIT_DST_NAME;
  64. char * _tzname[2] = { _stdname, _dstname };
  65. long _timezone = TZ_INIT_STD_OFFSET;
  66. int _daylight = TZ_INIT_DST_OFFSET;
  67. //******************************************************************************
  68. //******************************************************************************
  69. //** Local Functions Declaration
  70. //******************************************************************************
  71. //******************************************************************************
  72. static size_t scanTzString(char_t **tz, char_t *name);
  73. static int8_t scanTzOffset(char_t **tz, int32_t *offset);
  74. //******************************************************************************
  75. //******************************************************************************
  76. //** API Functions
  77. //******************************************************************************
  78. //******************************************************************************
  79. /*
  80. ********************************************************************************
  81. ** \brief Retarget implementation of the stdc library function.
  82. **
  83. ** This is the standard C library tzset() function from time.h.
  84. **
  85. ** The tzset() function shall use the value of the environment variable TZ to
  86. ** set time conversion information used by ctime(), localtime(), mktime() and
  87. ** strftime().
  88. ** The tzset() function also shall set the external variable daylight to 0
  89. ** if daylight savings time (DST) conversions should never be applied for the
  90. ** timezone in use; otherwise, non-zero. The external variable timezone shall be
  91. ** set to the difference, in seconds, between coordinated universal time (UTC)
  92. ** and local standard time.
  93. ********************************************************************************
  94. */
  95. void tzset( void )
  96. {
  97. char_t *tzdefault = TZ_DEFAULT;
  98. char_t std_name[TZNAME_MAX];
  99. char_t dst_name[TZNAME_MAX];
  100. int32_t std_offset = TZ_INIT_STD_OFFSET;
  101. int32_t dst_offset = TZ_INIT_DST_OFFSET;
  102. char_t *tz = getenv("TZ"); /* get the environment time zone setting */
  103. uint32_t cpu_flags;
  104. /* check, if tz string is valid */
  105. if (tz == NULL) {
  106. tz = tzdefault; /* if environment doesn't exist, use default */
  107. }
  108. /* extract std timzone name */
  109. if (scanTzString(&tz, std_name) == 0) {
  110. strcpy(std_name, TZ_INIT_STD_NAME);
  111. }
  112. /* extract std timzone offset (in s) */
  113. if (scanTzOffset(&tz, &std_offset) == 0) {
  114. std_offset = TZ_INIT_STD_OFFSET;
  115. }
  116. /* extract dst timzone name */
  117. if (scanTzString(&tz, dst_name) == 0) {
  118. strcpy(dst_name, TZ_INIT_DST_NAME);
  119. dst_offset = TZ_INIT_DST_OFFSET;
  120. }
  121. /* extract dst timzone offset (in s) relative to std */
  122. else if (scanTzOffset(&tz, &dst_offset) == 0) {
  123. dst_offset = TZ_DEFAULT_DST_OFFSET;
  124. }
  125. else {
  126. dst_offset -= std_offset;
  127. }
  128. //////////////////////////////////
  129. cpu_flags = st_enter_crit_func();
  130. //////////////////////////////////
  131. /* assign global values */
  132. _daylight = (strcmp(dst_name, "") != 0) ? dst_offset : 0;
  133. _timezone = std_offset;
  134. strcpy(tzname[0], std_name);
  135. strcpy(tzname[1], dst_name);
  136. //////////////////////////////
  137. st_exit_crit_func(cpu_flags);
  138. //////////////////////////////
  139. }
  140. //******************************************************************************
  141. //******************************************************************************
  142. //** Local Functions
  143. //******************************************************************************
  144. //******************************************************************************
  145. /*
  146. ********************************************************************************
  147. ** \brief Extracts (next) timezone (resp. DST) name from timezone string.
  148. **
  149. ** This function extracts the next occurrence of a timezone name (either std
  150. ** or dst) in the given timezone string.
  151. **
  152. ** \note A leading colon, which POSIX allows as an implementation-
  153. ** specific extension, is not supported.
  154. **
  155. ** \param tz (part of a) time zone string
  156. ** \param name extracted time zone (std resp. dst) name from first part of tz
  157. **
  158. ** \return length of extracted time zone name string
  159. ********************************************************************************
  160. */
  161. static size_t scanTzString(char_t **tz, char_t *name) {
  162. char_t *p = *tz;
  163. size_t i = 0;
  164. /* leading colon for implementation-specific extension is not supported */
  165. if (*p != ':') {
  166. while ((strchr("0123456789-+,", *p) == NULL) && (i < TZNAME_MAX)) {
  167. name[i++] = *p++;
  168. }
  169. /* finalize string */
  170. if (i == TZNAME_MAX) {
  171. --i;
  172. }
  173. name[i] = '\0';
  174. }
  175. *tz = p;
  176. return (i);
  177. }
  178. /*
  179. ********************************************************************************
  180. ** \brief Extracts (next) timezone (resp. DST) offset from timezone string.
  181. **
  182. ** This function extracts the next occurrence of a timezone offset (either std
  183. ** or dst) in the given timezone string.
  184. **
  185. ** \note A leading colon, which POSIX allows as an implementation-
  186. ** specific extension, is not supported.
  187. **
  188. ** \param tz (part of a) time zone string
  189. ** \param offset extracted time zone (std resp. dst) offset (in seconds) from
  190. ** first part of tz
  191. **
  192. ** \return
  193. ** - 1, if time zone value was successfully extracted and is valid,
  194. ** - 0, in error case
  195. ********************************************************************************
  196. */
  197. static int8_t scanTzOffset(char_t **tz, int32_t *offset) {
  198. int8_t sign;
  199. char_t *p;
  200. char_t *endp = 0;
  201. int32_t secs;
  202. int32_t v;
  203. /* check parameter valitidy */
  204. if ((offset == 0) || (tz == 0) || (*tz == 0)) {
  205. return (0);
  206. }
  207. /* extract hours value */
  208. v = strtol(*tz, &endp, 10);
  209. /* no offset value found */
  210. if (*tz == endp ) {
  211. return (0);
  212. }
  213. /* extract sign for correct calculation and latter assignment */
  214. sign = (v < 0) ? -1 : 1;
  215. v = v * sign;
  216. /* convert to seconds */
  217. secs = v * 3600L;
  218. /* extract minutes value */
  219. p = endp;
  220. if ( *p == ':' ) {
  221. p++;
  222. v = strtol(p, &endp, 10);
  223. if (p != endp) {
  224. secs += v * 60L;
  225. }
  226. /* extract seconds value */
  227. p = endp;
  228. if ( *p == ':' ) {
  229. p++;
  230. v = strtol(p, &endp, 10);
  231. if (p != endp) {
  232. secs += v;
  233. }
  234. p = endp;
  235. }
  236. }
  237. /* re-apply sign value */
  238. *offset = sign * secs;
  239. /* move timezone pointer to the residual string */
  240. *tz = p;
  241. return(1);
  242. }