Compare commits
10
Commits
7a98f8e79f
...
448ad42005
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
448ad42005 | ||
|
|
80c37496e8 | ||
|
|
a75bb863ff | ||
|
|
dc8d2a49cd | ||
|
|
8b4a748c9d | ||
|
|
175251496f | ||
|
|
1fda63ae78 | ||
|
|
6c6ddf936a | ||
|
|
bd8367db0e | ||
|
|
b07b9d92d4 |
@@ -62,7 +62,16 @@ static constexpr std::string numberToString(size_t value, uint8_t base, bool upp
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::putU64(size_t value, uint8_t base, bool uppercase, char fill, Align align, Sign sign, bool zeroPadding, size_t width, bool isNegative) const
|
void Builder::putU64(size_t value,
|
||||||
|
uint8_t base,
|
||||||
|
bool uppercase,
|
||||||
|
char fill,
|
||||||
|
Align align,
|
||||||
|
Sign sign,
|
||||||
|
bool alternativeForm,
|
||||||
|
bool zeroPadding,
|
||||||
|
size_t width,
|
||||||
|
bool isNegative) const
|
||||||
{
|
{
|
||||||
std::string string = numberToString(value, base, uppercase);
|
std::string string = numberToString(value, base, uppercase);
|
||||||
|
|
||||||
@@ -88,6 +97,25 @@ void Builder::putU64(size_t value, uint8_t base, bool uppercase, char fill, Alig
|
|||||||
string.insert(0, signCharacter);
|
string.insert(0, signCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alternative form
|
||||||
|
if (alternativeForm) {
|
||||||
|
switch (base) {
|
||||||
|
case 2:
|
||||||
|
string.insert(0, (uppercase) ? "0B" : "0b");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
string.insert(0, 1, '0');
|
||||||
|
case 10:
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
string.insert(0, (uppercase) ? "0X" : "0x");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Zero padding
|
// Zero padding
|
||||||
if (zeroPadding) {
|
if (zeroPadding) {
|
||||||
fill = '0';
|
fill = '0';
|
||||||
@@ -130,11 +158,19 @@ void Builder::putU64(size_t value, uint8_t base, bool uppercase, char fill, Alig
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::putI64(int64_t value, uint8_t base, bool uppercase, char fill, Align align, Sign sign, bool zeroPadding, size_t width) const
|
void Builder::putI64(int64_t value,
|
||||||
|
uint8_t base,
|
||||||
|
bool uppercase,
|
||||||
|
char fill,
|
||||||
|
Align align,
|
||||||
|
Sign sign,
|
||||||
|
bool alternativeForm,
|
||||||
|
bool zeroPadding,
|
||||||
|
size_t width) const
|
||||||
{
|
{
|
||||||
bool isNegative = value < 0;
|
bool isNegative = value < 0;
|
||||||
value = isNegative ? -value : value;
|
value = isNegative ? -value : value;
|
||||||
putU64(static_cast<uint64_t>(value), base, uppercase, fill, align, sign, zeroPadding, width, isNegative);
|
putU64(static_cast<uint64_t>(value), base, uppercase, fill, align, sign, alternativeForm, zeroPadding, width, isNegative);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::putF64(double number, uint8_t precision) const
|
void Builder::putF64(double number, uint8_t precision) const
|
||||||
|
|||||||
@@ -36,12 +36,30 @@ public:
|
|||||||
|
|
||||||
void putLiteral(std::string_view literal);
|
void putLiteral(std::string_view literal);
|
||||||
|
|
||||||
void putU64(size_t value, uint8_t base = 10, bool uppercase = false, char fill = ' ', Align align = Align::Right, Sign sign = Sign::Negative, bool zeroPadding = false, size_t width = 0, bool isNegative = false) const;
|
void putU64(size_t value,
|
||||||
void putI64(int64_t value, uint8_t base = 10, bool uppercase = false, char fill = ' ', Align align = Align::Right, Sign sign = Sign::Negative, bool zeroPadding = false, size_t width = 0) const;
|
uint8_t base = 10,
|
||||||
|
bool uppercase = false,
|
||||||
|
char fill = ' ',
|
||||||
|
Align align = Align::Right,
|
||||||
|
Sign sign = Sign::Negative,
|
||||||
|
bool alternativeForm = false,
|
||||||
|
bool zeroPadding = false,
|
||||||
|
size_t width = 0,
|
||||||
|
bool isNegative = false) const;
|
||||||
|
|
||||||
|
void putI64(int64_t value,
|
||||||
|
uint8_t base = 10,
|
||||||
|
bool uppercase = false,
|
||||||
|
char fill = ' ',
|
||||||
|
Align align = Align::Right,
|
||||||
|
Sign sign = Sign::Negative,
|
||||||
|
bool alternativeForm = false,
|
||||||
|
bool zeroPadding = false,
|
||||||
|
size_t width = 0) const;
|
||||||
|
|
||||||
void putF64(double number, uint8_t precision = 6) const;
|
void putF64(double number, uint8_t precision = 6) const;
|
||||||
void putCharacter(char character) const { m_builder.write(&character, 1); }
|
void putCharacter(char character) const { m_builder.write(&character, 1); }
|
||||||
void putString(std::string_view string, char fill = ' ', Align align = Align::Left, size_t width = 0) const;
|
void putString(std::string_view string, char fill = ' ', Align align = Align::Left, size_t width = 0) const;
|
||||||
void putPointer(const void* pointer) const { m_builder << pointer; }
|
|
||||||
|
|
||||||
const std::stringstream& builder() const { return m_builder; }
|
const std::stringstream& builder() const { return m_builder; }
|
||||||
std::stringstream& builder() { return m_builder; }
|
std::stringstream& builder() { return m_builder; }
|
||||||
|
|||||||
@@ -21,13 +21,38 @@ namespace Util::Format {
|
|||||||
template<>
|
template<>
|
||||||
void Formatter<char>::format(Builder& builder, char value) const
|
void Formatter<char>::format(Builder& builder, char value) const
|
||||||
{
|
{
|
||||||
builder.putCharacter(value);
|
if (specifier.type != PresentationType::None && specifier.type != PresentationType::Character) {
|
||||||
|
// "Type char is a distinct type that has an implementation-defined
|
||||||
|
// choice of “signed char” or “unsigned char” as its underlying type."
|
||||||
|
// http://eel.is/c++draft/basic#fundamental
|
||||||
|
Formatter<signed char> formatter { .specifier = specifier };
|
||||||
|
return formatter.format(builder, static_cast<signed char>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Formatter<std::string_view> formatter { .specifier = specifier };
|
||||||
|
return formatter.format(builder, { &value, 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Formatter<bool>::format(Builder& builder, bool value) const
|
void Formatter<bool>::format(Builder& builder, bool value) const
|
||||||
{
|
{
|
||||||
builder.putString(value ? "true" : "false");
|
switch (specifier.type) {
|
||||||
|
case PresentationType::Binary:
|
||||||
|
case PresentationType::BinaryUppercase:
|
||||||
|
case PresentationType::Character:
|
||||||
|
case PresentationType::Decimal:
|
||||||
|
case PresentationType::Octal:
|
||||||
|
case PresentationType::Hex:
|
||||||
|
case PresentationType::HexUppercase: {
|
||||||
|
Formatter<uint8_t> formatter { .specifier = specifier };
|
||||||
|
return formatter.format(builder, static_cast<uint8_t>(value));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
Formatter<std::string_view> formatter { .specifier = specifier };
|
||||||
|
formatter.format(builder, value ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
// String
|
// String
|
||||||
@@ -46,9 +71,10 @@ void Formatter<const char*>::parse(Parser& parser)
|
|||||||
void Formatter<const char*>::format(Builder& builder, const char* value) const
|
void Formatter<const char*>::format(Builder& builder, const char* value) const
|
||||||
{
|
{
|
||||||
if (specifier.type == PresentationType::Pointer) {
|
if (specifier.type == PresentationType::Pointer) {
|
||||||
Formatter<const void*> formatter { specifier };
|
Formatter<uintptr_t> formatter { .specifier = specifier };
|
||||||
formatter.format(builder, static_cast<const void*>(value));
|
formatter.specifier.alternativeForm = true;
|
||||||
return;
|
formatter.specifier.type = PresentationType::Hex;
|
||||||
|
return formatter.format(builder, reinterpret_cast<uintptr_t>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Formatter<std::string_view>::format(
|
Formatter<std::string_view>::format(
|
||||||
|
|||||||
+19
-10
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdint> // int8_t, int32_t, int64_t, uint8_t, uint32_t
|
#include <cstdint> // int8_t, int32_t, int64_t, uint8_t, uint32_t, uintptr_t
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@@ -68,7 +68,10 @@ struct Formatter {
|
|||||||
|
|
||||||
constexpr void parse(Parser& parser)
|
constexpr void parse(Parser& parser)
|
||||||
{
|
{
|
||||||
if (std::is_same_v<T, char>) {
|
if constexpr (std::is_same_v<T, char>) {
|
||||||
|
parser.parseSpecifier(specifier, Parser::ParameterType::Char);
|
||||||
|
}
|
||||||
|
else if (std::is_same_v<T, bool>) {
|
||||||
parser.parseSpecifier(specifier, Parser::ParameterType::Char);
|
parser.parseSpecifier(specifier, Parser::ParameterType::Char);
|
||||||
}
|
}
|
||||||
else if (std::is_same_v<T, std::string_view>) {
|
else if (std::is_same_v<T, std::string_view>) {
|
||||||
@@ -92,6 +95,14 @@ struct Formatter<T> {
|
|||||||
|
|
||||||
void format(Builder& builder, T value) const
|
void format(Builder& builder, T value) const
|
||||||
{
|
{
|
||||||
|
if (specifier.type == PresentationType::Character) {
|
||||||
|
assert(value >= 0 && value <= 127);
|
||||||
|
|
||||||
|
Formatter<std::string_view> formatter { .specifier = specifier };
|
||||||
|
formatter.specifier.type = PresentationType::String;
|
||||||
|
return formatter.format(builder, { reinterpret_cast<const char*>(&value), 1 });
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t base = 0;
|
uint8_t base = 0;
|
||||||
bool uppercase = false;
|
bool uppercase = false;
|
||||||
switch (specifier.type) {
|
switch (specifier.type) {
|
||||||
@@ -119,12 +130,12 @@ struct Formatter<T> {
|
|||||||
if constexpr (std::is_unsigned_v<T>) {
|
if constexpr (std::is_unsigned_v<T>) {
|
||||||
builder.putU64(
|
builder.putU64(
|
||||||
value, base, uppercase, specifier.fill, specifier.align, specifier.sign,
|
value, base, uppercase, specifier.fill, specifier.align, specifier.sign,
|
||||||
specifier.zeroPadding, specifier.width);
|
specifier.alternativeForm, specifier.zeroPadding, specifier.width);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
builder.putI64(
|
builder.putI64(
|
||||||
value, base, uppercase, specifier.fill, specifier.align, specifier.sign,
|
value, base, uppercase, specifier.fill, specifier.align, specifier.sign,
|
||||||
specifier.zeroPadding, specifier.width);
|
specifier.alternativeForm, specifier.zeroPadding, specifier.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -185,19 +196,17 @@ struct Formatter<char[N]> : Formatter<const char*> {
|
|||||||
// Pointer
|
// Pointer
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Formatter<T*> {
|
struct Formatter<T*> : Formatter<uintptr_t> {
|
||||||
Specifier specifier;
|
|
||||||
|
|
||||||
constexpr void parse(Parser& parser)
|
constexpr void parse(Parser& parser)
|
||||||
{
|
{
|
||||||
parser.parseSpecifier(specifier, Parser::ParameterType::Pointer);
|
parser.parseSpecifier(specifier, Parser::ParameterType::Pointer);
|
||||||
|
specifier.alternativeForm = true;
|
||||||
|
specifier.type = PresentationType::Hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void format(Builder& builder, T* value) const
|
void format(Builder& builder, T* value) const
|
||||||
{
|
{
|
||||||
value == nullptr
|
Formatter<uintptr_t>::format(builder, reinterpret_cast<uintptr_t>(value));
|
||||||
? builder.putString("nullptr")
|
|
||||||
: builder.putPointer(static_cast<const void*>(value));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+79
-45
@@ -33,10 +33,6 @@ Parser::~Parser()
|
|||||||
|
|
||||||
void Parser::checkFormatParameterConsistency()
|
void Parser::checkFormatParameterConsistency()
|
||||||
{
|
{
|
||||||
size_t length = m_input.length();
|
|
||||||
|
|
||||||
VERIFY(length >= m_parameterCount * 2, "format string does not reference all parameters");
|
|
||||||
|
|
||||||
size_t braceOpen = 0;
|
size_t braceOpen = 0;
|
||||||
size_t braceClose = 0;
|
size_t braceClose = 0;
|
||||||
while (!isEOF()) {
|
while (!isEOF()) {
|
||||||
@@ -68,13 +64,13 @@ void Parser::checkFormatParameterConsistency()
|
|||||||
}
|
}
|
||||||
m_index = 0;
|
m_index = 0;
|
||||||
|
|
||||||
// VERIFY(!(braceOpen < braceClose), "extra open braces in format string");
|
VERIFY(!(braceOpen < braceClose), "extra open braces in format string");
|
||||||
|
VERIFY(!(braceOpen > braceClose), "extra closing braces in format string");
|
||||||
|
|
||||||
// VERIFY(!(braceOpen > braceClose), "extra closing braces in format string");
|
if (m_mode == ArgumentIndexingMode::Automatic) {
|
||||||
|
VERIFY(!(braceOpen < m_parameterCount), "format string does not reference all passed parameters");
|
||||||
// VERIFY(!(braceOpen < m_parameterCount), "format string does not reference all passed parameters");
|
VERIFY(!(braceOpen > m_parameterCount), "format string references nonexistent parameter");
|
||||||
|
}
|
||||||
// VERIFY(!(braceOpen > m_parameterCount), "format string references nonexistent parameter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Parser::stringToNumber(std::string_view value)
|
size_t Parser::stringToNumber(std::string_view value)
|
||||||
@@ -204,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);
|
||||||
}
|
}
|
||||||
@@ -213,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;
|
||||||
}
|
}
|
||||||
@@ -223,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;
|
||||||
}
|
}
|
||||||
@@ -294,15 +284,81 @@ 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::checkSpecifierFloatingPointType(const Specifier& 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
|
||||||
|
// 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");
|
||||||
|
VERIFY(specifier.zeroPadding == false, "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)
|
||||||
@@ -312,41 +368,19 @@ 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:
|
||||||
VERIFY(specifier.type == PresentationType::None
|
checkSpecifierPointerType(specifier);
|
||||||
|| specifier.type == PresentationType::Pointer,
|
|
||||||
"invalid type specifier");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ 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 checkSpecifierType(const Specifier& specifier, ParameterType type);
|
constexpr void checkSpecifierType(const Specifier& specifier, ParameterType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user