mirror of https://git.musl-libc.org/git/musl
Browse Source
when strchr fails, and important piece of information already computed, the string length, is thrown away. have strchrnul (with namespace protection) be the underlying function so this information can be kept, and let strchr be a wrapper for it. this also allows strcspn to be considerably faster in the case where the match set has a single element that's not matched.rs-1.0
3 changed files with 29 additions and 25 deletions
@ -1,26 +1,9 @@ |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
#include <stdint.h> |
|||
#include <limits.h> |
|||
|
|||
#define ALIGN (sizeof(size_t)-1) |
|||
#define ONES ((size_t)-1/UCHAR_MAX) |
|||
#define HIGHS (ONES * (UCHAR_MAX/2+1)) |
|||
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) |
|||
char *__strchrnul(const char *, int); |
|||
|
|||
char *strchr(const char *s, int c) |
|||
{ |
|||
size_t *w, k; |
|||
|
|||
c = (unsigned char)c; |
|||
if (!c) return (char *)s + strlen(s); |
|||
|
|||
for (; ((uintptr_t)s & ALIGN); s++) |
|||
if (*(unsigned char *)s == c) return (char *)s; |
|||
else if (!*s) return 0; |
|||
k = ONES * c; |
|||
for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++); |
|||
for (s = (void *)w; *s; s++) |
|||
if (*(unsigned char *)s == c) return (char *)s; |
|||
return 0; |
|||
char *r = __strchrnul(s, c); |
|||
return *(unsigned char *)r == (unsigned char)c ? r : 0; |
|||
} |
|||
|
|||
@ -1,7 +1,27 @@ |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
#include <stdint.h> |
|||
#include <limits.h> |
|||
#include "libc.h" |
|||
|
|||
char *strchrnul(const char *s, int c) |
|||
#define ALIGN (sizeof(size_t)) |
|||
#define ONES ((size_t)-1/UCHAR_MAX) |
|||
#define HIGHS (ONES * (UCHAR_MAX/2+1)) |
|||
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) |
|||
|
|||
char *__strchrnul(const char *s, int c) |
|||
{ |
|||
char *p = strchr(s, c); |
|||
return p ? p : (char *)s + strlen(s); |
|||
size_t *w, k; |
|||
|
|||
c = (unsigned char)c; |
|||
if (!c) return (char *)s + strlen(s); |
|||
|
|||
for (; (uintptr_t)s % ALIGN; s++) |
|||
if (!*s || *(unsigned char *)s == c) return (char *)s; |
|||
k = ONES * c; |
|||
for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++); |
|||
for (s = (void *)w; *s && *(unsigned char *)s != c; s++); |
|||
return (char *)s; |
|||
} |
|||
|
|||
weak_alias(__strchrnul, strchrnul); |
|||
|
|||
Loading…
Reference in new issue