OSDN Git Service

Refactor <time.h> vs. <wchar.h> to avoid duplication.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Mon, 15 Feb 2016 14:37:15 +0000 (14:37 +0000)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Mon, 15 Feb 2016 14:37:15 +0000 (14:37 +0000)
mingwrt/ChangeLog
mingwrt/include/time.h
mingwrt/include/wchar.h

index f78f886..d91fd87 100644 (file)
@@ -1,3 +1,21 @@
+2016-02-15  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       Refactor <time.h> vs. <wchar.h> to avoid duplication.
+
+       * include/wchar.h (__WCHAR_H_SOURCED__): New macro; define it...
+       [_WCHAR_H]: ...at start of processing in this scope; delete at end.
+       (struct tm): Delete definition; delegate it, together with each of...
+       (_wctime, _wasctime, _wstrdate, _wstrtime, _wctime64, _wctime32)
+       (wcsftime): ...these function prototypes; delete them, but note in
+       comments, that they remain declared, via delegation to...
+       * include/time.h: ...this; include it selectively, subject to...
+       [defined __WCHAR_H_SOURCED__](__need_wchar_decls): ...this; define it.
+       [defined __WCHAR_H_SOURCED__](_TIME_H): Suppress its definition.
+       [_TIME_H]: Process all definitions and declarations; otherwise...
+       [__need_wchar_decls]: ...process only <wchar.h> shared content, but...
+       [_TIME_H && _WCHAR_H]: ...not on second, or later, time of processing.
+       (_WTIME_DEFINED): Obsolete macro; delete all references.
+
 2016-02-11  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Implement support for POSIX "%n$*m$" printf() format control.
index bf582ea..48b5db6 100644 (file)
@@ -6,7 +6,7 @@
  * $Id$
  *
  * Written by Rob Savoye <rob@cygnus.com>
- * Copyright (C) 1997-2007, 2011, 2015, MinGW.org Project.
+ * Copyright (C) 1997-2007, 2011, 2015, 2016, MinGW.org Project.
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  *
  */
 #ifndef _TIME_H
-#define _TIME_H
+#pragma GCC system_header
+
+/* To support selective partial inclusion, we do not immediately define
+ * the normal _TIME_H guard macro; initially, we also clear all of those
+ * declaraction subset selection macros which are applicable herein.
+ */
+#undef __need_struct_timespec
+#undef __need_wchar_decls
+
+#if defined __WCHAR_H_SOURCED__
+/* This is selective inclusion by <wchar.h>, exposing only a subset of the
+ * content from <time.h>; thus, we do not define the _TIME_H guard macro, so
+ * we need to fake it, to get content from <parts/time.h>
+ */
+# define _FAKE_TIME_H_SOURCED 1
+# define __need_wchar_decls 1
+
+/* Both ISO-C and POSIX stipulate that <wchar.h> shall declare "struct tm"
+ * as an incomplete structure, with its complete declaration to be provided
+ * by <time.h>; provide an incomplete forward declaration, to satisfy this
+ * minimal requirement for selective inclusion by <wchar.h>
+ */
+struct tm;
 
-/* All the headers include this file. */
+#else
+#define _TIME_H
+/* This is normal inclusion of <time.h>, in its own right.  All our system
+ * headers are required to include <_mingw.h>, but in the case of selective
+ * inclusion, we delegate that responsibility to the including header; when
+ * including <time.h> directly, we must fulfil this requirement now.
+ */
 #include <_mingw.h>
 
 /* Number of clock ticks per second. A clock tick is the unit by which
 #define CLOCKS_PER_SEC ((clock_t)(1000))
 #define CLK_TCK        CLOCKS_PER_SEC
 
+#define __need_struct_timespec 1
+#define __need_wchar_decls 1
+#endif
+
 #ifndef RC_INVOKED
-/*
- * Some elements declared in time.h may also be required by other
- * header files, without necessarily including time.h itself; such
- * elements are declared in the local parts/time.h system header file.
- * Declarations for such elements must be selected prior to inclusion:
+/* Some elements declared in <time.h> may also be required by other
+ * header files, without necessarily including <time.h> itself; such
+ * elements are declared in the local <parts/time.h> system header,
+ * and must be selected prior to inclusion:
  */
 #define __need_time_t
-#define __need_struct_timespec
 #include <parts/time.h>
 
