30#define _RWSTD_TEST_SRC
48#ifndef _RWSTD_NO_WCHAR_H
52#ifndef _RWSTD_NO_WCTYPE_H
75 __rw_memattr (
const void*,
size_t,
int);
87_rw_big_endian =
'\0' == _rw_one.bytes [0];
95#ifdef _RWSTD_LONG_LONG
113#define VA_ARG(va, T) \
114 (VarArgs::VA_list == (va).kind_ ? va_arg (*(va).arg_.pva_, T) \
115 : *((T*&)(va).arg_.pargs_)++)
144_rw_fmtwstr (
const FmtSpec&,
Buffer&,
const wchar_t*,
size_t);
148_rw_fmtstrarray (
FmtSpec*,
size_t,
Buffer&,
const char*
const*);
171static size_t _rw_usr_inx;
201_rw_fmtspec (
FmtSpec *pspec,
bool ext,
const char *fmt,
VarArgs *pva)
207 memset (pspec, 0,
sizeof *pspec);
215 const char*
const fmtbeg = fmt;
218 if (
'$' == *fmt &&
'}' != fmt [1]) {
228 const char*
const end = strchr (fmt,
'}');
237 char*
const tmp = (
char*)malloc (
len + 1);
243 return int (fmt - fmtbeg);
252 if (
'1' <= *fmt && *fmt <=
'9') {
254 const long tmp = strtol (fmt, &end, 10);
270 if (-1 == pspec->
width) {
274 case '-': pspec->
fl_minus =
true;
continue;
275 case '+': pspec->
fl_plus =
true;
continue;
276 case '#': pspec->
fl_pound =
true;
continue;
277 case ' ': pspec->
fl_space =
true;
continue;
278 case '0': pspec->
fl_zero =
true;
continue;
284 if (ext &&
'@' == *fmt &&
'}' != fmt [1]) {
290 if (
'0' <= fmt [1] && fmt [1] <=
'9') {
292 pspec->
base = int (strtol (fmt, &end, 10));
295 else if (
'*' == *fmt) {
304 if (-1 == pspec->
width) {
306 if (
'0' <= *fmt && *fmt <=
'9') {
308 pspec->
width = int (strtol (fmt, &end, 10));
311 else if (
'*' == *fmt) {
314 if (pspec->
width < 0) {
331 if (
'0' <= *fmt && *fmt <=
'9') {
333 pspec->
prec = int (strtol (fmt, &end, 10));
336 else if (
'*' == *fmt) {
346 const char mod = !ext ||
'}' != fmt [1] ? *fmt :
'\0';
358 if (
'h' == fmt [1] &&
'}' != fmt [2]) {
362 else if (
'}' != fmt [1]) {
369 if (
'l' == fmt [1] &&
'}' != fmt [2]) {
373 else if (
'}' != fmt [1]) {
408 else if (
'1' == fmt [0] &&
'6' == fmt [1]) {
412 else if (
'3' == fmt [0] &&
'2' == fmt [1]) {
416 else if (
'6' == fmt [0] &&
'4' == fmt [1]) {
432 return int (fmt - fmtbeg);
443 size_t buflen =
buf.endoff;
444 const size_t bufree = *
buf.pbuf ? *
buf.pbufsize - buflen : 0;
446 if (bufree <
len || !*
buf.pbuf) {
449 static const char guard[] =
"\xde\xad\xbe\xef";
451 const size_t guardsize =
sizeof guard - 1;
453 size_t newbufsize = *
buf.pbufsize * 2;
457 const size_t requiredsize = buflen +
len + 1;
458 if (newbufsize < requiredsize)
459 newbufsize = requiredsize * 2;
462 if (
buf.maxsize < newbufsize)
463 newbufsize =
buf.maxsize;
465 if (newbufsize < requiredsize) {
472 char*
const newbuf = (
char*)malloc (newbufsize + guardsize);
478 memcpy (newbuf, *
buf.pbuf, buflen);
481 memcpy (newbuf + newbufsize, guard, guardsize);
493 *
buf.pbufsize = newbufsize;
503 return *
buf.pbuf + buflen;
509_rw_vasnprintf_c99 (
FmtSpec *pspec,
520 FmtSpec &spec = pspec [paramno];
525#define PARAM(name, pva) \
527 ? pspec [spec.paramno - 1].param.name \
528 : VA_ARG (*pva, FmtSpec::name ## t))
539 len = _rw_fmtinteger (pspec, paramno,
buf, pva);
591 len = _rw_fmtwstr (spec,
buf,
str, _RWSTD_SIZE_MAX);
646#ifdef _RWSTD_LONG_LONG
661 *
ptr = long (
unsigned (
len));
668 *
ptr = ptrdiff_t (
unsigned (
len));
695 const size_t begoff =
buf.endoff;
708 size_t spec_bufsize =
sizeof specbuf /
sizeof *specbuf;
711 if (0 == fmt || 0 > _RW::__rw_memattr (fmt, _RWSTD_SIZE_MAX, -1))
714 for (
const char *fc = fmt; *fc; ) {
716 const char*
const pcnt = strchr (fc,
'%');
718 size_t nchars = pcnt ? pcnt - fmt : strlen (fc);
740 if (spec_bufsize == paramno) {
742 const size_t bytesize = spec_bufsize *
sizeof (
FmtSpec);
746 memcpy (
tmp, pspec, bytesize);
747 if (pspec != specbuf)
758 const char*
const endbrace = strchr (++fc,
'}');
760 if (0 == endbrace || fc == endbrace) {
761 const size_t flen = strlen (fc -= 2);
769 const size_t fmtlen = endbrace - fc;
774 memcpy (fmtspec, fc, fmtlen);
775 fmtspec [fmtlen] =
'\0';
784 const int speclen = _rw_fmtspec (pspec + paramno,
true, fc, pva);
791 pspec [paramno].
cond = 1;
793 if (backtrack [nextoff - 1] < 0) {
809 _rw_vasnprintf_ext (pspec, paramno,
buf, fmtspec, pva);
818 const size_t offinx = size_t (nextoff) - 1;
820 if (pspec [paramno].cond_end && pspec [paramno].cond_begin) {
825 RW_ASSERT (offinx <
sizeof backtrack /
sizeof *backtrack);
827 if (pspec [paramno].cond_true) {
835 len = -int (buflen) + backtrack [offinx];
839 backtrack [offinx] = ~backtrack [offinx];
847 backtrack [offinx] = int (buflen);
850 else if (pspec [paramno].cond_begin) {
856 if (pspec [paramno].cond_true)
857 backtrack [nextoff++] = ~int (buflen);
859 backtrack [nextoff++] = int (buflen);
865 else if (pspec [paramno].cond_end) {
868 if (!pspec [paramno].cond_true) {
871 RW_ASSERT (offinx <
sizeof backtrack /
sizeof *backtrack);
872 RW_ASSERT (backtrack [offinx] <=
int (buflen));
876 len = -int (buflen) + backtrack [offinx];
896 _rw_fmtspec (pspec + paramno,
false, fc, pva);
900 const int len = _rw_vasnprintf_c99 (pspec, paramno,
buf, pva);
907 if (-1 == pspec [paramno].paramno)
920 for (
size_t i = 0;
i != paramno; ++
i)
921 free (pspec [
i].strarg);
924 if (pspec != specbuf)
931 return int (
buf.endoff - begoff);
935 for (
size_t i = 0;
i != paramno; ++
i)
936 free (pspec [
i].strarg);
938 if (pspec != specbuf)
956#define varg DONT_TOUCH_ME
957#define vacpy DONT_TOUCH_ME
959 size_t default_bufsize = 1024;
961 pbufsize = &default_bufsize;
963 Buffer buf = { pbuf, pbufsize, _RWSTD_SIZE_MAX, 0 };
966 char*
const pbuf_save = *
buf.
pbuf;
972 &&
'%' == fmt [0] &&
'{' == fmt [1]
973 &&
'+' == fmt [2] &&
'}' == fmt [3]) {
978 buf.endoff = *
buf.pbuf ? strlen (*
buf.pbuf) : 0;
984 if (fmt &&
'%' == fmt [0] &&
'{' == fmt [1]) {
985 if (
'*' == fmt [2] &&
'}' == fmt [3]) {
986 const int n =
va_arg (*pva,
int);
994 buf.maxsize = size_t (
n);
997 else if (isdigit (fmt [2])) {
1000 const ULong n = strtoul (fmt + 2, &
end, 0);
1013 const int len = _rw_pvasnprintf (
buf, fmt, &args);
1018 const int error = errno;
1020 fprintf (
stderr,
"%s:%d: rw_vasnprintf(%p, %p, \"%s\", va_list) "
1021 "error: errno = %d: %s\n",
1022 __FILE__, __LINE__, (
void*)
buf.pbuf, (
void*)
buf.pbufsize,
1023 fmt, error, strerror (error));
1025 if (*
buf.pbuf != pbuf_save) {
1031 if (errno != error) {
1036 return len < 0 ?
len : -1;
1048static const char _rw_digits[] = {
1049 "0123456789abcdefghijklmnopqrstuvwxyz"
1050 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1063 const long upoff =
'X' == spec.
cvtspec ? 36 : 0;
1065 const bool is_signed =
'd' == spec.
cvtspec ||
'i' == spec.
cvtspec;
1066 const bool neg = 0 >
val && is_signed;
1071 *
end++ = _rw_digits [upoff + uval %
base];
1072 }
while (uval /=
base);
1081 switch (spec.
base) {
1083 *
end++ = upoff ?
'X' :
'x';
1093 else if (spec.
fl_plus && is_signed)
1101 for (
char *pc =
buffer; pc < --
end; ++pc) {
1102 const char tmp = *pc;
1118#ifdef _RWSTD_LONG_LONG
1130 const long upoff =
'X' == spec.
cvtspec ? 36 : 0;
1132 const bool is_signed =
'd' == spec.
cvtspec ||
'i' == spec.
cvtspec;
1133 const bool neg = 0 >
val && is_signed;
1139 *
end++ = _rw_digits [upoff + uval %
base];
1140 }
while (uval /=
base);
1149 switch (spec.
base) {
1151 *
end++ = upoff ?
'X' :
'x';
1161 else if (spec.
fl_plus && is_signed)
1169 for (
char *pc =
buffer; pc < --
end; ++pc) {
1170 const char tmp = *pc;
1177 newspec.fl_pound = 0;
1188template <
class IntT>
1192#ifdef _RWSTD_LONG_LONG
1196 const int len =
sizeof (
val) <=
sizeof (
long) ?
1216 FmtSpec &spec = pspec [paramno];
1246#ifdef _RWSTD_LONG_LONG
1249#elif 8 == _RWSTD_LONG_SIZE
1253 RW_ASSERT (!
"%lld, %lli: long long not supported");
1265 else if (1 == spec.
iwidth) {
1270 else if (2 == spec.
iwidth) {
1275 else if (3 == spec.
iwidth) {
1280 else if (4 == spec.
iwidth) {
1282#ifdef _RWSTD_INT64_T
1285 RW_ASSERT (!
"%I64d, %I64i: 64-bit types not supported");
1288#if 8 == _RWSTD_LONG_SIZE
1291#elif defined (_RWSTD_LONG_LONG)
1295 RW_ASSERT (!
"%I64d, %I64i: 64-bit types not supported");
1310 if (-1 == spec.
base)
1315 if (-1 == spec.
base)
1332#ifdef _RWSTD_LONG_LONG
1336#elif 8 == _RWSTD_LONG_SIZE
1358 else if (1 == spec.
iwidth) {
1363 else if (2 == spec.
iwidth) {
1368 else if (3 == spec.
iwidth) {
1373 else if (4 == spec.
iwidth) {
1374#ifdef _RWSTD_INT64_T
1377 RW_ASSERT (!
"%I64o, %I64u, %I64x: 64-bit types not supported");
1380#if 8 == _RWSTD_LONG_SIZE
1383#elif defined (_RWSTD_LONG_LONG)
1387 RW_ASSERT (!
"%I64o, %I64u, %I64x: 64-bit types not supported");
1459 pf += sprintf (
pf,
".%i", spec.
prec);
1468 char buffer [_RWSTD_LDBL_MAX_10_EXP + _RWSTD_LDBL_DIG + 3];
1473 if (_RWSTD_FLT_SIZE == spec.
width) {
1474 len = sprintf (
buffer, fmt, *(
const float*)pval);
1476 else if (_RWSTD_DBL_SIZE == spec.
width) {
1477 len = sprintf (
buffer, fmt, *(
const double*)pval);
1479 else if (_RWSTD_LDBL_SIZE == spec.
width) {
1480 len = sprintf (
buffer, fmt, *(
const long double*)pval);
1483 RW_ASSERT (!
"unknown floating point size");
1487 len = sprintf (
buffer, fmt, *(
const long double*)pval);
1489 len = sprintf (
buffer, fmt, *(
const double*)pval);
1493#if defined (_MSC_VER) || defined (__MINGW32__)
1523 const void *pptr,
size_t nelems)
1531 newspec.prec = _RWSTD_LONG_SIZE * 2;
1535 if (newspec.fl_pound) {
1543 newspec.fl_pound = 0;
1551 for (
size_t i = 0;
i != nelems; ++
i) {
1552 const size_t inx = _rw_big_endian ?
i : nelems -
i - 1;
1569 return _rw_fmtpointer (spec,
buf, &
val,
1570 sizeof val /
sizeof (
long));
1577 const void *
addr,
size_t objsize )
1582 const size_t off =
buf.endoff;
1584 const size_t num_addr = (size_t)
addr;
1586 if (objsize && (num_addr & (objsize - 1))) {
1602 return int (
buf.endoff -
off);
1613#ifdef _RWSTD_OS_SUNOS
1620 if (dladdr ((
void*)
val, &dli)) {
1622 dli.dli_fname =
"unknown";
1624 const size_t sym_off = size_t (dli.dli_saddr);
1629 const size_t addr_off = size_t (
val) < sym_off ?
1630 sym_off - size_t (
val) : size_t (
val) - sym_off;
1634 const int len = sprintf (
buffer,
"%#x=%s%c%lu",
1635 size_t (
val), dli.dli_sname,
1636 size_t (
val) < sym_off ?
'-' :
'+',
1640 newspec.mod_l = newspec.mod_none;
1649 return _rw_fmtpointer (spec,
buf, &
val,
1650 sizeof val /
sizeof (
long));
1658 return _rw_fmtpointer (spec,
buf, &
val,
1659 sizeof val /
sizeof (
long));
1667 if ( 0 == tmb || 0 > _RW::__rw_memattr (tmb,
sizeof *tmb, -1)
1668 || (
size_t)tmb & (
sizeof (
int) - 1)) {
1672 static const char*
const months[] = {
1673 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1674 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
1677 static const char*
const wdays[] = {
1678 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
1686 if ( tmb->tm_sec < 0 || 60 < tmb->tm_sec
1687 || tmb->tm_min < 0 || 59 < tmb->tm_min
1688 || tmb->tm_hour < 0 || 23 < tmb->tm_hour
1689 || tmb->tm_wday < 0 || 6 < tmb->tm_wday
1690 || tmb->tm_mday < 1 || 31 < tmb->tm_mday
1691 || _RWSTD_INT_MAX - 1900 < tmb->tm_year
1692 || tmb->tm_mon < 0 || 11 < tmb->tm_mon
1693 || tmb->tm_yday < 0 || 365 < tmb->tm_yday) {
1699 strcpy (vbuf, wdays [tmb->tm_wday]);
1701 strcat (vbuf, months [tmb->tm_mon]);
1704 sprintf (vbuf + strlen (vbuf),
"%2d %02d:%02d:%02d ",
1705 tmb->tm_mday, tmb->tm_hour, tmb->tm_min, tmb->tm_sec);
1708 strcat (vbuf,
"DST ");
1710 if (tmb->tm_year < -1899) {
1711 sprintf (vbuf + strlen (vbuf),
"%d BC",
1712 -(tmb->tm_year + 1899));
1715 sprintf (vbuf + strlen (vbuf),
"%d",
1716 tmb->tm_year + 1900);
1721 static const char comma[] =
", ";
1722 const char *sep =
"";
1724 strcpy (vbuf,
"{ ");
1727 sprintf (vbuf + strlen (vbuf),
"%stm_sec=%d", sep, tmb->tm_sec);
1728 if (tmb->tm_sec < 0 || 60 < tmb->tm_sec)
1729 strcat (vbuf,
" [0,60]");
1734 sprintf (vbuf + strlen (vbuf),
"%stm_min=%d", sep, tmb->tm_min);
1735 if (tmb->tm_min < 0 || 59 < tmb->tm_min)
1736 strcat (vbuf,
" [0,59]");
1741 sprintf (vbuf + strlen (vbuf),
"%stm_hour=%d", sep, tmb->tm_hour);
1742 if (tmb->tm_hour < 0 || 23 < tmb->tm_hour)
1743 strcat (vbuf,
" [0,23]");
1747 sprintf (vbuf + strlen (vbuf),
"%stm_mday=%d", sep, tmb->tm_mday);
1748 if (tmb->tm_mday < 1 || 31 < tmb->tm_mday)
1749 strcat (vbuf,
" [1,31]");
1753 sprintf (vbuf + strlen (vbuf),
"%stm_mon=%d", sep, tmb->tm_mon);
1754 if (tmb->tm_mon < 0 || 11 < tmb->tm_mon)
1755 strcat (vbuf,
" [0,11]");
1757 sprintf (vbuf + strlen (vbuf),
" %s",
1758 months [
unsigned (tmb->tm_mon) % 7]);
1763 sprintf (vbuf + strlen (vbuf),
"%stm_year=%d", sep, tmb->tm_year);
1764 if (_RWSTD_INT_MAX - 1900 < tmb->tm_year)
1765 sprintf (vbuf + strlen (vbuf),
" [%d,%d]",
1766 _RWSTD_INT_MIN, _RWSTD_INT_MAX - 1900);
1770 sprintf (vbuf + strlen (vbuf),
"%stm_wday=%d", sep, tmb->tm_wday);
1771 if (tmb->tm_wday < 0 || 6 < tmb->tm_wday)
1772 strcat (vbuf,
" [0,6]");
1774 sprintf (vbuf + strlen (vbuf),
" %s",
1775 wdays [
unsigned (tmb->tm_wday) % 7]);
1780 sprintf (vbuf + strlen (vbuf),
"%stm_yday=%d", sep, tmb->tm_yday);
1781 if (tmb->tm_yday < 0 || 365 < tmb->tm_yday)
1782 strcat (vbuf,
" [0,365]");
1786 sprintf (vbuf + strlen (vbuf),
"%stm_isdst=%d", sep, tmb->tm_isdst);
1788 strcat (vbuf,
" }");
1791 const size_t len = strlen (vbuf);
1801template <
class charT>
1809 if ((1 ==
sizeof wc || wi < 0x100U) && noesc) {
1810 buf [0] = char (wc);
1821 case '\a':
buf [1] =
'a';
buf [
len = 2] =
'\0';
break;
1822 case '\b':
buf [1] =
'b';
buf [
len = 2] =
'\0';
break;
1823 case '\f':
buf [1] =
'f';
buf [
len = 2] =
'\0';
break;
1824 case '\n':
buf [1] =
'n';
buf [
len = 2] =
'\0';
break;
1825 case '\r':
buf [1] =
'r';
buf [
len = 2] =
'\0';
break;
1826 case '\t':
buf [1] =
't';
buf [
len = 2] =
'\0';
break;
1827 case '\v':
buf [1] =
'v';
buf [
len = 2] =
'\0';
break;
1828 case '\\':
buf [1] =
'\\';
buf [
len = 2] =
'\0';
break;
1829 case '"' :
buf [1] =
'"';
buf [
len = 2] =
'\0';
break;
1831 if (wc <
' ' || wc >
'~') {
1838 else if (1 ==
sizeof wc) {
1844 wi > 0xfffffffUL ? 8 : wi > 0xffffffUL ? 7
1845 : wi > 0xfffffUL ? 6 : wi > 0xffffUL ? 5
1846 : wi > 0xfffUL ? 4 : wi > 0xffUL ? 3
1847 : wi > 0xfUL ? 2 : 2;
1849 len = 1 + sprintf (
buf + 1,
"x%0*lx", width,
ULong (wi));
1853 buf [0] = char (wc);
1870template <
class elemT>
1879 const size_t memlen = _RWSTD_SIZE_MAX == nelems
1880 ? _RWSTD_SIZE_MAX : nelems *
sizeof *
array;
1882 || 0 > _RW::__rw_memattr (
array, memlen, -1)
1889 if (_RWSTD_SIZE_MAX == nelems) {
1892 for (
const elemT *pc =
array; *pc; ++pc, ++nelems);
1900 const size_t seplen = strlen (sep);
1903 const size_t bufsize = (nelems + 1) * (65 + seplen) + 3;
1907 const char*
const bufend = next;
1916 for (
int w = 0;
w < spec.
width; ++
w)
1927 if (
flags &
A_ARRAY && _RWSTD_WCHAR_SIZE ==
sizeof (elemT))
1932 for (
int w = 0;
w < spec.
width; ++
w)
1937 buf.endoff += size_t (next - bufend);
1938 return int (next - bufend);
1945 bool any_repeats =
false;
1951 const ptrdiff_t
N = ptrdiff_t (
flags &
A_ESC ? 20 : 0);
1953 for (
const elemT *pelem =
last + 1; ; ++pelem) {
1955 if (
size_t (pelem -
array) < nelems && *pelem == *
last) {
1961 if (
N > 1 && pelem -
last >
N) {
1968 const long repeat = long (pelem -
last);
1974 s += sprintf (
s,
"%s'%s' <repeats %ld times>",
1975 -1 == last_repeat ?
""
1976 : 0 == last_repeat ?
"\", " :
", ",
1981 char *localbuf = elemstr;
1982 size_t localbufsize =
sizeof elemstr;
1985 &localbuf, &localbufsize,
sizeof elemstr, 0
1994 localbuf [intlen] =
'\0';
1999 s += sprintf (
s,
"%s%s <repeats %ld times>%s",
2000 last_repeat < 1 ?
"" : sep, elemstr, repeat, sep);
2006 last_repeat = repeat;
2013 if (last_repeat < 0) {
2016 && _RWSTD_WCHAR_SIZE ==
sizeof (elemT))
2023 else if (last_repeat > 0) {
2039 char *localbuf = elemstr;
2040 size_t localbufsize =
sizeof elemstr;
2043 &localbuf, &localbufsize,
sizeof elemstr, 0
2052 localbuf [intlen] =
'\0';
2058 const size_t elemlen = strlen (elemstr);
2061 memcpy (
s, elemstr, elemlen);
2063 memcpy (
s, sep, seplen + 1);
2069 if (
size_t (pelem -
array) == nelems) {
2081 if (
size_t (pelem -
array) == nelems) {
2093 const size_t len = strlen (next);
2094 memmove (next + 2, next,
len);
2097 next [
len + 2] =
' ';
2098 next [
len + 3] =
'}';
2099 next [
len + 4] =
'\0';
2103 buf.endoff += size_t (
s - bufend);
2105 return int (
s - bufend);
2108#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
2123# ifndef _RWSTD_NO_NATIVE_WCHAR_T
2142 FmtSpec &spec = pspec [paramno];
2145 const int width = spec.
width;
2155 const unsigned pound = spec.
fl_pound;
2159 const size_t nelems = size_t (spec.
prec);
2167 if (-1 == width || 1 == width) {
2169 const _RWSTD_UINT8_T*
const array = (_RWSTD_UINT8_T*)spec.
param.
ptr_;
2175 else if (2 == width) {
2177 const _RWSTD_UINT16_T*
const array = (_RWSTD_UINT16_T*)spec.
param.
ptr_;
2180 else if (4 == width) {
2182 const _RWSTD_UINT32_T*
const array = (_RWSTD_UINT32_T*)spec.
param.
ptr_;
2186#ifdef _RWSTD_UINT64_T
2188 else if (8 == width) {
2190 const _RWSTD_UINT64_T*
const array = (_RWSTD_UINT64_T*)spec.
param.
ptr_;
2197 RW_ASSERT (!
"%{Ac} not implemented for this character size");
2202 spec.
prec = int (nelems);
2213 const char*
const* argv)
2215 FmtSpec &spec = pspec [paramno];
2219 if (0 == argv || 0 > _RW::__rw_memattr (argv,
sizeof *argv, -1))
2222 size_t argc = spec.
prec;
2224 for (
size_t i = 0;
i != argc; ++
i) {
2225 if (_RWSTD_SIZE_MAX == argc && 0 == argv [
i])
2235 if (
i + 1 == argc || (_RWSTD_SIZE_MAX == argc && 0 == argv [
i + 1]))
2238 const unsigned pound = spec.
fl_pound;
2271 newspec.fl_pound = 0;
2285 if (0 == noesc &&
WEOF ==
val) {
2306 newspec.fl_pound = 0;
2321 if (0 ==
str || 0 > _RW::__rw_memattr (
str,
len, -1))
2324 if (_RWSTD_SIZE_MAX ==
len)
2337 const size_t width =
2342 const size_t pad =
len < width ? width -
len : 0;
2349 char *next = *
buf.pbuf +
buf.endoff;
2352 for (
size_t i = 0;
i != pad; ++
i)
2360 for (
size_t i = 0;
i != pad; ++
i)
2373#ifndef _RWSTD_NO_WCHAR_T
2377 const wchar_t *wstr,
size_t len)
2392 const size_t memlen = _RWSTD_SIZE_MAX ==
len
2393 ? _RWSTD_SIZE_MAX :
len *
sizeof *wstr;
2395 || 0 > _RW::__rw_memattr (wstr, memlen, -1)
2396 || ((
size_t)wstr & (
sizeof *wstr - 1)))
2399 if (_RWSTD_SIZE_MAX ==
len) {
2401#ifndef _RWSTD_NO_WCSLEN
2402 len = wcslen (wstr);
2405 for (
const wchar_t *pwc = wstr; *pwc; ++pwc, ++
len);
2420 const size_t width =
2425 const size_t pad =
len < width ? width -
len : 0;
2432 char *next = *
buf.pbuf +
buf.endoff;
2435 for (
size_t i = 0;
i != pad; ++
i)
2440 for (
const wchar_t *pwc = wstr; pwc != wstr +
len; ++pwc) {
2450 for (
size_t i = 0;
i != pad; ++
i)
2466_rw_vasnprintf_ext (
FmtSpec *pspec,
2476 FmtSpec &spec = pspec [paramno];
2482 for (
size_t i = _rw_usr_inx;
i-- && _rw_usr_fun [
i]; ) {
2487 if (_rw_usr_fun [
i]) {
2491 (*
buf.pbuf)[
buf.endoff] =
'\0';
2496 len = (_rw_usr_fun [
i])(
buf.pbuf,
buf.pbufsize, fmt,
2497 &pspec [spec.
paramno - 1].param);
2502 len = (_rw_usr_fun [
i])(
buf.pbuf,
buf.pbufsize, fmt,
2509 if (_RWSTD_INT_MIN !=
len) {
2536 if (0 == _rw_usr_inx)
2549 const char*
const tmp_fmt = (
const char*)spec.
param.
ptr_;
2550 len = _rw_fmtnested (spec,
buf, tmp_fmt, pva);
2575 static const char str[] =
"%{:}";
2587 static const char str[] =
"%{;}";
2651 spec.
param.
int_ = -1 == spec.
width ? GetLastError () : spec.width;
2696 if (-1 == spec.
base)
2706 if (-1 == spec.
base)
2712 if (-1 == spec.
base)
2718 if (-1 == spec.
base)
2725 len = _rw_fmtinteger (pspec, paramno,
buf, pva);
2761 const size_t nbytes = *
buf.pbufsize;
2777 *
ptr = short (nbytes);
2780#ifdef _RWSTD_LONG_LONG
2795 *
ptr = long (nbytes);
2802 *
ptr = ptrdiff_t (nbytes);
2809 *
ptr = int (nbytes);
2824 const char*
const*
const argv = (
char**)spec.
param.
ptr_;
2825 len = _rw_fmtstrarray (pspec, paramno,
buf, argv);
2833 const wchar_t*
const wstr = (
wchar_t*)spec.
param.
ptr_;
2834 const size_t wstr_len =
2835 spec.
width < 0 ? _RWSTD_SIZE_MAX : size_t (spec.
width);
2841 const size_t str_len =
2842 spec.
width < 0 ? _RWSTD_SIZE_MAX : size_t (spec.
width);
2854 const std::wstring*
const pstr = (std::wstring*)spec.
param.
ptr_;
2856 if ( 0 == pstr || 0 > _RW::__rw_memattr (pstr,
sizeof *pstr, -1)
2857 || (
size_t)pstr & (
sizeof (pstr) - 1)) {
2862 const wchar_t*
const wstr = pstr->data ();
2863 const std::wstring::size_type
size = pstr->size ();
2871 const std::string*
const pstr = (std::string*)spec.
param.
ptr_;
2873 if ( 0 == pstr || 0 > _RW::__rw_memattr (pstr,
sizeof *pstr, -1)
2874 || (
size_t)pstr & (
sizeof (pstr) - 1)) {
2878 const char*
const str = pstr->data ();
2879 const std::string::size_type
size = pstr->size ();
2889 const tm*
const tmb = (tm*)spec.
param.
ptr_;
2891 len = _rw_fmttm (spec,
buf, tmb);
2906 return _rw_fmtexpr (spec,
buf, pva);
2910 len = sprintf (text,
"%%{%.*s}",
int (
sizeof text - 3), fmt);
2927 char *param = spec.
strarg;
2930 char* word = strpbrk (param,
":+-=?!");
2933 if (
'+' == word [1] ||
'-' == word [1]
2934 ||
'=' == word [1] ||
'?' == word [1]) {
2935 oper [0] = word [0];
2936 oper [1] = word [1];
2945 else if (
'!' == word [0] &&
':' == word [1]) {
2947 oper [0] = word [0];
2948 oper [1] = word [1];
2960 if (
'*' == *param) {
2962 param =
VA_ARG (*pva,
char*);
2969 word =
VA_ARG (*pva,
char*);
2971 else if (
'@' == *word) {
2974 const char*
const fmt =
VA_ARG (*pva,
char*);
2976 size_t dummy_size = 0;
2977 Buffer tmpbuf = { &fmtword, &dummy_size, _RWSTD_SIZE_MAX, 0 };
2978 const int len = _rw_pvasnprintf (tmpbuf, fmt, pva);
2989 word = *tmpbuf.
pbuf;
2993 const char*
val = getenv (param);
3025 if (
'-' == oper [1]) {
3026 if (0 ==
val ||
'\0' == *
val)
3029 else if (
'=' == oper [1]) {
3030 if (0 ==
val ||
'\0' == *
val) {
3035 else if (
'?' == oper [1]) {
3036 if (0 ==
val ||
'\0' == *
val) {
3041 else if (
'+' == oper [1]) {
3042 if (0 ==
val ||
'\0' == *
val)
3077 val = word ? word :
"";
3091 int len = int (strlen (
val));
3096 char *pbuf = varbuf;
3098 const size_t varlen = strlen (param) + strlen (
val) + 2;
3099 if (
sizeof varbuf < varlen) {
3100 pbuf = (
char*)malloc (varlen);
3105 strcpy (pbuf, param);
3120 len = sprintf (text,
"%%{$%.*s}",
int (
sizeof text - 3), spec.
strarg);
3149_rw_fmtnested (
const FmtSpec &spec,
3158 const int nelems = spec.
prec < 0 ? 1 : spec.
prec;
3161 const char *sepstr =
"";
3173 tmparg.arg_.pargs_ =
VA_ARG (*pva,
void*);
3178 for (
int i = 0;
i != nelems; ++
i) {
3179 len += _rw_pvasnprintf (
buf, fmt, &tmparg);
3181 if (seplen &&
i + 1 < nelems && 0 ==
_rw_bufcat (
buf, sepstr, seplen))
3193 RW_ASSERT (0 == pbuf || 0 == *pbuf || pbufsize);
3208 if (0 == pbufsize) {
3210 pbufsize = &bufsize;
3222 if (pbuf == &bufptr) {
3298 memcpy (
buf, tmpbuf,
size_t (
nchars) + 1 );
3321 if (
size_t (
nchars) < bufsize) {
3322 memcpy (
buf, tmpbuf,
size_t (
nchars) + 1 );
3326 memcpy (
buf, tmpbuf, bufsize);
3328 buf [bufsize - 1] =
'\0';
3353_rw_vfprintf (rw_file *file,
const char *fmt, va_list va)
3374 nwrote = int (fwrite (
buf, 1,
size_t (
nchars), stdio_file));
3379 fflush (stdio_file);
3383 OutputDebugString (
buf);
3402 const int nchars = _rw_vfprintf (file, fmt, va);
#define _RWSTD_LDBL_PRINTF_PREFIX
#define va_start(va, name)
#define _RWSTD_VA_COPY(va_dst, va_src)
#define _RWSTD_REINTERPRET_CAST(T, x)
#define _RWSTD_UNUSED(arg)
#define _RWSTD_STATIC_CAST(T, x)
#define _RWSTD_NAMESPACE(name)
#define _RWSTD_UWCHAR_INT_T
#define _RWSTD_CONST_CAST(T, x)
int _rw_fmtcharmask(const FmtSpec &spec, Buffer &buf, int c)
int _rw_fmtmonpat(const FmtSpec &spec, Buffer &buf, const char pat[4])
int _rw_fmtlasterror(const FmtSpec &spec, Buffer &buf, int val)
int _rw_fmtbits(const FmtSpec &spec, Buffer &buf, const void *pelems, size_t elemsize)
int _rw_fmtmask(const FmtSpec &spec, Buffer &buf, int bits)
int _rw_fmtiostate(const FmtSpec &spec, Buffer &buf, int bits)
int _rw_fmtevent(const FmtSpec &spec, Buffer &buf, int event)
int _rw_fmtflags(const FmtSpec &spec, Buffer &buf, int bits)
int _rw_fmtlc(const FmtSpec &spec, Buffer &buf, int val)
int _rw_fmterrno(const FmtSpec &spec, Buffer &buf, int val)
int _rw_fmtseekdir(const FmtSpec &spec, Buffer &buf, int bits)
int _rw_fmtopenmode(const FmtSpec &spec, Buffer &buf, int bits)
int _rw_fmtsignal(const FmtSpec &spec, Buffer &buf, int val)
void(DummyStruct::* memptr_t)() const
@ error
throw a parse_error exception in case of a tag
_RWSTD_INTERNAL char * _rw_bufcat(Buffer &buf, const char *str, size_t len)
_TEST_EXPORT int rw_fprintf(rw_file *file, const char *fmt,...)
_TEST_EXPORT int rw_asnprintf(char **pbuf, size_t *pbufsize, const char *fmt,...)
_RWSTD_INTERNAL int _rw_fmtlong(const FmtSpec &, Buffer &, long)
_TEST_EXPORT int rw_sprintf(char *buf, const char *fmt,...)
int _rw_fmtstr(const FmtSpec &spec, Buffer &buf, const char *str, size_t len)
_TEST_EXPORT char * rw_snprintfa(char *buf, size_t bufsize, const char *fmt,...)
_TEST_EXPORT char * rw_sprintfa(const char *fmt,...)
int _rw_fmtarray(const FmtSpec &spec, Buffer &buf, const elemT *array, size_t nelems, int flags)
_TEST_EXPORT int rw_snprintf(char *buf, size_t bufsize, const char *fmt,...)
_TEST_EXPORT int rw_printf(const char *fmt,...)
int _rw_usr_cb_t(char **, size_t *, const char *,...)
_RWSTD_INTERNAL int _rw_fmtbadaddr(const FmtSpec &, Buffer &, const void *, size_t=0)
_TEST_EXPORT int rw_vasnprintf(char **pbuf, size_t *pbufsize, const char *fmt, va_list varg)
_RWSTD_INTERNAL int _rw_fmtptr(const FmtSpec &, Buffer &, const void *)
int _rw_quotechar(char *buf, charT wc, int noesc)
int rw_fmtinteger(const FmtSpec &spec, Buffer &buf, IntT val)
_TEST_EXPORT int rw_putenv(const char *, int=-1)