mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 10:02:02 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
325
sdk/lib/crt/time/strftime.c
Normal file
325
sdk/lib/crt/time/strftime.c
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* COPYRIGHT: LGPL, See LGPL.txt in the top level directory
|
||||
* PROJECT: ReactOS CRT library
|
||||
* FILE: lib/sdk/crt/time/strftime.c
|
||||
* PURPOSE:
|
||||
* PROGRAMER:
|
||||
*/
|
||||
#include <precomp.h>
|
||||
|
||||
static inline BOOL strftime_date(char *str, size_t *pos, size_t max,
|
||||
BOOL alternate, const struct tm *mstm, MSVCRT___lc_time_data *time_data)
|
||||
{
|
||||
char *format;
|
||||
SYSTEMTIME st;
|
||||
size_t ret;
|
||||
|
||||
st.wYear = mstm->tm_year + 1900;
|
||||
st.wMonth = mstm->tm_mon + 1;
|
||||
st.wDayOfWeek = mstm->tm_wday;
|
||||
st.wDay = mstm->tm_mday;
|
||||
st.wHour = mstm->tm_hour;
|
||||
st.wMinute = mstm->tm_min;
|
||||
st.wSecond = mstm->tm_sec;
|
||||
st.wMilliseconds = 0;
|
||||
|
||||
format = alternate ? time_data->str.names.date : time_data->str.names.short_date;
|
||||
ret = GetDateFormatA(time_data->lcid, 0, &st, format, NULL, 0);
|
||||
if(ret && ret<max-*pos)
|
||||
ret = GetDateFormatA(time_data->lcid, 0, &st, format, str+*pos, max-*pos);
|
||||
if(!ret) {
|
||||
*str = 0;
|
||||
*_errno() = EINVAL;
|
||||
return FALSE;
|
||||
}else if(ret > max-*pos) {
|
||||
*str = 0;
|
||||
*_errno() = ERANGE;
|
||||
return FALSE;
|
||||
}
|
||||
*pos += ret-1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline BOOL strftime_time(char *str, size_t *pos, size_t max,
|
||||
const struct tm *mstm, MSVCRT___lc_time_data *time_data)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
size_t ret;
|
||||
|
||||
st.wYear = mstm->tm_year + 1900;
|
||||
st.wMonth = mstm->tm_mon + 1;
|
||||
st.wDayOfWeek = mstm->tm_wday;
|
||||
st.wDay = mstm->tm_mday;
|
||||
st.wHour = mstm->tm_hour;
|
||||
st.wMinute = mstm->tm_min;
|
||||
st.wSecond = mstm->tm_sec;
|
||||
st.wMilliseconds = 0;
|
||||
|
||||
ret = GetTimeFormatA(time_data->lcid, 0, &st, time_data->str.names.time, NULL, 0);
|
||||
if(ret && ret<max-*pos)
|
||||
ret = GetTimeFormatA(time_data->lcid, 0, &st, time_data->str.names.time,
|
||||
str+*pos, max-*pos);
|
||||
if(!ret) {
|
||||
*str = 0;
|
||||
*_errno() = EINVAL;
|
||||
return FALSE;
|
||||
}else if(ret > max-*pos) {
|
||||
*str = 0;
|
||||
*_errno() = ERANGE;
|
||||
return FALSE;
|
||||
}
|
||||
*pos += ret-1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline BOOL strftime_str(char *str, size_t *pos, size_t max, char *src)
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
if(len > max-*pos) {
|
||||
*str = 0;
|
||||
*_errno() = ERANGE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(str+*pos, src, len);
|
||||
*pos += len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline BOOL strftime_int(char *str, size_t *pos, size_t max,
|
||||
int src, int prec, int l, int h)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if(src<l || src>h) {
|
||||
*str = 0;
|
||||
*_errno() = EINVAL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
len = _snprintf(str+*pos, max-*pos, "%0*d", prec, src);
|
||||
if(len == -1) {
|
||||
*str = 0;
|
||||
*_errno() = ERANGE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pos += len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _Strftime (MSVCRT.@)
|
||||
*/
|
||||
size_t CDECL _Strftime(char *str, size_t max, const char *format,
|
||||
const struct tm *mstm, MSVCRT___lc_time_data *time_data)
|
||||
{
|
||||
size_t ret, tmp;
|
||||
BOOL alternate;
|
||||
|
||||
TRACE("(%p %ld %s %p %p)\n", str, max, format, mstm, time_data);
|
||||
|
||||
if(!str || !format) {
|
||||
if(str && max)
|
||||
*str = 0;
|
||||
*_errno() = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!time_data)
|
||||
time_data = get_locinfo()->lc_time_curr;
|
||||
|
||||
for(ret=0; *format && ret<max; format++) {
|
||||
if(*format != '%') {
|
||||
str[ret++] = *format;
|
||||
continue;
|
||||
}
|
||||
|
||||
format++;
|
||||
if(*format == '#') {
|
||||
alternate = TRUE;
|
||||
format++;
|
||||
}else {
|
||||
alternate = FALSE;
|
||||
}
|
||||
|
||||
if(!mstm)
|
||||
goto einval_error;
|
||||
|
||||
switch(*format) {
|
||||
case 'c':
|
||||
if(!strftime_date(str, &ret, max, alternate, mstm, time_data))
|
||||
return 0;
|
||||
if(ret < max)
|
||||
str[ret++] = ' ';
|
||||
if(!strftime_time(str, &ret, max, mstm, time_data))
|
||||
return 0;
|
||||
break;
|
||||
case 'x':
|
||||
if(!strftime_date(str, &ret, max, alternate, mstm, time_data))
|
||||
return 0;
|
||||
break;
|
||||
case 'X':
|
||||
if(!strftime_time(str, &ret, max, mstm, time_data))
|
||||
return 0;
|
||||
break;
|
||||
case 'a':
|
||||
if(mstm->tm_wday<0 || mstm->tm_wday>6)
|
||||
goto einval_error;
|
||||
if(!strftime_str(str, &ret, max, time_data->str.names.short_wday[mstm->tm_wday]))
|
||||
return 0;
|
||||
break;
|
||||
case 'A':
|
||||
if(mstm->tm_wday<0 || mstm->tm_wday>6)
|
||||
goto einval_error;
|
||||
if(!strftime_str(str, &ret, max, time_data->str.names.wday[mstm->tm_wday]))
|
||||
return 0;
|
||||
break;
|
||||
case 'b':
|
||||
if(mstm->tm_mon<0 || mstm->tm_mon>11)
|
||||
goto einval_error;
|
||||
if(!strftime_str(str, &ret, max, time_data->str.names.short_mon[mstm->tm_mon]))
|
||||
return 0;
|
||||
break;
|
||||
case 'B':
|
||||
if(mstm->tm_mon<0 || mstm->tm_mon>11)
|
||||
goto einval_error;
|
||||
if(!strftime_str(str, &ret, max, time_data->str.names.mon[mstm->tm_mon]))
|
||||
return 0;
|
||||
break;
|
||||
case 'd':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_mday, alternate ? 0 : 2, 0, 31))
|
||||
return 0;
|
||||
break;
|
||||
case 'H':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_hour, alternate ? 0 : 2, 0, 23))
|
||||
return 0;
|
||||
break;
|
||||
case 'I':
|
||||
tmp = mstm->tm_hour;
|
||||
if(tmp > 12)
|
||||
tmp -= 12;
|
||||
else if(!tmp)
|
||||
tmp = 12;
|
||||
if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 1, 12))
|
||||
return 0;
|
||||
break;
|
||||
case 'j':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_yday+1, alternate ? 0 : 3, 1, 366))
|
||||
return 0;
|
||||
break;
|
||||
case 'm':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_mon+1, alternate ? 0 : 2, 1, 12))
|
||||
return 0;
|
||||
break;
|
||||
case 'M':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_min, alternate ? 0 : 2, 0, 59))
|
||||
return 0;
|
||||
break;
|
||||
case 'p':
|
||||
if(mstm->tm_hour<0 || mstm->tm_hour>23)
|
||||
goto einval_error;
|
||||
if(!strftime_str(str, &ret, max, mstm->tm_hour<12 ?
|
||||
time_data->str.names.am : time_data->str.names.pm))
|
||||
return 0;
|
||||
break;
|
||||
case 'S':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59))
|
||||
return 0;
|
||||
break;
|
||||
case 'w':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_wday, 0, 0, 6))
|
||||
return 0;
|
||||
break;
|
||||
case 'y':
|
||||
if(!strftime_int(str, &ret, max, mstm->tm_year%100, alternate ? 0 : 2, 0, 99))
|
||||
return 0;
|
||||
break;
|
||||
case 'Y':
|
||||
tmp = 1900+mstm->tm_year;
|
||||
if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 4, 0, 9999))
|
||||
return 0;
|
||||
break;
|
||||
case 'z':
|
||||
case 'Z':
|
||||
_tzset();
|
||||
if(_get_tzname(&tmp, str+ret, max-ret, mstm->tm_isdst ? 1 : 0))
|
||||
return 0;
|
||||
ret += tmp;
|
||||
break;
|
||||
case 'U':
|
||||
case 'W':
|
||||
if(mstm->tm_wday<0 || mstm->tm_wday>6 || mstm->tm_yday<0 || mstm->tm_yday>365)
|
||||
goto einval_error;
|
||||
if(*format == 'U')
|
||||
tmp = mstm->tm_wday;
|
||||
else if(!mstm->tm_wday)
|
||||
tmp = 6;
|
||||
else
|
||||
tmp = mstm->tm_wday-1;
|
||||
|
||||
tmp = mstm->tm_yday/7 + (tmp <= ((unsigned)mstm->tm_yday%7));
|
||||
if(!strftime_int(str, &ret, max, tmp, alternate ? 0 : 2, 0, 53))
|
||||
return 0;
|
||||
break;
|
||||
case '%':
|
||||
str[ret++] = '%';
|
||||
break;
|
||||
default:
|
||||
WARN("unknown format %c\n", *format);
|
||||
goto einval_error;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == max) {
|
||||
if(max)
|
||||
*str = 0;
|
||||
*_errno() = ERANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
str[ret] = 0;
|
||||
return ret;
|
||||
|
||||
einval_error:
|
||||
*str = 0;
|
||||
*_errno() = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* strftime (MSVCRT.@)
|
||||
*/
|
||||
size_t CDECL strftime( char *str, size_t max, const char *format,
|
||||
const struct tm *mstm )
|
||||
{
|
||||
return _Strftime(str, max, format, mstm, NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* wcsftime (MSVCRT.@)
|
||||
*/
|
||||
size_t CDECL wcsftime( wchar_t *str, size_t max,
|
||||
const wchar_t *format, const struct tm *mstm )
|
||||
{
|
||||
char *s, *fmt;
|
||||
size_t len;
|
||||
|
||||
TRACE("%p %ld %s %p\n", str, max, debugstr_w(format), mstm );
|
||||
|
||||
len = WideCharToMultiByte( CP_ACP, 0, format, -1, NULL, 0, NULL, NULL );
|
||||
if (!(fmt = malloc( len ))) return 0;
|
||||
WideCharToMultiByte( CP_ACP, 0, format, -1, fmt, len, NULL, NULL );
|
||||
|
||||
if ((s = malloc( max*4 )))
|
||||
{
|
||||
if (!strftime( s, max*4, fmt, mstm )) s[0] = 0;
|
||||
len = MultiByteToWideChar( CP_ACP, 0, s, -1, str, max );
|
||||
if (len) len--;
|
||||
free( s );
|
||||
}
|
||||
else len = 0;
|
||||
|
||||
free( fmt );
|
||||
return len;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue