mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
Use pointers for traversing arrays in strstr, strcasestr and memmem.
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
2012-08-21 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||||
|
|
||||||
|
* string/str-two-way.h (two_way_short_needle): Use pointers instead of
|
||||||
|
array references.
|
||||||
|
* string/strcasestr.c (TOLOWER): Make side-effect safe.
|
||||||
|
|
||||||
2012-08-21 Maxim Kuvyrkov <maxim@codesourcery.com>
|
2012-08-21 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||||
|
|
||||||
[BZ #11607]
|
[BZ #11607]
|
||||||
|
@@ -240,17 +240,24 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
j = 0;
|
j = 0;
|
||||||
while (AVAILABLE (haystack, haystack_len, j, needle_len))
|
while (AVAILABLE (haystack, haystack_len, j, needle_len))
|
||||||
{
|
{
|
||||||
|
const unsigned char *pneedle;
|
||||||
|
const unsigned char *phaystack;
|
||||||
|
|
||||||
/* Scan for matches in right half. */
|
/* Scan for matches in right half. */
|
||||||
i = MAX (suffix, memory);
|
i = MAX (suffix, memory);
|
||||||
while (i < needle_len && (CANON_ELEMENT (needle[i])
|
pneedle = &needle[i];
|
||||||
== CANON_ELEMENT (haystack[i + j])))
|
phaystack = &haystack[i + j];
|
||||||
|
while (i < needle_len && (CANON_ELEMENT (*pneedle++)
|
||||||
|
== CANON_ELEMENT (*phaystack++)))
|
||||||
++i;
|
++i;
|
||||||
if (needle_len <= i)
|
if (needle_len <= i)
|
||||||
{
|
{
|
||||||
/* Scan for matches in left half. */
|
/* Scan for matches in left half. */
|
||||||
i = suffix - 1;
|
i = suffix - 1;
|
||||||
while (memory < i + 1 && (CANON_ELEMENT (needle[i])
|
pneedle = &needle[i];
|
||||||
== CANON_ELEMENT (haystack[i + j])))
|
phaystack = &haystack[i + j];
|
||||||
|
while (memory < i + 1 && (CANON_ELEMENT (*pneedle--)
|
||||||
|
== CANON_ELEMENT (*phaystack--)))
|
||||||
--i;
|
--i;
|
||||||
if (i + 1 < memory + 1)
|
if (i + 1 < memory + 1)
|
||||||
return (RETURN_TYPE) (haystack + j);
|
return (RETURN_TYPE) (haystack + j);
|
||||||
@@ -268,6 +275,7 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const unsigned char *phaystack = &haystack[suffix];
|
||||||
/* The comparison always starts from needle[suffix], so cache it
|
/* The comparison always starts from needle[suffix], so cache it
|
||||||
and use an optimized first-character loop. */
|
and use an optimized first-character loop. */
|
||||||
unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]);
|
unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]);
|
||||||
@@ -279,23 +287,28 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
while (AVAILABLE1 (haystack, haystack_len, j, needle_len))
|
while (AVAILABLE1 (haystack, haystack_len, j, needle_len))
|
||||||
{
|
{
|
||||||
unsigned char haystack_char;
|
unsigned char haystack_char;
|
||||||
|
const unsigned char *pneedle;
|
||||||
|
|
||||||
/* TODO: The first-character loop can be sped up by adapting
|
/* TODO: The first-character loop can be sped up by adapting
|
||||||
longword-at-a-time implementation of memchr/strchr. */
|
longword-at-a-time implementation of memchr/strchr. */
|
||||||
if (needle_suffix
|
if (needle_suffix
|
||||||
!= (haystack_char = CANON_ELEMENT (haystack[suffix + j])))
|
!= (haystack_char = CANON_ELEMENT (*phaystack++)))
|
||||||
{
|
{
|
||||||
RET0_IF_0 (haystack_char);
|
RET0_IF_0 (haystack_char);
|
||||||
++j;
|
++j;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate J. */
|
||||||
|
j = phaystack - &haystack[suffix] - 1;
|
||||||
|
|
||||||
/* Scan for matches in right half. */
|
/* Scan for matches in right half. */
|
||||||
i = suffix + 1;
|
i = suffix + 1;
|
||||||
|
pneedle = &needle[i];
|
||||||
while (i < needle_len)
|
while (i < needle_len)
|
||||||
{
|
{
|
||||||
if (CANON_ELEMENT (needle[i])
|
if (CANON_ELEMENT (*pneedle++)
|
||||||
!= (haystack_char = CANON_ELEMENT (haystack[i + j])))
|
!= (haystack_char = CANON_ELEMENT (*phaystack++)))
|
||||||
{
|
{
|
||||||
RET0_IF_0 (haystack_char);
|
RET0_IF_0 (haystack_char);
|
||||||
break;
|
break;
|
||||||
@@ -306,10 +319,12 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
{
|
{
|
||||||
/* Scan for matches in left half. */
|
/* Scan for matches in left half. */
|
||||||
i = suffix - 1;
|
i = suffix - 1;
|
||||||
|
pneedle = &needle[i];
|
||||||
|
phaystack = &haystack[i + j];
|
||||||
while (i != SIZE_MAX)
|
while (i != SIZE_MAX)
|
||||||
{
|
{
|
||||||
if (CANON_ELEMENT (needle[i])
|
if (CANON_ELEMENT (*pneedle--)
|
||||||
!= (haystack_char = CANON_ELEMENT (haystack[i + j])))
|
!= (haystack_char = CANON_ELEMENT (*phaystack--)))
|
||||||
{
|
{
|
||||||
RET0_IF_0 (haystack_char);
|
RET0_IF_0 (haystack_char);
|
||||||
break;
|
break;
|
||||||
@@ -325,6 +340,8 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
|
|
||||||
if (!AVAILABLE2 (haystack, haystack_len, j, needle_len))
|
if (!AVAILABLE2 (haystack, haystack_len, j, needle_len))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
phaystack = &haystack[suffix + j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret0: __attribute__ ((unused))
|
ret0: __attribute__ ((unused))
|
||||||
@@ -379,6 +396,9 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
j = 0;
|
j = 0;
|
||||||
while (AVAILABLE (haystack, haystack_len, j, needle_len))
|
while (AVAILABLE (haystack, haystack_len, j, needle_len))
|
||||||
{
|
{
|
||||||
|
const unsigned char *pneedle;
|
||||||
|
const unsigned char *phaystack;
|
||||||
|
|
||||||
/* Check the last byte first; if it does not match, then
|
/* Check the last byte first; if it does not match, then
|
||||||
shift to the next possible match location. */
|
shift to the next possible match location. */
|
||||||
shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
|
shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
|
||||||
@@ -398,15 +418,19 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
/* Scan for matches in right half. The last byte has
|
/* Scan for matches in right half. The last byte has
|
||||||
already been matched, by virtue of the shift table. */
|
already been matched, by virtue of the shift table. */
|
||||||
i = MAX (suffix, memory);
|
i = MAX (suffix, memory);
|
||||||
while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
|
pneedle = &needle[i];
|
||||||
== CANON_ELEMENT (haystack[i + j])))
|
phaystack = &haystack[i + j];
|
||||||
|
while (i < needle_len - 1 && (CANON_ELEMENT (*pneedle++)
|
||||||
|
== CANON_ELEMENT (*phaystack++)))
|
||||||
++i;
|
++i;
|
||||||
if (needle_len - 1 <= i)
|
if (needle_len - 1 <= i)
|
||||||
{
|
{
|
||||||
/* Scan for matches in left half. */
|
/* Scan for matches in left half. */
|
||||||
i = suffix - 1;
|
i = suffix - 1;
|
||||||
while (memory < i + 1 && (CANON_ELEMENT (needle[i])
|
pneedle = &needle[i];
|
||||||
== CANON_ELEMENT (haystack[i + j])))
|
phaystack = &haystack[i + j];
|
||||||
|
while (memory < i + 1 && (CANON_ELEMENT (*pneedle--)
|
||||||
|
== CANON_ELEMENT (*phaystack--)))
|
||||||
--i;
|
--i;
|
||||||
if (i + 1 < memory + 1)
|
if (i + 1 < memory + 1)
|
||||||
return (RETURN_TYPE) (haystack + j);
|
return (RETURN_TYPE) (haystack + j);
|
||||||
@@ -431,6 +455,9 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
j = 0;
|
j = 0;
|
||||||
while (AVAILABLE (haystack, haystack_len, j, needle_len))
|
while (AVAILABLE (haystack, haystack_len, j, needle_len))
|
||||||
{
|
{
|
||||||
|
const unsigned char *pneedle;
|
||||||
|
const unsigned char *phaystack;
|
||||||
|
|
||||||
/* Check the last byte first; if it does not match, then
|
/* Check the last byte first; if it does not match, then
|
||||||
shift to the next possible match location. */
|
shift to the next possible match location. */
|
||||||
shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
|
shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
|
||||||
@@ -442,15 +469,19 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
|
|||||||
/* Scan for matches in right half. The last byte has
|
/* Scan for matches in right half. The last byte has
|
||||||
already been matched, by virtue of the shift table. */
|
already been matched, by virtue of the shift table. */
|
||||||
i = suffix;
|
i = suffix;
|
||||||
while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
|
pneedle = &needle[i];
|
||||||
== CANON_ELEMENT (haystack[i + j])))
|
phaystack = &haystack[i + j];
|
||||||
|
while (i < needle_len - 1 && (CANON_ELEMENT (*pneedle++)
|
||||||
|
== CANON_ELEMENT (*phaystack++)))
|
||||||
++i;
|
++i;
|
||||||
if (needle_len - 1 <= i)
|
if (needle_len - 1 <= i)
|
||||||
{
|
{
|
||||||
/* Scan for matches in left half. */
|
/* Scan for matches in left half. */
|
||||||
i = suffix - 1;
|
i = suffix - 1;
|
||||||
while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
|
pneedle = &needle[i];
|
||||||
== CANON_ELEMENT (haystack[i + j])))
|
phaystack = &haystack[i + j];
|
||||||
|
while (i != SIZE_MAX && (CANON_ELEMENT (*pneedle--)
|
||||||
|
== CANON_ELEMENT (*phaystack--)))
|
||||||
--i;
|
--i;
|
||||||
if (i == SIZE_MAX)
|
if (i == SIZE_MAX)
|
||||||
return (RETURN_TYPE) (haystack + j);
|
return (RETURN_TYPE) (haystack + j);
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
|
#define TOLOWER(Ch) tolower (Ch)
|
||||||
|
|
||||||
/* Two-Way algorithm. */
|
/* Two-Way algorithm. */
|
||||||
#define RETURN_TYPE char *
|
#define RETURN_TYPE char *
|
||||||
|
Reference in New Issue
Block a user