diff options
Diffstat (limited to 'string')
-rw-r--r-- | string/strcspn.c | 43 | ||||
-rw-r--r-- | string/strpbrk.c | 120 | ||||
-rw-r--r-- | string/test-strcspn.c | 15 | ||||
-rw-r--r-- | string/test-strpbrk.c | 14 |
4 files changed, 116 insertions, 76 deletions
diff --git a/string/strcspn.c b/string/strcspn.c index 2694d2a..2a82dd2 100644 --- a/string/strcspn.c +++ b/string/strcspn.c @@ -1,41 +1,2 @@ -/* Copyright (C) 1991-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <string.h> - -#undef strcspn - -#ifndef STRCSPN -# define STRCSPN strcspn -#endif - -/* Return the length of the maximum initial segment of S - which contains no characters from REJECT. */ -size_t -STRCSPN (const char *s, const char *reject) -{ - size_t count = 0; - - while (*s != '\0') - if (strchr (reject, *s++) == NULL) - ++count; - else - return count; - - return count; -} -libc_hidden_builtin_def (strcspn) +#define AS_STRCSPN +#include "strpbrk.c" diff --git a/string/strpbrk.c b/string/strpbrk.c index 4f1d9b7..01cd55a 100644 --- a/string/strpbrk.c +++ b/string/strpbrk.c @@ -16,26 +16,124 @@ <http://www.gnu.org/licenses/>. */ #include <string.h> - +#include <stdint.h> #undef strpbrk +#undef strcspn + + +#ifdef AS_STRCSPN +# ifndef STRPBRK +# define STRPBRK strcspn +# endif +# define RETURN_TYPE size_t +# define RETURN(c) return c +#else +# define RETURN_TYPE char * +# define RETURN(c) return (char *) (s[c] != '\0' ? s + c : NULL) +#endif #ifndef STRPBRK #define STRPBRK strpbrk #endif + /* Find the first occurrence in S of any character in ACCEPT. */ -char * -STRPBRK (const char *s, const char *accept) +RETURN_TYPE +STRPBRK (const char *_s, const char *_accept) { - while (*s != '\0') + unsigned char *s = (unsigned char *) _s; + unsigned char *a = (unsigned char *) _accept; + +#ifndef LATE_CHECK + /* We need to align s to 4 bytes. We do check now to avoid expensive table + construction. */ + do + { + if (s[0] == *a) + RETURN(0); + } + while (*a++); + a = (unsigned char *) _accept; + + /* We couldn't do these checks in one loop as gcc + messes up register allocation. */ + do + { + if (s[1] == *a) + RETURN(1); + } + while (*a++); + a = (unsigned char *) _accept; + + do + { + if (s[2] == *a) + RETURN(2); + } + while (*a++); + a = (unsigned char *) _accept; + + do + { + if (s[3] == *a) + RETURN(3); + } + while (*a++); + a = (unsigned char *) _accept; + +#endif + + unsigned char table[256]; + memset (table, 0, 256); + do { - const char *a = accept; - while (*a != '\0') - if (*a++ == *s) - return (char *) s; - ++s; + table[*a] = 1; } + while (*a++); + unsigned char s0, s1, s2, s3; + size_t count = 0; +#ifdef LATE_CHECK + s0 = s[count + 0]; + s1 = s[count + 1]; + s2 = s[count + 2]; + s3 = s[count + 3]; + if (table[s0]) + goto ret0; + if (table[s1]) + goto ret1; + if (table[s2]) + goto ret2; + if (table[s3]) + goto ret3; - return NULL; +#endif + + count = 4 - ((uintptr_t) s) % 4; + + while (1) + { + s0 = s[count + 0]; + s1 = s[count + 1]; + s2 = s[count + 2]; + s3 = s[count + 3]; + if (table[s0]) + goto ret0; + if (table[s1]) + goto ret1; + if (table[s2]) + goto ret2; + if (table[s3]) + goto ret3; + count += 4; + } + ret3: + count++; + ret2: + count++; + ret1: + count++; + ret0: + RETURN(count); } -libc_hidden_builtin_def (strpbrk) + +libc_hidden_builtin_def (STRPBRK) diff --git a/string/test-strcspn.c b/string/test-strcspn.c index b60a048..50a06e4 100644 --- a/string/test-strcspn.c +++ b/string/test-strcspn.c @@ -31,18 +31,9 @@ IMPL (stupid_strcspn, 0) IMPL (simple_strcspn, 0) IMPL (strcspn, 1) -size_t -simple_strcspn (const char *s, const char *rej) -{ - const char *r, *str = s; - char c; - - while ((c = *s++) != '\0') - for (r = rej; *r != '\0'; ++r) - if (*r == c) - return s - str - 1; - return s - str - 1; -} +#define AS_STRCSPN +#define STRPBRK simple_strcspn +#include "string/strpbrk.c" size_t stupid_strcspn (const char *s, const char *rej) diff --git a/string/test-strpbrk.c b/string/test-strpbrk.c index b4ac389..f389e9d 100644 --- a/string/test-strpbrk.c +++ b/string/test-strpbrk.c @@ -32,18 +32,8 @@ IMPL (stupid_strpbrk, 0) IMPL (simple_strpbrk, 0) IMPL (strpbrk, 1) -char * -simple_strpbrk (const char *s, const char *rej) -{ - const char *r; - char c; - - while ((c = *s++) != '\0') - for (r = rej; *r != '\0'; ++r) - if (*r == c) - return (char *) s - 1; - return NULL; -} +#define STRPBRK simple_strpbrk +#include "string/strpbrk.c" char * stupid_strpbrk (const char *s, const char *rej) |