some fix about parse_uint

This commit is contained in:
blueloveTH 2024-06-07 22:26:46 +08:00
parent 4268cff072
commit ae3a27c91d
2 changed files with 16 additions and 22 deletions

View File

@ -54,9 +54,9 @@
// Hash table load factor (smaller ones mean less collision but more memory) // Hash table load factor (smaller ones mean less collision but more memory)
// For class instance // For class instance
#define PK_INST_ATTR_LOAD_FACTOR 0.67 #define PK_INST_ATTR_LOAD_FACTOR 0.67f
// For class itself // For class itself
#define PK_TYPE_ATTR_LOAD_FACTOR 0.5 #define PK_TYPE_ATTR_LOAD_FACTOR 0.5f
#ifdef _WIN32 #ifdef _WIN32
#define PK_PLATFORM_SEP '\\' #define PK_PLATFORM_SEP '\\'

View File

@ -532,20 +532,16 @@ vector<Token> Lexer::run() {
return std::move(nexts); return std::move(nexts);
} }
constexpr inline bool f_startswith_2(std::string_view t, const char* prefix) {
if(t.length() < 2) return false;
return t[0] == prefix[0] && t[1] == prefix[1];
}
IntParsingResult parse_uint(std::string_view text, i64* out, int base) { IntParsingResult parse_uint(std::string_view text, i64* out, int base) {
*out = 0; *out = 0;
if(base == -1) { if(base == -1) {
if(f_startswith_2(text, "0b")) if(text.substr(0, 2) == "0b")
base = 2; base = 2;
else if(f_startswith_2(text, "0o")) else if(text.substr(0, 2) == "0o")
base = 8; base = 8;
else if(f_startswith_2(text, "0x")) else if(text.substr(0, 2) == "0x")
base = 16; base = 16;
else else
base = 10; base = 10;
@ -556,61 +552,59 @@ IntParsingResult parse_uint(std::string_view text, i64* out, int base) {
if(text.length() == 0) return IntParsingResult::Failure; if(text.length() == 0) return IntParsingResult::Failure;
for(char c: text) { for(char c: text) {
if(c >= '0' && c <= '9') { if(c >= '0' && c <= '9') {
i64 prev_out = *out;
*out = (*out * 10) + (c - '0'); *out = (*out * 10) + (c - '0');
if(*out < prev_out) return IntParsingResult::Overflow;
} else { } else {
return IntParsingResult::Failure; return IntParsingResult::Failure;
} }
} }
const std::string_view INT64_MAX_S = "9223372036854775807";
if(text.length() >= INT64_MAX_S.length()) return IntParsingResult::Overflow;
return IntParsingResult::Success; return IntParsingResult::Success;
} else if(base == 2) { } else if(base == 2) {
// 2-base 0b101010 // 2-base 0b101010
if(f_startswith_2(text, "0b")) text.remove_prefix(2); if(text.substr(0, 2) == "0b") text.remove_prefix(2);
if(text.length() == 0) return IntParsingResult::Failure; if(text.length() == 0) return IntParsingResult::Failure;
for(char c: text) { for(char c: text) {
if(c == '0' || c == '1') { if(c == '0' || c == '1') {
i64 prev_out = *out;
*out = (*out << 1) | (c - '0'); *out = (*out << 1) | (c - '0');
if(*out < prev_out) return IntParsingResult::Overflow;
} else { } else {
return IntParsingResult::Failure; return IntParsingResult::Failure;
} }
} }
const std::string_view INT64_MAX_S = "111111111111111111111111111111111111111111111111111111111111111";
if(text.length() >= INT64_MAX_S.length()) return IntParsingResult::Overflow;
return IntParsingResult::Success; return IntParsingResult::Success;
} else if(base == 8) { } else if(base == 8) {
// 8-base 0o123 // 8-base 0o123
if(f_startswith_2(text, "0o")) text.remove_prefix(2); if(text.substr(0, 2) == "0o") text.remove_prefix(2);
if(text.length() == 0) return IntParsingResult::Failure; if(text.length() == 0) return IntParsingResult::Failure;
for(char c: text) { for(char c: text) {
if(c >= '0' && c <= '7') { if(c >= '0' && c <= '7') {
i64 prev_out = *out;
*out = (*out << 3) | (c - '0'); *out = (*out << 3) | (c - '0');
if(*out < prev_out) return IntParsingResult::Overflow;
} else { } else {
return IntParsingResult::Failure; return IntParsingResult::Failure;
} }
} }
const std::string_view INT64_MAX_S = "777777777777777777777";
if(text.length() >= INT64_MAX_S.length()) return IntParsingResult::Overflow;
return IntParsingResult::Success; return IntParsingResult::Success;
} else if(base == 16) { } else if(base == 16) {
// 16-base 0x123 // 16-base 0x123
if(f_startswith_2(text, "0x")) text.remove_prefix(2); if(text.substr(0, 2) == "0x") text.remove_prefix(2);
if(text.length() == 0) return IntParsingResult::Failure; if(text.length() == 0) return IntParsingResult::Failure;
for(char c: text) { for(char c: text) {
i64 prev_out = *out;
if(c >= '0' && c <= '9') { if(c >= '0' && c <= '9') {
*out = (*out << 4) | (c - '0'); *out = (*out << 4) | (c - '0');
if(*out < prev_out) return IntParsingResult::Overflow;
} else if(c >= 'a' && c <= 'f') { } else if(c >= 'a' && c <= 'f') {
*out = (*out << 4) | (c - 'a' + 10); *out = (*out << 4) | (c - 'a' + 10);
if(*out < prev_out) return IntParsingResult::Overflow;
} else if(c >= 'A' && c <= 'F') { } else if(c >= 'A' && c <= 'F') {
*out = (*out << 4) | (c - 'A' + 10); *out = (*out << 4) | (c - 'A' + 10);
if(*out < prev_out) return IntParsingResult::Overflow;
} else { } else {
return IntParsingResult::Failure; return IntParsingResult::Failure;
} }
} }
const std::string_view INT64_MAX_S = "7fffffffffffffff";
if(text.length() >= INT64_MAX_S.length()) return IntParsingResult::Overflow;
return IntParsingResult::Success; return IntParsingResult::Success;
} }
return IntParsingResult::Failure; return IntParsingResult::Failure;