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.
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);

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");
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;

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
/// 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

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);
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