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