Module: wine Branch: refs/heads/master Commit: f9e5b0f5f03e47d46b05d9fe276ae390fd0ab95f URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=f9e5b0f5f03e47d46b05d9fe...
Author: Alexandre Julliard julliard@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