1 /* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file.
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
11 #include "../include/cygwin/version.h"
12 #include "tz_posixrules.h"
14 static NO_COPY muto tzset_guard
;
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()
20 // Set these NetBSD-related option #defines appropriately for Cygwin
21 //#define STD_INSPIRED // early-include private.h below does this
23 #define HAVE_POSIX_DECLS 0
25 #define NO_ERROR_IN_DST_GAP
28 // Turn a specific known kind of const parameter into non-const
29 #define __UNCONST(X) ((char *) (X))
31 // Turn off these NetBSD audit-related definitions
33 #define _DIAGASSERT(X)
35 // Supply this Cygwin-specific function in advance of its use in localtime.c
37 tzgetwintzi (char *wildabbr
, char *outbuf
)
39 TIME_ZONE_INFORMATION tzi
;
44 GetTimeZoneInformation (&tzi
);
46 for (wsrc
= tzi
.StandardName
; *wsrc
; wsrc
++)
47 if (*wsrc
>= L
'A' && *wsrc
<= L
'Z')
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
);
58 d
= div (tzi
.Bias
+ tzi
.StandardBias
, 60);
59 __small_sprintf (cp
, "%d", d
.quot
);
61 __small_sprintf (cp
= strchr (cp
, 0), ":%d", abs (d
.rem
));
62 if (tzi
.StandardDate
.wMonth
)
66 for (wsrc
= tzi
.DaylightName
; *wsrc
; wsrc
++)
67 if (*wsrc
>= L
'A' && *wsrc
<= L
'Z')
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
);
78 d
= div (tzi
.Bias
+ tzi
.DaylightBias
, 60);
79 __small_sprintf (cp
, "%d", d
.quot
);
81 __small_sprintf (cp
= strchr (cp
, 0), ":%d", abs (d
.rem
));
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
);
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
);
107 /* __small_printf ("TZ deduced as `%s'\n", outbuf); */
111 // Get ready to wrap NetBSD's localtime.c
116 // Pull these in early to catch any small issues before the real test
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()
127 #include "localtime.c.patched"
133 // Don't forget these Cygwin-specific additions from this point to EOF
134 EXPORT_ALIAS (tzset_unlocked
, _tzset_unlocked
)
137 __cygwin_gettzoffset (const struct tm
*tmp
)
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
;
151 extern "C" const char *
152 __cygwin_gettzname (const struct tm
*tmp
)
155 if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS
)
158 return _tzname
[tmp
->tm_isdst
> 0];