mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-01 14:10:06 +00:00
Implement '#' flag.
This commit is contained in:
parent
3f73987a62
commit
73f13eeb5b
23
format.cc
23
format.cc
@ -55,7 +55,7 @@ using fmt::StringRef;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Flags.
|
// Flags.
|
||||||
enum { SIGN_FLAG = 1, PLUS_FLAG = 2, HEX_PREFIX_FLAG = 4 };
|
enum { SIGN_FLAG = 1, PLUS_FLAG = 2, HASH_FLAG = 4 };
|
||||||
|
|
||||||
void ReportUnknownType(char code, const char *type) {
|
void ReportUnknownType(char code, const char *type) {
|
||||||
if (std::isprint(static_cast<unsigned char>(code))) {
|
if (std::isprint(static_cast<unsigned char>(code))) {
|
||||||
@ -236,7 +236,7 @@ void Formatter::FormatInt(T value, const FormatSpec &spec) {
|
|||||||
}
|
}
|
||||||
case 'x': case 'X': {
|
case 'x': case 'X': {
|
||||||
UnsignedType n = abs_value;
|
UnsignedType n = abs_value;
|
||||||
bool print_prefix = (spec.flags & HEX_PREFIX_FLAG) != 0;
|
bool print_prefix = (spec.flags & HASH_FLAG) != 0;
|
||||||
if (print_prefix) size += 2;
|
if (print_prefix) size += 2;
|
||||||
do {
|
do {
|
||||||
++size;
|
++size;
|
||||||
@ -250,12 +250,14 @@ void Formatter::FormatInt(T value, const FormatSpec &spec) {
|
|||||||
} while ((n >>= 4) != 0);
|
} while ((n >>= 4) != 0);
|
||||||
if (print_prefix) {
|
if (print_prefix) {
|
||||||
*p-- = spec.type;
|
*p-- = spec.type;
|
||||||
*p-- = '0';
|
*p = '0';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'o': {
|
case 'o': {
|
||||||
UnsignedType n = abs_value;
|
UnsignedType n = abs_value;
|
||||||
|
bool print_prefix = (spec.flags & HASH_FLAG) != 0;
|
||||||
|
if (print_prefix) ++size;
|
||||||
do {
|
do {
|
||||||
++size;
|
++size;
|
||||||
} while ((n >>= 3) != 0);
|
} while ((n >>= 3) != 0);
|
||||||
@ -264,6 +266,8 @@ void Formatter::FormatInt(T value, const FormatSpec &spec) {
|
|||||||
do {
|
do {
|
||||||
*p-- = '0' + (n & 7);
|
*p-- = '0' + (n & 7);
|
||||||
} while ((n >>= 3) != 0);
|
} while ((n >>= 3) != 0);
|
||||||
|
if (print_prefix)
|
||||||
|
*p = '0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -310,11 +314,13 @@ void Formatter::FormatDouble(T value, const FormatSpec &spec, int precision) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build format string.
|
// Build format string.
|
||||||
enum { MAX_FORMAT_SIZE = 10}; // longest format: %+0*.*Lg
|
enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
|
||||||
char format[MAX_FORMAT_SIZE];
|
char format[MAX_FORMAT_SIZE];
|
||||||
char *format_ptr = format;
|
char *format_ptr = format;
|
||||||
*format_ptr++ = '%';
|
*format_ptr++ = '%';
|
||||||
unsigned width_for_sprintf = width;
|
unsigned width_for_sprintf = width;
|
||||||
|
if ((spec.flags & HASH_FLAG) != 0)
|
||||||
|
*format_ptr++ = '#';
|
||||||
if (spec.align == ALIGN_CENTER) {
|
if (spec.align == ALIGN_CENTER) {
|
||||||
width_for_sprintf = 0;
|
width_for_sprintf = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -503,6 +509,13 @@ void Formatter::DoFormat() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*s == '#') {
|
||||||
|
if (arg.type > LAST_NUMERIC_TYPE)
|
||||||
|
ReportError(s, "format specifier '#' requires numeric argument");
|
||||||
|
spec.flags |= HASH_FLAG;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse width and zero flag.
|
// Parse width and zero flag.
|
||||||
if ('0' <= *s && *s <= '9') {
|
if ('0' <= *s && *s <= '9') {
|
||||||
if (*s == '0') {
|
if (*s == '0') {
|
||||||
@ -634,7 +647,7 @@ void Formatter::DoFormat() {
|
|||||||
case POINTER:
|
case POINTER:
|
||||||
if (spec.type && spec.type != 'p')
|
if (spec.type && spec.type != 'p')
|
||||||
ReportUnknownType(spec.type, "pointer");
|
ReportUnknownType(spec.type, "pointer");
|
||||||
spec.flags = HEX_PREFIX_FLAG;
|
spec.flags = HASH_FLAG;
|
||||||
spec.type = 'x';
|
spec.type = 'x';
|
||||||
FormatInt(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
|
FormatInt(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
|
||||||
break;
|
break;
|
||||||
|
@ -425,6 +425,39 @@ TEST(FormatterTest, SpaceSign) {
|
|||||||
FormatError, "format specifier ' ' requires numeric argument");
|
FormatError, "format specifier ' ' requires numeric argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatterTest, HashFlag) {
|
||||||
|
// TODO
|
||||||
|
EXPECT_EQ("42", str(Format("{0:#}") << 42));
|
||||||
|
EXPECT_EQ("-42", str(Format("{0:#}") << -42));
|
||||||
|
EXPECT_EQ("0x42", str(Format("{0:#x}") << 0x42));
|
||||||
|
EXPECT_EQ("-0x42", str(Format("{0:#x}") << -0x42));
|
||||||
|
EXPECT_EQ("042", str(Format("{0:#o}") << 042));
|
||||||
|
EXPECT_EQ("-042", str(Format("{0:#o}") << -042));
|
||||||
|
EXPECT_EQ("42", str(Format("{0:#}") << 42u));
|
||||||
|
EXPECT_EQ("0x42", str(Format("{0:#x}") << 0x42u));
|
||||||
|
EXPECT_EQ("042", str(Format("{0:#o}") << 042u));
|
||||||
|
EXPECT_EQ("-42", str(Format("{0:#}") << -42l));
|
||||||
|
EXPECT_EQ("0x42", str(Format("{0:#x}") << 0x42l));
|
||||||
|
EXPECT_EQ("-0x42", str(Format("{0:#x}") << -0x42l));
|
||||||
|
EXPECT_EQ("042", str(Format("{0:#o}") << 042l));
|
||||||
|
EXPECT_EQ("-042", str(Format("{0:#o}") << -042l));
|
||||||
|
EXPECT_EQ("42", str(Format("{0:#}") << 42ul));
|
||||||
|
EXPECT_EQ("0x42", str(Format("{0:#x}") << 0x42ul));
|
||||||
|
EXPECT_EQ("042", str(Format("{0:#o}") << 042ul));
|
||||||
|
EXPECT_EQ("-42.0000", str(Format("{0:#}") << -42.0));
|
||||||
|
EXPECT_EQ("-42.0000", str(Format("{0:#}") << -42.0l));
|
||||||
|
EXPECT_THROW_MSG(Format("{0:#") << 'c',
|
||||||
|
FormatError, "unmatched '{' in format");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:#}") << 'c',
|
||||||
|
FormatError, "format specifier '#' requires numeric argument");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:#}") << "abc",
|
||||||
|
FormatError, "format specifier '#' requires numeric argument");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:#}") << reinterpret_cast<void*>(0x42),
|
||||||
|
FormatError, "format specifier '#' requires numeric argument");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:#}") << TestString(),
|
||||||
|
FormatError, "format specifier '#' requires numeric argument");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, ZeroFlag) {
|
TEST(FormatterTest, ZeroFlag) {
|
||||||
EXPECT_EQ("42", str(Format("{0:0}") << 42));
|
EXPECT_EQ("42", str(Format("{0:0}") << 42));
|
||||||
EXPECT_EQ("-0042", str(Format("{0:05}") << -42));
|
EXPECT_EQ("-0042", str(Format("{0:05}") << -42));
|
||||||
|
Loading…
Reference in New Issue
Block a user