From 35ca42413d1cc38fe2ac591de85a5181fcbc7393 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Tue, 27 Jul 2021 17:59:52 +0200 Subject: [PATCH] Simplify some parse_util functions Don't just reflexively drop down to wchar_t. --- src/builtin_commandline.cpp | 2 +- src/parse_util.cpp | 48 +++++++++++-------------------------- src/parse_util.h | 2 +- src/reader.cpp | 2 +- 4 files changed, 17 insertions(+), 37 deletions(-) diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp index 512a10c2e..f57e81f38 100644 --- a/src/builtin_commandline.cpp +++ b/src/builtin_commandline.cpp @@ -348,7 +348,7 @@ maybe_t builtin_commandline(parser_t &parser, io_streams_t &streams, const if (line_mode) { streams.out.append_format(L"%d\n", - parse_util_lineno(rstate.text.c_str(), rstate.cursor_pos)); + parse_util_lineno(rstate.text, rstate.cursor_pos)); return STATUS_CMD_OK; } diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 870b081e6..427c20043 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -42,51 +42,31 @@ /// Maximum length of a variable name to show in error reports before truncation static constexpr int var_err_len = 16; -int parse_util_lineno(const wchar_t *str, size_t offset) { - if (!str) return 0; +int parse_util_lineno(const wcstring &str, size_t offset) { + // Return the line number of position offset, starting with 1. + if (str.empty()) return 0; - int res = 1; - for (size_t i = 0; i < offset && str[i] != L'\0'; i++) { - if (str[i] == L'\n') { - res++; - } - } - return res; + auto end = offset > str.length() ? str.end() : str.begin() + offset; + return std::count(str.begin(), end, L'\n') + 1; } int parse_util_get_line_from_offset(const wcstring &str, size_t pos) { - const wchar_t *buff = str.c_str(); - int count = 0; - for (size_t i = 0; i < pos; i++) { - if (!buff[i]) { - return -1; - } - - if (buff[i] == L'\n') { - count++; - } - } - return count; + // Return the line pos is on, or -1 if it's after the end. + if (str.length() > pos) return -1; + return std::count(str.begin() + pos, str.end(), L'\n'); } size_t parse_util_get_offset_from_line(const wcstring &str, int line) { - const wchar_t *buff = str.c_str(); - size_t i; - int count = 0; - + // Return the first position on line X, counting from 0. if (line < 0) return static_cast(-1); if (line == 0) return 0; - for (i = 0;; i++) { - if (!buff[i]) return static_cast(-1); - - if (buff[i] == L'\n') { - count++; - if (count == line) { - return i + 1; - } - } + ssize_t i = 0; + while (auto pos = str.find(L'\n')) { + i++; + if (i == line) return pos + 1; } + return static_cast(-1); } size_t parse_util_get_offset(const wcstring &str, int line, long line_offset) { diff --git a/src/parse_util.h b/src/parse_util.h index c290072a5..42396975a 100644 --- a/src/parse_util.h +++ b/src/parse_util.h @@ -79,7 +79,7 @@ void parse_util_token_extent(const wchar_t *buff, size_t cursor_pos, const wchar const wchar_t **prev_end); /// Get the linenumber at the specified character offset. -int parse_util_lineno(const wchar_t *str, size_t offset); +int parse_util_lineno(const wcstring &str, size_t offset); /// Calculate the line number of the specified cursor position. int parse_util_get_line_from_offset(const wcstring &str, size_t pos); diff --git a/src/reader.cpp b/src/reader.cpp index 551830f03..78785d485 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -3573,7 +3573,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat else line_new = line_old + 1; - int line_count = parse_util_lineno(el->text().c_str(), el->size()) - 1; + int line_count = parse_util_lineno(el->text(), el->size()) - 1; if (line_new >= 0 && line_new <= line_count) { auto indents = parse_util_compute_indents(el->text());