mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor: move reverse_text to strings.c as it's a string operation
Also add tests for reverse_text. Co-authored-by: Kalle Ranki <kalle.ranki@gmail.com>
This commit is contained in:
parent
1d160a76ec
commit
1a0de90068
@ -204,31 +204,6 @@ char_u *get_search_pat(void)
|
|||||||
return mr_pattern;
|
return mr_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Reverse text into allocated memory.
|
|
||||||
* Returns the allocated string.
|
|
||||||
*
|
|
||||||
* TODO(philix): move reverse_text() to strings.c
|
|
||||||
*/
|
|
||||||
char_u *reverse_text(char_u *s) FUNC_ATTR_NONNULL_RET
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Reverse the pattern.
|
|
||||||
*/
|
|
||||||
size_t len = STRLEN(s);
|
|
||||||
char_u *rev = xmalloc(len + 1);
|
|
||||||
size_t rev_i = len;
|
|
||||||
for (size_t s_i = 0; s_i < len; s_i++) {
|
|
||||||
const int mb_len = utfc_ptr2len((char *)s + s_i);
|
|
||||||
rev_i -= mb_len;
|
|
||||||
memmove(rev + rev_i, s + s_i, mb_len);
|
|
||||||
s_i += mb_len - 1;
|
|
||||||
}
|
|
||||||
rev[len] = NUL;
|
|
||||||
|
|
||||||
return rev;
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_re_pat(int idx, char_u *pat, int magic)
|
void save_re_pat(int idx, char_u *pat, int magic)
|
||||||
{
|
{
|
||||||
if (spats[idx].pat != pat) {
|
if (spats[idx].pat != pat) {
|
||||||
|
@ -1507,3 +1507,24 @@ int kv_do_printf(StringBuilder *str, const char *fmt, ...)
|
|||||||
str->size += (size_t)printed;
|
str->size += (size_t)printed;
|
||||||
return printed;
|
return printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reverse text into allocated memory.
|
||||||
|
///
|
||||||
|
/// @return the allocated string.
|
||||||
|
char_u *reverse_text(char_u *s)
|
||||||
|
FUNC_ATTR_NONNULL_RET
|
||||||
|
{
|
||||||
|
// Reverse the pattern.
|
||||||
|
size_t len = STRLEN(s);
|
||||||
|
char_u *rev = xmalloc(len + 1);
|
||||||
|
size_t rev_i = len;
|
||||||
|
for (size_t s_i = 0; s_i < len; s_i++) {
|
||||||
|
const int mb_len = utfc_ptr2len((char *)s + s_i);
|
||||||
|
rev_i -= (size_t)mb_len;
|
||||||
|
memmove(rev + rev_i, s + s_i, (size_t)mb_len);
|
||||||
|
s_i += (size_t)mb_len - 1;
|
||||||
|
}
|
||||||
|
rev[len] = NUL;
|
||||||
|
|
||||||
|
return rev;
|
||||||
|
}
|
||||||
|
@ -5,6 +5,8 @@ local to_cstr = helpers.to_cstr
|
|||||||
local eq = helpers.eq
|
local eq = helpers.eq
|
||||||
|
|
||||||
local search = helpers.cimport("./src/nvim/search.h")
|
local search = helpers.cimport("./src/nvim/search.h")
|
||||||
|
local globals = helpers.cimport('./src/nvim/globals.h')
|
||||||
|
local ffi = helpers.ffi
|
||||||
|
|
||||||
itp('pat_has_uppercase', function()
|
itp('pat_has_uppercase', function()
|
||||||
-- works on empty string
|
-- works on empty string
|
||||||
@ -31,3 +33,25 @@ itp('pat_has_uppercase', function()
|
|||||||
eq(false, search.pat_has_uppercase(to_cstr("aa\\%Ab")))
|
eq(false, search.pat_has_uppercase(to_cstr("aa\\%Ab")))
|
||||||
eq(true, search.pat_has_uppercase(to_cstr("aab\\%AU")))
|
eq(true, search.pat_has_uppercase(to_cstr("aab\\%AU")))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('search_regcomp', function()
|
||||||
|
local search_regcomp = function(pat, pat_save, pat_use, options )
|
||||||
|
local regmatch = ffi.new("regmmatch_T")
|
||||||
|
local fail = search.search_regcomp(to_cstr(pat), pat_save, pat_use, options, regmatch)
|
||||||
|
return fail, regmatch
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_search_pat = function()
|
||||||
|
return helpers.internalize(search.get_search_pat())
|
||||||
|
end
|
||||||
|
|
||||||
|
itp("accepts regexp pattern with invalid utf", function()
|
||||||
|
--crafted to call reverse_text with invalid utf
|
||||||
|
globals.curwin.w_onebuf_opt.wo_rl = 1
|
||||||
|
globals.curwin.w_onebuf_opt.wo_rlc = to_cstr('s')
|
||||||
|
globals.cmdmod.keeppatterns = 1
|
||||||
|
local fail = search_regcomp("a\192", 0,0,0)
|
||||||
|
eq(1, fail)
|
||||||
|
eq("\192a", get_search_pat())
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
@ -150,3 +150,38 @@ describe('strcase_save()' , function()
|
|||||||
eq("a", strcase_save("\xc1\x81", false))
|
eq("a", strcase_save("\xc1\x81", false))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe("reverse_text", function()
|
||||||
|
local reverse_text = function(str)
|
||||||
|
return helpers.internalize(strings.reverse_text(to_cstr(str)))
|
||||||
|
end
|
||||||
|
|
||||||
|
itp("handles empty string", function()
|
||||||
|
eq("", reverse_text(""))
|
||||||
|
end)
|
||||||
|
|
||||||
|
itp("handles simple cases", function()
|
||||||
|
eq("a", reverse_text("a"))
|
||||||
|
eq("ba", reverse_text("ab"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
itp("handles multibyte characters", function()
|
||||||
|
eq("bα", reverse_text("αb"))
|
||||||
|
eq("Yötön yö", reverse_text("öy nötöY"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
itp("handles combining chars", function()
|
||||||
|
local utf8_COMBINING_RING_ABOVE = "\204\138"
|
||||||
|
local utf8_COMBINING_RING_BELOW = "\204\165"
|
||||||
|
eq("bba" .. utf8_COMBINING_RING_ABOVE .. utf8_COMBINING_RING_BELOW .. "aa",
|
||||||
|
reverse_text("aaa" .. utf8_COMBINING_RING_ABOVE .. utf8_COMBINING_RING_BELOW .. "bb"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
itp("treats invalid utf as separate characters", function()
|
||||||
|
eq("\192ba", reverse_text("ab\192"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
itp("treats an incomplete utf continuation sequence as valid", function()
|
||||||
|
eq("\194ba", reverse_text("ab\194"))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user