Browse Source

Util: Implement specifier option checks

master
Riyyi 2 years ago
parent
commit
80c37496e8
  1. 99
      src/util/format/parser.cpp
  2. 4
      src/util/format/parser.h

99
src/util/format/parser.cpp

@ -200,8 +200,6 @@ void Parser::parseSpecifier(Specifier& specifier, ParameterType type)
// Sign is only valid for numeric types
if (peek0 == '+' || peek0 == '-' || peek0 == ' ') {
VERIFY(state < State::AfterSign, "unexpected '%c' at this position", peek0);
VERIFY(type == ParameterType::Integral || type == ParameterType::FloatingPoint,
"sign option is only valid for numeric types");
state = State::AfterSign;
specifier.sign = static_cast<Builder::Sign>(peek0);
}
@ -209,8 +207,6 @@ void Parser::parseSpecifier(Specifier& specifier, ParameterType type)
// Alternative form is only valid for numeric types
if (peek0 == '#') {
VERIFY(state < State::AfterAlternativeForm, "unexpected '#' at this position");
VERIFY(type == ParameterType::Integral || type == ParameterType::FloatingPoint,
"'#' option is only valid for numeric types");
state = State::AfterAlternativeForm;
specifier.alternativeForm = true;
}
@ -219,8 +215,6 @@ void Parser::parseSpecifier(Specifier& specifier, ParameterType type)
if (peek0 == '0') {
if (state < State::AfterWidth) {
VERIFY(state < State::AfterZeroPadding, "unexpected '0' at this position");
VERIFY(type == ParameterType::Integral || type == ParameterType::FloatingPoint,
"zero padding option is only valid for numeric types");
state = State::AfterZeroPadding;
specifier.zeroPadding = true;
}
@ -290,23 +284,64 @@ constexpr void Parser::checkSpecifierIntegralType(const Specifier& specifier)
case PresentationType::None:
case PresentationType::Binary:
case PresentationType::BinaryUppercase:
case PresentationType::Character:
case PresentationType::Decimal:
case PresentationType::Octal:
case PresentationType::Hex:
case PresentationType::HexUppercase:
case PresentationType::Character:
break;
default:
VERIFY("invalid type spcifier");
VERIFY(false, "invalid type specifier");
};
// Invalid: precision
VERIFY(specifier.precision == -1, "invalid specifier option");
}
constexpr void Parser::checkSpecifierPointerType(const Specifier& specifier)
constexpr void Parser::checkSpecifierFloatingPointType(const Specifier& specifier)
{
VERIFY(specifier.type == PresentationType::None || specifier.type == PresentationType::Pointer,
"invalid type specifier");
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(false, "invalid type specifier");
}
}
constexpr void Parser::checkSpecifierCharType(const Specifier& specifier)
{
checkSpecifierIntegralType(specifier);
// Valid: fill, align, width
// Valid: fill, align, width
// Invalid: sign, alternativeForm, zeroPadding, precision
if (specifier.type == PresentationType::None
|| specifier.type == PresentationType::Character) {
VERIFY(specifier.sign == Builder::Sign::None, "invalid specifier option");
VERIFY(specifier.alternativeForm == false, "invalid specifier option");
VERIFY(specifier.zeroPadding == false, "invalid specifier option");
}
// Precision checked in Integral
}
constexpr void Parser::checkSpecifierCStringType(const Specifier& specifier)
{
switch (specifier.type) {
case PresentationType::None:
case PresentationType::String:
case PresentationType::Pointer:
break;
default:
VERIFY(false, "invalid type specifier");
}
// Valid: fill, align, width
// Invalid: sign, alternativeForm, zeroPadding, precision
VERIFY(specifier.sign == Builder::Sign::None, "invalid specifier option");
VERIFY(specifier.alternativeForm == false, "invalid specifier option");
@ -314,6 +349,18 @@ constexpr void Parser::checkSpecifierPointerType(const Specifier& specifier)
VERIFY(specifier.precision == -1, "invalid specifier option");
}
constexpr void Parser::checkSpecifierStringType(const Specifier& specifier)
{
checkSpecifierCStringType(specifier);
VERIFY(specifier.type != PresentationType::Pointer, "invalid type specifier");
}
constexpr void Parser::checkSpecifierPointerType(const Specifier& specifier)
{
checkSpecifierCStringType(specifier);
VERIFY(specifier.type != PresentationType::String, "invalid type specifier");
}
constexpr void Parser::checkSpecifierType(const Specifier& specifier, ParameterType type)
{
switch (type) {
@ -321,36 +368,16 @@ constexpr void Parser::checkSpecifierType(const Specifier& specifier, ParameterT
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");
}
checkSpecifierFloatingPointType(specifier);
break;
case ParameterType::Char:
if (specifier.type != PresentationType::None
&& specifier.type != PresentationType::Character) {
checkSpecifierIntegralType(specifier);
}
checkSpecifierCharType(specifier);
break;
case ParameterType::CString:
VERIFY(specifier.type == PresentationType::None
|| specifier.type == PresentationType::String
|| specifier.type == PresentationType::Pointer,
"invalid type specifier");
checkSpecifierCStringType(specifier);
break;
case ParameterType::String:
VERIFY(specifier.type == PresentationType::None
|| specifier.type == PresentationType::String,
"invalid type specifier");
checkSpecifierStringType(specifier);
break;
case ParameterType::Pointer:
checkSpecifierPointerType(specifier);

4
src/util/format/parser.h

@ -44,6 +44,10 @@ public:
void parseSpecifier(Specifier& specifier, ParameterType type);
constexpr void checkSpecifierIntegralType(const Specifier& specifier);
constexpr void checkSpecifierFloatingPointType(const Specifier& specifier);
constexpr void checkSpecifierCharType(const Specifier& specifier);
constexpr void checkSpecifierCStringType(const Specifier& specifier);
constexpr void checkSpecifierStringType(const Specifier& specifier);
constexpr void checkSpecifierPointerType(const Specifier& specifier);
constexpr void checkSpecifierType(const Specifier& specifier, ParameterType type);

Loading…
Cancel
Save