Overload fish_wcstod for wcstring and length

This lets us skip wcslen a bunch
This commit is contained in:
Fabian Homborg 2022-03-25 15:56:31 +01:00
parent fa1ecb8c67
commit 42ea2758b6
4 changed files with 15 additions and 6 deletions

View File

@ -669,13 +669,14 @@ bool parenthetical_expression::evaluate(io_streams_t *streams, wcstring_list_t &
} }
// Parse a double from arg. Return true on success, false on failure. // Parse a double from arg. Return true on success, false on failure.
static bool parse_double(const wchar_t *arg, double *out_res) { static bool parse_double(const wcstring &argstr, double *out_res) {
// Consume leading spaces. // Consume leading spaces.
const wchar_t *arg = argstr.c_str();
while (arg && *arg != L'\0' && iswspace(*arg)) arg++; while (arg && *arg != L'\0' && iswspace(*arg)) arg++;
if (!arg) return false; if (!arg) return false;
errno = 0; errno = 0;
wchar_t *end = nullptr; wchar_t *end = nullptr;
*out_res = fish_wcstod(arg, &end); *out_res = fish_wcstod(arg, &end, argstr.size() - (arg - argstr.c_str()));
// Consume trailing spaces. // Consume trailing spaces.
while (end && *end != L'\0' && iswspace(*end)) end++; while (end && *end != L'\0' && iswspace(*end)) end++;
return errno == 0 && end > arg && *end == L'\0'; return errno == 0 && end > arg && *end == L'\0';
@ -688,7 +689,7 @@ static bool parse_double(const wchar_t *arg, double *out_res) {
static bool parse_number(const wcstring &arg, number_t *number, wcstring_list_t &errors) { static bool parse_number(const wcstring &arg, number_t *number, wcstring_list_t &errors) {
const wchar_t *argcs = arg.c_str(); const wchar_t *argcs = arg.c_str();
double floating = 0; double floating = 0;
bool got_float = parse_double(argcs, &floating); bool got_float = parse_double(arg, &floating);
errno = 0; errno = 0;
long long integral = fish_wcstoll(argcs); long long integral = fish_wcstoll(argcs);
bool got_int = (errno == 0); bool got_int = (errno == 0);

View File

@ -445,7 +445,7 @@ static void update_fish_color_support(const environment_t &vars) {
FLOGF(term_support, L"Truecolor support: Enabling for st"); FLOGF(term_support, L"Truecolor support: Enabling for st");
support_term24bit = true; support_term24bit = true;
} else if (auto vte = vars.get(L"VTE_VERSION")) { } else if (auto vte = vars.get(L"VTE_VERSION")) {
if (fish_wcstod(vte->as_string().c_str(), nullptr) > 3600) { if (fish_wcstod(vte->as_string(), nullptr) > 3600) {
FLOGF(term_support, L"Truecolor support: Enabling for VTE version %ls", FLOGF(term_support, L"Truecolor support: Enabling for VTE version %ls",
vte->as_string().c_str()); vte->as_string().c_str());
support_term24bit = true; support_term24bit = true;

View File

@ -692,11 +692,10 @@ unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr, int
/// Like wcstod(), but wcstod() is enormously expensive on some platforms so this tries to have a /// Like wcstod(), but wcstod() is enormously expensive on some platforms so this tries to have a
/// fast path. /// fast path.
double fish_wcstod(const wchar_t *str, wchar_t **endptr) { double fish_wcstod(const wchar_t *str, wchar_t **endptr, size_t len) {
// We can ignore the locale because we use LC_NUMERIC=C! // We can ignore the locale because we use LC_NUMERIC=C!
// The "fast path." If we're all ASCII and we fit inline, use strtod(). // The "fast path." If we're all ASCII and we fit inline, use strtod().
char narrow[128]; char narrow[128];
size_t len = std::wcslen(str);
size_t len_plus_0 = 1 + len; size_t len_plus_0 = 1 + len;
auto is_ascii = [](wchar_t c) { return 0 <= c && c <= 127; }; auto is_ascii = [](wchar_t c) { return 0 <= c && c <= 127; };
if (len_plus_0 <= sizeof narrow && std::all_of(str, str + len, is_ascii)) { if (len_plus_0 <= sizeof narrow && std::all_of(str, str + len, is_ascii)) {
@ -713,6 +712,13 @@ double fish_wcstod(const wchar_t *str, wchar_t **endptr) {
return std::wcstod(str, endptr); return std::wcstod(str, endptr);
} }
double fish_wcstod(const wchar_t *str, wchar_t **endptr) {
return fish_wcstod(str, endptr, std::wcslen(str));
}
double fish_wcstod(const wcstring &str, wchar_t **endptr) {
return fish_wcstod(str.c_str(), endptr, str.size());
}
/// Like wcstod(), but allows underscore separators. Leading, trailing, and multiple underscores are /// Like wcstod(), but allows underscore separators. Leading, trailing, and multiple underscores are
/// allowed, as are underscores next to decimal (.), exponent (E/e/P/p), and hexadecimal (X/x) /// allowed, as are underscores next to decimal (.), exponent (E/e/P/p), and hexadecimal (X/x)
/// delimiters. This consumes trailing underscores -- endptr will point past the last underscore /// delimiters. This consumes trailing underscores -- endptr will point past the last underscore

View File

@ -132,7 +132,9 @@ long fish_wcstol(const wchar_t *str, const wchar_t **endptr = nullptr, int base
long long fish_wcstoll(const wchar_t *str, const wchar_t **endptr = nullptr, int base = 10); long long fish_wcstoll(const wchar_t *str, const wchar_t **endptr = nullptr, int base = 10);
unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr = nullptr, unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr = nullptr,
int base = 10); int base = 10);
double fish_wcstod(const wchar_t *str, wchar_t **endptr, size_t len);
double fish_wcstod(const wchar_t *str, wchar_t **endptr); double fish_wcstod(const wchar_t *str, wchar_t **endptr);
double fish_wcstod(const wcstring &str, wchar_t **endptr);
double fish_wcstod_underscores(const wchar_t *str, wchar_t **endptr); double fish_wcstod_underscores(const wchar_t *str, wchar_t **endptr);
/// Class for representing a file's inode. We use this to detect and avoid symlink loops, among /// Class for representing a file's inode. We use this to detect and avoid symlink loops, among