mirror of
https://github.com/dlang/phobos.git
synced 2025-05-10 14:08:32 +03:00
fix Issue 7300 - std.regex.ShiftOr!dchar.search is broken
Rework problematic memchr codepath to properly test for end of string. More importantly it's overall cleaner.
This commit is contained in:
parent
ba5eecf086
commit
e53e6d64e9
1 changed files with 28 additions and 18 deletions
46
std/regex.d
46
std/regex.d
|
@ -2743,7 +2743,7 @@ public:
|
||||||
// returns only valid UTF indexes
|
// returns only valid UTF indexes
|
||||||
// (that given the haystack in question is valid UTF string)
|
// (that given the haystack in question is valid UTF string)
|
||||||
@trusted size_t search(const(Char)[] haystack, size_t idx)
|
@trusted size_t search(const(Char)[] haystack, size_t idx)
|
||||||
{
|
{//@BUG: apparently assumes little endian machines
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
auto p = cast(const(ubyte)*)(haystack.ptr+idx);
|
auto p = cast(const(ubyte)*)(haystack.ptr+idx);
|
||||||
uint state = uint.max;
|
uint state = uint.max;
|
||||||
|
@ -2756,9 +2756,10 @@ public:
|
||||||
while(p != end)
|
while(p != end)
|
||||||
{
|
{
|
||||||
if(!~state)
|
if(!~state)
|
||||||
{
|
{//speed up seeking first matching place
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
assert(p <= end, text(p," vs ", end));
|
||||||
p = cast(ubyte*)memchr(p, fChar, end - p);
|
p = cast(ubyte*)memchr(p, fChar, end - p);
|
||||||
if(!p)
|
if(!p)
|
||||||
return haystack.length;
|
return haystack.length;
|
||||||
|
@ -2773,31 +2774,40 @@ public:
|
||||||
{
|
{
|
||||||
state = (state<<1) | table[p[1]];
|
state = (state<<1) | table[p[1]];
|
||||||
state = (state<<1) | table[p[2]];
|
state = (state<<1) | table[p[2]];
|
||||||
p += 3;
|
p += 4;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
//first char is already tested, see if that's all
|
p++;
|
||||||
if(!(state & limit))//division rounds down for dchar
|
//first char is tested, see if that's all
|
||||||
return (p-cast(ubyte*)haystack.ptr)/Char.sizeof
|
if(!(state & limit))
|
||||||
-length+1;
|
return (p-cast(ubyte*)haystack.ptr)/Char.sizeof
|
||||||
static if(charSize == 3)
|
-length;
|
||||||
{
|
|
||||||
state = (state<<1) | table[p[1]];
|
|
||||||
state = (state<<1) | table[p[2]];
|
|
||||||
state = (state<<1) | table[p[3]];
|
|
||||||
p+=4;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{//have some bits/states for possible matches,
|
||||||
state = (state<<1) | table[p[1]];
|
//use the usual shift-or cycle
|
||||||
p++;
|
static if(charSize == 3)
|
||||||
|
{
|
||||||
|
state = (state<<1) | table[p[0]];
|
||||||
|
state = (state<<1) | table[p[1]];
|
||||||
|
state = (state<<1) | table[p[2]];
|
||||||
|
p+=4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = (state<<1) | table[p[0]];
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if(!(state & limit))
|
||||||
|
return (p-cast(ubyte*)haystack.ptr)/Char.sizeof
|
||||||
|
-length;
|
||||||
}
|
}
|
||||||
debug(fred_search) writefln("State: %32b", state);
|
debug(fred_search) writefln("State: %32b", state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//in this path we have to shift first
|
//normal path, partially unrolled for char/wchar
|
||||||
static if(charSize == 3)
|
static if(charSize == 3)
|
||||||
{
|
{
|
||||||
const(ubyte)* end = cast(ubyte*)(haystack.ptr + haystack.length);
|
const(ubyte)* end = cast(ubyte*)(haystack.ptr + haystack.length);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue