]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/tzcode/localtime_wrapper.c
Cygwin: move localtime.o build rule to end of file
[newlib-cygwin.git] / winsup / cygwin / tzcode / localtime_wrapper.c
1 /* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file.
2
3 This file is part of Cygwin.
4
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
8
9 #include "../winsup.h"
10 #include "../sync.h"
11 #include "../include/cygwin/version.h"
12 #include "tz_posixrules.h"
13
14 static 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
36 static char *
37 tzgetwintzi (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
113 extern "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
134 EXPORT_ALIAS (tzset_unlocked, _tzset_unlocked)
135
136 extern "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
151 extern "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.042519 seconds and 5 git commands to generate.