Cygwin: rename localtime.cc to localtime_wrapper.c
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
159
winsup/cygwin/tzcode/localtime_wrapper.c
Normal file
159
winsup/cygwin/tzcode/localtime_wrapper.c
Normal file
@ -0,0 +1,159 @@
|
||||
/* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include "../winsup.h"
|
||||
#include "../sync.h"
|
||||
#include "../include/cygwin/version.h"
|
||||
#include "tz_posixrules.h"
|
||||
|
||||
static NO_COPY muto tzset_guard;
|
||||
|
||||
// Convert these NetBSD rwlock ops into Cygwin muto ops
|
||||
#define rwlock_wrlock(X) tzset_guard.init("tzset_guard")->acquire()
|
||||
#define rwlock_unlock(X) tzset_guard.release()
|
||||
|
||||
// Set these NetBSD-related option #defines appropriately for Cygwin
|
||||
//#define STD_INSPIRED // early-include private.h below does this
|
||||
#define lint
|
||||
#define HAVE_POSIX_DECLS 0
|
||||
#define USG_COMPAT 1
|
||||
#define NO_ERROR_IN_DST_GAP
|
||||
#define state __state
|
||||
|
||||
// Turn a specific known kind of const parameter into non-const
|
||||
#define __UNCONST(X) ((char *) (X))
|
||||
|
||||
// Turn off these NetBSD audit-related definitions
|
||||
#define __aconst
|
||||
#define _DIAGASSERT(X)
|
||||
|
||||
// Supply this Cygwin-specific function in advance of its use in localtime.c
|
||||
static char *
|
||||
tzgetwintzi (char *wildabbr, char *outbuf)
|
||||
{
|
||||
TIME_ZONE_INFORMATION tzi;
|
||||
char *cp, *dst;
|
||||
wchar_t *wsrc;
|
||||
div_t d;
|
||||
|
||||
GetTimeZoneInformation (&tzi);
|
||||
dst = cp = outbuf;
|
||||
for (wsrc = tzi.StandardName; *wsrc; wsrc++)
|
||||
if (*wsrc >= L'A' && *wsrc <= L'Z')
|
||||
*dst++ = *wsrc;
|
||||
if ((dst - cp) < 3)
|
||||
{
|
||||
/* In non-english Windows, converted tz.StandardName
|
||||
may not contain a valid standard timezone name. */
|
||||
strcpy (cp, wildabbr);
|
||||
cp += strlen (wildabbr);
|
||||
}
|
||||
else
|
||||
cp = dst;
|
||||
d = div (tzi.Bias + tzi.StandardBias, 60);
|
||||
__small_sprintf (cp, "%d", d.quot);
|
||||
if (d.rem)
|
||||
__small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
|
||||
if (tzi.StandardDate.wMonth)
|
||||
{
|
||||
cp = strchr (cp, 0);
|
||||
dst = cp;
|
||||
for (wsrc = tzi.DaylightName; *wsrc; wsrc++)
|
||||
if (*wsrc >= L'A' && *wsrc <= L'Z')
|
||||
*dst++ = *wsrc;
|
||||
if ((dst - cp) < 3)
|
||||
{
|
||||
/* In non-english Windows, converted tz.DaylightName
|
||||
may not contain a valid daylight timezone name. */
|
||||
strcpy (cp, wildabbr);
|
||||
cp += strlen (wildabbr);
|
||||
}
|
||||
else
|
||||
cp = dst;
|
||||
d = div (tzi.Bias + tzi.DaylightBias, 60);
|
||||
__small_sprintf (cp, "%d", d.quot);
|
||||
if (d.rem)
|
||||
__small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
|
||||
cp = strchr (cp, 0);
|
||||
__small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
|
||||
tzi.DaylightDate.wMonth,
|
||||
tzi.DaylightDate.wDay,
|
||||
tzi.DaylightDate.wDayOfWeek,
|
||||
tzi.DaylightDate.wHour);
|
||||
if (tzi.DaylightDate.wMinute || tzi.DaylightDate.wSecond)
|
||||
__small_sprintf (cp = strchr (cp, 0), ":%d",
|
||||
tzi.DaylightDate.wMinute);
|
||||
if (tzi.DaylightDate.wSecond)
|
||||
__small_sprintf (cp = strchr (cp, 0), ":%d",
|
||||
tzi.DaylightDate.wSecond);
|
||||
cp = strchr (cp, 0);
|
||||
__small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
|
||||
tzi.StandardDate.wMonth,
|
||||
tzi.StandardDate.wDay,
|
||||
tzi.StandardDate.wDayOfWeek,
|
||||
tzi.StandardDate.wHour);
|
||||
if (tzi.StandardDate.wMinute || tzi.StandardDate.wSecond)
|
||||
__small_sprintf (cp = strchr (cp, 0), ":%d",
|
||||
tzi.StandardDate.wMinute);
|
||||
if (tzi.StandardDate.wSecond)
|
||||
__small_sprintf (cp = strchr (cp, 0), ":%d",
|
||||
tzi.StandardDate.wSecond);
|
||||
}
|
||||
/* __small_printf ("TZ deduced as `%s'\n", outbuf); */
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
// Get ready to wrap NetBSD's localtime.c
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Pull these in early to catch any small issues before the real test
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
/* Some NetBSD differences were too difficult to work around..
|
||||
so #include a patched copy of localtime.c rather than the NetBSD original.
|
||||
Here is a list of the patches...
|
||||
(1) fix an erroneous decl of tzdirslash size (flagged by g++)
|
||||
(2) add conditional call to Cygwin's tzgetwintzi() from tzsetlcl()
|
||||
(3) add Cygwin's historical "posixrules" support to tzloadbody()
|
||||
*/
|
||||
#include "localtime.c.patched"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Don't forget these Cygwin-specific additions from this point to EOF
|
||||
EXPORT_ALIAS (tzset_unlocked, _tzset_unlocked)
|
||||
|
||||
extern "C" long
|
||||
__cygwin_gettzoffset (const struct tm *tmp)
|
||||
{
|
||||
#ifdef TM_GMTOFF
|
||||
if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
|
||||
return tmp->TM_GMTOFF;
|
||||
#endif /* defined TM_GMTOFF */
|
||||
__tzinfo_type *tz = __gettzinfo ();
|
||||
/* The sign of this is exactly opposite the envvar TZ. We
|
||||
could directly use the global _timezone for tm_isdst==0,
|
||||
but have to use __tzrule for daylight savings. */
|
||||
long offset = -tz->__tzrule[tmp->tm_isdst > 0].offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
extern "C" const char *
|
||||
__cygwin_gettzname (const struct tm *tmp)
|
||||
{
|
||||
#ifdef TM_ZONE
|
||||
if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
|
||||
return tmp->TM_ZONE;
|
||||
#endif
|
||||
return _tzname[tmp->tm_isdst > 0];
|
||||
}
|
Reference in New Issue
Block a user