Util: Add specifier type checking
This commit is contained in:
@@ -88,11 +88,20 @@ void Formatter<std::string_view>::format(Builder& builder, std::string_view valu
|
||||
builder.putString(value, specifier.width, specifier.align, specifier.fill);
|
||||
}
|
||||
|
||||
void Formatter<const char*>::parse(Parser& parser)
|
||||
{
|
||||
parser.parseSpecifier(specifier, Parser::ParameterType::CString);
|
||||
}
|
||||
|
||||
void Formatter<const char*>::format(Builder& builder, const char* value) const
|
||||
{
|
||||
Formatter<std::string_view>::format(
|
||||
builder,
|
||||
value != nullptr ? std::string_view { value, strlen(value) } : "nullptr");
|
||||
if (specifier.type == PresentationType::Pointer) {
|
||||
Formatter<const void*> formatter { specifier };
|
||||
formatter.format(builder, static_cast<const void*>(value));
|
||||
return;
|
||||
}
|
||||
|
||||
builder.putString(value != nullptr ? std::string_view { value, strlen(value) } : "nullptr");
|
||||
}
|
||||
|
||||
// Pointer
|
||||
|
||||
@@ -124,6 +124,7 @@ struct Formatter<std::string> : Formatter<std::string_view> {
|
||||
|
||||
template<>
|
||||
struct Formatter<const char*> : Formatter<std::string_view> {
|
||||
void parse(Parser& parser);
|
||||
void format(Builder& builder, const char* value) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -284,6 +284,73 @@ void Parser::parseSpecifier(Specifier& specifier, ParameterType type)
|
||||
}
|
||||
specifier.precision = static_cast<int8_t>(stringToNumber(m_input.substr(precisionBegin, precisionEnd - precisionBegin)));
|
||||
}
|
||||
|
||||
checkSpecifierType(specifier, type);
|
||||
}
|
||||
|
||||
constexpr void Parser::checkSpecifierIntegralType(const Specifier& specifier)
|
||||
{
|
||||
switch (specifier.type) {
|
||||
case PresentationType::None:
|
||||
case PresentationType::Binary:
|
||||
case PresentationType::BinaryUppercase:
|
||||
case PresentationType::Decimal:
|
||||
case PresentationType::Octal:
|
||||
case PresentationType::Hex:
|
||||
case PresentationType::HexUppercase:
|
||||
case PresentationType::Character:
|
||||
break;
|
||||
default:
|
||||
VERIFY("invalid type spcifier");
|
||||
};
|
||||
}
|
||||
|
||||
constexpr void Parser::checkSpecifierType(const Specifier& specifier, ParameterType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ParameterType::Integral:
|
||||
checkSpecifierIntegralType(specifier);
|
||||
break;
|
||||
case ParameterType::FloatingPoint:
|
||||
switch (specifier.type) {
|
||||
case PresentationType::Hexfloat:
|
||||
case PresentationType::HexfloatUppercase:
|
||||
case PresentationType::Exponent:
|
||||
case PresentationType::ExponentUppercase:
|
||||
case PresentationType::FixedPoint:
|
||||
case PresentationType::FixedPointUppercase:
|
||||
case PresentationType::General:
|
||||
case PresentationType::GeneralUppercase:
|
||||
break;
|
||||
default:
|
||||
VERIFY("invalid type spcifier");
|
||||
}
|
||||
break;
|
||||
case ParameterType::Char:
|
||||
if (specifier.type != PresentationType::None
|
||||
&& specifier.type != PresentationType::Character) {
|
||||
checkSpecifierIntegralType(specifier);
|
||||
}
|
||||
break;
|
||||
case ParameterType::CString:
|
||||
VERIFY(specifier.type == PresentationType::None
|
||||
|| specifier.type == PresentationType::String
|
||||
|| specifier.type == PresentationType::Pointer,
|
||||
"invalid type specifier");
|
||||
break;
|
||||
case ParameterType::String:
|
||||
VERIFY(specifier.type == PresentationType::None
|
||||
|| specifier.type == PresentationType::String,
|
||||
"invalid type specifier");
|
||||
break;
|
||||
case ParameterType::Pointer:
|
||||
VERIFY(specifier.type == PresentationType::None
|
||||
|| specifier.type == PresentationType::Pointer,
|
||||
"invalid type specifier");
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Util::Format
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
Integral,
|
||||
FloatingPoint,
|
||||
Char,
|
||||
CString,
|
||||
String,
|
||||
Pointer,
|
||||
};
|
||||
@@ -42,6 +43,8 @@ public:
|
||||
std::optional<size_t> consumeIndex();
|
||||
|
||||
void parseSpecifier(Specifier& specifier, ParameterType type);
|
||||
constexpr void checkSpecifierIntegralType(const Specifier& specifier);
|
||||
constexpr void checkSpecifierType(const Specifier& specifier, ParameterType type);
|
||||
|
||||
private:
|
||||
ArgumentIndexingMode m_mode { ArgumentIndexingMode::Automatic };
|
||||
|
||||
Reference in New Issue
Block a user