Browse Source

Util: Add specifier type checking

master
Riyyi 2 years ago
parent
commit
7cff165f08
  1. 15
      src/util/format/formatter.cpp
  2. 1
      src/util/format/formatter.h
  3. 67
      src/util/format/parser.cpp
  4. 3
      src/util/format/parser.h

15
src/util/format/formatter.cpp

@ -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

1
src/util/format/formatter.h

@ -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;
};

67
src/util/format/parser.cpp

@ -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

3
src/util/format/parser.h

@ -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 };

Loading…
Cancel
Save