Alexandre Julliard : msvcrt: Implemented asctime, ctime and strftime instead of using the libc ones.

Alexandre Julliard julliard at wine.codeweavers.com
Sat Jan 14 10:56:38 CST 2006


Module: wine
Branch: refs/heads/master
Commit: f9e5b0f5f03e47d46b05d9fe276ae390fd0ab95f
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=f9e5b0f5f03e47d46b05d9fe276ae390fd0ab95f

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Sat Jan 14 17:22:03 2006 +0100

msvcrt: Implemented asctime, ctime and strftime instead of using the libc ones.
Make the code thread-safe by using asctime_r if available.

---

 configure               |    2 +
 configure.ac            |    1 +
 dlls/msvcrt/main.c      |    1 +
 dlls/msvcrt/msvcrt.h    |    3 +-
 dlls/msvcrt/msvcrt.spec |    6 ++-
 dlls/msvcrt/time.c      |   84 +++++++++++++++++++++++++++++++++++++++--------
 include/config.h.in     |    3 ++
 7 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/configure b/configure
index 9a49b2c..1880b82 100755
--- a/configure
+++ b/configure
@@ -14619,6 +14619,7 @@ fi
 
 
 
+
 for ac_func in \
 	_lwp_create \
 	_lwp_self \
@@ -14629,6 +14630,7 @@ for ac_func in \
 	_stricmp \
 	_strnicmp \
 	_vsnprintf \
+	asctime_r \
 	chsize \
 	clone \
 	epoll_create \
diff --git a/configure.ac b/configure.ac
index eebf34c..b458d7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1157,6 +1157,7 @@ AC_CHECK_FUNCS(\
 	_stricmp \
 	_strnicmp \
 	_vsnprintf \
+	asctime_r \
 	chsize \
 	clone \
 	epoll_create \
diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c
index 779a293..6697c1c 100644
--- a/dlls/msvcrt/main.c
+++ b/dlls/msvcrt/main.c
@@ -73,6 +73,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, 
     if (tls)
     {
 	HeapFree(GetProcessHeap(),0,tls->efcvt_buffer);
+	HeapFree(GetProcessHeap(),0,tls->asctime_buffer);
 	HeapFree(GetProcessHeap(),0,tls->wasctime_buffer);
     }
     HeapFree(GetProcessHeap(), 0, tls);
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 68f5ca6..badea9e 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -95,7 +95,8 @@ struct __thread_data {
     unsigned long                   thread_doserrno;
     unsigned char                  *mbstok_next;        /* next ptr for mbstok() */
     char                           *efcvt_buffer;       /* buffer for ecvt/fcvt */
-    MSVCRT_wchar_t                 *wasctime_buffer;    /* buffer for asctime */
+    char                           *asctime_buffer;     /* buffer for asctime */
+    MSVCRT_wchar_t                 *wasctime_buffer;    /* buffer for wasctime */
     struct MSVCRT_tm                time_buffer;        /* buffer for localtime/gmtime */
     int                             fpecode;
     MSVCRT_terminate_function       terminate_handler;
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 69aa578..6d496fd 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -570,7 +570,7 @@
 @ cdecl abort() MSVCRT_abort
 @ cdecl abs(long)
 @ cdecl acos(double)
-@ cdecl asctime(ptr)
+@ cdecl asctime(ptr) MSVCRT_asctime
 @ cdecl asin(double)
 @ cdecl atan(double)
 @ cdecl atan2(double double)
@@ -585,7 +585,7 @@
 @ cdecl clock() MSVCRT_clock
 @ cdecl cos(double)
 @ cdecl cosh(double)
-@ cdecl ctime(ptr)
+@ cdecl ctime(ptr) MSVCRT_ctime
 @ cdecl difftime(long long) MSVCRT_difftime
 @ cdecl div(long long) MSVCRT_div
 @ cdecl exit(long) MSVCRT_exit
@@ -704,7 +704,7 @@
 @ cdecl strcpy(ptr str)
 @ cdecl strcspn(str str)
 @ cdecl strerror(long) MSVCRT_strerror
-@ cdecl strftime(str long str ptr)
+@ cdecl strftime(str long str ptr) MSVCRT_strftime
 @ cdecl strlen(str)
 @ cdecl strncat(str str long)
 @ cdecl strncmp(str str long)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c
index 9b26770..3c1b0ba 100644
--- a/dlls/msvcrt/time.c
+++ b/dlls/msvcrt/time.c
@@ -47,6 +47,20 @@ static inline int IsLeapYear(int Year)
     return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0);
 }
 
