mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Implement space sign.
This commit is contained in:
43
format.cc
43
format.cc
@ -54,7 +54,7 @@ using fmt::StringRef;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Flags.
|
// Flags.
|
||||||
enum { PLUS_FLAG = 1, HEX_PREFIX_FLAG = 2 };
|
enum { SIGN_FLAG = 1, PLUS_FLAG = 2, HEX_PREFIX_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))) {
|
||||||
@ -129,7 +129,7 @@ void FormatDecimal(char *buffer, uint64_t value, unsigned num_digits) {
|
|||||||
*buffer = static_cast<char>('0' + value);
|
*buffer = static_cast<char>('0' + value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned index = value * 2;
|
unsigned index = static_cast<unsigned>(value * 2);
|
||||||
buffer[1] = DIGITS[index + 1];
|
buffer[1] = DIGITS[index + 1];
|
||||||
buffer[0] = DIGITS[index];
|
buffer[0] = DIGITS[index];
|
||||||
}
|
}
|
||||||
@ -205,8 +205,8 @@ void Formatter::FormatInt(T value, const FormatSpec &spec) {
|
|||||||
sign = '-';
|
sign = '-';
|
||||||
++size;
|
++size;
|
||||||
abs_value = 0 - abs_value;
|
abs_value = 0 - abs_value;
|
||||||
} else if ((spec.flags & PLUS_FLAG) != 0) {
|
} else if ((spec.flags & SIGN_FLAG) != 0) {
|
||||||
sign = '+';
|
sign = (spec.flags & PLUS_FLAG) != 0 ? '+' : ' ';
|
||||||
++size;
|
++size;
|
||||||
}
|
}
|
||||||
switch (spec.type) {
|
switch (spec.type) {
|
||||||
@ -280,8 +280,8 @@ void Formatter::FormatDouble(T value, const FormatSpec &spec, int precision) {
|
|||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
sign = '-';
|
sign = '-';
|
||||||
value = -value;
|
value = -value;
|
||||||
} else if ((spec.flags & PLUS_FLAG) != 0) {
|
} else if ((spec.flags & SIGN_FLAG) != 0) {
|
||||||
sign = '+';
|
sign = (spec.flags & PLUS_FLAG) != 0 ? '+' : ' ';
|
||||||
}
|
}
|
||||||
size_t offset = buffer_.size();
|
size_t offset = buffer_.size();
|
||||||
unsigned width = spec.width;
|
unsigned width = spec.width;
|
||||||
@ -401,6 +401,18 @@ const Formatter::Arg &Formatter::ParseArgIndex(const char *&s) const {
|
|||||||
return *args_[arg_index];
|
return *args_[arg_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Formatter::CheckSign(const char *&s, const Arg &arg) {
|
||||||
|
if (arg.type > LAST_NUMERIC_TYPE) {
|
||||||
|
ReportError(s,
|
||||||
|
Format("format specifier '{0}' requires numeric argument") << *s);
|
||||||
|
}
|
||||||
|
if (arg.type == UINT || arg.type == ULONG) {
|
||||||
|
ReportError(s,
|
||||||
|
Format("format specifier '{0}' requires signed argument") << *s);
|
||||||
|
}
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
void Formatter::DoFormat() {
|
void Formatter::DoFormat() {
|
||||||
const char *start = format_;
|
const char *start = format_;
|
||||||
format_ = 0;
|
format_ = 0;
|
||||||
@ -462,18 +474,15 @@ void Formatter::DoFormat() {
|
|||||||
// Parse sign.
|
// Parse sign.
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '+':
|
case '+':
|
||||||
spec.flags |= PLUS_FLAG;
|
CheckSign(s, arg);
|
||||||
// Fall through.
|
spec.flags |= SIGN_FLAG | PLUS_FLAG;
|
||||||
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if (arg.type > LAST_NUMERIC_TYPE) {
|
CheckSign(s, arg);
|
||||||
ReportError(s,
|
break;
|
||||||
Format("format specifier '{0}' requires numeric argument") << *s);
|
case ' ':
|
||||||
}
|
CheckSign(s, arg);
|
||||||
if (arg.type == UINT || arg.type == ULONG) {
|
spec.flags |= SIGN_FLAG;
|
||||||
ReportError(s,
|
|
||||||
Format("format specifier '{0}' requires signed argument") << *s);
|
|
||||||
}
|
|
||||||
++s;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
format.h
2
format.h
@ -319,6 +319,8 @@ class Formatter {
|
|||||||
// Parses argument index and returns an argument with this index.
|
// Parses argument index and returns an argument with this index.
|
||||||
const Arg &ParseArgIndex(const char *&s) const;
|
const Arg &ParseArgIndex(const char *&s) const;
|
||||||
|
|
||||||
|
void CheckSign(const char *&s, const Arg &arg);
|
||||||
|
|
||||||
void DoFormat();
|
void DoFormat();
|
||||||
|
|
||||||
void CompleteFormatting() {
|
void CompleteFormatting() {
|
||||||
|
@ -402,6 +402,29 @@ TEST(FormatterTest, MinusSign) {
|
|||||||
FormatError, "format specifier '-' requires numeric argument");
|
FormatError, "format specifier '-' requires numeric argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatterTest, SpaceSign) {
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0: }") << 42));
|
||||||
|
EXPECT_EQ("-42", str(Format("{0: }") << -42));
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0: }") << 42));
|
||||||
|
EXPECT_THROW_MSG(Format("{0: }") << 42u,
|
||||||
|
FormatError, "format specifier ' ' requires signed argument");
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0: }") << 42l));
|
||||||
|
EXPECT_THROW_MSG(Format("{0: }") << 42ul,
|
||||||
|
FormatError, "format specifier ' ' requires signed argument");
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0: }") << 42.0));
|
||||||
|
EXPECT_EQ(" 42", 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));
|
||||||
|
Reference in New Issue
Block a user