+2015-12-14 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * benchtests/bench-strtok.c (oldstrtok): Add old implementation.
+ * string/strtok.c (strtok): Change to tailcall __strtok_r.
+ * string/strtok_r.c (__strtok_r): Optimize for performance.
+ * string/string-inlines.c (__old_strtok_r_1c): New function.
+ * string/bits/string2.h (__strtok_r): Move to string-inlines.c.
+
2016-12-14 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
* math/Makefile (gen-libm-calls): Add w_log1pF.
#define TEST_NAME "strtok"
#include "bench-string.h"
-#define STRTOK strtok_string
-#include <string/strtok.c>
+char *
+oldstrtok (char *s, const char *delim)
+{
+ static char *olds;
+ char *token;
+
+ if (s == NULL)
+ s = olds;
+
+ /* Scan leading delimiters. */
+ s += strspn (s, delim);
+ if (*s == '\0')
+ {
+ olds = s;
+ return NULL;
+ }
+ /* Find the end of the token. */
+ token = s;
+ s = strpbrk (token, delim);
+ if (s == NULL)
+ /* This token finishes the string. */
+ olds = __rawmemchr (token, '\0');
+ else
+ {
+ /* Terminate the token and make OLDS point past it. */
+ *s = '\0';
+ olds = s + 1;
+ }
+ return token;
+}
typedef char *(*proto_t) (const char *, const char *);
-IMPL (strtok_string, 0)
+IMPL (oldstrtok, 0)
IMPL (strtok, 1)
static void
#endif
-#if !defined _HAVE_STRING_ARCH_strtok_r || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_strtok_r
-# define __strtok_r(s, sep, nextp) \
- (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \
- && ((const char *) (sep))[0] != '\0' \
- && ((const char *) (sep))[1] == '\0' \
- ? __strtok_r_1c (s, ((const char *) (sep))[0], nextp) \
- : __strtok_r (s, sep, nextp)))
-# endif
-
-__STRING_INLINE char *__strtok_r_1c (char *__s, char __sep, char **__nextp);
-__STRING_INLINE char *
-__strtok_r_1c (char *__s, char __sep, char **__nextp)
-{
- char *__result;
- if (__s == NULL)
- __s = *__nextp;
- while (*__s == __sep)
- ++__s;
- __result = NULL;
- if (*__s != '\0')
- {
- __result = __s++;
- while (*__s != '\0')
- if (*__s++ == __sep)
- {
- __s[-1] = '\0';
- break;
- }
- }
- *__nextp = __s;
- return __result;
-}
-# ifdef __USE_POSIX
-# define strtok_r(s, sep, nextp) __strtok_r (s, sep, nextp)
-# endif
-#endif
-
-
#if !defined _HAVE_STRING_ARCH_strsep || defined _FORCE_INLINES
# ifndef _HAVE_STRING_ARCH_strsep
#include "shlib-compat.h"
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
+/* The inline functions are not used from GLIBC 2.25 and forward, however
+ they are required to provide the symbols through string-inlines.c
+ (if inlining is not possible for compatibility reasons). */
+
+char *
+__old_strtok_r_1c (char *__s, char __sep, char **__nextp)
+{
+ char *__result;
+ if (__s == NULL)
+ __s = *__nextp;
+ while (*__s == __sep)
+ ++__s;
+ __result = NULL;
+ if (*__s != '\0')
+ {
+ __result = __s++;
+ while (*__s != '\0')
+ if (*__s++ == __sep)
+ {
+ __s[-1] = '\0';
+ break;
+ }
+ }
+ *__nextp = __s;
+ return __result;
+}
+compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
+#endif
+
#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
/* The inline functions are not used from GLIBC 2.24 and forward, however
they are required to provide the symbols through string-inlines.c
#include <string.h>
-static char *olds;
-
-#undef strtok
-
-#ifndef STRTOK
-# define STRTOK strtok
-#endif
-
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the last string strtok() was called with is
used. For example:
// s = "abc\0=-def\0"
*/
char *
-STRTOK (char *s, const char *delim)
+strtok (char *s, const char *delim)
{
- char *token;
-
- if (s == NULL)
- s = olds;
-
- /* Scan leading delimiters. */
- s += strspn (s, delim);
- if (*s == '\0')
- {
- olds = s;
- return NULL;
- }
-
- /* Find the end of the token. */
- token = s;
- s = strpbrk (token, delim);
- if (s == NULL)
- /* This token finishes the string. */
- olds = __rawmemchr (token, '\0');
- else
- {
- /* Terminate the token and make OLDS point past it. */
- *s = '\0';
- olds = s + 1;
- }
- return token;
+ static char *olds;
+ return __strtok_r (s, delim, &olds);
}
#include <string.h>
-#undef strtok_r
-#undef __strtok_r
-
#ifndef _LIBC
/* Get specification. */
# include "strtok_r.h"
# define __strtok_r strtok_r
-# define __rawmemchr strchr
#endif
/* Parse S into tokens separated by characters in DELIM.
char *
__strtok_r (char *s, const char *delim, char **save_ptr)
{
- char *token;
+ char *end;
if (s == NULL)
s = *save_ptr;
+ if (*s == '\0')
+ {
+ *save_ptr = s;
+ return NULL;
+ }
+
/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0')
}
/* Find the end of the token. */
- token = s;
- s = strpbrk (token, delim);
- if (s == NULL)
- /* This token finishes the string. */
- *save_ptr = __rawmemchr (token, '\0');
- else
+ end = s + strcspn (s, delim);
+ if (*end == '\0')
{
- /* Terminate the token and make *SAVE_PTR point past it. */
- *s = '\0';
- *save_ptr = s + 1;
+ *save_ptr = end;
+ return s;
}
- return token;
+
+ /* Terminate the token and make *SAVE_PTR point past it. */
+ *end = '\0';
+ *save_ptr = end + 1;
+ return s;
}
#ifdef weak_alias
libc_hidden_def (__strtok_r)