mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 12:20:07 +00:00
msvcrt: Implemented asctime, ctime and strftime instead of using the libc ones.
Make the code thread-safe by using asctime_r if available.
This commit is contained in:
parent
b52146d95f
commit
f9e5b0f5f0
2
configure
vendored
2
configure
vendored
@ -14617,6 +14617,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_func in \
|
||||
@ -14629,6 +14630,7 @@ for ac_func in \
|
||||
_stricmp \
|
||||
_strnicmp \
|
||||
_vsnprintf \
|
||||
asctime_r \
|
||||
chsize \
|
||||
clone \
|
||||
epoll_create \
|
||||
|
@ -1157,6 +1157,7 @@ AC_CHECK_FUNCS(\
|
||||
_stricmp \
|
||||
_strnicmp \
|
||||
_vsnprintf \
|
||||
asctime_r \
|
||||
chsize \
|
||||
clone \
|
||||
epoll_create \
|
||||
|
@ -73,6 +73,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
if (tls)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,tls->efcvt_buffer);
|
||||
HeapFree(GetProcessHeap(),0,tls->asctime_buffer);
|
||||
HeapFree(GetProcessHeap(),0,tls->wasctime_buffer);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, tls);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
thread_data_t *data = msvcrt_get_thread_data();
|
||||
struct tm xtm;
|
||||
MSVCRT_size_t MSVCRT_strftime( char *str, MSVCRT_size_t max, const char *format,
|
||||
const struct MSVCRT_tm *mstm )
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
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;
|
||||
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 tm;
|
||||
|
||||
msvcrt_tm_to_unix( &tm, mstm );
|
||||
|
||||
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) );
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user