From 42ea2758b6c1a3a7d7fad6aeb570717ab8510373 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Fri, 25 Mar 2022 15:56:31 +0100 Subject: [PATCH] Overload fish_wcstod for wcstring and length This lets us skip wcslen a bunch --- src/builtins/test.cpp | 7 ++++--- src/env_dispatch.cpp | 2 +- src/wutil.cpp | 10 ++++++++-- src/wutil.h | 2 ++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/builtins/test.cpp b/src/builtins/test.cpp index dfd92da7c..4f3d2f0ea 100644 --- a/src/builtins/test.cpp +++ b/src/builtins/test.cpp @@ -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. -static bool parse_double(const wchar_t *arg, double *out_res) { +static bool parse_double(const wcstring &argstr, double *out_res) { // Consume leading spaces. + const wchar_t *arg = argstr.c_str(); while (arg && *arg != L'\0' && iswspace(*arg)) arg++; if (!arg) return false; errno = 0; 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. while (end && *end != L'\0' && iswspace(*end)) end++; 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) { const wchar_t *argcs = arg.c_str(); double floating = 0; - bool got_float = parse_double(argcs, &floating); + bool got_float = parse_double(arg, &floating); errno = 0; long long integral = fish_wcstoll(argcs); bool got_int = (errno == 0); diff --git a/src/env_dispatch.cpp b/src/env_dispatch.cpp index 4181743e4..4e477754b 100644 --- a/src/env_dispatch.cpp +++ b/src/env_dispatch.cpp @@ -445,7 +445,7 @@ static void update_fish_color_support(const environment_t &vars) { FLOGF(term_support, L"Truecolor support: Enabling for st"); support_term24bit = true; } 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", vte->as_string().c_str()); support_term24bit = true; diff --git a/src/wutil.cpp b/src/wutil.cpp index ccacb24c4..e3791b6b2 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -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 /// 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! // The "fast path." If we're all ASCII and we fit inline, use strtod(). char narrow[128]; - size_t len = std::wcslen(str); size_t len_plus_0 = 1 + len; 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)) { @@ -713,6 +712,13 @@ double fish_wcstod(const wchar_t *str, wchar_t **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 /// 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 diff --git a/src/wutil.h b/src/wutil.h index dcb7f8345..accb4e189 100644 --- a/src/wutil.h +++ b/src/wutil.h @@ -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); unsigned long long fish_wcstoull(const wchar_t *str, const wchar_t **endptr = nullptr, 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 wcstring &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