+static inline void msvcrt_tm_to_unix( struct tm *dest, const struct MSVCRT_tm *src )
+{
+    memset( dest, 0, sizeof(*dest) );
+    dest->tm_sec   = src->tm_sec;
+    dest->tm_min   = src->tm_min;
+    dest->tm_hour  = src->tm_hour;
+    dest->tm_mday  = src->tm_mday;
+    dest->tm_mon   = src->tm_mon;
+    dest->tm_year  = src->tm_year;
+    dest->tm_wday  = src->tm_wday;
+    dest->tm_yday  = src->tm_yday;
+    dest->tm_isdst = src->tm_isdst;
+}
+
 #define SECSPERDAY        86400
 /* 1601 to 1970 is 369 years plus 89 leap days */
 #define SECS_1601_TO_1970  ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
@@ -412,33 +426,73 @@ void MSVCRT__tzset(void)
 }
 
 /*********************************************************************
- *		_wctime (MSVCRT.@)
+ *		strftime (MSVCRT.@)
  */
-MSVCRT_wchar_t *MSVCRT__wasctime(const struct MSVCRT_tm *mstm) {
+MSVCRT_size_t MSVCRT_strftime( char *str, MSVCRT_size_t max, const char *format,
+                               const struct MSVCRT_tm *mstm )
+{
+    struct tm tm;
+
+    msvcrt_tm_to_unix( &tm, mstm );
+    return strftime( str, max, format, &tm );
+}
+
+/*********************************************************************
+ *		asctime (MSVCRT.@)
+ */
+char *MSVCRT_asctime(const struct MSVCRT_tm *mstm)
+{
     thread_data_t *data = msvcrt_get_thread_data();
-    struct tm xtm;
+    struct tm tm;
+
+    msvcrt_tm_to_unix( &tm, mstm );
 
-    memset(&xtm,0,sizeof(xtm));
-    xtm.tm_sec = mstm->tm_sec;
-    xtm.tm_min = mstm->tm_min;
-    xtm.tm_hour = mstm->tm_hour;
-    xtm.tm_mday = mstm->tm_mday;
-    xtm.tm_mon = mstm->tm_mon;
-    xtm.tm_year = mstm->tm_year;
-    xtm.tm_wday = mstm->tm_wday;
-    xtm.tm_yday = mstm->tm_yday;
-    xtm.tm_isdst = mstm->tm_isdst;
+    if (!data->asctime_buffer)
+        data->asctime_buffer = MSVCRT_malloc( 30 ); /* ought to be enough */
+
+    /* FIXME: may want to map from Unix codepage to CP_ACP */
+#ifdef HAVE_ASCTIME_R
+    asctime_r( &tm, data->asctime_buffer );
+#else
+    strcpy( data->asctime_buffer, asctime(&tm) );
+#endif
+    return data->asctime_buffer;
+}
+
+/*********************************************************************
+ *		_wasctime (MSVCRT.@)
+ */
+MSVCRT_wchar_t *MSVCRT__wasctime(const struct MSVCRT_tm *mstm)
+{
+    thread_data_t *data = msvcrt_get_thread_data();
+    struct tm tm;
+    char buffer[30];
+
+    msvcrt_tm_to_unix( &tm, mstm );
 
     if (!data->wasctime_buffer)
         data->wasctime_buffer = MSVCRT_malloc( 30*sizeof(MSVCRT_wchar_t) ); /* ought to be enough */
-    MultiByteToWideChar( CP_UNIXCP, 0, asctime(&xtm), -1, data->wasctime_buffer, 30 );
+#ifdef HAVE_ASCTIME_R
+    asctime_r( &tm, buffer );
+#else
+    strcpy( buffer, asctime(&tm) );
+#endif
+    MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, data->wasctime_buffer, 30 );
     return data->wasctime_buffer;
 }
 
 /*********************************************************************
+ *		ctime (MSVCRT.@)
+ */
+char *MSVCRT_ctime(const MSVCRT_time_t *time)
+{
+    return MSVCRT_asctime( MSVCRT_localtime(time) );
+}
+
+/*********************************************************************
  *		_wctime (MSVCRT.@)
  */
-MSVCRT_wchar_t *MSVCRT__wctime(MSVCRT_time_t *time)
+MSVCRT_wchar_t *MSVCRT__wctime(const MSVCRT_time_t *time)
 {
     return MSVCRT__wasctime( MSVCRT_localtime(time) );
 }
diff --git a/include/config.h.in b/include/config.h.in
index d3eedd7..51ecdc5 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -20,6 +20,9 @@
 /* Define if you have ARTS sound server */
 #undef HAVE_ARTS
 
+/* Define to 1 if you have the `asctime_r' function. */
+#undef HAVE_ASCTIME_R
+
 /* Define to 1 if you have the <asm/types.h> header file. */
 #undef HAVE_ASM_TYPES_H
 




More information about the wine-cvs mailing list