]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/tzcode/localtime_wrapper.c
Cygwin: rename localtime.cc to localtime_wrapper.c
[newlib-cygwin.git] / winsup / cygwin / tzcode / localtime_wrapper.c
CommitLineData
63ff2b84
MG
1/* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file.
2
3This file is part of Cygwin.
4
5This software is a copyrighted work licensed under the terms of the
6Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7details. */
8
9#include "../winsup.h"
10#include "../sync.h"
11#include "../include/cygwin/version.h"
12#include "tz_posixrules.h"
13
14static NO_COPY muto tzset_guard;
15
16// Convert these NetBSD rwlock ops into Cygwin muto ops
17#define rwlock_wrlock(X) tzset_guard.init("tzset_guard")->acquire()
18#define rwlock_unlock(X) tzset_guard.release()
19
20// Set these NetBSD-related option #defines appropriately for Cygwin
21//#define STD_INSPIRED // early-include private.h below does this
22#define lint
23#define HAVE_POSIX_DECLS 0
24#define USG_COMPAT 1
25#define NO_ERROR_IN_DST_GAP
26#define state __state
27
28// Turn a specific known kind of const parameter into non-const
29#define __UNCONST(X) ((char *) (X))
30
31// Turn off these NetBSD audit-related definitions
32#define __aconst
33#define _DIAGASSERT(X)
34
35// Supply this Cygwin-specific function in advance of its use in localtime.c
36static char *
37tzgetwintzi (char *wildabbr, char *outbuf)
38{
39 TIME_ZONE_INFORMATION tzi;
40 char *cp, *dst;
41 wchar_t *wsrc;
42 div_t d;
43
44 GetTimeZoneInformation (&tzi);
45 dst = cp = outbuf;
46 for (wsrc = tzi.StandardName; *wsrc; wsrc++)
47 if (*wsrc >= L'A' && *wsrc <= L'Z')
48 *dst++ = *wsrc;
49 if ((dst - cp) < 3)
50 {
51 /* In non-english Windows, converted tz.StandardName
52 may not contain a valid standard timezone name. */
53 strcpy (cp, wildabbr);
54 cp += strlen (wildabbr);
55 }
56 else
57 cp = dst;
58 d = div (tzi.Bias + tzi.StandardBias, 60);
59 __small_sprintf (cp, "%d", d.quot);
60 if (d.rem)
61 __small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
62 if (tzi.StandardDate.wMonth)
63 {
64 cp = strchr (cp, 0);
65 dst = cp;
66 for (wsrc = tzi.DaylightName; *wsrc; wsrc++)
67 if (*wsrc >= L'A' && *wsrc <= L'Z')
68 *dst++ = *wsrc;
69 if ((dst - cp) < 3)
70 {
71 /* In non-english Windows, converted tz.DaylightName
72 may not contain a valid daylight timezone name. */
73 strcpy (cp, wildabbr);
74 cp += strlen (wildabbr);
75 }
76 else
77 cp = dst;
78 d = div (tzi.Bias + tzi.DaylightBias, 60);
79 __small_sprintf (cp, "%d", d.quot);
80 if (d.rem)
81 __small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
82 cp = strchr (cp, 0);
83 __small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
84 tzi.DaylightDate.wMonth,
85 tzi.DaylightDate.wDay,
86 tzi.DaylightDate.wDayOfWeek,
87 tzi.DaylightDate.wHour);
88 if (tzi.DaylightDate.wMinute || tzi.DaylightDate.wSecond)
89 __small_sprintf (cp = strchr (cp, 0), ":%d",
90 tzi.DaylightDate.wMinute);
91 if (tzi.DaylightDate.wSecond)
92 __small_sprintf (cp = strchr (cp, 0), ":%d",
93 tzi.DaylightDate.wSecond);
94 cp = strchr (cp, 0);
95 __small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
96 tzi.StandardDate.wMonth,
97 tzi.StandardDate.wDay,
98 tzi.StandardDate.wDayOfWeek,
99 tzi.StandardDate.wHour);
100 if (tzi.StandardDate.wMinute || tzi.StandardDate.wSecond)
101 __small_sprintf (cp = strchr (cp, 0), ":%d",
102 tzi.StandardDate.wMinute);
103 if (tzi.StandardDate.wSecond)
104 __small_sprintf (cp = strchr (cp, 0), ":%d",
105 tzi.StandardDate.wSecond);
106 }
107 /* __small_printf ("TZ deduced as `%s'\n", outbuf); */
108 return outbuf;
109}
110
111// Get ready to wrap NetBSD's localtime.c
112#ifdef __cplusplus
113extern "C" {
114#endif
115
116// Pull these in early to catch any small issues before the real test
117#include "private.h"
118#include "tzfile.h"
119
120/* Some NetBSD differences were too difficult to work around..
121 so #include a patched copy of localtime.c rather than the NetBSD original.
122 Here is a list of the patches...
123 (1) fix an erroneous decl of tzdirslash size (flagged by g++)
124 (2) add conditional call to Cygwin's tzgetwintzi() from tzsetlcl()
125 (3) add Cygwin's historical "posixrules" support to tzloadbody()
126*/
127#include "localtime.c.patched"
128
129#ifdef __cplusplus
130}
131#endif
132
133// Don't forget these Cygwin-specific additions from this point to EOF
134EXPORT_ALIAS (tzset_unlocked, _tzset_unlocked)
135
136extern "C" long
137__cygwin_gettzoffset (const struct tm *tmp)
138{
139#ifdef TM_GMTOFF
140 if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
141 return tmp->TM_GMTOFF;
142#endif /* defined TM_GMTOFF */
143 __tzinfo_type *tz = __gettzinfo ();
144 /* The sign of this is exactly opposite the envvar TZ. We
145 could directly use the global _timezone for tm_isdst==0,
146 but have to use __tzrule for daylight savings. */
147 long offset = -tz->__tzrule[tmp->tm_isdst > 0].offset;
148 return offset;
149}
150
151extern "C" const char *
152__cygwin_gettzname (const struct tm *tmp)
153{
154#ifdef TM_ZONE
155 if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
156 return tmp->TM_ZONE;
157#endif
158 return _tzname[tmp->tm_isdst > 0];
159}
This page took 0.036924 seconds and 5 git commands to generate.