mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-15 15:05:27 +08:00
const_strlen to be aware of interior nul chars
Prior to this change, const_strlen would only look for trailing nul chars. Teach it about interior nul chars and add some tests.
This commit is contained in:
parent
ccd1b4e4f4
commit
a638c4f01d
@ -1975,13 +1975,3 @@ bool is_console_session() {
|
||||
return console_session;
|
||||
}
|
||||
|
||||
static_assert(const_strcmp("", "a") < 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("a", "a") == 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("a", "") > 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("aa", "a") > 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("a", "aa") < 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("b", "aa") > 0, "const_strcmp failure");
|
||||
|
||||
static_assert(const_strlen("") == 0, "const_strlen failure");
|
||||
static_assert(const_strlen("a") == 1, "const_strlen failure");
|
||||
static_assert(const_strlen("hello") == 5, "const_strlen failure");
|
||||
|
20
src/common.h
20
src/common.h
@ -701,19 +701,13 @@ constexpr ssize_t const_strcmp(const T *lhs, const T *rhs) {
|
||||
|
||||
/// Compile-time agnostic-size strlen/wcslen implementation. Unicode-unaware.
|
||||
template <typename T, size_t N>
|
||||
constexpr size_t const_strlen(const T (&val)[N], ssize_t index = -1) {
|
||||
// N is the length of the character array, but that includes one **or more** trailing nuls.
|
||||
static_assert(N > 0, "Invalid input to const_strlen");
|
||||
return index == -1
|
||||
?
|
||||
// Assume a minimum of one trailing nul and do a quick check for the usual case
|
||||
// (single trailing nul) before recursing:
|
||||
N - 1 - (N <= 2 || val[N - 2] != static_cast<T>(0) ? 0 : const_strlen(val, N - 2))
|
||||
// Prevent an underflow in case the string is comprised of all \0 bytes
|
||||
: index == 0
|
||||
? 0
|
||||
// Keep back-tracking until a non-nul byte is found
|
||||
: (val[index] != static_cast<T>(0) ? 0 : 1 + const_strlen(val, index - 1));
|
||||
constexpr size_t const_strlen(const T (&val)[N], size_t last_checked_idx = N,
|
||||
size_t first_nul_idx = N) {
|
||||
// Assume there's a nul char at the end (index N) but there may be one before that that.
|
||||
return last_checked_idx == 0
|
||||
? first_nul_idx
|
||||
: const_strlen(val, last_checked_idx - 1,
|
||||
val[last_checked_idx - 1] ? first_nul_idx : last_checked_idx - 1);
|
||||
}
|
||||
|
||||
/// Compile-time assertion of alphabetical sort of array `array`, by specified
|
||||
|
@ -1671,10 +1671,39 @@ static void test_wcsfilecmp() {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_const_strlen() {
|
||||
do_test(const_strlen("") == 0);
|
||||
do_test(const_strlen(L"") == 0);
|
||||
do_test(const_strlen("\0") == 0);
|
||||
do_test(const_strlen(L"\0") == 0);
|
||||
do_test(const_strlen("\0abc") == 0);
|
||||
do_test(const_strlen(L"\0abc") == 0);
|
||||
do_test(const_strlen("x") == 1);
|
||||
do_test(const_strlen(L"x") == 1);
|
||||
do_test(const_strlen("abc") == 3);
|
||||
do_test(const_strlen(L"abc") == 3);
|
||||
do_test(const_strlen("abc\0def") == 3);
|
||||
do_test(const_strlen(L"abc\0def") == 3);
|
||||
do_test(const_strlen("abcdef\0") == 6);
|
||||
do_test(const_strlen(L"abcdef\0") == 6);
|
||||
static_assert(const_strlen("hello") == 5, "const_strlen failure");
|
||||
}
|
||||
|
||||
static void test_const_strcmp() {
|
||||
static_assert(const_strcmp("", "a") < 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("a", "a") == 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("a", "") > 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("aa", "a") > 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("a", "aa") < 0, "const_strcmp failure");
|
||||
static_assert(const_strcmp("b", "aa") > 0, "const_strcmp failure");
|
||||
}
|
||||
|
||||
static void test_utility_functions() {
|
||||
say(L"Testing utility functions");
|
||||
test_wcsfilecmp();
|
||||
test_parse_util_cmdsubst_extent();
|
||||
test_const_strlen();
|
||||
test_const_strcmp();
|
||||
}
|
||||
|
||||
// UTF8 tests taken from Alexey Vatchenko's utf8 library. See http://www.bsdua.org/libbsdua.html.
|
||||
|
Loading…
x
Reference in New Issue
Block a user