-/* time.h is also required to duplicate the following type definitions,
- * which are nominally defined in stddef.h
+#ifdef _TIME_H
+#ifdef _MINGW32_EXTENDED_SOURCE
+__CRT_ALIAS __LIBIMPL__(( FUNCTION = mingw_timespec ))
+/* This non-ANSI convenience function facilitates access to entities
+ * defined as struct timespec, while exposing the broken down form of
+ * the tv_sec field, as declared within struct __mingw32_timespec.  It
+ * is exposed only when _MINGW32_EXTENDED_SOURCE is defined, which is
+ * normally implicitly the case, except when in __STRICT_ANSI__ mode
+ * unless the user defines it explicitly.
+ */
+struct __mingw32_expanded_timespec *mingw_timespec( struct timespec *__tv )
+{ return (struct __mingw32_expanded_timespec *)(__tv); }
+#endif
+
+/* <time.h> is also required to duplicate the following type definitions,
+ * which are nominally defined in <stddef.h>
  */
 #define __need_NULL
 #define __need_wchar_t
  */
 typedef long clock_t;
 
-#ifndef _TM_DEFINED
-/*
- * A structure for storing all kinds of useful information about the
- * current (or another) time.
- */
 struct tm
-{
-       int     tm_sec;         /* Seconds: 0-59 (K&R says 0-61?) */
-       int     tm_min;         /* Minutes: 0-59 */
-       int     tm_hour;        /* Hours since midnight: 0-23 */
-       int     tm_mday;        /* Day of the month: 1-31 */
-       int     tm_mon;         /* Months *since* january: 0-11 */
-       int     tm_year;        /* Years since 1900 */
-       int     tm_wday;        /* Days since Sunday (0-6) */
-       int     tm_yday;        /* Days since Jan. 1: 0-365 */
-       int     tm_isdst;       /* +1 Daylight Savings Time, 0 No DST,
-                                * -1 don't know */
+{ /* A structure for storing the attributes of a broken-down time; (once
+   * again, it isn't defined elsewhere, so no guard is necessary).  Note
+   * that we are within the scope of <time.h> itself, so we must provide
+   * the complete structure declaration here.
+   */
+  int  tm_sec;         /* Seconds: 0-60 (to accommodate leap seconds) */
+  int  tm_min;         /* Minutes: 0-59 */
+  int  tm_hour;        /* Hours since midnight: 0-23 */
+  int  tm_mday;        /* Day of the month: 1-31 */
+  int  tm_mon;         /* Months *since* January: 0-11 */
+  int  tm_year;        /* Years since 1900 */
+  int  tm_wday;        /* Days since Sunday (0-6) */
+  int  tm_yday;        /* Days since Jan. 1: 0-365 */
+  int  tm_isdst;       /* +1=Daylight Savings Time, 0=No DST, -1=unknown */
 };
-#define _TM_DEFINED
-#endif
 
 _BEGIN_C_DECLS
 
-_CRTIMP clock_t __cdecl __MINGW_NOTHROW        clock (void);
-#if __MSVCRT_VERSION__ < 0x0800
-_CRTIMP time_t __cdecl __MINGW_NOTHROW time (time_t*);
-_CRTIMP double __cdecl __MINGW_NOTHROW difftime (time_t, time_t);
-_CRTIMP time_t __cdecl __MINGW_NOTHROW mktime (struct tm*);
+_CRTIMP __cdecl __MINGW_NOTHROW  clock_t  clock (void);
+
+#if __MSVCRT_VERSION__ < __MSVCR80_DLL
+ /* Although specified as ISO-C functions, Microsoft withdrew direct
+  * support for these, with their ISO-C names, from MSVCR80.DLL onwards,
+  * preferring to map them via header file macros, to alternatively named
+  * DLL functions with ambiguous time_t representations; they remain in
+  * MSVCRT.DLL, however, with their original ISO-C names, and time_t
+  * unambiguously represented as a 32-bit data type.
+  */
+_CRTIMP __cdecl __MINGW_NOTHROW  time_t time (time_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW  double difftime (time_t, time_t);
+_CRTIMP __cdecl __MINGW_NOTHROW  time_t mktime (struct tm *);
 #endif
 
-/*
- * These functions write to and return pointers to static buffers that may
+/* These functions write to and return pointers to static buffers that may
  * be overwritten by other function calls. Yikes!
  *
  * NOTE: localtime, and perhaps the others of the four functions grouped
@@ -105,64 +152,113 @@ _CRTIMP time_t __cdecl __MINGW_NOTHROW   mktime (struct tm*);
  * Fault and crap out your program. Guess how I know. Hint: stat called on
  * a directory gives 'invalid' times in st_atime etc...
  */
-_CRTIMP char* __cdecl __MINGW_NOTHROW          asctime (const struct tm*);
-#if __MSVCRT_VERSION__ < 0x0800
-_CRTIMP char* __cdecl __MINGW_NOTHROW          ctime (const time_t*);
-_CRTIMP struct tm*  __cdecl __MINGW_NOTHROW    gmtime (const time_t*);
-_CRTIMP struct tm*  __cdecl __MINGW_NOTHROW    localtime (const time_t*);
+_CRTIMP __cdecl __MINGW_NOTHROW  char *asctime (const struct tm *);
+
+#if __MSVCRT_VERSION__ < __MSVCR80_DLL
+ /* Once again, these have been withdrawn from MSVCR80.DLL, (and later),
+  * but remain in MSVCRT.DLL, with unambiguously 32-bit time_t.
+  */
+_CRTIMP __cdecl __MINGW_NOTHROW  char *ctime (const time_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW  struct tm *gmtime (const time_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW  struct tm *localtime (const time_t *);
 #endif
 
-_CRTIMP size_t __cdecl __MINGW_NOTHROW         strftime (char*, size_t, const char*, const struct tm*);
+_CRTIMP __cdecl __MINGW_NOTHROW
+size_t strftime (char *, size_t, const char *, const struct tm *);
 
 #ifndef __STRICT_ANSI__
-
-extern _CRTIMP void __cdecl __MINGW_NOTHROW    _tzset (void);
+extern _CRTIMP __cdecl __MINGW_NOTHROW  void _tzset (void);
 
 #ifndef _NO_OLDNAMES
-extern _CRTIMP void __cdecl __MINGW_NOTHROW    tzset (void);
+extern _CRTIMP __cdecl __MINGW_NOTHROW  void tzset (void);
 #endif
 
-_CRTIMP char* __cdecl __MINGW_NOTHROW  _strdate(char*);
-_CRTIMP char* __cdecl __MINGW_NOTHROW  _strtime(char*);
-
-/* These require newer versions of msvcrt.dll (6.10 or higher). */
-#if __MSVCRT_VERSION__ >= 0x0601
-_CRTIMP __time64_t __cdecl __MINGW_NOTHROW  _time64( __time64_t*);
-_CRTIMP __time64_t __cdecl __MINGW_NOTHROW  _mktime64 (struct tm*);
-_CRTIMP char* __cdecl __MINGW_NOTHROW _ctime64 (const __time64_t*);
-_CRTIMP struct tm*  __cdecl __MINGW_NOTHROW _gmtime64 (const __time64_t*);
-_CRTIMP struct tm*  __cdecl __MINGW_NOTHROW _localtime64 (const __time64_t*);
-#endif /* __MSVCRT_VERSION__ >= 0x0601 */
-
-/* These require newer versions of msvcrt.dll (8.00 or higher). */
-#if __MSVCRT_VERSION__ >= 0x0800
-_CRTIMP __time32_t __cdecl __MINGW_NOTHROW     _time32 (__time32_t*);
-_CRTIMP double    __cdecl __MINGW_NOTHROW      _difftime32 (__time32_t, __time32_t);
-_CRTIMP double    __cdecl __MINGW_NOTHROW      _difftime64 (__time64_t, __time64_t);
-_CRTIMP __time32_t __cdecl __MINGW_NOTHROW     _mktime32 (struct tm*);
-_CRTIMP __time32_t __cdecl __MINGW_NOTHROW     _mkgmtime32 (struct tm*);
-_CRTIMP __time64_t __cdecl __MINGW_NOTHROW     _mkgmtime64 (struct tm*);
-_CRTIMP char*     __cdecl __MINGW_NOTHROW      _ctime32 (const __time32_t*);
-_CRTIMP struct tm* __cdecl __MINGW_NOTHROW     _gmtime32 (const __time32_t*);
-_CRTIMP struct tm* __cdecl __MINGW_NOTHROW     _localtime32 (const __time32_t*);
-#ifndef _USE_32BIT_TIME_T
-_CRTALIAS time_t          __cdecl __MINGW_NOTHROW      time (time_t* _v)                 { return(_time64 (_v)); }
-_CRTALIAS double          __cdecl __MINGW_NOTHROW      difftime (time_t _v1, time_t _v2) { return(_difftime64 (_v1,_v2)); }
-_CRTALIAS time_t          __cdecl __MINGW_NOTHROW      mktime (struct tm* _v)            { return(_mktime64 (_v)); }
-_CRTALIAS time_t          __cdecl __MINGW_NOTHROW      _mkgmtime (struct tm* _v)         { return(_mkgmtime64 (_v)); }
-_CRTALIAS char*                   __cdecl __MINGW_NOTHROW      ctime (const time_t* _v)          { return(_ctime64 (_v)); }
-_CRTALIAS struct tm*      __cdecl __MINGW_NOTHROW      gmtime (const time_t* _v)         { return(_gmtime64 (_v)); }
-_CRTALIAS struct tm*      __cdecl __MINGW_NOTHROW      localtime (const time_t* _v)      { return(_localtime64 (_v)); }
-#else
-_CRTALIAS time_t          __cdecl __MINGW_NOTHROW      time (time_t* _v)                 { return(_time32 (_v)); }
-_CRTALIAS double          __cdecl __MINGW_NOTHROW      difftime (time_t _v1, time_t _v2) { return(_difftime32 (_v1,_v2)); }
-_CRTALIAS time_t          __cdecl __MINGW_NOTHROW      mktime (struct tm* _v)            { return(_mktime32 (_v)); }
-_CRTALIAS time_t          __cdecl __MINGW_NOTHROW      _mkgmtime (struct tm* _v)         { return(_mkgmtime32 (_v)); }
-_CRTALIAS char*                   __cdecl __MINGW_NOTHROW      ctime (const time_t* _v)          { return(_ctime32 (_v)); }
-_CRTALIAS struct tm*      __cdecl __MINGW_NOTHROW      gmtime (const time_t* _v)         { return(_gmtime32 (_v)); }
-_CRTALIAS struct tm*      __cdecl __MINGW_NOTHROW      localtime (const time_t* _v)      { return(_localtime32 (_v)); }
-#endif /* !_USE_32BIT_TIME_T */
-#endif /* __MSVCRT_VERSION__ >= 0x0800 */
+_CRTIMP __cdecl __MINGW_NOTHROW  char *_strdate (char *);
+_CRTIMP __cdecl __MINGW_NOTHROW  char *_strtime (char *);
+
+#if __MSVCRT_VERSION__ >= __MSVCR61_DLL || _WIN32_WINNT >= _WIN32_WINNT_WIN2K
+/* These 64-bit time_t variant functions first became available in
+ * MSVCR61.DLL, and its descendants; they were subsequently included
+ * in MSVCRT.DLL, from its Win2K release onwards.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW  __time64_t _time64( __time64_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW  __time64_t _mktime64 (struct tm *);
+_CRTIMP __cdecl __MINGW_NOTHROW    char *_ctime64 (const __time64_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW    struct tm *_gmtime64 (const __time64_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW    struct tm *_localtime64 (const __time64_t *);
+
+#endif /* __MSVCR61_DLL, _WIN32_WINNT_WIN2K, and descendants. */
+
+#if __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA
+ /* The following were introduced in MSVCR80.DLL, and they subsequently
+  * appeared in MSVCRT.DLL, from Windows-Vista onwards.
+  */
+_CRTIMP __cdecl __MINGW_NOTHROW    char *_ctime32 (const __time32_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW    double _difftime32 (__time32_t, __time32_t);
+_CRTIMP __cdecl __MINGW_NOTHROW    double _difftime64 (__time64_t, __time64_t);
+_CRTIMP __cdecl __MINGW_NOTHROW    struct tm *_gmtime32 (const __time32_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW    struct tm *_localtime32 (const __time32_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW  __time32_t _mktime32 (struct tm *);
+_CRTIMP __cdecl __MINGW_NOTHROW  __time32_t _mkgmtime32 (struct tm *);
+_CRTIMP __cdecl __MINGW_NOTHROW  __time64_t _mkgmtime64 (struct tm *);
+_CRTIMP __cdecl __MINGW_NOTHROW  __time32_t _time32 (__time32_t *);
+
+# if __MSVCRT_VERSION__ >= __MSVCR80_DLL && defined _USE_32BIT_TIME_T
+  /* Users of MSVCR80.DLL and later, (but not users of MSVCRT.DLL, even
+   * for _WIN32_WINNT_VISTA and later), must contend with the omission of
+   * the following functions from their DLL of choice, thus requiring these
+   * brain damaged mappings, in terms of an ambiguously defined 'time_t';
+   * thus, when 'time_t' is declared to be equivalent to '__time32_t':
+   */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  time_t time (time_t *__v)
+ { return _time32 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  double difftime (time_t __v1, time_t __v2)
+ { return _difftime32 (__v1, __v2); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  time_t mktime (struct tm *__v)
+ { return _mktime32 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  time_t _mkgmtime (struct tm *__v)
+ { return _mkgmtime32 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  char *ctime (const time_t *__v)
+ { return _ctime32 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  struct tm *gmtime (const time_t *__v)
+ { return _gmtime32 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  struct tm *localtime (const time_t *__v)
+ { return _localtime32 (__v); }
+
+# elif __MSVCRT_VERSION__ >= __MSVCR80_DLL
+  /* Correspondingly, for users of MSVCR80.DLL and later only, when there
+   * is no explicit declaration to direct the specification of 'time_t', and
+   * thus 'time_t' is assumed to be equivalent to '__time64_t':
+   */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  time_t time (time_t *__v)
+ { return _time64 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  double difftime (time_t __v1, time_t __v2)
+ { return _difftime64 (__v1, __v2); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  time_t mktime (struct tm *__v)
+ { return _mktime64 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  time_t _mkgmtime (struct tm *__v)
+ { return _mkgmtime64 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  char *ctime (const time_t *__v)
+ { return _ctime64 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  struct tm *gmtime (const time_t *__v)
+ { return _gmtime64 (__v); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  struct tm *localtime (const time_t *__v)
+ { return _localtime64 (__v); }
+
+# endif /* _USE_32BIT_TIME_T brain damage */
+#endif /* >=__MSVCR80.DLL || >=_WIN32_WINNT_VISTA */
 
 /* _daylight: non zero if daylight savings time is used.
  * _timezone: difference in seconds between GMT and local time.
@@ -171,35 +267,35 @@ _CRTALIAS struct tm*         __cdecl __MINGW_NOTHROW      localtime (const time_t* _v)      {
  */
 #ifdef __MSVCRT__
 
-/* These are for compatibility with pre-VC 5.0 suppied MSVCRT. */
-extern _CRTIMP int* __cdecl __MINGW_NOTHROW    __p__daylight (void);
-extern _CRTIMP long* __cdecl __MINGW_NOTHROW   __p__timezone (void);
-extern _CRTIMP char** __cdecl __MINGW_NOTHROW  __p__tzname (void);
-
-__MINGW_IMPORT int     _daylight;
-__MINGW_IMPORT long    _timezone;
-__MINGW_IMPORT char    *_tzname[2];
+/* These are for compatibility with pre-VC 5.0 supplied MSVCRT.DLL
+ */
+extern _CRTIMP __cdecl __MINGW_NOTHROW  int   *__p__daylight (void);
+extern _CRTIMP __cdecl __MINGW_NOTHROW  long  *__p__timezone (void);
+extern _CRTIMP __cdecl __MINGW_NOTHROW  char **__p__tzname (void);
 
-#else /* not __MSVCRT (ie. crtdll) */
+__MINGW_IMPORT int   _daylight;
+__MINGW_IMPORT long  _timezone;
+__MINGW_IMPORT char *_tzname[2];
 
+#else /* !__MSVCRT__ (i.e. using CRTDLL.DLL) */
 #ifndef __DECLSPEC_SUPPORTED
 
-extern int*    _imp___daylight_dll;
-extern long*   _imp___timezone_dll;
-extern char**  _imp___tzname;
+extern int   *_imp___daylight_dll;
+extern long  *_imp___timezone_dll;
+extern char **_imp___tzname;
 
-#define _daylight      (*_imp___daylight_dll)
-#define _timezone      (*_imp___timezone_dll)
-#define _tzname                (*_imp___tzname)
+#define _daylight  (*_imp___daylight_dll)
+#define _timezone  (*_imp___timezone_dll)
+#define _tzname           (*_imp___tzname)
 
 #else /* __DECLSPEC_SUPPORTED */
 
-__MINGW_IMPORT int     _daylight_dll;
-__MINGW_IMPORT long    _timezone_dll;
-__MINGW_IMPORT char*   _tzname[2];
+__MINGW_IMPORT int   _daylight_dll;
+__MINGW_IMPORT long  _timezone_dll;
+__MINGW_IMPORT char *_tzname[2];
 
-#define _daylight      _daylight_dll
-#define _timezone      _timezone_dll
+#define _daylight  _daylight_dll
+#define _timezone  _timezone_dll
 
 #endif /* __DECLSPEC_SUPPORTED */
 #endif /* ! __MSVCRT__ */
@@ -210,17 +306,16 @@ __MINGW_IMPORT char*      _tzname[2];
 
 /* These go in the oldnames import library for MSVCRT.
  */
-__MINGW_IMPORT int     daylight;
-__MINGW_IMPORT long    timezone;
-__MINGW_IMPORT char    *tzname[2];
+__MINGW_IMPORT int   daylight;
+__MINGW_IMPORT long  timezone;
+__MINGW_IMPORT char *tzname[2];
 
 #else /* ! __MSVCRT__ */
-/*
- * CRTDLL is royally messed up when it comes to these macros.
+/* CRTDLL is royally messed up when it comes to these macros.
  * TODO: import and alias these via oldnames import library instead
  * of macros.
  */
-#define daylight        _daylight
+#define daylight  _daylight
 /*
  * NOTE: timezone not defined as a macro because it would conflict with
  * struct timezone in sys/time.h.  Also, tzname used to a be macro, but
@@ -228,51 +323,82 @@ __MINGW_IMPORT char       *tzname[2];
  */
 __MINGW_IMPORT char    *tzname[2];
 
-#endif /* ! __MSVCRT__ */
-#endif /* ! _NO_OLDNAMES */
-
-#ifndef _WTIME_DEFINED
-/* wide function prototypes, also declared in wchar.h */
-#ifndef __STRICT_ANSI__
-#ifdef __MSVCRT__
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wasctime(const struct tm*);
-#if __MSVCRT_VERSION__ < 0x0800
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wctime(const time_t*);
-#endif
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wstrdate(wchar_t*);
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wstrtime(wchar_t*);
-#if __MSVCRT_VERSION__ >= 0x0601
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wctime64 (const __time64_t*);
+#endif /* ! __MSVCRT__ */
+#endif /* ! _NO_OLDNAMES */
+#endif /* _TIME_H included in its own right */
+
+#if __need_wchar_decls && ! (defined _TIME_H && defined _WCHAR_H)
+/* Wide character time function prototypes.  These are nominally declared
+ * both here, in <time.h>, and also in <wchar.h>; we declare them here, and
+ * make them available for selective inclusion by <wchar.h>, but such that
+ * the declarations, and in particular any in-line implementation of the
+ * _wctime() function, are visible only on the first time parse, when
+ * one of either _TIME_H, or _WCHAR_H, but not both, is defined.
+ */
+#if defined __MSVCRT__ && ! defined __STRICT_ANSI__
+_CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_wasctime (const struct tm *);
+_CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_wstrdate (wchar_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_wstrtime (wchar_t *);
+
+#if __MSVCRT_VERSION__ >= __MSVCR61_DLL || _WIN32_WINNT >= _WIN32_WINNT_WIN2K
+/* A __time64_t specific variant of _wctime(), identified as _wctime64(),
+ * first appeared in the non-free MSVC specific MSVCR61.DLL, and was added
+ * to the freely available platform MSVCRT.DLL from Win2K onwards...
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_wctime64 (const __time64_t *);
 #endif
-#if __MSVCRT_VERSION__ >= 0x0800
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wctime32 (const __time32_t*);
-#ifndef _USE_32BIT_TIME_T
-_CRTALIAS wchar_t* __cdecl __MINGW_NOTHROW     _wctime (const time_t* _v) { return(_wctime64 (_v)); }
-#else
-_CRTALIAS wchar_t* __cdecl __MINGW_NOTHROW     _wctime (const time_t* _v) { return(_wctime32 (_v)); }
+#if __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* ...whereas its __time32_t specific counterpart, _wctime32(), did not
+ * make an appearance until MSVCR80.DLL, and was not added to MSVCRT.DLL
+ * until the release of Vista.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_wctime32 (const __time32_t *);
 #endif
-#endif /* __MSVCRT_VERSION__ >= 0x0800 */
-#endif /*  __MSVCRT__ */
-#endif /* __STRICT_ANSI__ */
-_CRTIMP size_t __cdecl __MINGW_NOTHROW         wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*);
-#define _WTIME_DEFINED
-#endif /* _WTIME_DEFINED */
+#if __MSVCRT_VERSION__ < __MSVCR80_DLL
+/* Present in all versions of MSVCRT.DLL, but withdrawn from non-free
+ * MSVC specific releases from MSVCR80.DLL onwards; in all versions of
+ * MSVCRT.DLL, _wctime() accepts a 32-bit time_t argument pointer.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_wctime (const time_t *);
 
-#ifdef _MINGW32_EXTENDED_SOURCE
-__CRT_ALIAS __LIBIMPL__(( FUNCTION = mingw_timespec ))
-/*
- * This non-ANSI convenience function facilitates access to entities
- * defined as struct timespec, while exposing the broken down form of
- * the tv_sec field, as declared within struct __mingw32_timespec.  It
- * is exposed only when _MINGW32_EXTENDED_SOURCE is defined, which is
- * normally implicitly the case, except when in __STRICT_ANSI__ mode
- * unless the user defines it explicitly.
+#else /* __MSVCRT_VERSION__ >= __MSVCR80_DLL */
+/* For users of the non-free MSVC libraries, we must deal with both the
+ * absence of _wctime(), and with Microsoft's attendant _USE_32BIT_TIME_T
+ * brain damage, as we map an inline replacement...
  */
-struct __mingw32_expanded_timespec *mingw_timespec( struct timespec *__tv )
-{ return (struct __mingw32_expanded_timespec *)(__tv); }
-#endif
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  wchar_t *_wctime (const time_t *__v)
+{
+  /* ...in terms of an appropriately selected time_t size specific
+   * alternative function, which should be available...
+   */
+# ifdef _USE_32BIT_TIME_T
+  /* ...i.e. the __time32_t specific _wctime32(), when the user has
+   * enabled this choice; (the only sane choice, if compatibility with
+   * MSVCRT.DLL is desired)...
+   */
+  return _wctime32 (__v);
+
+# else /* !_USE_32BIT_TIME_T */
+  /* ...or otherwise, the __time64_t specific _wctime64(), (in which
+   * case, compatibility with MSVCRT.DLL must be sacrificed).
+   */
+  return _wctime64 (__v);
+# endif        /* !_USE_32BIT_TIME_T */
+}
+#endif /* __MSVCRT_VERSION__ >= __MSVCR80_DLL */
+#endif /* __MSVCRT__ && !__STRICT_ANSI__ */
+
+_CRTIMP __cdecl __MINGW_NOTHROW
+size_t wcsftime (wchar_t *, size_t, const wchar_t *, const struct tm *);
+
+#endif /* ! (defined _TIME_H && defined _WCHAR_H) */
 
 _END_C_DECLS
 
+/* We're done with all <time.h> specific content selectors; clear them.
+ */
+#undef __need_struct_timespec
+#undef __need_wchar_decls
+
 #endif /* ! RC_INVOKED */
 #endif /* ! _TIME_H: $RCSfile$: end of file */
index 83db1e8..d78aa5a 100644 (file)
@@ -54,7 +54,7 @@
 #define WCHAR_MIN      0
 #define WCHAR_MAX      0xffff
 
-# define WEOF          (wchar_t)(0xffff)
+#define WEOF           (wchar_t)(0xffff)
 
 #ifndef RC_INVOKED
 #define __WCHAR_H_SOURCED__
  *  wint_t  fputwc (wchar_t, FILE *);
  *  wint_t  ungetwc (wchar_t, FILE *);
  *
- *  The following pair of Microsoft functions conflict with their
- *  corresponding ISO-C prototypes; consequently they will not be
- *  declared when "__STRICT_ANSI__" checking is in effect:
+ * The following pair of Microsoft functions conflict with their
+ * corresponding ISO-C prototypes; consequently they will not be
+ * declared when "__STRICT_ANSI__" checking is in effect:
  *
  *  int  swprintf (wchar_t *, const wchar_t *, ...);
  *  int  vswprintf (wchar_t *, const wchar_t *, __VALIST);
  *
- *  The following group of functions is specified by ISO-C, but
- *  their Microsoft implementations are available only if use of
- *  "__MSVCRT__" is specified:
+ * The following group of functions is specified by ISO-C, but
+ * their Microsoft implementations are available only if use of
+ * "__MSVCRT__" is specified:
  *
  *  wchar_t * fgetws (wchar_t *, int, FILE *);
  *  int       fputws (const wchar_t *, FILE *);
  *  wint_t    putwc (wint_t, FILE *);
  *  wint_t    putwchar (wint_t);
  *
- *  The following group of functions is also dependent on use of
- *  "__MSVCRT__"; however, these are Microsoft specific, so their
- *  are not declared if "__STRICT_ANSI__" checking is specified:
+ * The following group of functions is also dependent on use of
+ * "__MSVCRT__"; however, these are Microsoft specific, so they
+ * are not declared if "__STRICT_ANSI__" checking is specified:
  *
  *  wchar_t * _getws (wchar_t *);
  *  int       _putws (const wchar_t *);
- *  FILE    * _wfdopen(int, const wchar_t *);
+ *  FILE    * _wfdopen (int, const wchar_t *);
  *  FILE    * _wfopen (const wchar_t *, const wchar_t *);
  *  FILE    * _wfreopen (const wchar_t *, const wchar_t *, FILE *);
  *  FILE    * _wfsopen (const wchar_t *, const wchar_t *, int);
@@ -150,32 +150,42 @@ _CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wfullpath (wchar_t*, const wchar_t*, s
 #define  _WSTDLIB_DEFINED
 #endif /* _WSTDLIB_DEFINED */
 
-#ifndef _WTIME_DEFINED
-#if defined __MSVCRT__ && ! defined __STRICT_ANSI__
-/* Wide function prototypes, also declared in time.h; FIXME: factor out.
+/* Also in similar fashion, from...
+ */
+#include <time.h>
+/* ...we obtain an opaque forward declaration of:
+ *
+ *  struct tm
+ *
+ * ...prototype declarations for the following ISO-C99 function,
+ * (which is always provided):
+ *
+ *  size_t wcsftime (wchar_t *, size_t, const wchar_t *, const struct tm *);
+ *
+ * ...together with the following non-ISO-C functions, (which are
+ * NOT exposed when "__STRICT_ANSI__" checking is enabled):
+ *
+ *  wchar_t *_wctime (const time_t *);
+ *  wchar_t *_wasctime (const struct tm *);
+ *  wchar_t *_wstrdate (wchar_t *);
+ *  wchar_t *_wstrtime (wchar_t *);
+ *
+ * Of the preceding group, we also note that, while it remains in
+ * all versions of MSVCRT.DLL, (using a strictly 32-bit data type
+ * to represent its "time_t" argument), the _wctime() function is
+ * NOT present in MSVCR80.DLL, and later versions of the non-free
+ * MSVC runtime libraries, in which it is replaced by either of:
+ *
+ *  wchar_t *_wctime64 (const __time64_t *);
+ *  wchar_t *_wctime32 (const __time32_t *);
+ *
+ * ...with the actual replacement being chosen at compile time, on
+ * the basis of the user specified "_USE_32BIT_TIME_T" feature test
+ * macro, (a Microsoft specific, brain damaged concept), which maps
+ * _wctime() function itself, as in in-line alias for the selected
+ * replacement library function.
+ *
  */
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wasctime (const struct tm*);
-#if __MSVCRT_VERSION__ < 0x0800
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wctime (const time_t*);
-#endif
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wstrdate (wchar_t*);
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wstrtime (wchar_t*);
-#if __MSVCRT_VERSION__ >= 0x601
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wctime64 (const __time64_t*);
-#endif
-#if __MSVCRT_VERSION__ >= 0x0800
-_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW       _wctime32 (const __time32_t*);
-#ifndef _USE_32BIT_TIME_T
-_CRTALIAS wchar_t* __cdecl __MINGW_NOTHROW     _wctime (const time_t* _v)      { return(_wctime64 (_v)); }
-#else
-_CRTALIAS wchar_t* __cdecl __MINGW_NOTHROW     _wctime (const time_t* _v)      { return(_wctime32 (_v)); }
-#endif
-#endif
-
-#endif /* __MSVCRT__ && ! __STRICT_ANSI__ */
-_CRTIMP size_t __cdecl __MINGW_NOTHROW wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*);
-#define _WTIME_DEFINED
-#endif /* _WTIME_DEFINED */
 
 
 /* Wide character string functions must be specified here, as required