1
0
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:
Maxim Kuvyrkov
2012-05-28 23:32:12 -07:00
parent 400726deef
commit 99677e5755
3 changed files with 55 additions and 18 deletions

View File

@@ -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]

View File

@@ -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);

View File

@@ -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 *