Util: Implement specifier option checks
This commit is contained in:
+63
-36
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
// Valid: fill, align, width
|
||||
constexpr void Parser::checkSpecifierCharType(const Specifier& specifier)
|
||||
{
|
||||
checkSpecifierIntegralType(specifier);
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user