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