From f2bb48d37cccc836f0c639c2d45ac1c1a9a58fe0 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Andersen Date: Wed, 3 Dec 2025 14:34:33 +0100 Subject: [PATCH] Do not use internal `Base.first_utf8_byte` This has been removed in Julia 1.13+. Re-implement it. --- Project.toml | 2 +- src/search.jl | 11 ++++++++--- test/runtests.jl | 5 +++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index 51b97a3..913ec9b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "StringViews" uuid = "354b36f9-a18e-4713-926e-db85100087ba" authors = ["Steven G. Johnson "] -version = "1.3.5" +version = "1.3.6" [compat] julia = "1.6" diff --git a/src/search.jl b/src/search.jl index 8dca703..c45e66f 100644 --- a/src/search.jl +++ b/src/search.jl @@ -2,6 +2,11 @@ nothing_sentinel(x) = iszero(x) ? nothing : x +function first_utf8_byte(x::Char)::UInt8 + u = reinterpret(UInt32, x) + (u >> 24) % UInt8 +end + function Base.findnext(pred::Base.Fix2{<:Union{typeof(isequal),typeof(==)},<:AbstractChar}, s::StringViewAndSub, i::Integer) if i < 1 || i > sizeof(s) @@ -9,10 +14,10 @@ function Base.findnext(pred::Base.Fix2{<:Union{typeof(isequal),typeof(==)},<:Abs throw(BoundsError(s, i)) end @inbounds isvalid(s, i) || Base.string_index_err(s, i) - c = pred.x + c = Char(pred.x)::Char c ≤ '\x7f' && return nothing_sentinel(Base._search(s, c % UInt8, i)) while true - i = Base._search(s, Base.first_utf8_byte(c), i) + i = Base._search(s, first_utf8_byte(c), i) i == 0 && return nothing pred(s[i]) && return i i = nextind(s, i) @@ -45,7 +50,7 @@ function Base.findprev(pred::Base.Fix2{<:Union{typeof(isequal),typeof(==)},<:Abs s::StringViewAndSub, i::Integer) c = pred.x c ≤ '\x7f' && return nothing_sentinel(Base._rsearch(s, c % UInt8, i)) - b = Base.first_utf8_byte(c) + b = first_utf8_byte(c) while true i = Base._rsearch(s, b, i) i == 0 && return nothing diff --git a/test/runtests.jl b/test/runtests.jl index 616044d..53d3832 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -142,6 +142,11 @@ end pat = r"(\.[\d]{3})\d+" => s"\g<1>" @test replace(String(copy(v)), pat) == replace(StringView(v), pat) end + + @test findfirst(==('ø'), StringView("abc")) === nothing + @test findfirst(==('ø'), StringView("abæø")) == 5 + @test findlast(==('ø'), StringView("abc")) === nothing + @test findlast(==('ø'), StringView("abæø")) == 5 end @testset "replace" begin