|
@@ -1782,6 +1782,13 @@ PAL_MultiByteToWideChar(
|
|
|
return PAL_MultiByteToWideCharCP(gConfig.uCodePage, mbs, mbslength, wcs, wcslength);
|
|
|
}
|
|
|
|
|
|
+INT
|
|
|
+PAL_swprintf(
|
|
|
+ LPWSTR buffer,
|
|
|
+ size_t count,
|
|
|
+ LPCWSTR format,
|
|
|
+ ...
|
|
|
+)
|
|
|
|
|
|
Purpose:
|
|
|
|
|
@@ -1807,13 +1814,6 @@ PAL_MultiByteToWideChar(
|
|
|
The length of outputed wide string, not including the termination null character.
|
|
|
|
|
|
--*/
|
|
|
-INT
|
|
|
-PAL_swprintf(
|
|
|
- LPWSTR buffer,
|
|
|
- size_t count,
|
|
|
- LPCWSTR format,
|
|
|
- ...
|
|
|
-)
|
|
|
{
|
|
|
va_list ap;
|
|
|
const WCHAR * const format_end = format + wcslen(format);
|
|
@@ -1825,6 +1825,7 @@ PAL_swprintf(
|
|
|
int precision, width;
|
|
|
int state, left_aligned, wide, narrow, width_var, precision_var, precision_defined;
|
|
|
|
|
|
+
|
|
|
if (buffer == NULL || format == NULL)
|
|
|
{
|
|
|
errno = EINVAL;
|
|
@@ -1846,7 +1847,6 @@ PAL_swprintf(
|
|
|
{
|
|
|
*buffer++ = *format++;
|
|
|
count++;
|
|
|
- break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -1856,6 +1856,7 @@ PAL_swprintf(
|
|
|
precision_defined = 0;
|
|
|
state = 1;
|
|
|
}
|
|
|
+ continue;
|
|
|
case 1:
|
|
|
switch (*format)
|
|
|
{
|
|
@@ -1898,7 +1899,7 @@ PAL_swprintf(
|
|
|
precision = precision_var = 0;
|
|
|
precision_defined = 1;
|
|
|
state = 3;
|
|
|
- break;
|
|
|
+ continue;
|
|
|
default:
|
|
|
state = 4;
|
|
|
continue;
|
|
@@ -1938,23 +1939,30 @@ PAL_swprintf(
|
|
|
case 5:
|
|
|
if (*format == 'c' || *format == 's')
|
|
|
{
|
|
|
+
|
|
|
LPWSTR buf;
|
|
|
size_t len;
|
|
|
int i;
|
|
|
|
|
|
+
|
|
|
if (width_var)
|
|
|
{
|
|
|
width = va_arg(ap, int);
|
|
|
left_aligned = (width < 0);
|
|
|
width = left_aligned ? -width : width;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
if (precision_var)
|
|
|
precision = va_arg(ap, int);
|
|
|
else if (!precision_defined)
|
|
|
- precision = (unsigned long)(-1);
|
|
|
+ precision = INT_MAX;
|
|
|
|
|
|
if (*format == 's')
|
|
|
{
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
if (wide)
|
|
|
{
|
|
|
buf = va_arg(ap, LPWSTR);
|
|
@@ -1968,6 +1976,7 @@ PAL_swprintf(
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+
|
|
|
if (wide)
|
|
|
chr_buf[0] = va_arg(ap, WCHAR);
|
|
|
else
|
|
@@ -1975,41 +1984,52 @@ PAL_swprintf(
|
|
|
buf = chr_buf; len = 1;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
if (precision > (int)len)
|
|
|
precision = len;
|
|
|
|
|
|
+
|
|
|
for (i = 0; !left_aligned && i < width - precision && buffer < buffer_end; i++)
|
|
|
*buffer++ = L' ', count++;
|
|
|
|
|
|
+
|
|
|
if (buffer + precision > buffer_end)
|
|
|
precision = buffer_end - buffer;
|
|
|
|
|
|
+
|
|
|
if (*format == 's' && !wide)
|
|
|
PAL_MultiByteToWideChar((LPCSTR)buf, -1, buffer, precision);
|
|
|
else
|
|
|
wcsncpy(buffer, buf, precision);
|
|
|
buffer += precision; count += precision;
|
|
|
|
|
|
+
|
|
|
for (i = 0; left_aligned && i < width - precision && buffer < buffer_end; i++)
|
|
|
*buffer++ = L' ', count++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+
|
|
|
int cur_cnt = 0;
|
|
|
va_list apd;
|
|
|
|
|
|
+
|
|
|
if (fmt_len < (size_t)(format - fmt_start + 1))
|
|
|
cur_fmt = realloc(cur_fmt, ((fmt_len = format - fmt_start + 1) + 1) * sizeof(WCHAR));
|
|
|
wcsncpy(cur_fmt, fmt_start, fmt_len);
|
|
|
cur_fmt[fmt_len] = L'\0';
|
|
|
+
|
|
|
va_copy(apd, ap);
|
|
|
cur_cnt = vswprintf(buffer, buffer_end - buffer, cur_fmt, apd);
|
|
|
va_end(apd);
|
|
|
buffer += cur_cnt; count += cur_cnt;
|
|
|
|
|
|
+
|
|
|
+
|
|
|
if (width_var) va_arg(ap, int);
|
|
|
if (precision_var) va_arg(ap, int);
|
|
|
|
|
|
+
|
|
|
switch (*format)
|
|
|
{
|
|
|
case 'd':
|
|
@@ -2045,6 +2065,25 @@ PAL_swprintf(
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ if (state && buffer < buffer_end)
|
|
|
+ {
|
|
|
+ int fmt_len = format - fmt_start;
|
|
|
+ int buf_len = buffer_end - buffer;
|
|
|
+ if (fmt_len <= buf_len)
|
|
|
+ {
|
|
|
+ wcsncpy(buffer, fmt_start, buf_len);
|
|
|
+ buffer += fmt_len;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ wcsncpy(buffer, fmt_start, buf_len);
|
|
|
+ buffer += buf_len;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
*buffer = L'\0';
|
|
|
|
|
|
va_end(ap);
|