From 56c2ca3381a34573b9759843193a6d7777ca011e Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 19 Nov 2022 15:27:55 +0100 Subject: [PATCH] Add _strtoi and _strtou --- luna/NumberParsing.h | 113 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/luna/NumberParsing.h b/luna/NumberParsing.h index aaa20c62..a0fca6f2 100644 --- a/luna/NumberParsing.h +++ b/luna/NumberParsing.h @@ -38,3 +38,116 @@ inline isize _atos(const char** str) return neg ? -val : val; } + +inline usize _strtou(const char* str, const char** endptr, int base) +{ + usize val = 0; + + auto valid_digit = [](int _base, char c) -> bool { + if (_base <= 10) + { + if (!_isdigit(c)) return false; + if ((c - '0') < _base) return true; + } + else + { + if (!_isalnum(c)) return false; + if (_isdigit(c)) return true; + bool lower = _islower(c); + if (((c - lower ? 'a' : 'A') + 10) < _base) return true; + return false; + } + }; + + auto to_digit = [](char c) -> usize { + if (_isdigit(c)) return c - '0'; + if (_islower(c)) return (c - 'a') + 10; + return (c - 'A') + 10; + }; + + while (_isspace(*str)) str++; + + if ((base == 0 || base == 16) && *str == '0') + { + str++; + if (_tolower(*str) == 'x') + { + base = 16; + str++; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; + + while (valid_digit(base, *str)) + { + val = (base * val) + to_digit(*str); + str++; + } + + if (endptr) *endptr = str; + + return val; +} + +inline isize _strtoi(const char* str, const char** endptr, int base) +{ + isize val = 0; + bool negative = false; + + auto valid_digit = [](int _base, char c) -> bool { + if (_base <= 10) + { + if (!_isdigit(c)) return false; + if ((c - '0') < _base) return true; + } + else + { + if (!_isalnum(c)) return false; + if (_isdigit(c)) return true; + bool lower = _islower(c); + if (((c - lower ? 'a' : 'A') + 10) < _base) return true; + return false; + } + }; + + auto to_digit = [](char c) -> isize { + if (_isdigit(c)) return c - '0'; + if (_islower(c)) return (c - 'a') + 10; + return (c - 'A') + 10; + }; + + while (_isspace(*str)) str++; + + if (*str == '-' || *str == '+') + { + if (*str == '-') negative = true; + str++; + } + + if ((base == 0 || base == 16) && *str == '0') + { + str++; + if (_tolower(*str) == 'x') + { + base = 16; + str++; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; + + while (valid_digit(base, *str)) + { + val = (base * val) + to_digit(*str); + str++; + } + + if (endptr) *endptr = str; + + return negative ? -val : val; +}