mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 17:25:03 +02:00
[Format] add variable width support (#1743)
* add variable width test cases * add variable width support * update the documentation for variable width
This commit is contained in:
parent
fd1d113acb
commit
303e398803
@ -82,11 +82,11 @@ std::string Foundation_API format(const std::string& fmt, const Any& value);
|
||||
/// * h argument is short (d, i), unsigned short (o, u, x, X) or float (e, E, f, g, G)
|
||||
/// * ? argument is any signed or unsigned int, short, long, or 64-bit integer (d, i, o, x, X)
|
||||
///
|
||||
/// The width argument is a nonnegative decimal integer controlling the minimum number of characters printed.
|
||||
/// The width argument is a nonnegative decimal integer or '*' with an additional nonnegative integer value preceding the value to be formated, controlling the minimum number of characters printed.
|
||||
/// If the number of characters in the output value is less than the specified width, blanks or
|
||||
/// leading zeros are added, according to the specified flags (-, +, 0).
|
||||
///
|
||||
/// Precision is a nonnegative decimal integer, preceded by a period (.), which specifies the number of characters
|
||||
/// Precision is a nonnegative decimal integer or '*' with an additional nonnegative integer value preceding the value to be formated, preceded by a period (.), which specifies the number of characters
|
||||
/// to be printed, the number of decimal places, or the number of significant digits.
|
||||
///
|
||||
/// Throws an InvalidArgumentException if an argument index is out of range.
|
||||
|
@ -46,28 +46,44 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
void parseWidth(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
|
||||
void parseWidth(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
|
||||
{
|
||||
int width = 0;
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
if (itFmt != endFmt && *itFmt == '*')
|
||||
{
|
||||
width = 10*width + *itFmt - '0';
|
||||
++itFmt;
|
||||
width = AnyCast<int>(*itVal++);
|
||||
}
|
||||
if (width != 0) str.width(width);
|
||||
else
|
||||
{
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
{
|
||||
width = 10*width + *itFmt - '0';
|
||||
++itFmt;
|
||||
}
|
||||
}
|
||||
if (width > 0) str.width(width);
|
||||
}
|
||||
|
||||
|
||||
void parsePrec(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
|
||||
void parsePrec(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
|
||||
{
|
||||
if (itFmt != endFmt && *itFmt == '.')
|
||||
{
|
||||
++itFmt;
|
||||
int prec = 0;
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
if (itFmt != endFmt && *itFmt == '*')
|
||||
{
|
||||
prec = 10*prec + *itFmt - '0';
|
||||
++itFmt;
|
||||
prec = AnyCast<int>(*itVal++);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (itFmt != endFmt && Ascii::isDigit(*itFmt))
|
||||
{
|
||||
prec = 10*prec + *itFmt - '0';
|
||||
++itFmt;
|
||||
}
|
||||
}
|
||||
if (prec >= 0) str.precision(prec);
|
||||
}
|
||||
@ -155,8 +171,8 @@ namespace
|
||||
try
|
||||
{
|
||||
parseFlags(str, itFmt, endFmt);
|
||||
parseWidth(str, itFmt, endFmt);
|
||||
parsePrec(str, itFmt, endFmt);
|
||||
parseWidth(str, itFmt, endFmt, itVal);
|
||||
parsePrec(str, itFmt, endFmt, itVal);
|
||||
char mod = parseMod(itFmt, endFmt);
|
||||
if (itFmt != endFmt)
|
||||
{
|
||||
|
@ -44,6 +44,11 @@ void FormatTest::testChar()
|
||||
s = format("%-2c", c);
|
||||
assert(s == "a ");
|
||||
|
||||
s = format("%*c", 2, c);
|
||||
assert(s == " a");
|
||||
s = format("%-*c", 2, c);
|
||||
assert(s == "a ");
|
||||
|
||||
s = format("%c", std::string("foo"));
|
||||
assert(s == "[ERRFMT]");
|
||||
}
|
||||
@ -59,6 +64,11 @@ void FormatTest::testInt()
|
||||
s = format("%04d", i);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*d", 4, i);
|
||||
assert (s == " 42");
|
||||
s = format("%0*d", 4, i);
|
||||
assert (s == "0042");
|
||||
|
||||
short h = 42;
|
||||
s = format("%hd", h);
|
||||
assert (s == "42");
|
||||
@ -67,6 +77,11 @@ void FormatTest::testInt()
|
||||
s = format("%04hd", h);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*hd", 4, h);
|
||||
assert (s == " 42");
|
||||
s = format("%0*hd", 4, h);
|
||||
assert (s == "0042");
|
||||
|
||||
unsigned short hu = 42;
|
||||
s = format("%hu", hu);
|
||||
assert (s == "42");
|
||||
@ -74,6 +89,11 @@ void FormatTest::testInt()
|
||||
assert (s == " 42");
|
||||
s = format("%04hu", hu);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*hu", 4, hu);
|
||||
assert (s == " 42");
|
||||
s = format("%0*hu", 4, hu);
|
||||
assert (s == "0042");
|
||||
|
||||
unsigned x = 0x42;
|
||||
s = format("%x", x);
|
||||
@ -83,6 +103,11 @@ void FormatTest::testInt()
|
||||
s = format("%04x", x);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*x", 4, x);
|
||||
assert (s == " 42");
|
||||
s = format("%0*x", 4, x);
|
||||
assert (s == "0042");
|
||||
|
||||
unsigned o = 042;
|
||||
s = format("%o", o);
|
||||
assert (s == "42");
|
||||
@ -91,6 +116,11 @@ void FormatTest::testInt()
|
||||
s = format("%04o", o);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*o", 4, o);
|
||||
assert (s == " 42");
|
||||
s = format("%0*o", 4, o);
|
||||
assert (s == "0042");
|
||||
|
||||
unsigned u = 42;
|
||||
s = format("%u", u);
|
||||
assert (s == "42");
|
||||
@ -98,6 +128,11 @@ void FormatTest::testInt()
|
||||
assert (s == " 42");
|
||||
s = format("%04u", u);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*u", 4, u);
|
||||
assert (s == " 42");
|
||||
s = format("%0*u", 4, u);
|
||||
assert (s == "0042");
|
||||
|
||||
long l = 42;
|
||||
s = format("%ld", l);
|
||||
@ -107,6 +142,11 @@ void FormatTest::testInt()
|
||||
s = format("%04ld", l);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*ld", 4, l);
|
||||
assert (s == " 42");
|
||||
s = format("%0*ld", 4, l);
|
||||
assert (s == "0042");
|
||||
|
||||
unsigned long ul = 42;
|
||||
s = format("%lu", ul);
|
||||
assert (s == "42");
|
||||
@ -114,6 +154,11 @@ void FormatTest::testInt()
|
||||
assert (s == " 42");
|
||||
s = format("%04lu", ul);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*lu", 4, ul);
|
||||
assert (s == " 42");
|
||||
s = format("%0*lu", 4, ul);
|
||||
assert (s == "0042");
|
||||
|
||||
unsigned long xl = 0x42;
|
||||
s = format("%lx", xl);
|
||||
@ -122,6 +167,11 @@ void FormatTest::testInt()
|
||||
assert (s == " 42");
|
||||
s = format("%04lx", xl);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*lx", 4, xl);
|
||||
assert (s == " 42");
|
||||
s = format("%0*lx", 4, xl);
|
||||
assert (s == "0042");
|
||||
|
||||
Int64 i64 = 42;
|
||||
s = format("%Ld", i64);
|
||||
@ -130,6 +180,11 @@ void FormatTest::testInt()
|
||||
assert (s == " 42");
|
||||
s = format("%04Ld", i64);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*Ld", 4, i64);
|
||||
assert (s == " 42");
|
||||
s = format("%0*Ld", 4, i64);
|
||||
assert (s == "0042");
|
||||
|
||||
UInt64 ui64 = 42;
|
||||
s = format("%Lu", ui64);
|
||||
@ -138,6 +193,11 @@ void FormatTest::testInt()
|
||||
assert (s == " 42");
|
||||
s = format("%04Lu", ui64);
|
||||
assert (s == "0042");
|
||||
|
||||
s = format("%*Lu", 4, ui64);
|
||||
assert (s == " 42");
|
||||
s = format("%0*Lu", 4, ui64);
|
||||
assert (s == "0042");
|
||||
|
||||
x = 0xaa;
|
||||
s = format("%x", x);
|
||||
@ -154,6 +214,10 @@ void FormatTest::testInt()
|
||||
assert (s == "-42");
|
||||
s = format("%+04d", i);
|
||||
assert (s == "-042");
|
||||
|
||||
s = format("%+0*d", 4, i);
|
||||
assert (s == "-042");
|
||||
|
||||
s = format("%d", i);
|
||||
assert (s == "-42");
|
||||
|
||||
@ -266,10 +330,18 @@ void FormatTest::testFloatFix()
|
||||
s = format("%10f", d);
|
||||
assert (s.find(" 1.50") != std::string::npos);
|
||||
|
||||
s = format("%*f", 10, d);
|
||||
assert (s.find(" 1.50") != std::string::npos);
|
||||
|
||||
s = format("%6.2f", d);
|
||||
assert (s == " 1.50");
|
||||
s = format("%-6.2f", d);
|
||||
assert (s == "1.50 ");
|
||||
|
||||
s = format("%*.*f", 6, 2, d);
|
||||
assert (s == " 1.50");
|
||||
s = format("%-*.*f", 6,2, d);
|
||||
assert (s == "1.50 ");
|
||||
|
||||
float f = 1.5;
|
||||
s = format("%hf", f);
|
||||
@ -277,6 +349,9 @@ void FormatTest::testFloatFix()
|
||||
|
||||
s = format("%.0f", 1.0);
|
||||
assert (s == "1");
|
||||
|
||||
s = format("%.*f", 0, 1.0);
|
||||
assert (s == "1");
|
||||
}
|
||||
|
||||
|
||||
@ -291,12 +366,23 @@ void FormatTest::testFloatSci()
|
||||
assert (s.find(" 1.50") != std::string::npos);
|
||||
assert (s.find("0e+0") != std::string::npos);
|
||||
|
||||
s = format("%*e", 20, d);
|
||||
assert (s.find(" 1.50") != std::string::npos);
|
||||
assert (s.find("0e+0") != std::string::npos);
|
||||
|
||||
s = format("%10.2e", d);
|
||||
assert (s == " 1.50e+000" || s == " 1.50e+00");
|
||||
s = format("%-10.2e", d);
|
||||
assert (s == "1.50e+000 " || s == "1.50e+00 ");
|
||||
s = format("%-10.2E", d);
|
||||
assert (s == "1.50E+000 " || s == "1.50E+00 ");
|
||||
|
||||
s = format("%*.*e", 10, 2, d);
|
||||
assert (s == " 1.50e+000" || s == " 1.50e+00");
|
||||
s = format("%-*.*e", 10, 2, d);
|
||||
assert (s == "1.50e+000 " || s == "1.50e+00 ");
|
||||
s = format("%-*.*E", 10, 2, d);
|
||||
assert (s == "1.50E+000 " || s == "1.50E+00 ");
|
||||
}
|
||||
|
||||
|
||||
@ -312,6 +398,12 @@ void FormatTest::testString()
|
||||
s = format("%-5s", foo);
|
||||
assert (s == "foo ");
|
||||
|
||||
s = format("%*s", 5, foo);
|
||||
assert (s == " foo");
|
||||
|
||||
s = format("%-*s", 5, foo);
|
||||
assert (s == "foo ");
|
||||
|
||||
s = format("%s%%a", foo);
|
||||
assert (s == "foo%a");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user