summaryrefslogtreecommitdiff
path: root/string
diff options
context:
space:
mode:
Diffstat (limited to 'string')
-rw-r--r--string/Makefile49
-rw-r--r--string/Versions5
-rw-r--r--string/_strerror.c2
-rw-r--r--string/argz-addsep.c2
-rw-r--r--string/argz-append.c2
-rw-r--r--string/argz-count.c2
-rw-r--r--string/argz-create.c2
-rw-r--r--string/argz-ctsep.c2
-rw-r--r--string/argz-delete.c2
-rw-r--r--string/argz-extract.c2
-rw-r--r--string/argz-insert.c2
-rw-r--r--string/argz-next.c4
-rw-r--r--string/argz-replace.c2
-rw-r--r--string/argz-stringify.c2
-rw-r--r--string/argz.h38
-rw-r--r--string/basename.c2
-rw-r--r--string/bcopy.c2
-rw-r--r--string/bits/string2.h1329
-rw-r--r--string/bits/string_fortified.h (renamed from string/bits/string3.h)46
-rw-r--r--string/bits/strings_fortified.h34
-rw-r--r--string/bug-envz1.c5
-rw-r--r--string/bug-strcoll2.c7
-rw-r--r--string/bug-strncat1.c8
-rw-r--r--string/bug-strpbrk1.c8
-rw-r--r--string/bug-strspn1.c8
-rw-r--r--string/bug-strtok1.c5
-rw-r--r--string/byteswap.h2
-rw-r--r--string/bzero.c2
-rw-r--r--string/endian.h27
-rw-r--r--string/envz.c2
-rw-r--r--string/envz.h2
-rw-r--r--string/explicit_bzero.c38
-rw-r--r--string/ffs.c2
-rw-r--r--string/ffsll.c2
-rw-r--r--string/memccpy.c2
-rw-r--r--string/memchr.c2
-rw-r--r--string/memcmp.c7
-rw-r--r--string/memcpy.c2
-rw-r--r--string/memfrob.c2
-rw-r--r--string/memmem.c3
-rw-r--r--string/memmove.c2
-rw-r--r--string/memory.h2
-rw-r--r--string/mempcpy.c2
-rw-r--r--string/memrchr.c29
-rw-r--r--string/memset.c2
-rw-r--r--string/rawmemchr.c163
-rw-r--r--string/stpcpy.c2
-rw-r--r--string/stpncpy.c2
-rw-r--r--string/str-two-way.h58
-rw-r--r--string/stratcliff.c283
-rw-r--r--string/strcasecmp.c6
-rw-r--r--string/strcasecmp_l.c2
-rw-r--r--string/strcasestr.c10
-rw-r--r--string/strcat.c2
-rw-r--r--string/strchr.c2
-rw-r--r--string/strchrnul.c2
-rw-r--r--string/strcmp.c2
-rw-r--r--string/strcoll.c2
-rw-r--r--string/strcoll_l.c27
-rw-r--r--string/strcpy.c2
-rw-r--r--string/strcspn.c49
-rw-r--r--string/strdup.c2
-rw-r--r--string/strerror.c2
-rw-r--r--string/strerror_l.c17
-rw-r--r--string/strfry.c2
-rw-r--r--string/string-inlines.c556
-rw-r--r--string/string.h200
-rw-r--r--string/strings.h87
-rw-r--r--string/strlen.c2
-rw-r--r--string/strncase.c6
-rw-r--r--string/strncase_l.c2
-rw-r--r--string/strncat.c7
-rw-r--r--string/strncmp.c2
-rw-r--r--string/strncpy.c2
-rw-r--r--string/strndup.c2
-rw-r--r--string/strnlen.c2
-rw-r--r--string/strpbrk.c14
-rw-r--r--string/strrchr.c2
-rw-r--r--string/strsep.c29
-rw-r--r--string/strsignal.c2
-rw-r--r--string/strspn.c61
-rw-r--r--string/strstr.c7
-rw-r--r--string/strtok.c40
-rw-r--r--string/strtok_r.c33
-rw-r--r--string/strverscmp.c2
-rw-r--r--string/strxfrm.c2
-rw-r--r--string/strxfrm_l.c4
-rw-r--r--string/swab.c2
-rw-r--r--string/test-bcopy.c2
-rw-r--r--string/test-bzero.c2
-rw-r--r--string/test-endian-file-scope.c44
-rw-r--r--string/test-endian-sign-conversion.c48
-rw-r--r--string/test-endian-types.c49
-rw-r--r--string/test-explicit_bzero.c20
-rw-r--r--string/test-ffs.c7
-rw-r--r--string/test-memccpy.c4
-rw-r--r--string/test-memchr.c55
-rw-r--r--string/test-memcmp.c16
-rw-r--r--string/test-memcpy.c57
-rw-r--r--string/test-memmem.c4
-rw-r--r--string/test-memmove.c63
-rw-r--r--string/test-mempcpy.c3
-rw-r--r--string/test-memrchr.c21
-rw-r--r--string/test-memset.c14
-rw-r--r--string/test-rawmemchr.c4
-rw-r--r--string/test-stpcpy.c2
-rw-r--r--string/test-stpncpy.c2
-rw-r--r--string/test-strcasecmp.c4
-rw-r--r--string/test-strcasestr.c5
-rw-r--r--string/test-strcat.c4
-rw-r--r--string/test-strchr.c4
-rw-r--r--string/test-strchrnul.c2
-rw-r--r--string/test-strcmp.c4
-rw-r--r--string/test-strcpy.c4
-rw-r--r--string/test-strcspn.c2
-rw-r--r--string/test-string.h58
-rw-r--r--string/test-strlen.c4
-rw-r--r--string/test-strncasecmp.c4
-rw-r--r--string/test-strncat.c19
-rw-r--r--string/test-strncmp.c10
-rw-r--r--string/test-strncpy.c4
-rw-r--r--string/test-strnlen.c58
-rw-r--r--string/test-strpbrk.c4
-rw-r--r--string/test-strrchr.c4
-rw-r--r--string/test-strspn.c4
-rw-r--r--string/test-strstr.c6
-rw-r--r--string/testcopy.c18
-rw-r--r--string/tester.c115
-rw-r--r--string/tst-bswap.c7
-rw-r--r--string/tst-cmp.c227
-rw-r--r--string/tst-endian.c7
-rw-r--r--string/tst-inlcall.c7
-rw-r--r--string/tst-strcoll-overflow.c38
-rw-r--r--string/tst-strfry.c5
-rw-r--r--string/tst-strlen.c5
-rw-r--r--string/tst-strtok.c5
-rw-r--r--string/tst-strtok_r.c4
-rw-r--r--string/tst-strxfrm.c5
-rw-r--r--string/tst-strxfrm2.c5
-rw-r--r--string/tst-svc.c5
-rw-r--r--string/tst-svc2.c5
-rw-r--r--string/tst-xbzero-opt.c321
-rw-r--r--string/wordcopy.c2
-rw-r--r--string/xpg-strerror.c2
144 files changed, 2469 insertions, 2342 deletions
diff --git a/string/Makefile b/string/Makefile
index 9c87419ad9..680431f921 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2016 Free Software Foundation, Inc.
+# Copyright (C) 1991-2018 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
@@ -22,9 +22,11 @@ subdir := string
include ../Makeconfig
-headers := string.h strings.h memory.h endian.h bits/endian.h \
- argz.h envz.h byteswap.h bits/byteswap.h bits/byteswap-16.h \
- bits/string.h bits/string2.h bits/string3.h
+headers := string.h bits/string_fortified.h \
+ strings.h bits/strings_fortified.h \
+ byteswap.h bits/byteswap.h \
+ endian.h bits/endian.h bits/uintn-identity.h \
+ memory.h argz.h envz.h
routines := strcat strchr strcmp strcoll strcpy strcspn \
strverscmp strdup strndup \
@@ -41,21 +43,25 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
addsep replace) \
envz basename \
strcoll_l strxfrm_l string-inlines memrchr \
- xpg-strerror strerror_l
+ xpg-strerror strerror_l explicit_bzero
strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
strlen strncmp strncpy strpbrk strrchr strspn memmem \
strstr strcasestr strnlen strcasecmp strncasecmp \
- strncat rawmemchr strchrnul bcopy bzero memrchr
+ strncat rawmemchr strchrnul bcopy bzero memrchr \
+ explicit_bzero
tests := tester inl-tester noinl-tester testcopy test-ffs \
tst-strlen stratcliff tst-svc tst-inlcall \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
bug-strtok1 $(addprefix test-,$(strop-tests)) \
bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \
- tst-strtok_r bug-strcoll2
+ tst-strtok_r bug-strcoll2 tst-cmp tst-xbzero-opt \
+ test-endian-types test-endian-file-scope \
+ test-endian-sign-conversion
+# This test allocates a lot of memory and can run for a long time.
xtests = tst-strcoll-overflow
ifeq ($(run-built-tests),yes)
@@ -64,12 +70,26 @@ endif
include ../Rules
-CFLAGS-inl-tester.c = -fno-builtin
-CFLAGS-noinl-tester.c = -fno-builtin
-CFLAGS-tst-strlen.c = -fno-builtin
-CFLAGS-stratcliff.c = -fno-builtin
-CFLAGS-test-ffs.c = -fno-builtin
-CFLAGS-tst-inlcall.c = -fno-builtin
+CFLAGS-inl-tester.c += -fno-builtin
+CFLAGS-noinl-tester.c += -fno-builtin
+CFLAGS-tst-strlen.c += -fno-builtin
+CFLAGS-stratcliff.c += -fno-builtin
+CFLAGS-test-ffs.c += -fno-builtin
+CFLAGS-tst-inlcall.c += -fno-builtin
+CFLAGS-tst-xbzero-opt.c += -O3
+CFLAGS-test-endian-sign-conversion.c += -Werror -Wsign-conversion
+# BZ 21006: Resolve all functions but at least explicit_bzero at startup.
+# Otherwise the test fails on s390x as the memcpy in prepare_test_buffer is
+# done by loading r4 / r5 with the test_pattern and using store multiple
+# instruction to store r4 / r5 to buf. If explicit_bzero would be resolved in
+# setup_explicit_clear, r4 / r5 would be stored to stack by _dl_runtime_resolve
+# and the call to memmem in count_test_patterns will find a hit of the
+# test_pattern on the stack.
+LDFLAGS-tst-xbzero-opt = -z now
+
+# Called during TLS initialization.
+CFLAGS-memcpy.c += $(no-stack-protector)
+CFLAGS-wordcopy.c += $(no-stack-protector)
ifeq ($(run-built-tests),yes)
$(objpfx)tst-svc-cmp.out: tst-svc.expect $(objpfx)tst-svc.out
@@ -78,7 +98,7 @@ $(objpfx)tst-svc-cmp.out: tst-svc.expect $(objpfx)tst-svc.out
LOCALES := de_DE.UTF-8 en_US.ISO-8859-1 en_US.UTF-8 \
tr_TR.ISO-8859-9 tr_TR.UTF-8 cs_CZ.UTF-8 \
- da_DK.ISO-8859-1
+ da_DK.ISO-8859-1 en_GB.UTF-8
include ../gen-locales.mk
$(objpfx)test-strcasecmp.out: $(gen-locales)
@@ -87,5 +107,6 @@ $(objpfx)tst-strxfrm.out: $(gen-locales)
$(objpfx)tst-strxfrm2.out: $(gen-locales)
# bug-strcoll2 needs cs_CZ.UTF-8 and da_DK.ISO-8859-1.
$(objpfx)bug-strcoll2.out: $(gen-locales)
+$(objpfx)tst-strcoll-overflow.out: $(gen-locales)
endif
diff --git a/string/Versions b/string/Versions
index 59bf35a3bd..9b709d12a9 100644
--- a/string/Versions
+++ b/string/Versions
@@ -80,4 +80,9 @@ libc {
GLIBC_2.6 {
strerror_l;
}
+ GLIBC_2.24 {
+ }
+ GLIBC_2.25 {
+ explicit_bzero;
+ }
}
diff --git a/string/_strerror.c b/string/_strerror.c
index 4f5d9a27ca..bd2934bd02 100644
--- a/string/_strerror.c
+++ b/string/_strerror.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/argz-addsep.c b/string/argz-addsep.c
index 677f0eeb3b..868f04f935 100644
--- a/string/argz-addsep.c
+++ b/string/argz-addsep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
diff --git a/string/argz-append.c b/string/argz-append.c
index e8d3812a9c..d605880f56 100644
--- a/string/argz-append.c
+++ b/string/argz-append.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>
diff --git a/string/argz-count.c b/string/argz-count.c
index 1556112228..f850caad6d 100644
--- a/string/argz-count.c
+++ b/string/argz-count.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>
diff --git a/string/argz-create.c b/string/argz-create.c
index c287054795..fa0226ea5c 100644
--- a/string/argz-create.c
+++ b/string/argz-create.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>
diff --git a/string/argz-ctsep.c b/string/argz-ctsep.c
index a3858ea771..9da296beef 100644
--- a/string/argz-ctsep.c
+++ b/string/argz-ctsep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
diff --git a/string/argz-delete.c b/string/argz-delete.c
index f274f41ac7..5d3aaecade 100644
--- a/string/argz-delete.c
+++ b/string/argz-delete.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.org>
diff --git a/string/argz-extract.c b/string/argz-extract.c
index d8270ed92d..95ebdce0b3 100644
--- a/string/argz-extract.c
+++ b/string/argz-extract.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.org>
diff --git a/string/argz-insert.c b/string/argz-insert.c
index 71e70eeaf6..5932d422ef 100644
--- a/string/argz-insert.c
+++ b/string/argz-insert.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>
diff --git a/string/argz-next.c b/string/argz-next.c
index 72ef39c313..9200eda4d9 100644
--- a/string/argz-next.c
+++ b/string/argz-next.c
@@ -1,5 +1,5 @@
/* Iterate through the elements of an argz block.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.org>
@@ -36,4 +36,6 @@ __argz_next (const char *argz, size_t argz_len, const char *entry)
else
return NULL;
}
+libc_hidden_def (__argz_next)
weak_alias (__argz_next, argz_next)
+libc_hidden_weak (argz_next)
diff --git a/string/argz-replace.c b/string/argz-replace.c
index 924ff6f4d9..0b171e2acf 100644
--- a/string/argz-replace.c
+++ b/string/argz-replace.c
@@ -1,5 +1,5 @@
/* String replacement in an argz vector
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>
diff --git a/string/argz-stringify.c b/string/argz-stringify.c
index 254b7c5f7b..2463caae03 100644
--- a/string/argz-stringify.c
+++ b/string/argz-stringify.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.org>
diff --git a/string/argz.h b/string/argz.h
index c1bc5f736c..9c496f5ef5 100644
--- a/string/argz.h
+++ b/string/argz.h
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated arg vectors.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 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
@@ -20,18 +20,18 @@
#define _ARGZ_H 1
#include <features.h>
-
-#define __need_error_t
#include <errno.h>
#include <string.h> /* Need size_t, and strchr is called below. */
+__BEGIN_DECLS
+
+/* error_t may or may not be available from errno.h, depending on the
+ operating system. */
#ifndef __error_t_defined
+# define __error_t_defined 1
typedef int error_t;
#endif
-
-__BEGIN_DECLS
-
/* Make a '\0' separated arg vector from a unix argv vector, returning it in
ARGZ, and the total length in LEN. If a memory allocation error occurs,
ENOMEM is returned, otherwise 0. The result can be destroyed using free. */
@@ -44,9 +44,6 @@ extern error_t argz_create (char *const __argv[], char **__restrict __argz,
STRING, returning it in ARGZ, and the total length in LEN. If a
memory allocation error occurs, ENOMEM is returned, otherwise 0.
The result can be destroyed using free. */
-extern error_t __argz_create_sep (const char *__restrict __string,
- int __sep, char **__restrict __argz,
- size_t *__restrict __len) __THROW;
extern error_t argz_create_sep (const char *__restrict __string,
int __sep, char **__restrict __argz,
size_t *__restrict __len) __THROW;
@@ -70,38 +67,24 @@ extern void __argz_stringify (char *__argz, size_t __len, int __sep) __THROW;
extern void argz_stringify (char *__argz, size_t __len, int __sep) __THROW;
/* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */
-extern error_t __argz_append (char **__restrict __argz,
- size_t *__restrict __argz_len,
- const char *__restrict __buf, size_t __buf_len)
- __THROW;
extern error_t argz_append (char **__restrict __argz,
size_t *__restrict __argz_len,
const char *__restrict __buf, size_t __buf_len)
__THROW;
/* Append STR to the argz vector in ARGZ & ARGZ_LEN. */
-extern error_t __argz_add (char **__restrict __argz,
- size_t *__restrict __argz_len,
- const char *__restrict __str) __THROW;
extern error_t argz_add (char **__restrict __argz,
size_t *__restrict __argz_len,
const char *__restrict __str) __THROW;
/* Append SEP separated list in STRING to the argz vector in ARGZ &
ARGZ_LEN. */
-extern error_t __argz_add_sep (char **__restrict __argz,
- size_t *__restrict __argz_len,
- const char *__restrict __string, int __delim)
- __THROW;
extern error_t argz_add_sep (char **__restrict __argz,
size_t *__restrict __argz_len,
const char *__restrict __string, int __delim)
__THROW;
/* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */
-extern void __argz_delete (char **__restrict __argz,
- size_t *__restrict __argz_len,
- char *__restrict __entry) __THROW;
extern void argz_delete (char **__restrict __argz,
size_t *__restrict __argz_len,
char *__restrict __entry) __THROW;
@@ -112,10 +95,6 @@ extern void argz_delete (char **__restrict __argz,
ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
ARGZ, ENOMEM is returned, else 0. */
-extern error_t __argz_insert (char **__restrict __argz,
- size_t *__restrict __argz_len,
- char *__restrict __before,
- const char *__restrict __entry) __THROW;
extern error_t argz_insert (char **__restrict __argz,
size_t *__restrict __argz_len,
char *__restrict __before,
@@ -124,11 +103,6 @@ extern error_t argz_insert (char **__restrict __argz,
/* Replace any occurrences of the string STR in ARGZ with WITH, reallocating
ARGZ as necessary. If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be
incremented by number of replacements performed. */
-extern error_t __argz_replace (char **__restrict __argz,
- size_t *__restrict __argz_len,
- const char *__restrict __str,
- const char *__restrict __with,
- unsigned int *__restrict __replace_count);
extern error_t argz_replace (char **__restrict __argz,
size_t *__restrict __argz_len,
const char *__restrict __str,
diff --git a/string/basename.c b/string/basename.c
index 9c811be375..20a877f43b 100644
--- a/string/basename.c
+++ b/string/basename.c
@@ -1,5 +1,5 @@
/* Return the name-within-directory of a file name.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 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
diff --git a/string/bcopy.c b/string/bcopy.c
index b3ccd28dd7..2c244ffcbf 100644
--- a/string/bcopy.c
+++ b/string/bcopy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/bits/string2.h b/string/bits/string2.h
deleted file mode 100644
index 8200ef173d..0000000000
--- a/string/bits/string2.h
+++ /dev/null
@@ -1,1329 +0,0 @@
-/* Machine-independant string function optimizations.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
- 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/>. */
-
-#ifndef _STRING_H
-# error "Never use <bits/string2.h> directly; include <string.h> instead."
-#endif
-
-#ifndef __NO_STRING_INLINES
-
-/* Unlike the definitions in the header <bits/string.h> the
- definitions contained here are not optimized down to assembler
- level. Those optimizations are not always a good idea since this
- means the code size increases a lot. Instead the definitions here
- optimize some functions in a way which do not dramatically
- increase the code size and which do not use assembler. The main
- trick is to use GCC's `__builtin_constant_p' function.
-
- Every function XXX which has a defined version in
- <bits/string.h> must be accompanied by a symbol _HAVE_STRING_ARCH_XXX
- to make sure we don't get redefinitions.
-
- We must use here macros instead of inline functions since the
- trick won't work with the latter. */
-
-#ifndef __STRING_INLINE
-# ifdef __cplusplus
-# define __STRING_INLINE inline
-# else
-# define __STRING_INLINE __extern_inline
-# endif
-#endif
-
-#if _STRING_INLINE_unaligned
-/* If we can do unaligned memory accesses we must know the endianess. */
-# include <endian.h>
-# include <bits/types.h>
-
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define __STRING2_SMALL_GET16(src, idx) \
- (((const unsigned char *) (const char *) (src))[idx + 1] << 8 \
- | ((const unsigned char *) (const char *) (src))[idx])
-# define __STRING2_SMALL_GET32(src, idx) \
- (((((const unsigned char *) (const char *) (src))[idx + 3] << 8 \
- | ((const unsigned char *) (const char *) (src))[idx + 2]) << 8 \
- | ((const unsigned char *) (const char *) (src))[idx + 1]) << 8 \
- | ((const unsigned char *) (const char *) (src))[idx])
-# else
-# define __STRING2_SMALL_GET16(src, idx) \
- (((const unsigned char *) (const char *) (src))[idx] << 8 \
- | ((const unsigned char *) (const char *) (src))[idx + 1])
-# define __STRING2_SMALL_GET32(src, idx) \
- (((((const unsigned char *) (const char *) (src))[idx] << 8 \
- | ((const unsigned char *) (const char *) (src))[idx + 1]) << 8 \
- | ((const unsigned char *) (const char *) (src))[idx + 2]) << 8 \
- | ((const unsigned char *) (const char *) (src))[idx + 3])
-# endif
-#else
-/* These are a few types we need for the optimizations if we cannot
- use unaligned memory accesses. */
-# define __STRING2_COPY_TYPE(N) \
- typedef struct { unsigned char __arr[N]; } \
- __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
-__STRING2_COPY_TYPE (2);
-__STRING2_COPY_TYPE (3);
-__STRING2_COPY_TYPE (4);
-__STRING2_COPY_TYPE (5);
-__STRING2_COPY_TYPE (6);
-__STRING2_COPY_TYPE (7);
-__STRING2_COPY_TYPE (8);
-# undef __STRING2_COPY_TYPE
-#endif
-
-/* Dereferencing a pointer arg to run sizeof on it fails for the void
- pointer case, so we use this instead.
- Note that __x is evaluated twice. */
-#define __string2_1bptr_p(__x) \
- ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)
-
-/* Set N bytes of S to C. */
-#if !defined _HAVE_STRING_ARCH_memset
-# if !__GNUC_PREREQ (3, 0)
-# if _STRING_INLINE_unaligned
-# define memset(s, c, n) \
- (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
- ? ((n) == 1 \
- ? __memset_1 (s, c) \
- : __memset_gc (s, c, n)) \
- : (__builtin_constant_p (c) && (c) == '\0' \
- ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
- : memset (s, c, n))))
-
-# define __memset_1(s, c) ({ void *__s = (s); \
- *((__uint8_t *) __s) = (__uint8_t) c; __s; })
-
-# define __memset_gc(s, c, n) \
- ({ void *__s = (s); \
- union { \
- unsigned int __ui; \
- unsigned short int __usi; \
- unsigned char __uc; \
- } *__u = __s; \
- __uint8_t __c = (__uint8_t) (c); \
- \
- /* This `switch' statement will be removed at compile-time. */ \
- switch ((unsigned int) (n)) \
- { \
- case 15: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 11: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 7: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 3: \
- __u->__usi = (unsigned short int) __c * 0x0101; \
- __u = __extension__ ((void *) __u + 2); \
- __u->__uc = (unsigned char) __c; \
- break; \
- \
- case 14: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 10: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 6: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 2: \
- __u->__usi = (unsigned short int) __c * 0x0101; \
- break; \
- \
- case 13: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 9: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 5: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 1: \
- __u->__uc = (unsigned char) __c; \
- break; \
- \
- case 16: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 12: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 8: \
- __u->__ui = __c * 0x01010101; \
- __u = __extension__ ((void *) __u + 4); \
- case 4: \
- __u->__ui = __c * 0x01010101; \
- case 0: \
- break; \
- } \
- \
- __s; })
-# else
-# define memset(s, c, n) \
- (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
- ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
- : memset (s, c, n)))
-# endif
-# endif
-
-/* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
- The optimization is broken before EGCS 1.1.
- GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
- if it decides to call the library function, it calls memset
- and not bzero. */
-# if __GNUC_PREREQ (2, 91)
-# define __bzero(s, n) __builtin_memset (s, '\0', n)
-# endif
-
-#endif
-
-
-/* Copy N bytes from SRC to DEST, returning pointer to byte following the
- last copied. */
-#ifdef __USE_GNU
-# if !defined _HAVE_STRING_ARCH_mempcpy || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_mempcpy
-# if __GNUC_PREREQ (3, 4)
-# define __mempcpy(dest, src, n) __builtin_mempcpy (dest, src, n)
-# elif __GNUC_PREREQ (3, 0)
-# define __mempcpy(dest, src, n) \
- (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
- && __string2_1bptr_p (src) && n <= 8 \
- ? __builtin_memcpy (dest, src, n) + (n) \
- : __mempcpy (dest, src, n)))
-# else
-# define __mempcpy(dest, src, n) \
- (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
- && __string2_1bptr_p (src) && n <= 8 \
- ? __mempcpy_small (dest, __mempcpy_args (src), n) \
- : __mempcpy (dest, src, n)))
-# endif
-/* In glibc we use this function frequently but for namespace reasons
- we have to use the name `__mempcpy'. */
-# define mempcpy(dest, src, n) __mempcpy (dest, src, n)
-# endif
-
-# if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
-# if _STRING_INLINE_unaligned
-# ifndef _FORCE_INLINES
-# define __mempcpy_args(src) \
- ((const char *) (src))[0], ((const char *) (src))[2], \
- ((const char *) (src))[4], ((const char *) (src))[6], \
- __extension__ __STRING2_SMALL_GET16 (src, 0), \
- __extension__ __STRING2_SMALL_GET16 (src, 4), \
- __extension__ __STRING2_SMALL_GET32 (src, 0), \
- __extension__ __STRING2_SMALL_GET32 (src, 4)
-# endif
-__STRING_INLINE void *__mempcpy_small (void *, char, char, char, char,
- __uint16_t, __uint16_t, __uint32_t,
- __uint32_t, size_t);
-__STRING_INLINE void *
-__mempcpy_small (void *__dest1,
- char __src0_1, char __src2_1, char __src4_1, char __src6_1,
- __uint16_t __src0_2, __uint16_t __src4_2,
- __uint32_t __src0_4, __uint32_t __src4_4,
- size_t __srclen)
-{
- union {
- __uint32_t __ui;
- __uint16_t __usi;
- unsigned char __uc;
- unsigned char __c;
- } *__u = __dest1;
- switch ((unsigned int) __srclen)
- {
- case 1:
- __u->__c = __src0_1;
- __u = __extension__ ((void *) __u + 1);
- break;
- case 2:
- __u->__usi = __src0_2;
- __u = __extension__ ((void *) __u + 2);
- break;
- case 3:
- __u->__usi = __src0_2;
- __u = __extension__ ((void *) __u + 2);
- __u->__c = __src2_1;
- __u = __extension__ ((void *) __u + 1);
- break;
- case 4:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- break;
- case 5:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__c = __src4_1;
- __u = __extension__ ((void *) __u + 1);
- break;
- case 6:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__usi = __src4_2;
- __u = __extension__ ((void *) __u + 2);
- break;
- case 7:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__usi = __src4_2;
- __u = __extension__ ((void *) __u + 2);
- __u->__c = __src6_1;
- __u = __extension__ ((void *) __u + 1);
- break;
- case 8:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__ui = __src4_4;
- __u = __extension__ ((void *) __u + 4);
- break;
- }
- return (void *) __u;
-}
-# else
-# ifndef _FORCE_INLINES
-# define __mempcpy_args(src) \
- ((const char *) (src))[0], \
- __extension__ ((__STRING2_COPY_ARR2) \
- { { ((const char *) (src))[0], ((const char *) (src))[1] } }), \
- __extension__ ((__STRING2_COPY_ARR3) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2] } }), \
- __extension__ ((__STRING2_COPY_ARR4) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3] } }), \
- __extension__ ((__STRING2_COPY_ARR5) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4] } }), \
- __extension__ ((__STRING2_COPY_ARR6) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5] } }), \
- __extension__ ((__STRING2_COPY_ARR7) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5], \
- ((const char *) (src))[6] } }), \
- __extension__ ((__STRING2_COPY_ARR8) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5], \
- ((const char *) (src))[6], ((const char *) (src))[7] } })
-# endif
-__STRING_INLINE void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2,
- __STRING2_COPY_ARR3,
- __STRING2_COPY_ARR4,
- __STRING2_COPY_ARR5,
- __STRING2_COPY_ARR6,
- __STRING2_COPY_ARR7,
- __STRING2_COPY_ARR8, size_t);
-__STRING_INLINE void *
-__mempcpy_small (void *__dest, char __src1,
- __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
- __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
- __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
- __STRING2_COPY_ARR8 __src8, size_t __srclen)
-{
- union {
- char __c;
- __STRING2_COPY_ARR2 __sca2;
- __STRING2_COPY_ARR3 __sca3;
- __STRING2_COPY_ARR4 __sca4;
- __STRING2_COPY_ARR5 __sca5;
- __STRING2_COPY_ARR6 __sca6;
- __STRING2_COPY_ARR7 __sca7;
- __STRING2_COPY_ARR8 __sca8;
- } *__u = __dest;
- switch ((unsigned int) __srclen)
- {
- case 1:
- __u->__c = __src1;
- break;
- case 2:
- __extension__ __u->__sca2 = __src2;
- break;
- case 3:
- __extension__ __u->__sca3 = __src3;
- break;
- case 4:
- __extension__ __u->__sca4 = __src4;
- break;
- case 5:
- __extension__ __u->__sca5 = __src5;
- break;
- case 6:
- __extension__ __u->__sca6 = __src6;
- break;
- case 7:
- __extension__ __u->__sca7 = __src7;
- break;
- case 8:
- __extension__ __u->__sca8 = __src8;
- break;
- }
- return __extension__ ((void *) __u + __srclen);
-}
-# endif
-# endif
-# endif
-#endif
-
-
-/* Return pointer to C in S. */
-#ifndef _HAVE_STRING_ARCH_strchr
-extern void *__rawmemchr (const void *__s, int __c);
-# if __GNUC_PREREQ (3, 2)
-# define strchr(s, c) \
- (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \
- && (c) == '\0' \
- ? (char *) __rawmemchr (s, c) \
- : __builtin_strchr (s, c)))
-# else
-# define strchr(s, c) \
- (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
- ? (char *) __rawmemchr (s, c) \
- : strchr (s, c)))
-# endif
-#endif
-
-
-/* Copy SRC to DEST. */
-#if (!defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)) \
- || defined _FORCE_INLINES
-# if !defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)
-# define strcpy(dest, src) \
- (__extension__ (__builtin_constant_p (src) \
- ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
- ? __strcpy_small (dest, __strcpy_args (src), \
- strlen (src) + 1) \
- : (char *) memcpy (dest, src, strlen (src) + 1)) \
- : strcpy (dest, src)))
-# endif
-
-# if _STRING_INLINE_unaligned
-# ifndef _FORCE_INLINES
-# define __strcpy_args(src) \
- __extension__ __STRING2_SMALL_GET16 (src, 0), \
- __extension__ __STRING2_SMALL_GET16 (src, 4), \
- __extension__ __STRING2_SMALL_GET32 (src, 0), \
- __extension__ __STRING2_SMALL_GET32 (src, 4)
-# endif
-__STRING_INLINE char *__strcpy_small (char *, __uint16_t, __uint16_t,
- __uint32_t, __uint32_t, size_t);
-__STRING_INLINE char *
-__strcpy_small (char *__dest,
- __uint16_t __src0_2, __uint16_t __src4_2,
- __uint32_t __src0_4, __uint32_t __src4_4,
- size_t __srclen)
-{
- union {
- __uint32_t __ui;
- __uint16_t __usi;
- unsigned char __uc;
- } *__u = (void *) __dest;
- switch ((unsigned int) __srclen)
- {
- case 1:
- __u->__uc = '\0';
- break;
- case 2:
- __u->__usi = __src0_2;
- break;
- case 3:
- __u->__usi = __src0_2;
- __u = __extension__ ((void *) __u + 2);
- __u->__uc = '\0';
- break;
- case 4:
- __u->__ui = __src0_4;
- break;
- case 5:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__uc = '\0';
- break;
- case 6:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__usi = __src4_2;
- break;
- case 7:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__usi = __src4_2;
- __u = __extension__ ((void *) __u + 2);
- __u->__uc = '\0';
- break;
- case 8:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__ui = __src4_4;
- break;
- }
- return __dest;
-}
-# else
-# ifndef _FORCE_INLINES
-# define __strcpy_args(src) \
- __extension__ ((__STRING2_COPY_ARR2) \
- { { ((const char *) (src))[0], '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR3) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR4) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR5) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR6) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR7) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5], \
- '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR8) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5], \
- ((const char *) (src))[6], '\0' } })
-# endif
-__STRING_INLINE char *__strcpy_small (char *, __STRING2_COPY_ARR2,
- __STRING2_COPY_ARR3,
- __STRING2_COPY_ARR4,
- __STRING2_COPY_ARR5,
- __STRING2_COPY_ARR6,
- __STRING2_COPY_ARR7,
- __STRING2_COPY_ARR8, size_t);
-__STRING_INLINE char *
-__strcpy_small (char *__dest,
- __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
- __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
- __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
- __STRING2_COPY_ARR8 __src8, size_t __srclen)
-{
- union {
- char __c;
- __STRING2_COPY_ARR2 __sca2;
- __STRING2_COPY_ARR3 __sca3;
- __STRING2_COPY_ARR4 __sca4;
- __STRING2_COPY_ARR5 __sca5;
- __STRING2_COPY_ARR6 __sca6;
- __STRING2_COPY_ARR7 __sca7;
- __STRING2_COPY_ARR8 __sca8;
- } *__u = (void *) __dest;
- switch ((unsigned int) __srclen)
- {
- case 1:
- __u->__c = '\0';
- break;
- case 2:
- __extension__ __u->__sca2 = __src2;
- break;
- case 3:
- __extension__ __u->__sca3 = __src3;
- break;
- case 4:
- __extension__ __u->__sca4 = __src4;
- break;
- case 5:
- __extension__ __u->__sca5 = __src5;
- break;
- case 6:
- __extension__ __u->__sca6 = __src6;
- break;
- case 7:
- __extension__ __u->__sca7 = __src7;
- break;
- case 8:
- __extension__ __u->__sca8 = __src8;
- break;
- }
- return __dest;
-}
-# endif
-#endif
-
-
-/* Copy SRC to DEST, returning pointer to final NUL byte. */
-#ifdef __USE_GNU
-# if !defined _HAVE_STRING_ARCH_stpcpy || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_stpcpy
-# if __GNUC_PREREQ (3, 4)
-# define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
-# elif __GNUC_PREREQ (3, 0)
-# define __stpcpy(dest, src) \
- (__extension__ (__builtin_constant_p (src) \
- ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
- ? __builtin_strcpy (dest, src) + strlen (src) \
- : ((char *) (__mempcpy) (dest, src, strlen (src) + 1) \
- - 1)) \
- : __stpcpy (dest, src)))
-# else
-# define __stpcpy(dest, src) \
- (__extension__ (__builtin_constant_p (src) \
- ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
- ? __stpcpy_small (dest, __stpcpy_args (src), \
- strlen (src) + 1) \
- : ((char *) (__mempcpy) (dest, src, strlen (src) + 1) \
- - 1)) \
- : __stpcpy (dest, src)))
-# endif
-/* In glibc we use this function frequently but for namespace reasons
- we have to use the name `__stpcpy'. */
-# define stpcpy(dest, src) __stpcpy (dest, src)
-# endif
-
-# if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
-# if _STRING_INLINE_unaligned
-# ifndef _FORCE_INLINES
-# define __stpcpy_args(src) \
- __extension__ __STRING2_SMALL_GET16 (src, 0), \
- __extension__ __STRING2_SMALL_GET16 (src, 4), \
- __extension__ __STRING2_SMALL_GET32 (src, 0), \
- __extension__ __STRING2_SMALL_GET32 (src, 4)
-# endif
-__STRING_INLINE char *__stpcpy_small (char *, __uint16_t, __uint16_t,
- __uint32_t, __uint32_t, size_t);
-__STRING_INLINE char *
-__stpcpy_small (char *__dest,
- __uint16_t __src0_2, __uint16_t __src4_2,
- __uint32_t __src0_4, __uint32_t __src4_4,
- size_t __srclen)
-{
- union {
- unsigned int __ui;
- unsigned short int __usi;
- unsigned char __uc;
- char __c;
- } *__u = (void *) __dest;
- switch ((unsigned int) __srclen)
- {
- case 1:
- __u->__uc = '\0';
- break;
- case 2:
- __u->__usi = __src0_2;
- __u = __extension__ ((void *) __u + 1);
- break;
- case 3:
- __u->__usi = __src0_2;
- __u = __extension__ ((void *) __u + 2);
- __u->__uc = '\0';
- break;
- case 4:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 3);
- break;
- case 5:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__uc = '\0';
- break;
- case 6:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__usi = __src4_2;
- __u = __extension__ ((void *) __u + 1);
- break;
- case 7:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__usi = __src4_2;
- __u = __extension__ ((void *) __u + 2);
- __u->__uc = '\0';
- break;
- case 8:
- __u->__ui = __src0_4;
- __u = __extension__ ((void *) __u + 4);
- __u->__ui = __src4_4;
- __u = __extension__ ((void *) __u + 3);
- break;
- }
- return &__u->__c;
-}
-# else
-# ifndef _FORCE_INLINES
-# define __stpcpy_args(src) \
- __extension__ ((__STRING2_COPY_ARR2) \
- { { ((const char *) (src))[0], '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR3) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR4) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR5) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR6) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR7) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5], \
- '\0' } }), \
- __extension__ ((__STRING2_COPY_ARR8) \
- { { ((const char *) (src))[0], ((const char *) (src))[1], \
- ((const char *) (src))[2], ((const char *) (src))[3], \
- ((const char *) (src))[4], ((const char *) (src))[5], \
- ((const char *) (src))[6], '\0' } })
-# endif
-__STRING_INLINE char *__stpcpy_small (char *, __STRING2_COPY_ARR2,
- __STRING2_COPY_ARR3,
- __STRING2_COPY_ARR4,
- __STRING2_COPY_ARR5,
- __STRING2_COPY_ARR6,
- __STRING2_COPY_ARR7,
- __STRING2_COPY_ARR8, size_t);
-__STRING_INLINE char *
-__stpcpy_small (char *__dest,
- __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
- __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
- __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
- __STRING2_COPY_ARR8 __src8, size_t __srclen)
-{
- union {
- char __c;
- __STRING2_COPY_ARR2 __sca2;
- __STRING2_COPY_ARR3 __sca3;
- __STRING2_COPY_ARR4 __sca4;
- __STRING2_COPY_ARR5 __sca5;
- __STRING2_COPY_ARR6 __sca6;
- __STRING2_COPY_ARR7 __sca7;
- __STRING2_COPY_ARR8 __sca8;
- } *__u = (void *) __dest;
- switch ((unsigned int) __srclen)
- {
- case 1:
- __u->__c = '\0';
- break;
- case 2:
- __extension__ __u->__sca2 = __src2;
- break;
- case 3:
- __extension__ __u->__sca3 = __src3;
- break;
- case 4:
- __extension__ __u->__sca4 = __src4;
- break;
- case 5:
- __extension__ __u->__sca5 = __src5;
- break;
- case 6:
- __extension__ __u->__sca6 = __src6;
- break;
- case 7:
- __extension__ __u->__sca7 = __src7;
- break;
- case 8:
- __extension__ __u->__sca8 = __src8;
- break;
- }
- return __dest + __srclen - 1;
-}
-# endif
-# endif
-# endif
-#endif
-
-
-/* Copy no more than N characters of SRC to DEST. */
-#ifndef _HAVE_STRING_ARCH_strncpy
-# if __GNUC_PREREQ (3, 2)
-# define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)
-# else
-# define strncpy(dest, src, n) \
- (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
- ? (strlen (src) + 1 >= ((size_t) (n)) \
- ? (char *) memcpy (dest, src, n) \
- : strncpy (dest, src, n)) \
- : strncpy (dest, src, n)))
-# endif
-#endif
-
-
-/* Append no more than N characters from SRC onto DEST. */
-#ifndef _HAVE_STRING_ARCH_strncat
-# ifdef _USE_STRING_ARCH_strchr
-# define strncat(dest, src, n) \
- (__extension__ ({ char *__dest = (dest); \
- __builtin_constant_p (src) && __builtin_constant_p (n) \
- ? (strlen (src) < ((size_t) (n)) \
- ? strcat (__dest, src) \
- : (*((char *) __mempcpy (strchr (__dest, '\0'), \
- src, n)) = '\0', __dest)) \
- : strncat (dest, src, n); }))
-# elif __GNUC_PREREQ (3, 2)
-# define strncat(dest, src, n) __builtin_strncat (dest, src, n)
-# else
-# define strncat(dest, src, n) \
- (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
- ? (strlen (src) < ((size_t) (n)) \
- ? strcat (dest, src) \
- : strncat (dest, src, n)) \
- : strncat (dest, src, n)))
-# endif
-#endif
-
-
-/* Compare characters of S1 and S2. */
-#ifndef _HAVE_STRING_ARCH_strcmp
-# if __GNUC_PREREQ (3, 2)
-# define strcmp(s1, s2) \
- __extension__ \
- ({ size_t __s1_len, __s2_len; \
- (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
- && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
- (!__string2_1bptr_p (s1) || __s1_len >= 4) \
- && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
- ? __builtin_strcmp (s1, s2) \
- : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
- && (__s1_len = strlen (s1), __s1_len < 4) \
- ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
- ? __builtin_strcmp (s1, s2) \
- : __strcmp_cg (s1, s2, __s1_len)) \
- : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
- && (__s2_len = strlen (s2), __s2_len < 4) \
- ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
- ? __builtin_strcmp (s1, s2) \
- : __strcmp_gc (s1, s2, __s2_len)) \
- : __builtin_strcmp (s1, s2)))); })
-# else
-# define strcmp(s1, s2) \
- __extension__ \
- ({ size_t __s1_len, __s2_len; \
- (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
- && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
- (!__string2_1bptr_p (s1) || __s1_len >= 4) \
- && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
- ? memcmp ((const char *) (s1), (const char *) (s2), \
- (__s1_len < __s2_len ? __s1_len : __s2_len) + 1) \
- : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
- && (__s1_len = strlen (s1), __s1_len < 4) \
- ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
- ? __strcmp_cc (s1, s2, __s1_len) \
- : __strcmp_cg (s1, s2, __s1_len)) \
- : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
- && (__s2_len = strlen (s2), __s2_len < 4) \
- ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
- ? __strcmp_cc (s1, s2, __s2_len) \
- : __strcmp_gc (s1, s2, __s2_len)) \
- : strcmp (s1, s2)))); })
-# endif
-
-# define __strcmp_cc(s1, s2, l) \
- (__extension__ ({ int __result = \
- (((const unsigned char *) (const char *) (s1))[0] \
- - ((const unsigned char *) (const char *)(s2))[0]); \
- if (l > 0 && __result == 0) \
- { \
- __result = (((const unsigned char *) \
- (const char *) (s1))[1] \
- - ((const unsigned char *) \
- (const char *) (s2))[1]); \
- if (l > 1 && __result == 0) \
- { \
- __result = \
- (((const unsigned char *) \
- (const char *) (s1))[2] \
- - ((const unsigned char *) \
- (const char *) (s2))[2]); \
- if (l > 2 && __result == 0) \
- __result = \
- (((const unsigned char *) \
- (const char *) (s1))[3] \
- - ((const unsigned char *) \
- (const char *) (s2))[3]); \
- } \
- } \
- __result; }))
-
-# define __strcmp_cg(s1, s2, l1) \
- (__extension__ ({ const unsigned char *__s2 = \
- (const unsigned char *) (const char *) (s2); \
- int __result = \
- (((const unsigned char *) (const char *) (s1))[0] \
- - __s2[0]); \
- if (l1 > 0 && __result == 0) \
- { \
- __result = (((const unsigned char *) \
- (const char *) (s1))[1] - __s2[1]); \
- if (l1 > 1 && __result == 0) \
- { \
- __result = (((const unsigned char *) \
- (const char *) (s1))[2] - __s2[2]); \
- if (l1 > 2 && __result == 0) \
- __result = (((const unsigned char *) \
- (const char *) (s1))[3] \
- - __s2[3]); \
- } \
- } \
- __result; }))
-
-# define __strcmp_gc(s1, s2, l2) (- __strcmp_cg (s2, s1, l2))
-#endif
-
-
-/* Compare N characters of S1 and S2. */
-#ifndef _HAVE_STRING_ARCH_strncmp
-# define strncmp(s1, s2, n) \
- (__extension__ (__builtin_constant_p (n) \
- && ((__builtin_constant_p (s1) \
- && strlen (s1) < ((size_t) (n))) \
- || (__builtin_constant_p (s2) \
- && strlen (s2) < ((size_t) (n)))) \
- ? strcmp (s1, s2) : strncmp (s1, s2, n)))
-#endif
-
-
-/* Return the length of the initial segment of S which
- consists entirely of characters not in REJECT. */
-#if !defined _HAVE_STRING_ARCH_strcspn || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_strcspn
-# if __GNUC_PREREQ (3, 2)
-# define strcspn(s, reject) \
- __extension__ \
- ({ char __r0, __r1, __r2; \
- (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
- ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
- ? __builtin_strcspn (s, reject) \
- : ((__r0 = ((const char *) (reject))[0], __r0 == '\0') \
- ? strlen (s) \
- : ((__r1 = ((const char *) (reject))[1], __r1 == '\0') \
- ? __strcspn_c1 (s, __r0) \
- : ((__r2 = ((const char *) (reject))[2], __r2 == '\0') \
- ? __strcspn_c2 (s, __r0, __r1) \
- : (((const char *) (reject))[3] == '\0' \
- ? __strcspn_c3 (s, __r0, __r1, __r2) \
- : __builtin_strcspn (s, reject)))))) \
- : __builtin_strcspn (s, reject)); })
-# else
-# define strcspn(s, reject) \
- __extension__ \
- ({ char __r0, __r1, __r2; \
- (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
- ? ((__r0 = ((const char *) (reject))[0], __r0 == '\0') \
- ? strlen (s) \
- : ((__r1 = ((const char *) (reject))[1], __r1 == '\0') \
- ? __strcspn_c1 (s, __r0) \
- : ((__r2 = ((const char *) (reject))[2], __r2 == '\0') \
- ? __strcspn_c2 (s, __r0, __r1) \
- : (((const char *) (reject))[3] == '\0' \
- ? __strcspn_c3 (s, __r0, __r1, __r2) \
- : strcspn (s, reject))))) \
- : strcspn (s, reject)); })
-# endif
-# endif
-
-__STRING_INLINE size_t __strcspn_c1 (const char *__s, int __reject);
-__STRING_INLINE size_t
-__strcspn_c1 (const char *__s, int __reject)
-{
- size_t __result = 0;
- while (__s[__result] != '\0' && __s[__result] != __reject)
- ++__result;
- return __result;
-}
-
-__STRING_INLINE size_t __strcspn_c2 (const char *__s, int __reject1,
- int __reject2);
-__STRING_INLINE size_t
-__strcspn_c2 (const char *__s, int __reject1, int __reject2)
-{
- size_t __result = 0;
- while (__s[__result] != '\0' && __s[__result] != __reject1
- && __s[__result] != __reject2)
- ++__result;
- return __result;
-}
-
-__STRING_INLINE size_t __strcspn_c3 (const char *__s, int __reject1,
- int __reject2, int __reject3);
-__STRING_INLINE size_t
-__strcspn_c3 (const char *__s, int __reject1, int __reject2,
- int __reject3)
-{
- size_t __result = 0;
- while (__s[__result] != '\0' && __s[__result] != __reject1
- && __s[__result] != __reject2 && __s[__result] != __reject3)
- ++__result;
- return __result;
-}
-#endif
-
-
-/* Return the length of the initial segment of S which
- consists entirely of characters in ACCEPT. */
-#if !defined _HAVE_STRING_ARCH_strspn || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_strspn
-# if __GNUC_PREREQ (3, 2)
-# define strspn(s, accept) \
- __extension__ \
- ({ char __a0, __a1, __a2; \
- (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
- ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
- ? __builtin_strspn (s, accept) \
- : ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
- ? ((void) (s), (size_t) 0) \
- : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
- ? __strspn_c1 (s, __a0) \
- : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
- ? __strspn_c2 (s, __a0, __a1) \
- : (((const char *) (accept))[3] == '\0' \
- ? __strspn_c3 (s, __a0, __a1, __a2) \
- : __builtin_strspn (s, accept)))))) \
- : __builtin_strspn (s, accept)); })
-# else
-# define strspn(s, accept) \
- __extension__ \
- ({ char __a0, __a1, __a2; \
- (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
- ? ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
- ? ((void) (s), (size_t) 0) \
- : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
- ? __strspn_c1 (s, __a0) \
- : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
- ? __strspn_c2 (s, __a0, __a1) \
- : (((const char *) (accept))[3] == '\0' \
- ? __strspn_c3 (s, __a0, __a1, __a2) \
- : strspn (s, accept))))) \
- : strspn (s, accept)); })
-# endif
-# endif
-
-__STRING_INLINE size_t __strspn_c1 (const char *__s, int __accept);
-__STRING_INLINE size_t
-__strspn_c1 (const char *__s, int __accept)
-{
- size_t __result = 0;
- /* Please note that __accept never can be '\0'. */
- while (__s[__result] == __accept)
- ++__result;
- return __result;
-}
-
-__STRING_INLINE size_t __strspn_c2 (const char *__s, int __accept1,
- int __accept2);
-__STRING_INLINE size_t
-__strspn_c2 (const char *__s, int __accept1, int __accept2)
-{
- size_t __result = 0;
- /* Please note that __accept1 and __accept2 never can be '\0'. */
- while (__s[__result] == __accept1 || __s[__result] == __accept2)
- ++__result;
- return __result;
-}
-
-__STRING_INLINE size_t __strspn_c3 (const char *__s, int __accept1,
- int __accept2, int __accept3);
-__STRING_INLINE size_t
-__strspn_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
-{
- size_t __result = 0;
- /* Please note that __accept1 to __accept3 never can be '\0'. */
- while (__s[__result] == __accept1 || __s[__result] == __accept2
- || __s[__result] == __accept3)
- ++__result;
- return __result;
-}
-#endif
-
-
-/* Find the first occurrence in S of any character in ACCEPT. */
-#if !defined _HAVE_STRING_ARCH_strpbrk || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_strpbrk
-# if __GNUC_PREREQ (3, 2)
-# define strpbrk(s, accept) \
- __extension__ \
- ({ char __a0, __a1, __a2; \
- (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
- ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
- ? __builtin_strpbrk (s, accept) \
- : ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
- ? ((void) (s), (char *) NULL) \
- : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
- ? __builtin_strchr (s, __a0) \
- : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
- ? __strpbrk_c2 (s, __a0, __a1) \
- : (((const char *) (accept))[3] == '\0' \
- ? __strpbrk_c3 (s, __a0, __a1, __a2) \
- : __builtin_strpbrk (s, accept)))))) \
- : __builtin_strpbrk (s, accept)); })
-# else
-# define strpbrk(s, accept) \
- __extension__ \
- ({ char __a0, __a1, __a2; \
- (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
- ? ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
- ? ((void) (s), (char *) NULL) \
- : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
- ? strchr (s, __a0) \
- : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
- ? __strpbrk_c2 (s, __a0, __a1) \
- : (((const char *) (accept))[3] == '\0' \
- ? __strpbrk_c3 (s, __a0, __a1, __a2) \
- : strpbrk (s, accept))))) \
- : strpbrk (s, accept)); })
-# endif
-# endif
-
-__STRING_INLINE char *__strpbrk_c2 (const char *__s, int __accept1,
- int __accept2);
-__STRING_INLINE char *
-__strpbrk_c2 (const char *__s, int __accept1, int __accept2)
-{
- /* Please note that __accept1 and __accept2 never can be '\0'. */
- while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
- ++__s;
- return *__s == '\0' ? NULL : (char *) (size_t) __s;
-}
-
-__STRING_INLINE char *__strpbrk_c3 (const char *__s, int __accept1,
- int __accept2, int __accept3);
-__STRING_INLINE char *
-__strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
-{
- /* Please note that __accept1 to __accept3 never can be '\0'. */
- while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
- && *__s != __accept3)
- ++__s;
- return *__s == '\0' ? NULL : (char *) (size_t) __s;
-}
-#endif
-
-
-/* Find the first occurrence of NEEDLE in HAYSTACK. Newer gcc versions
- do this itself. */
-#if !defined _HAVE_STRING_ARCH_strstr && !__GNUC_PREREQ (2, 97)
-# define strstr(haystack, needle) \
- (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
- ? (((const char *) (needle))[0] == '\0' \
- ? (char *) (size_t) (haystack) \
- : (((const char *) (needle))[1] == '\0' \
- ? strchr (haystack, \
- ((const char *) (needle))[0]) \
- : strstr (haystack, needle))) \
- : strstr (haystack, needle)))
-#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
-
-extern char *__strsep_g (char **__stringp, const char *__delim);
-# define __strsep(s, reject) \
- __extension__ \
- ({ char __r0, __r1, __r2; \
- (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
- && (__r0 = ((const char *) (reject))[0], \
- ((const char *) (reject))[0] != '\0') \
- ? ((__r1 = ((const char *) (reject))[1], \
- ((const char *) (reject))[1] == '\0') \
- ? __strsep_1c (s, __r0) \
- : ((__r2 = ((const char *) (reject))[2], __r2 == '\0') \
- ? __strsep_2c (s, __r0, __r1) \
- : (((const char *) (reject))[3] == '\0' \
- ? __strsep_3c (s, __r0, __r1, __r2) \
- : __strsep_g (s, reject)))) \
- : __strsep_g (s, reject)); })
-# endif
-
-__STRING_INLINE char *__strsep_1c (char **__s, char __reject);
-__STRING_INLINE char *
-__strsep_1c (char **__s, char __reject)
-{
- char *__retval = *__s;
- if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
- *(*__s)++ = '\0';
- return __retval;
-}
-
-__STRING_INLINE char *__strsep_2c (char **__s, char __reject1, char __reject2);
-__STRING_INLINE char *
-__strsep_2c (char **__s, char __reject1, char __reject2)
-{
- char *__retval = *__s;
- if (__retval != NULL)
- {
- char *__cp = __retval;
- while (1)
- {
- if (*__cp == '\0')
- {
- __cp = NULL;
- break;
- }
- if (*__cp == __reject1 || *__cp == __reject2)
- {
- *__cp++ = '\0';
- break;
- }
- ++__cp;
- }
- *__s = __cp;
- }
- return __retval;
-}
-
-__STRING_INLINE char *__strsep_3c (char **__s, char __reject1, char __reject2,
- char __reject3);
-__STRING_INLINE char *
-__strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
-{
- char *__retval = *__s;
- if (__retval != NULL)
- {
- char *__cp = __retval;
- while (1)
- {
- if (*__cp == '\0')
- {
- __cp = NULL;
- break;
- }
- if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
- {
- *__cp++ = '\0';
- break;
- }
- ++__cp;
- }
- *__s = __cp;
- }
- return __retval;
-}
-# ifdef __USE_MISC
-# define strsep(s, reject) __strsep (s, reject)
-# endif
-#endif
-
-/* We need the memory allocation functions for inline strdup().
- Referring to stdlib.h (even minimally) is not allowed
- in any of the tight standards compliant modes. */
-#ifdef __USE_MISC
-
-# if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup
-# define __need_malloc_and_calloc
-# include <stdlib.h>
-# endif
-
-# ifndef _HAVE_STRING_ARCH_strdup
-
-extern char *__strdup (const char *__string) __THROW __attribute_malloc__;
-# define __strdup(s) \
- (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
- ? (((const char *) (s))[0] == '\0' \
- ? (char *) calloc ((size_t) 1, (size_t) 1) \
- : ({ size_t __len = strlen (s) + 1; \
- char *__retval = (char *) malloc (__len); \
- if (__retval != NULL) \
- __retval = (char *) memcpy (__retval, s, __len); \
- __retval; })) \
- : __strdup (s)))
-
-# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
-# define strdup(s) __strdup (s)
-# endif
-# endif
-
-# ifndef _HAVE_STRING_ARCH_strndup
-
-extern char *__strndup (const char *__string, size_t __n)
- __THROW __attribute_malloc__;
-# define __strndup(s, n) \
- (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
- ? (((const char *) (s))[0] == '\0' \
- ? (char *) calloc ((size_t) 1, (size_t) 1) \
- : ({ size_t __len = strlen (s) + 1; \
- size_t __n = (n); \
- char *__retval; \
- if (__n < __len) \
- __len = __n + 1; \
- __retval = (char *) malloc (__len); \
- if (__retval != NULL) \
- { \
- __retval[__len - 1] = '\0'; \
- __retval = (char *) memcpy (__retval, s, \
- __len - 1); \
- } \
- __retval; })) \
- : __strndup (s, n)))
-
-# ifdef __USE_XOPEN2K8
-# define strndup(s, n) __strndup (s, n)
-# endif
-# endif
-
-#endif /* Use misc. or use GNU. */
-
-#ifndef _FORCE_INLINES
-# undef __STRING_INLINE
-#endif
-
-#endif /* No string inlines. */
diff --git a/string/bits/string3.h b/string/bits/string_fortified.h
index dd8db68aa2..a07ab0dbc8 100644
--- a/string/bits/string3.h
+++ b/string/bits/string_fortified.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 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
@@ -15,8 +15,11 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#ifndef _BITS_STRING_FORTIFIED_H
+#define _BITS_STRING_FORTIFIED_H 1
+
#ifndef _STRING_H
-# error "Never use <bits/string3.h> directly; include <string.h> instead."
+# error "Never use <bits/string_fortified.h> directly; include <string.h> instead."
#endif
#if !__GNUC_PREREQ (5,0)
@@ -24,28 +27,6 @@ __warndecl (__warn_memset_zero_len,
"memset used with constant zero length parameter; this could be due to transposed parameters");
#endif
-#ifndef __cplusplus
-/* XXX This is temporarily. We should not redefine any of the symbols
- and instead integrate the error checking into the original
- definitions. */
-# undef memcpy
-# undef memmove
-# undef memset
-# undef strcat
-# undef strcpy
-# undef strncat
-# undef strncpy
-# ifdef __USE_GNU
-# undef mempcpy
-# undef stpcpy
-# endif
-# ifdef __USE_MISC
-# undef bcopy
-# undef bzero
-# endif
-#endif
-
-
__fortify_function void *
__NTH (memcpy (void *__restrict __dest, const void *__restrict __src,
size_t __len))
@@ -91,16 +72,15 @@ __NTH (memset (void *__dest, int __ch, size_t __len))
}
#ifdef __USE_MISC
-__fortify_function void
-__NTH (bcopy (const void *__src, void *__dest, size_t __len))
-{
- (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
-}
+# include <bits/strings_fortified.h>
+
+void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen)
+ __THROW __nonnull ((1));
__fortify_function void
-__NTH (bzero (void *__dest, size_t __len))
+__NTH (explicit_bzero (void *__dest, size_t __len))
{
- (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest));
+ __explicit_bzero_chk (__dest, __len, __bos0 (__dest));
}
#endif
@@ -126,7 +106,7 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
}
-// XXX We have no corresponding builtin yet.
+/* XXX We have no corresponding builtin yet. */
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
size_t __destlen) __THROW;
extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src,
@@ -155,3 +135,5 @@ __NTH (strncat (char *__restrict __dest, const char *__restrict __src,
{
return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
}
+
+#endif /* bits/string_fortified.h */
diff --git a/string/bits/strings_fortified.h b/string/bits/strings_fortified.h
new file mode 100644
index 0000000000..d9b2804525
--- /dev/null
+++ b/string/bits/strings_fortified.h
@@ -0,0 +1,34 @@
+/* Fortify macros for strings.h functions.
+ Copyright (C) 2017-2018 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/>. */
+
+#ifndef __STRINGS_FORTIFIED
+# define __STRINGS_FORTIFIED 1
+
+__fortify_function void
+__NTH (bcopy (const void *__src, void *__dest, size_t __len))
+{
+ (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+
+__fortify_function void
+__NTH (bzero (void *__dest, size_t __len))
+{
+ (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest));
+}
+
+#endif
diff --git a/string/bug-envz1.c b/string/bug-envz1.c
index e8a60972b5..931a0559fe 100644
--- a/string/bug-envz1.c
+++ b/string/bug-envz1.c
@@ -25,7 +25,7 @@ static const struct
#define nstrs (sizeof (strs) / sizeof (strs[0]))
-static int
+int
do_test (void)
{
@@ -72,5 +72,4 @@ do_test (void)
return result;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/bug-strcoll2.c b/string/bug-strcoll2.c
index 870d51e50c..ff4595eb62 100644
--- a/string/bug-strcoll2.c
+++ b/string/bug-strcoll2.c
@@ -1,5 +1,5 @@
/* Bug 18589: sort-test.sh fails at random.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 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
@@ -79,7 +79,7 @@ test_da_DK (void)
}
}
-static int
+int
do_test (void)
{
int err = 0;
@@ -88,5 +88,4 @@ do_test (void)
return err;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/bug-strncat1.c b/string/bug-strncat1.c
index f1b5c37c5c..b22beba4d3 100644
--- a/string/bug-strncat1.c
+++ b/string/bug-strncat1.c
@@ -4,13 +4,21 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <libc-diag.h>
char d[3] = "\0\1\2";
int
main (void)
{
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (8, 0)
+ /* GCC 8 warns about strncat truncating output; this is deliberately
+ tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+#endif
strncat (d, "\5\6", 1);
+ DIAG_POP_NEEDS_COMMENT;
if (d[0] != '\5')
{
puts ("d[0] != '\\5'");
diff --git a/string/bug-strpbrk1.c b/string/bug-strpbrk1.c
index 28238b0f50..8e909a1e21 100644
--- a/string/bug-strpbrk1.c
+++ b/string/bug-strpbrk1.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <libc-diag.h>
int
main (void)
@@ -11,7 +12,14 @@ main (void)
const char *a = "abc";
const char *b = a;
+ DIAG_PUSH_NEEDS_COMMENT;
+ /* GCC 9 correctly warns that this call to strpbrk is useless. That
+ is deliberate; this test is verifying that a side effect in an
+ argument still occurs when the call itself is useless and could
+ be optimized to return a constant. */
+ DIAG_IGNORE_NEEDS_COMMENT (9, "-Wunused-value");
strpbrk (b++, "");
+ DIAG_POP_NEEDS_COMMENT;
if (b != a + 1)
return 1;
diff --git a/string/bug-strspn1.c b/string/bug-strspn1.c
index a657bafc43..e3487ab8f9 100644
--- a/string/bug-strspn1.c
+++ b/string/bug-strspn1.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <libc-diag.h>
int
main (void)
@@ -11,7 +12,14 @@ main (void)
const char *a = "abc";
const char *b = a;
+ DIAG_PUSH_NEEDS_COMMENT;
+ /* GCC 9 correctly warns that this call to strspn is useless. That
+ is deliberate; this test is verifying that a side effect in an
+ argument still occurs when the call itself is useless and could
+ be optimized to return a constant. */
+ DIAG_IGNORE_NEEDS_COMMENT (9, "-Wunused-value");
strspn (b++, "");
+ DIAG_POP_NEEDS_COMMENT;
if (b != a + 1)
return 1;
diff --git a/string/bug-strtok1.c b/string/bug-strtok1.c
index da30acf2e6..a47b2f3531 100644
--- a/string/bug-strtok1.c
+++ b/string/bug-strtok1.c
@@ -2,7 +2,7 @@
#include <string.h>
#include <stdio.h>
-static int
+int
do_test (void)
{
const char str[] = "axaaba";
@@ -41,5 +41,4 @@ do_test (void)
return result;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/byteswap.h b/string/byteswap.h
index d98618c67e..a45b3e20ed 100644
--- a/string/byteswap.h
+++ b/string/byteswap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2018 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
diff --git a/string/bzero.c b/string/bzero.c
index f2b3d0fd09..30e4940562 100644
--- a/string/bzero.c
+++ b/string/bzero.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/endian.h b/string/endian.h
index b13ddaa7ad..9c9ec17f49 100644
--- a/string/endian.h
+++ b/string/endian.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 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
@@ -58,37 +58,38 @@
#if defined __USE_MISC && !defined __ASSEMBLER__
/* Conversion interfaces. */
# include <bits/byteswap.h>
+# include <bits/uintn-identity.h>
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htobe16(x) __bswap_16 (x)
-# define htole16(x) (x)
+# define htole16(x) __uint16_identity (x)
# define be16toh(x) __bswap_16 (x)
-# define le16toh(x) (x)
+# define le16toh(x) __uint16_identity (x)
# define htobe32(x) __bswap_32 (x)
-# define htole32(x) (x)
+# define htole32(x) __uint32_identity (x)
# define be32toh(x) __bswap_32 (x)
-# define le32toh(x) (x)
+# define le32toh(x) __uint32_identity (x)
# define htobe64(x) __bswap_64 (x)
-# define htole64(x) (x)
+# define htole64(x) __uint64_identity (x)
# define be64toh(x) __bswap_64 (x)
-# define le64toh(x) (x)
+# define le64toh(x) __uint64_identity (x)
# else
-# define htobe16(x) (x)
+# define htobe16(x) __uint16_identity (x)
# define htole16(x) __bswap_16 (x)
-# define be16toh(x) (x)
+# define be16toh(x) __uint16_identity (x)
# define le16toh(x) __bswap_16 (x)
-# define htobe32(x) (x)
+# define htobe32(x) __uint32_identity (x)
# define htole32(x) __bswap_32 (x)
-# define be32toh(x) (x)
+# define be32toh(x) __uint32_identity (x)
# define le32toh(x) __bswap_32 (x)
-# define htobe64(x) (x)
+# define htobe64(x) __uint64_identity (x)
# define htole64(x) __bswap_64 (x)
-# define be64toh(x) (x)
+# define be64toh(x) __uint64_identity (x)
# define le64toh(x) __bswap_64 (x)
# endif
#endif
diff --git a/string/envz.c b/string/envz.c
index 68343f3d45..3a494deed9 100644
--- a/string/envz.c
+++ b/string/envz.c
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated environment vectors
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.org>
diff --git a/string/envz.h b/string/envz.h
index 1f75f3de52..fb4a6d2e4a 100644
--- a/string/envz.h
+++ b/string/envz.h
@@ -1,5 +1,5 @@
/* Routines for dealing with '\0' separated environment vectors
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 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
diff --git a/string/explicit_bzero.c b/string/explicit_bzero.c
new file mode 100644
index 0000000000..7ba3f0f62c
--- /dev/null
+++ b/string/explicit_bzero.c
@@ -0,0 +1,38 @@
+/* Erasure of sensitive data, generic implementation.
+ Copyright (C) 2016-2018 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/>. */
+
+/* An assembler implementation of explicit_bzero can be created as an
+ assembler alias of an optimized bzero implementation.
+ Architecture-specific implementations also need to define
+ __explicit_bzero_chk. */
+
+#include <string.h>
+
+/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero
+ redirects to that. */
+#undef explicit_bzero
+
+/* Set LEN bytes of S to 0. The compiler will not delete a call to
+ this function, even if S is dead after the call. */
+void
+explicit_bzero (void *s, size_t len)
+{
+ memset (s, '\0', len);
+ /* Compiler barrier. */
+ asm volatile ("" ::: "memory");
+}
diff --git a/string/ffs.c b/string/ffs.c
index 9294750031..759039aab2 100644
--- a/string/ffs.c
+++ b/string/ffs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/ffsll.c b/string/ffsll.c
index 6bddc55278..fe57f60cfd 100644
--- a/string/ffsll.c
+++ b/string/ffsll.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/memccpy.c b/string/memccpy.c
index 58da4d3ed5..906a94d87c 100644
--- a/string/memccpy.c
+++ b/string/memccpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/memchr.c b/string/memchr.c
index ca9fd99f21..c4e21b86f1 100644
--- a/string/memchr.c
+++ b/string/memchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
diff --git a/string/memcmp.c b/string/memcmp.c
index 135bb689ec..aea5129917 100644
--- a/string/memcmp.c
+++ b/string/memcmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
@@ -20,9 +20,6 @@
# include "config.h"
#endif
-#undef __ptr_t
-#define __ptr_t void *
-
#if defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#endif
@@ -301,7 +298,7 @@ memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
}
int
-MEMCMP (const __ptr_t s1, const __ptr_t s2, size_t len)
+MEMCMP (const void *s1, const void *s2, size_t len)
{
op_t a0;
op_t b0;
diff --git a/string/memcpy.c b/string/memcpy.c
index e4aa4dd208..ecfa221847 100644
--- a/string/memcpy.c
+++ b/string/memcpy.c
@@ -1,6 +1,6 @@
/* Copy memory to memory until the specified number of bytes
has been copied. Overlap is NOT handled correctly.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/memfrob.c b/string/memfrob.c
index d14ef5606c..ddf755c768 100644
--- a/string/memfrob.c
+++ b/string/memfrob.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 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
diff --git a/string/memmem.c b/string/memmem.c
index d4083dccc0..43efaa3fb7 100644
--- a/string/memmem.c
+++ b/string/memmem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -31,6 +31,7 @@
#define RETURN_TYPE void *
#define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l))
+#define FASTSEARCH(S,C,N) (void*) memchr ((void *)(S), (C), (N))
#include "str-two-way.h"
#undef memmem
diff --git a/string/memmove.c b/string/memmove.c
index f0a145eacd..6b9321bf4c 100644
--- a/string/memmove.c
+++ b/string/memmove.c
@@ -1,6 +1,6 @@
/* Copy memory to memory until the specified number of bytes
has been copied. Overlap is handled correctly.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/memory.h b/string/memory.h
index 10ecaa24ba..ed67bb9a9b 100644
--- a/string/memory.h
+++ b/string/memory.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/mempcpy.c b/string/mempcpy.c
index b39a00cec7..5883e17d75 100644
--- a/string/mempcpy.c
+++ b/string/mempcpy.c
@@ -1,7 +1,7 @@
/* Copy memory to memory until the specified number of bytes
has been copied, return pointer to following byte.
Overlap is NOT handled correctly.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/memrchr.c b/string/memrchr.c
index b9b0c9e802..191b89a229 100644
--- a/string/memrchr.c
+++ b/string/memrchr.c
@@ -1,5 +1,5 @@
/* memrchr -- find the last occurrence of a byte in a memory block
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
@@ -27,9 +27,6 @@
# include <config.h>
#endif
-#undef __ptr_t
-#define __ptr_t void *
-
#if defined _LIBC
# include <string.h>
# include <memcopy.h>
@@ -55,13 +52,13 @@
#endif
/* Search no more than N bytes of S for C. */
-__ptr_t
+void *
#ifndef MEMRCHR
__memrchr
#else
MEMRCHR
#endif
- (const __ptr_t s, int c_in, size_t n)
+ (const void *s, int c_in, size_t n)
{
const unsigned char *char_ptr;
const unsigned long int *longword_ptr;
@@ -77,7 +74,7 @@ MEMRCHR
& (sizeof (longword) - 1)) != 0;
--n)
if (*--char_ptr == c)
- return (__ptr_t) char_ptr;
+ return (void *) char_ptr;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to 8-byte longwords. */
@@ -162,22 +159,22 @@ MEMRCHR
#if LONG_MAX > 2147483647
if (cp[7] == c)
- return (__ptr_t) &cp[7];
+ return (void *) &cp[7];
if (cp[6] == c)
- return (__ptr_t) &cp[6];
+ return (void *) &cp[6];
if (cp[5] == c)
- return (__ptr_t) &cp[5];
+ return (void *) &cp[5];
if (cp[4] == c)
- return (__ptr_t) &cp[4];
+ return (void *) &cp[4];
#endif
if (cp[3] == c)
- return (__ptr_t) &cp[3];
+ return (void *) &cp[3];
if (cp[2] == c)
- return (__ptr_t) &cp[2];
+ return (void *) &cp[2];
if (cp[1] == c)
- return (__ptr_t) &cp[1];
+ return (void *) &cp[1];
if (cp[0] == c)
- return (__ptr_t) cp;
+ return (void *) cp;
}
n -= sizeof (longword);
@@ -188,7 +185,7 @@ MEMRCHR
while (n-- > 0)
{
if (*--char_ptr == c)
- return (__ptr_t) char_ptr;
+ return (void *) char_ptr;
}
return 0;
diff --git a/string/memset.c b/string/memset.c
index a17f1a0d5b..9e56bb62ae 100644
--- a/string/memset.c
+++ b/string/memset.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/rawmemchr.c b/string/rawmemchr.c
index fa3176d6ac..2ef0c47752 100644
--- a/string/rawmemchr.c
+++ b/string/rawmemchr.c
@@ -1,10 +1,5 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
- with help from Dan Sahlin (dan@sics.se) and
- commentary by Jim Blandy (jimb@ai.mit.edu);
- adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
- and implemented by Roland McGrath (roland@ai.mit.edu).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -20,157 +15,27 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#undef __ptr_t
-#define __ptr_t void *
-
-#if defined (_LIBC)
-# include <string.h>
-# include <memcopy.h>
-# include <stdlib.h>
-#endif
-
-#if defined (HAVE_LIMITS_H) || defined (_LIBC)
-# include <limits.h>
-#endif
-
-#define LONG_MAX_32_BITS 2147483647
-
-#ifndef LONG_MAX
-#define LONG_MAX LONG_MAX_32_BITS
-#endif
-
-#include <sys/types.h>
-
-#undef memchr
+#include <string.h>
+#include <libc-diag.h>
#ifndef RAWMEMCHR
# define RAWMEMCHR __rawmemchr
#endif
/* Find the first occurrence of C in S. */
-__ptr_t
-RAWMEMCHR (const __ptr_t s, int c_in)
+void *
+RAWMEMCHR (const void *s, int c)
{
- const unsigned char *char_ptr;
- const unsigned long int *longword_ptr;
- unsigned long int longword, magic_bits, charmask;
- unsigned char c;
-
- c = (unsigned char) c_in;
-
- /* Handle the first few characters by reading one character at a time.
- Do this until CHAR_PTR is aligned on a longword boundary. */
- for (char_ptr = (const unsigned char *) s;
- ((unsigned long int) char_ptr & (sizeof (longword) - 1)) != 0;
- ++char_ptr)
- if (*char_ptr == c)
- return (__ptr_t) char_ptr;
-
- /* All these elucidatory comments refer to 4-byte longwords,
- but the theory applies equally well to 8-byte longwords. */
-
- longword_ptr = (unsigned long int *) char_ptr;
-
- /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
- the "holes." Note that there is a hole just to the left of
- each byte, with an extra at the end:
-
- bits: 01111110 11111110 11111110 11111111
- bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
-
- The 1-bits make sure that carries propagate to the next 0-bit.
- The 0-bits provide holes for carries to fall into. */
- magic_bits = -1;
- magic_bits = magic_bits / 0xff * 0xfe << 1 >> 1 | 1;
-
- /* Set up a longword, each of whose bytes is C. */
- charmask = c | (c << 8);
- charmask |= charmask << 16;
-#if LONG_MAX > LONG_MAX_32_BITS
- charmask |= charmask << 32;
-#endif
-
- /* Instead of the traditional loop which tests each character,
- we will test a longword at a time. The tricky part is testing
- if *any of the four* bytes in the longword in question are zero. */
- while (1)
- {
- /* We tentatively exit the loop if adding MAGIC_BITS to
- LONGWORD fails to change any of the hole bits of LONGWORD.
-
- 1) Is this safe? Will it catch all the zero bytes?
- Suppose there is a byte with all zeros. Any carry bits
- propagating from its left will fall into the hole at its
- least significant bit and stop. Since there will be no
- carry from its most significant bit, the LSB of the
- byte to the left will be unchanged, and the zero will be
- detected.
-
- 2) Is this worthwhile? Will it ignore everything except
- zero bytes? Suppose every byte of LONGWORD has a bit set
- somewhere. There will be a carry into bit 8. If bit 8
- is set, this will carry into bit 16. If bit 8 is clear,
- one of bits 9-15 must be set, so there will be a carry
- into bit 16. Similarly, there will be a carry into bit
- 24. If one of bits 24-30 is set, there will be a carry
- into bit 31, so all of the hole bits will be changed.
-
- The one misfire occurs when bits 24-30 are clear and bit
- 31 is set; in this case, the hole at bit 31 is not
- changed. If we had access to the processor carry flag,
- we could close this loophole by putting the fourth hole
- at bit 32!
-
- So it ignores everything except 128's, when they're aligned
- properly.
-
- 3) But wait! Aren't we looking for C, not zero?
- Good point. So what we do is XOR LONGWORD with a longword,
- each of whose bytes is C. This turns each byte that is C
- into a zero. */
-
- longword = *longword_ptr++ ^ charmask;
-
- /* Add MAGIC_BITS to LONGWORD. */
- if ((((longword + magic_bits)
-
- /* Set those bits that were unchanged by the addition. */
- ^ ~longword)
-
- /* Look at only the hole bits. If any of the hole bits
- are unchanged, most likely one of the bytes was a
- zero. */
- & ~magic_bits) != 0)
- {
- /* Which of the bytes was C? If none of them were, it was
- a misfire; continue the search. */
-
- const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
-
- if (cp[0] == c)
- return (__ptr_t) cp;
- if (cp[1] == c)
- return (__ptr_t) &cp[1];
- if (cp[2] == c)
- return (__ptr_t) &cp[2];
- if (cp[3] == c)
- return (__ptr_t) &cp[3];
-#if LONG_MAX > 2147483647
- if (cp[4] == c)
- return (__ptr_t) &cp[4];
- if (cp[5] == c)
- return (__ptr_t) &cp[5];
- if (cp[6] == c)
- return (__ptr_t) &cp[6];
- if (cp[7] == c)
- return (__ptr_t) &cp[7];
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 8 warns about the size passed to memchr being larger than
+ PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
#endif
- }
- }
+ if (c != '\0')
+ return memchr (s, c, (size_t)-1);
+ DIAG_POP_NEEDS_COMMENT;
+ return (char *)s + strlen (s);
}
libc_hidden_def (__rawmemchr)
weak_alias (__rawmemchr, rawmemchr)
diff --git a/string/stpcpy.c b/string/stpcpy.c
index 46e876c28f..c6e760b4ee 100644
--- a/string/stpcpy.c
+++ b/string/stpcpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 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
diff --git a/string/stpncpy.c b/string/stpncpy.c
index 0cafc84217..2ac58a7e58 100644
--- a/string/stpncpy.c
+++ b/string/stpncpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2018 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
diff --git a/string/str-two-way.h b/string/str-two-way.h
index dcf1d65aaf..523d946c59 100644
--- a/string/str-two-way.h
+++ b/string/str-two-way.h
@@ -1,5 +1,5 @@
/* Byte-wise substring search, using the Two-Way algorithm.
- Copyright (C) 2008-2016 Free Software Foundation, Inc.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Eric Blake <ebb9@byu.net>, 2008.
@@ -281,50 +281,50 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
}
else
{
- const unsigned char *phaystack = &haystack[suffix];
+ const unsigned char *phaystack;
/* The comparison always starts from needle[suffix], so cache it
and use an optimized first-character loop. */
unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]);
-#if CHECK_EOL
- /* We start matching from the SUFFIX'th element, so make sure we
- don't hit '\0' before that. */
- if (haystack_len < suffix + 1
- && !AVAILABLE (haystack, haystack_len, 0, suffix + 1))
- return NULL;
-#endif
-
/* The two halves of needle are distinct; no extra memory is
required, and any mismatch results in a maximal shift. */
period = MAX (suffix, needle_len - suffix) + 1;
j = 0;
- while (1
-#if !CHECK_EOL
- && AVAILABLE (haystack, haystack_len, j, needle_len)
-#endif
- )
+ while (AVAILABLE (haystack, haystack_len, j, needle_len))
{
unsigned char haystack_char;
const unsigned char *pneedle;
- /* TODO: The first-character loop can be sped up by adapting
- longword-at-a-time implementation of memchr/strchr. */
- if (needle_suffix
+ phaystack = &haystack[suffix + j];
+
+#ifdef FASTSEARCH
+ if (*phaystack++ != needle_suffix)
+ {
+ phaystack = FASTSEARCH (phaystack, needle_suffix,
+ haystack_len - needle_len - j);
+ if (phaystack == NULL)
+ goto ret0;
+ j = phaystack - &haystack[suffix];
+ phaystack++;
+ }
+#else
+ while (needle_suffix
!= (haystack_char = CANON_ELEMENT (*phaystack++)))
{
RET0_IF_0 (haystack_char);
-#if !CHECK_EOL
+# if !CHECK_EOL
++j;
-#endif
- continue;
+ if (!AVAILABLE (haystack, haystack_len, j, needle_len))
+ goto ret0;
+# endif
}
-#if CHECK_EOL
+# if CHECK_EOL
/* Calculate J if it wasn't kept up-to-date in the first-character
loop. */
j = phaystack - &haystack[suffix] - 1;
+# endif
#endif
-
/* Scan for matches in right half. */
i = suffix + 1;
pneedle = &needle[i];
@@ -338,6 +338,11 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
}
++i;
}
+#if CHECK_EOL
+ /* Update minimal length of haystack. */
+ if (phaystack > haystack + haystack_len)
+ haystack_len = phaystack - haystack;
+#endif
if (needle_len <= i)
{
/* Scan for matches in left half. */
@@ -360,13 +365,6 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
}
else
j += i - suffix + 1;
-
-#if CHECK_EOL
- if (!AVAILABLE (haystack, haystack_len, j, needle_len))
- break;
-#endif
-
- phaystack = &haystack[suffix + j];
}
}
ret0: __attribute__ ((unused))
diff --git a/string/stratcliff.c b/string/stratcliff.c
index 463a045b26..f6e3010720 100644
--- a/string/stratcliff.c
+++ b/string/stratcliff.c
@@ -1,5 +1,5 @@
/* Test for string function add boundaries of usable memory.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -55,11 +55,11 @@
#define STRINGIFY2(s) #s
-static int
+int
do_test (void)
{
- int size = sysconf (_SC_PAGESIZE);
- int nchars = size / sizeof (CHAR);
+ size_t size = sysconf (_SC_PAGESIZE);
+ size_t nchars = size / sizeof (CHAR);
CHAR *adr;
CHAR *dest;
int result = 0;
@@ -80,7 +80,17 @@ do_test (void)
}
else
{
- int inner, middle, outer;
+ size_t inner, middle, outer, nchars64, max128;
+
+ if (nchars > 64)
+ nchars64 = nchars - 64;
+ else
+ nchars64 = 0;
+
+ if (nchars > 128)
+ max128 = nchars - 128;
+ else
+ max128 = 0;
mprotect (adr, size, PROT_NONE);
mprotect (adr + 2 * nchars, size, PROT_NONE);
@@ -93,59 +103,65 @@ do_test (void)
MEMSET (adr, L('T'), nchars);
/* strlen/wcslen test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if (STRLEN (&adr[outer]) != (size_t) (inner - outer))
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STRLEN), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* strnlen/wcsnlen test */
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if (STRNLEN (&adr[outer], inner - outer + 1)
!= (size_t) (inner - outer))
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STRNLEN), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner <= nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner <= nchars; ++inner)
{
if (STRNLEN (&adr[outer], inner - outer)
!= (size_t) (inner - outer))
{
- printf ("%s flunked bounded for outer = %d, inner = %d\n",
+ printf ("%s flunked bounded for outer = %zu, inner = %zu\n",
STRINGIFY (STRNLEN), outer, inner);
result = 1;
}
}
+ if (outer == 0)
+ break;
}
/* strchr/wcschr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
for (inner = middle; inner < nchars; ++inner)
{
@@ -158,8 +174,8 @@ do_test (void)
|| (inner != middle
&& (cp - &adr[outer]) != middle - outer))
{
- printf ("%s flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRCHR), outer, middle, inner);
result = 1;
}
@@ -168,6 +184,8 @@ do_test (void)
adr[middle] = L('T');
}
}
+ if (outer == 0)
+ break;
}
/* Special test. */
@@ -180,9 +198,9 @@ do_test (void)
}
/* strrchr/wcsrchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
for (inner = middle; inner < nchars; ++inner)
{
@@ -195,8 +213,8 @@ do_test (void)
|| (inner != middle
&& (cp - &adr[outer]) != middle - outer))
{
- printf ("%s flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRRCHR), outer, middle, inner);
result = 1;
}
@@ -205,12 +223,14 @@ do_test (void)
adr[middle] = L('T');
}
}
+ if (outer == 0)
+ break;
}
/* memchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('V');
@@ -218,32 +238,36 @@ do_test (void)
if (cp - &adr[outer] != middle - outer)
{
- printf ("%s flunked for outer = %d, middle = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu\n",
STRINGIFY (MEMCHR), outer, middle);
result = 1;
}
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer);
if (cp != NULL)
{
- printf ("%s flunked for outer = %d\n",
+ printf ("%s flunked for outer = %zu\n",
STRINGIFY (MEMCHR), outer);
result = 1;
}
+ if (outer == 0)
+ break;
}
/* These functions only exist for single-byte characters. */
#ifndef WCSTEST
/* rawmemchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('V');
@@ -251,19 +275,21 @@ do_test (void)
if (cp - &adr[outer] != middle - outer)
{
- printf ("%s flunked for outer = %d, middle = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu\n",
STRINGIFY (rawmemchr), outer, middle);
result = 1;
}
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
/* memrchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('V');
@@ -271,44 +297,50 @@ do_test (void)
if (cp - &adr[outer] != middle - outer)
{
- printf ("%s flunked for outer = %d, middle = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu\n",
STRINGIFY (memrchr), outer, middle);
result = 1;
}
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer);
if (cp != NULL)
{
- printf ("%s flunked for outer = %d\n",
+ printf ("%s flunked for outer = %zu\n",
STRINGIFY (memrchr), outer);
result = 1;
}
+ if (outer == 0)
+ break;
}
#endif
/* strcpy/wcscpy test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if (STRCPY (dest, &adr[outer]) != dest
|| STRLEN (dest) != (size_t) (inner - outer))
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STRCPY), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* strcmp/wcscmp tests */
@@ -322,14 +354,14 @@ do_test (void)
if (STRCMP (adr + middle, dest + nchars - outer) <= 0)
{
- printf ("%s 1 flunked for outer = %d, middle = %d\n",
+ printf ("%s 1 flunked for outer = %zu, middle = %zu\n",
STRINGIFY (STRCMP), outer, middle);
result = 1;
}
if (STRCMP (dest + nchars - outer, adr + middle) >= 0)
{
- printf ("%s 2 flunked for outer = %d, middle = %d\n",
+ printf ("%s 2 flunked for outer = %zu, middle = %zu\n",
STRINGIFY (STRCMP), outer, middle);
result = 1;
}
@@ -348,16 +380,16 @@ do_test (void)
{
if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0)
{
- printf ("%s 1 flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s 1 flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRNCMP), outer, middle, inner);
result = 1;
}
if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0)
{
- printf ("%s 2 flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s 2 flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRNCMP), outer, middle, inner);
result = 1;
}
@@ -365,14 +397,14 @@ do_test (void)
if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0)
{
- printf ("%s 1 flunked for outer = %d, middle = %d, full\n",
+ printf ("%s 1 flunked for outer = %zu, middle = %zu, full\n",
STRINGIFY (STRNCMP), outer, middle);
result = 1;
}
if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0)
{
- printf ("%s 2 flunked for outer = %d, middle = %d, full\n",
+ printf ("%s 2 flunked for outer = %zu, middle = %zu, full\n",
STRINGIFY (STRNCMP), outer, middle);
result = 1;
}
@@ -380,7 +412,7 @@ do_test (void)
/* strncpy/wcsncpy tests */
adr[nchars - 1] = L('T');
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
size_t len;
@@ -389,17 +421,19 @@ do_test (void)
if (STRNCPY (dest, &adr[outer], len) != dest
|| MEMCMP (dest, &adr[outer], len) != 0)
{
- printf ("outer %s flunked for outer = %d, len = %Zd\n",
+ printf ("outer %s flunked for outer = %zu, len = %zu\n",
STRINGIFY (STRNCPY), outer, len);
result = 1;
}
}
+ if (outer == 0)
+ break;
}
adr[nchars - 1] = L('\0');
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
size_t len;
@@ -413,8 +447,8 @@ do_test (void)
|| (inner - outer < len
&& STRLEN (dest) != (inner - outer)))
{
- printf ("%s flunked for outer = %d, inner = %d, "
- "len = %Zd\n",
+ printf ("%s flunked for outer = %zu, inner = %zu, "
+ "len = %zu\n",
STRINGIFY (STRNCPY), outer, inner, len);
result = 1;
}
@@ -424,8 +458,8 @@ do_test (void)
|| (inner - outer < len
&& STRLEN (dest + 1) != (inner - outer)))
{
- printf ("%s+1 flunked for outer = %d, inner = %d, "
- "len = %Zd\n",
+ printf ("%s+1 flunked for outer = %zu, inner = %zu, "
+ "len = %zu\n",
STRINGIFY (STRNCPY), outer, inner, len);
result = 1;
}
@@ -433,29 +467,33 @@ do_test (void)
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* stpcpy/wcpcpy test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer)
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STPCPY), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* stpncpy/wcpncpy test */
adr[nchars - 1] = L('T');
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
size_t len;
@@ -464,17 +502,19 @@ do_test (void)
if (STPNCPY (dest, &adr[outer], len) != dest + len
|| MEMCMP (dest, &adr[outer], len) != 0)
{
- printf ("outer %s flunked for outer = %d, len = %Zd\n",
+ printf ("outer %s flunked for outer = %zu, len = %zu\n",
STRINGIFY (STPNCPY), outer, len);
result = 1;
}
}
+ if (outer == 0)
+ break;
}
adr[nchars - 1] = L('\0');
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('\0');
@@ -483,8 +523,8 @@ do_test (void)
if ((STPNCPY (dest, &adr[outer], inner) - dest)
!= MIN (inner, middle - outer))
{
- printf ("%s flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STPNCPY), outer, middle, inner);
result = 1;
}
@@ -492,71 +532,88 @@ do_test (void)
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
/* memcpy/wmemcpy test */
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
- for (inner = 0; inner < nchars - outer; ++inner)
- if (MEMCPY (dest, &adr[outer], inner) != dest)
- {
- printf ("%s flunked for outer = %d, inner = %d\n",
- STRINGIFY (MEMCPY), outer, inner);
- result = 1;
- }
+ for (outer = nchars; outer >= max128; --outer)
+ {
+ for (inner = 0; inner < nchars - outer; ++inner)
+ if (MEMCPY (dest, &adr[outer], inner) != dest)
+ {
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
+ STRINGIFY (MEMCPY), outer, inner);
+ result = 1;
+ }
+ if (outer == 0)
+ break;
+ }
/* mempcpy/wmempcpy test */
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
- for (inner = 0; inner < nchars - outer; ++inner)
- if (MEMPCPY (dest, &adr[outer], inner) != dest + inner)
- {
- printf ("%s flunked for outer = %d, inner = %d\n",
- STRINGIFY (MEMPCPY), outer, inner);
- result = 1;
- }
+ for (outer = nchars; outer >= max128; --outer)
+ {
+ for (inner = 0; inner < nchars - outer; ++inner)
+ if (MEMPCPY (dest, &adr[outer], inner) != dest + inner)
+ {
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
+ STRINGIFY (MEMPCPY), outer, inner);
+ result = 1;
+ }
+ if (outer == 0)
+ break;
+ }
/* This function only exists for single-byte characters. */
#ifndef WCSTEST
/* memccpy test */
memset (adr, '\0', nchars);
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
- for (inner = 0; inner < nchars - outer; ++inner)
- if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
- {
- printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
- outer, inner);
- result = 1;
- }
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
- for (middle = 0; middle < nchars - outer; ++middle)
- {
- memset (dest, L('\2'), middle + 1);
- for (inner = 0; inner < middle; ++inner)
+ for (outer = nchars; outer >= max128; --outer)
+ {
+ for (inner = 0; inner < nchars - outer; ++inner)
+ if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
{
- adr[outer + inner] = L('\1');
-
- if (memccpy (dest, &adr[outer], '\1', middle + 128)
- != dest + inner + 1)
- {
- printf ("\
-memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
- outer, middle, inner);
- result = 1;
- }
- else if (dest[inner + 1] != L('\2'))
- {
- printf ("\
-memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
- outer, middle, inner);
- result = 1;
- }
- adr[outer + inner] = L('\0');
+ printf ("memccpy flunked full copy for outer = %zu, inner = %zu\n",
+ outer, inner);
+ result = 1;
}
- }
+ if (outer == 0)
+ break;
+ }
+ for (outer = nchars - 1; outer >= max128; --outer)
+ {
+ for (middle = 0; middle < nchars - outer; ++middle)
+ {
+ memset (dest, L('\2'), middle + 1);
+ for (inner = 0; inner < middle; ++inner)
+ {
+ adr[outer + inner] = L('\1');
+
+ if (memccpy (dest, &adr[outer], '\1', middle + 128)
+ != dest + inner + 1)
+ {
+ printf ("\
+ memccpy flunked partial copy for outer = %zu, middle = %zu, inner = %zu\n",
+ outer, middle, inner);
+ result = 1;
+ }
+ else if (dest[inner + 1] != L('\2'))
+ {
+ printf ("\
+ memccpy copied too much for outer = %zu, middle = %zu, inner = %zu\n",
+ outer, middle, inner);
+ result = 1;
+ }
+ adr[outer + inner] = L('\0');
+ }
+ }
+ if (outer == 0)
+ break;
+ }
#endif
}
return result;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/strcasecmp.c b/string/strcasecmp.c
index 38372a55db..420b7504f3 100644
--- a/string/strcasecmp.c
+++ b/string/strcasecmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -34,7 +34,7 @@
#endif
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
-# define LOCALE_PARAM , __locale_t loc
+# define LOCALE_PARAM , locale_t loc
#else
# define LOCALE_PARAM
#endif
@@ -46,7 +46,7 @@ int
__strcasecmp (const char *s1, const char *s2 LOCALE_PARAM)
{
#if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL
- __locale_t loc = _NL_CURRENT_LOCALE;
+ locale_t loc = _NL_CURRENT_LOCALE;
#endif
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
diff --git a/string/strcasecmp_l.c b/string/strcasecmp_l.c
index 84c4149852..4189d7dbb0 100644
--- a/string/strcasecmp_l.c
+++ b/string/strcasecmp_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2018 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
diff --git a/string/strcasestr.c b/string/strcasestr.c
index 734af6556d..5909fe3cdb 100644
--- a/string/strcasestr.c
+++ b/string/strcasestr.c
@@ -1,5 +1,5 @@
/* Return the offset of one string within another.
- Copyright (C) 1994-2016 Free Software Foundation, Inc.
+ Copyright (C) 1994-2018 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
@@ -25,10 +25,6 @@
*
* Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
/* Specification. */
#include <string.h>
@@ -41,8 +37,8 @@
/* Two-Way algorithm. */
#define RETURN_TYPE char *
#define AVAILABLE(h, h_l, j, n_l) \
- (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
- && ((h_l) = (j) + (n_l)))
+ (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
+ (j) + (n_l) <= (h_l)))
#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
#define CANON_ELEMENT(c) TOLOWER (c)
diff --git a/string/strcat.c b/string/strcat.c
index f229e4d831..48e1b3538b 100644
--- a/string/strcat.c
+++ b/string/strcat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strchr.c b/string/strchr.c
index 25c2fe4771..a63fdfc282 100644
--- a/string/strchr.c
+++ b/string/strchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
diff --git a/string/strchrnul.c b/string/strchrnul.c
index 629db465b8..5a17602edd 100644
--- a/string/strchrnul.c
+++ b/string/strchrnul.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
diff --git a/string/strcmp.c b/string/strcmp.c
index 4b16f9946b..e198d192b9 100644
--- a/string/strcmp.c
+++ b/string/strcmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strcoll.c b/string/strcoll.c
index 7449197244..93e0546fd8 100644
--- a/string/strcoll.c
+++ b/string/strcoll.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
diff --git a/string/strcoll_l.c b/string/strcoll_l.c
index 4d1e3ab15e..c001ff4ad4 100644
--- a/string/strcoll_l.c
+++ b/string/strcoll_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@gnu.org>, 1995.
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <string.h>
#include <sys/param.h>
+#include <libc-diag.h>
#ifndef STRING_TYPE
# define STRING_TYPE char
@@ -170,7 +171,19 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
}
}
+ /* With GCC 5.3 when compiling with -Os the compiler complains
+ that idx, taken from seq->idx (seq1 or seq2 from STRCOLL) may
+ be used uninitialized. In general this can't possibly be true
+ since seq1.idx and seq2.idx are initialized to zero in the
+ outer function. Only one case where seq->idx is restored from
+ seq->save_idx might result in an uninitialized idx value, but
+ it is guarded by a sequence of checks against backw_stop which
+ ensures that seq->save_idx was saved to first and contains a
+ valid value. */
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
len = weights[idx++];
+ DIAG_POP_NEEDS_COMMENT;
/* Skip over indices of previous levels. */
for (int i = 0; i < pass; i++)
{
@@ -242,7 +255,7 @@ out:
}
int
-STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, locale_t l)
{
struct __locale_data *current = l->__locales[LC_COLLATE];
uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
@@ -279,7 +292,17 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
int result = 0, rule = 0;
+ /* With GCC 7 when compiling with -Os the compiler warns that
+ seq1.back_us and seq2.back_us might be used uninitialized.
+ Sometimes this warning appears at locations in locale/weightwc.h
+ where the actual use is, but on architectures other than x86_64,
+ x86 and s390x, a warning appears at the definitions of seq1 and
+ seq2. This uninitialized use is impossible for the same reason
+ as described in comments in locale/weightwc.h. */
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_Os_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
coll_seq seq1, seq2;
+ DIAG_POP_NEEDS_COMMENT;
seq1.len = 0;
seq1.idxmax = 0;
seq1.rule = 0;
diff --git a/string/strcpy.c b/string/strcpy.c
index f049e62211..a4cce892df 100644
--- a/string/strcpy.c
+++ b/string/strcpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strcspn.c b/string/strcspn.c
index 8888919639..3c091b0a66 100644
--- a/string/strcspn.c
+++ b/string/strcspn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -16,6 +16,8 @@
<http://www.gnu.org/licenses/>. */
#include <string.h>
+#include <stdint.h>
+#include <libc-pointer-arith.h>
#undef strcspn
@@ -26,16 +28,45 @@
/* 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)
+STRCSPN (const char *str, const char *reject)
{
- size_t count = 0;
+ if (__glibc_unlikely (reject[0] == '\0') ||
+ __glibc_unlikely (reject[1] == '\0'))
+ return __strchrnul (str, reject [0]) - str;
- while (*s != '\0')
- if (strchr (reject, *s++) == NULL)
- ++count;
- else
- return count;
+ /* Use multiple small memsets to enable inlining on most targets. */
+ unsigned char table[256];
+ unsigned char *p = memset (table, 0, 64);
+ memset (p + 64, 0, 64);
+ memset (p + 128, 0, 64);
+ memset (p + 192, 0, 64);
- return count;
+ unsigned char *s = (unsigned char*) reject;
+ unsigned char tmp;
+ do
+ p[tmp = *s++] = 1;
+ while (tmp);
+
+ s = (unsigned char*) str;
+ if (p[s[0]]) return 0;
+ if (p[s[1]]) return 1;
+ if (p[s[2]]) return 2;
+ if (p[s[3]]) return 3;
+
+ s = (unsigned char *) PTR_ALIGN_DOWN (s, 4);
+
+ unsigned int c0, c1, c2, c3;
+ do
+ {
+ s += 4;
+ c0 = p[s[0]];
+ c1 = p[s[1]];
+ c2 = p[s[2]];
+ c3 = p[s[3]];
+ }
+ while ((c0 | c1 | c2 | c3) == 0);
+
+ size_t count = s - (unsigned char *) str;
+ return (c0 | c1) != 0 ? count - c0 + 1 : count - c2 + 3;
}
libc_hidden_builtin_def (strcspn)
diff --git a/string/strdup.c b/string/strdup.c
index 21e8ee2a79..52a38cc243 100644
--- a/string/strdup.c
+++ b/string/strdup.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strerror.c b/string/strerror.c
index 7319c56b2f..34f3db727b 100644
--- a/string/strerror.c
+++ b/string/strerror.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strerror_l.c b/string/strerror_l.c
index 13f7606c3e..2a62b1f12c 100644
--- a/string/strerror_l.c
+++ b/string/strerror_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2018 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
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
-
+#include <libc-symbols.h>
static __thread char *last_value;
@@ -56,16 +56,9 @@ strerror_l (int errnum, locale_t loc)
return (char *) translate (_sys_errlist_internal[errnum], loc);
}
-
-#ifdef _LIBC
-# ifdef _LIBC_REENTRANT
-/* This is called when a thread is exiting to free the last_value string. */
-static void __attribute__ ((section ("__libc_thread_freeres_fn")))
-strerror_thread_freeres (void)
+void
+__strerror_thread_freeres (void)
{
free (last_value);
}
-text_set_element (__libc_thread_subfreeres, strerror_thread_freeres);
-text_set_element (__libc_subfreeres, strerror_thread_freeres);
-# endif
-#endif
+text_set_element (__libc_subfreeres, __strerror_thread_freeres);
diff --git a/string/strfry.c b/string/strfry.c
index 87b69fcc31..6c735fc147 100644
--- a/string/strfry.c
+++ b/string/strfry.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 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
diff --git a/string/string-inlines.c b/string/string-inlines.c
index 16db3ea308..1eb67cc36d 100644
--- a/string/string-inlines.c
+++ b/string/string-inlines.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2018 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
@@ -15,20 +15,546 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* <bits/string.h> and <bits/string2.h> declare some extern inline
- functions. These functions are declared additionally here if
- inlining is not possible. */
-
-#undef __USE_STRING_INLINES
-#define __USE_STRING_INLINES
-#define _FORCE_INLINES
-#define __STRING_INLINE /* empty */
-#define __NO_INLINE__
+/* This file contains compatibility definitions of functions that were
+ formerly defined as "extern inline" in string.h; it's conceivable
+ that old binaries contain references to them. */
+#define __NO_STRING_INLINES
#include <string.h>
-#undef index
-#undef rindex
-#undef __NO_INLINE__
-#include <bits/string.h>
-#include <bits/string2.h>
+#include "shlib-compat.h"
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
+/* These functions were removed from string.h in glibc 2.25. */
+
+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);
+
+char *
+__old_strsep_1c (char **__s, char __reject)
+{
+ char *__retval = *__s;
+ if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
+ *(*__s)++ = '\0';
+ return __retval;
+}
+compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
+
+char *
+__old_strsep_2c (char **__s, char __reject1, char __reject2)
+{
+ char *__retval = *__s;
+ if (__retval != NULL)
+ {
+ char *__cp = __retval;
+ while (1)
+ {
+ if (*__cp == '\0')
+ {
+ __cp = NULL;
+ break;
+ }
+ if (*__cp == __reject1 || *__cp == __reject2)
+ {
+ *__cp++ = '\0';
+ break;
+ }
+ ++__cp;
+ }
+ *__s = __cp;
+ }
+ return __retval;
+}
+compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
+
+char *
+__old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
+{
+ char *__retval = *__s;
+ if (__retval != NULL)
+ {
+ char *__cp = __retval;
+ while (1)
+ {
+ if (*__cp == '\0')
+ {
+ __cp = NULL;
+ break;
+ }
+ if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
+ {
+ *__cp++ = '\0';
+ break;
+ }
+ ++__cp;
+ }
+ *__s = __cp;
+ }
+ return __retval;
+}
+compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
+/* These functions were removed from string.h in glibc 2.24. */
+
+size_t
+__old_strcspn_c1 (const char *__s, int __reject)
+{
+ size_t __result = 0;
+ while (__s[__result] != '\0' && __s[__result] != __reject)
+ ++__result;
+ return __result;
+}
+compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
+
+size_t
+__old_strcspn_c2 (const char *__s, int __reject1, int __reject2)
+{
+ size_t __result = 0;
+ while (__s[__result] != '\0' && __s[__result] != __reject1
+ && __s[__result] != __reject2)
+ ++__result;
+ return __result;
+}
+compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
+
+size_t
+__old_strcspn_c3 (const char *__s, int __reject1, int __reject2,
+ int __reject3)
+{
+ size_t __result = 0;
+ while (__s[__result] != '\0' && __s[__result] != __reject1
+ && __s[__result] != __reject2 && __s[__result] != __reject3)
+ ++__result;
+ return __result;
+}
+compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
+
+size_t
+__old_strspn_c1 (const char *__s, int __accept)
+{
+ size_t __result = 0;
+ /* Please note that __accept never can be '\0'. */
+ while (__s[__result] == __accept)
+ ++__result;
+ return __result;
+}
+compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
+
+size_t
+__old_strspn_c2 (const char *__s, int __accept1, int __accept2)
+{
+ size_t __result = 0;
+ /* Please note that __accept1 and __accept2 never can be '\0'. */
+ while (__s[__result] == __accept1 || __s[__result] == __accept2)
+ ++__result;
+ return __result;
+}
+compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
+
+size_t
+__old_strspn_c3 (const char *__s, int __accept1, int __accept2,
+ int __accept3)
+{
+ size_t __result = 0;
+ /* Please note that __accept1 to __accept3 never can be '\0'. */
+ while (__s[__result] == __accept1 || __s[__result] == __accept2
+ || __s[__result] == __accept3)
+ ++__result;
+ return __result;
+}
+compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
+
+char *
+__old_strpbrk_c2 (const char *__s, int __accept1, int __accept2)
+{
+ /* Please note that __accept1 and __accept2 never can be '\0'. */
+ while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
+ ++__s;
+ return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
+
+char *
+__old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
+{
+ /* Please note that __accept1 to __accept3 never can be '\0'. */
+ while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
+ && *__s != __accept3)
+ ++__s;
+ return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
+
+# if defined __mc68020__ || defined __s390__ || defined __i386__
+# define _STRING_INLINE_unaligned 1
+# else
+# define _STRING_INLINE_unaligned 0
+/* These are a few types we need for the optimizations if we cannot
+ use unaligned memory accesses. */
+# define __STRING2_COPY_TYPE(N) \
+ typedef struct { unsigned char __arr[N]; } \
+ __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
+__STRING2_COPY_TYPE (2);
+__STRING2_COPY_TYPE (3);
+__STRING2_COPY_TYPE (4);
+__STRING2_COPY_TYPE (5);
+__STRING2_COPY_TYPE (6);
+__STRING2_COPY_TYPE (7);
+__STRING2_COPY_TYPE (8);
+# undef __STRING2_COPY_TYPE
+# endif
+
+# if _STRING_INLINE_unaligned
+void *
+__old_mempcpy_small (void *__dest1,
+ char __src0_1, char __src2_1, char __src4_1, char __src6_1,
+ __uint16_t __src0_2, __uint16_t __src4_2,
+ __uint32_t __src0_4, __uint32_t __src4_4,
+ size_t __srclen)
+{
+ union {
+ __uint32_t __ui;
+ __uint16_t __usi;
+ unsigned char __uc;
+ unsigned char __c;
+ } *__u = __dest1;
+ switch ((unsigned int) __srclen)
+ {
+ case 1:
+ __u->__c = __src0_1;
+ __u = __extension__ ((void *) __u + 1);
+ break;
+ case 2:
+ __u->__usi = __src0_2;
+ __u = __extension__ ((void *) __u + 2);
+ break;
+ case 3:
+ __u->__usi = __src0_2;
+ __u = __extension__ ((void *) __u + 2);
+ __u->__c = __src2_1;
+ __u = __extension__ ((void *) __u + 1);
+ break;
+ case 4:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ break;
+ case 5:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__c = __src4_1;
+ __u = __extension__ ((void *) __u + 1);
+ break;
+ case 6:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__usi = __src4_2;
+ __u = __extension__ ((void *) __u + 2);
+ break;
+ case 7:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__usi = __src4_2;
+ __u = __extension__ ((void *) __u + 2);
+ __u->__c = __src6_1;
+ __u = __extension__ ((void *) __u + 1);
+ break;
+ case 8:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__ui = __src4_4;
+ __u = __extension__ ((void *) __u + 4);
+ break;
+ }
+ return (void *) __u;
+}
+
+# else
+
+void *
+__old_mempcpy_small (void *__dest, char __src1,
+ __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
+ __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
+ __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
+ __STRING2_COPY_ARR8 __src8, size_t __srclen)
+{
+ union {
+ char __c;
+ __STRING2_COPY_ARR2 __sca2;
+ __STRING2_COPY_ARR3 __sca3;
+ __STRING2_COPY_ARR4 __sca4;
+ __STRING2_COPY_ARR5 __sca5;
+ __STRING2_COPY_ARR6 __sca6;
+ __STRING2_COPY_ARR7 __sca7;
+ __STRING2_COPY_ARR8 __sca8;
+ } *__u = __dest;
+ switch ((unsigned int) __srclen)
+ {
+ case 1:
+ __u->__c = __src1;
+ break;
+ case 2:
+ __extension__ __u->__sca2 = __src2;
+ break;
+ case 3:
+ __extension__ __u->__sca3 = __src3;
+ break;
+ case 4:
+ __extension__ __u->__sca4 = __src4;
+ break;
+ case 5:
+ __extension__ __u->__sca5 = __src5;
+ break;
+ case 6:
+ __extension__ __u->__sca6 = __src6;
+ break;
+ case 7:
+ __extension__ __u->__sca7 = __src7;
+ break;
+ case 8:
+ __extension__ __u->__sca8 = __src8;
+ break;
+ }
+ return __extension__ ((void *) __u + __srclen);
+}
+# endif
+compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
+
+# if _STRING_INLINE_unaligned
+char *
+__old_strcpy_small (char *__dest,
+ __uint16_t __src0_2, __uint16_t __src4_2,
+ __uint32_t __src0_4, __uint32_t __src4_4,
+ size_t __srclen)
+{
+ union {
+ __uint32_t __ui;
+ __uint16_t __usi;
+ unsigned char __uc;
+ } *__u = (void *) __dest;
+ switch ((unsigned int) __srclen)
+ {
+ case 1:
+ __u->__uc = '\0';
+ break;
+ case 2:
+ __u->__usi = __src0_2;
+ break;
+ case 3:
+ __u->__usi = __src0_2;
+ __u = __extension__ ((void *) __u + 2);
+ __u->__uc = '\0';
+ break;
+ case 4:
+ __u->__ui = __src0_4;
+ break;
+ case 5:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__uc = '\0';
+ break;
+ case 6:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__usi = __src4_2;
+ break;
+ case 7:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__usi = __src4_2;
+ __u = __extension__ ((void *) __u + 2);
+ __u->__uc = '\0';
+ break;
+ case 8:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__ui = __src4_4;
+ break;
+ }
+ return __dest;
+}
+
+# else
+
+char *
+__old_strcpy_small (char *__dest,
+ __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
+ __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
+ __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
+ __STRING2_COPY_ARR8 __src8, size_t __srclen)
+{
+ union {
+ char __c;
+ __STRING2_COPY_ARR2 __sca2;
+ __STRING2_COPY_ARR3 __sca3;
+ __STRING2_COPY_ARR4 __sca4;
+ __STRING2_COPY_ARR5 __sca5;
+ __STRING2_COPY_ARR6 __sca6;
+ __STRING2_COPY_ARR7 __sca7;
+ __STRING2_COPY_ARR8 __sca8;
+ } *__u = (void *) __dest;
+ switch ((unsigned int) __srclen)
+ {
+ case 1:
+ __u->__c = '\0';
+ break;
+ case 2:
+ __extension__ __u->__sca2 = __src2;
+ break;
+ case 3:
+ __extension__ __u->__sca3 = __src3;
+ break;
+ case 4:
+ __extension__ __u->__sca4 = __src4;
+ break;
+ case 5:
+ __extension__ __u->__sca5 = __src5;
+ break;
+ case 6:
+ __extension__ __u->__sca6 = __src6;
+ break;
+ case 7:
+ __extension__ __u->__sca7 = __src7;
+ break;
+ case 8:
+ __extension__ __u->__sca8 = __src8;
+ break;
+ }
+ return __dest;
+}
+# endif
+compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
+
+# if _STRING_INLINE_unaligned
+char *
+__old_stpcpy_small (char *__dest,
+ __uint16_t __src0_2, __uint16_t __src4_2,
+ __uint32_t __src0_4, __uint32_t __src4_4,
+ size_t __srclen)
+{
+ union {
+ unsigned int __ui;
+ unsigned short int __usi;
+ unsigned char __uc;
+ char __c;
+ } *__u = (void *) __dest;
+ switch ((unsigned int) __srclen)
+ {
+ case 1:
+ __u->__uc = '\0';
+ break;
+ case 2:
+ __u->__usi = __src0_2;
+ __u = __extension__ ((void *) __u + 1);
+ break;
+ case 3:
+ __u->__usi = __src0_2;
+ __u = __extension__ ((void *) __u + 2);
+ __u->__uc = '\0';
+ break;
+ case 4:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 3);
+ break;
+ case 5:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__uc = '\0';
+ break;
+ case 6:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__usi = __src4_2;
+ __u = __extension__ ((void *) __u + 1);
+ break;
+ case 7:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__usi = __src4_2;
+ __u = __extension__ ((void *) __u + 2);
+ __u->__uc = '\0';
+ break;
+ case 8:
+ __u->__ui = __src0_4;
+ __u = __extension__ ((void *) __u + 4);
+ __u->__ui = __src4_4;
+ __u = __extension__ ((void *) __u + 3);
+ break;
+ }
+ return &__u->__c;
+}
+
+# else
+
+char *
+__old_stpcpy_small (char *__dest,
+ __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
+ __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
+ __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
+ __STRING2_COPY_ARR8 __src8, size_t __srclen)
+{
+ union {
+ char __c;
+ __STRING2_COPY_ARR2 __sca2;
+ __STRING2_COPY_ARR3 __sca3;
+ __STRING2_COPY_ARR4 __sca4;
+ __STRING2_COPY_ARR5 __sca5;
+ __STRING2_COPY_ARR6 __sca6;
+ __STRING2_COPY_ARR7 __sca7;
+ __STRING2_COPY_ARR8 __sca8;
+ } *__u = (void *) __dest;
+ switch ((unsigned int) __srclen)
+ {
+ case 1:
+ __u->__c = '\0';
+ break;
+ case 2:
+ __extension__ __u->__sca2 = __src2;
+ break;
+ case 3:
+ __extension__ __u->__sca3 = __src3;
+ break;
+ case 4:
+ __extension__ __u->__sca4 = __src4;
+ break;
+ case 5:
+ __extension__ __u->__sca5 = __src5;
+ break;
+ case 6:
+ __extension__ __u->__sca6 = __src6;
+ break;
+ case 7:
+ __extension__ __u->__sca7 = __src7;
+ break;
+ case 8:
+ __extension__ __u->__sca8 = __src8;
+ break;
+ }
+ return __dest + __srclen - 1;
+}
+# endif
+compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
+
+#endif
diff --git a/string/string.h b/string/string.h
index 1f3e348834..150cfd8b13 100644
--- a/string/string.h
+++ b/string/string.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -22,7 +22,8 @@
#ifndef _STRING_H
#define _STRING_H 1
-#include <features.h>
+#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
+#include <bits/libc-header-start.h>
__BEGIN_DECLS
@@ -37,7 +38,6 @@ __BEGIN_DECLS
#endif
-__BEGIN_NAMESPACE_STD
/* Copy N bytes of SRC to DEST. */
extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
size_t __n) __THROW __nonnull ((1, 2));
@@ -45,7 +45,6 @@ extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
correct behavior for overlapping strings. */
extern void *memmove (void *__dest, const void *__src, size_t __n)
__THROW __nonnull ((1, 2));
-__END_NAMESPACE_STD
/* Copy no more than N bytes of SRC to DEST, stopping when C is found.
Return the position in DEST one byte past where C was copied,
@@ -57,7 +56,6 @@ extern void *memccpy (void *__restrict __dest, const void *__restrict __src,
#endif /* Misc || X/Open. */
-__BEGIN_NAMESPACE_STD
/* Set N bytes of S to C. */
extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1));
@@ -92,7 +90,6 @@ memchr (const void *__s, int __c, size_t __n) __THROW
extern void *memchr (const void *__s, int __c, size_t __n)
__THROW __attribute_pure__ __nonnull ((1));
#endif
-__END_NAMESPACE_STD
#ifdef __USE_GNU
/* Search in S for C. This is similar to `memchr' but there is no
@@ -120,7 +117,6 @@ extern void *memrchr (const void *__s, int __c, size_t __n)
#endif
-__BEGIN_NAMESPACE_STD
/* Copy SRC to DEST. */
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
__THROW __nonnull ((1, 2));
@@ -150,23 +146,22 @@ extern int strcoll (const char *__s1, const char *__s2)
extern size_t strxfrm (char *__restrict __dest,
const char *__restrict __src, size_t __n)
__THROW __nonnull ((2));
-__END_NAMESPACE_STD
#ifdef __USE_XOPEN2K8
-/* The following functions are equivalent to the both above but they
- take the locale they use for the collation as an extra argument.
- This is not standardsized but something like will come. */
-# include <xlocale.h>
+/* POSIX.1-2008 extended locale interface (see locale.h). */
+# include <bits/types/locale_t.h>
-/* Compare the collated forms of S1 and S2 using rules from L. */
-extern int strcoll_l (const char *__s1, const char *__s2, __locale_t __l)
+/* Compare the collated forms of S1 and S2, using sorting rules from L. */
+extern int strcoll_l (const char *__s1, const char *__s2, locale_t __l)
__THROW __attribute_pure__ __nonnull ((1, 2, 3));
-/* Put a transformation of SRC into no more than N bytes of DEST. */
+/* Put a transformation of SRC into no more than N bytes of DEST,
+ using sorting rules from L. */
extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n,
- __locale_t __l) __THROW __nonnull ((2, 4));
+ locale_t __l) __THROW __nonnull ((2, 4));
#endif
-#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
+#if (defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 \
+ || __GLIBC_USE (LIB_EXT2))
/* Duplicate S, returning an identical malloc'd string. */
extern char *strdup (const char *__s)
__THROW __attribute_malloc__ __nonnull ((1));
@@ -175,7 +170,7 @@ extern char *strdup (const char *__s)
/* Return a malloc'd copy of at most N bytes of STRING. The
resultant string is terminated even if no null terminator
appears before STRING[N]. */
-#if defined __USE_XOPEN2K8
+#if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2)
extern char *strndup (const char *__string, size_t __n)
__THROW __attribute_malloc__ __nonnull ((1));
#endif
@@ -203,7 +198,6 @@ extern char *strndup (const char *__string, size_t __n)
}))
#endif
-__BEGIN_NAMESPACE_STD
/* Find the first occurrence of C in S. */
#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
extern "C++"
@@ -258,7 +252,6 @@ strrchr (const char *__s, int __c) __THROW
extern char *strrchr (const char *__s, int __c)
__THROW __attribute_pure__ __nonnull ((1));
#endif
-__END_NAMESPACE_STD
#ifdef __USE_GNU
/* This function is similar to `strchr'. But it returns a pointer to
@@ -274,7 +267,6 @@ extern char *strchrnul (const char *__s, int __c)
# endif
#endif
-__BEGIN_NAMESPACE_STD
/* Return the length of the initial segment of S which
consists entirely of characters not in REJECT. */
extern size_t strcspn (const char *__s, const char *__reject)
@@ -342,7 +334,6 @@ extern char *strstr (const char *__haystack, const char *__needle)
/* Divide S into tokens separated by characters in DELIM. */
extern char *strtok (char *__restrict __s, const char *__restrict __delim)
__THROW __nonnull ((2));
-__END_NAMESPACE_STD
/* Divide S into tokens separated by characters in DELIM. Information
passed between calls are stored in SAVE_PTR. */
@@ -389,11 +380,9 @@ extern void *mempcpy (void *__restrict __dest,
#endif
-__BEGIN_NAMESPACE_STD
/* Return the length of S. */
extern size_t strlen (const char *__s)
__THROW __attribute_pure__ __nonnull ((1));
-__END_NAMESPACE_STD
#ifdef __USE_XOPEN2K8
/* Find the length of STRING, but scan at most MAXLEN characters.
@@ -403,10 +392,8 @@ extern size_t strnlen (const char *__string, size_t __maxlen)
#endif
-__BEGIN_NAMESPACE_STD
/* Return a string describing the meaning of the `errno' code in ERRNUM. */
extern char *strerror (int __errnum) __THROW;
-__END_NAMESPACE_STD
#ifdef __USE_XOPEN2K
/* Reentrant version of `strerror'.
There are 2 flavors of `strerror_r', GNU which returns the string
@@ -437,116 +424,16 @@ extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
#ifdef __USE_XOPEN2K8
/* Translate error number to string according to the locale L. */
-extern char *strerror_l (int __errnum, __locale_t __l) __THROW;
+extern char *strerror_l (int __errnum, locale_t __l) __THROW;
#endif
-
-/* We define this function always since `bzero' is sometimes needed when
- the namespace rules does not allow this. */
-extern void __bzero (void *__s, size_t __n) __THROW __nonnull ((1));
-
#ifdef __USE_MISC
-/* Copy N bytes of SRC to DEST (like memmove, but args reversed). */
-extern void bcopy (const void *__src, void *__dest, size_t __n)
- __THROW __nonnull ((1, 2));
-
-/* Set N bytes of S to 0. */
-extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1));
-
-/* Compare N bytes of S1 and S2 (same as memcmp). */
-extern int bcmp (const void *__s1, const void *__s2, size_t __n)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-
-/* Find the first occurrence of C in S (same as strchr). */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *index (char *__s, int __c)
- __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
-extern const char *index (const char *__s, int __c)
- __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
+# include <strings.h>
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRINGS_H_PROTO
-__extern_always_inline char *
-index (char *__s, int __c) __THROW
-{
- return __builtin_index (__s, __c);
-}
+/* Set N bytes of S to 0. The compiler will not delete a call to this
+ function, even if S is dead after the call. */
+extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1));
-__extern_always_inline const char *
-index (const char *__s, int __c) __THROW
-{
- return __builtin_index (__s, __c);
-}
-# endif
-}
-# else
-extern char *index (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
-
-/* Find the last occurrence of C in S (same as strrchr). */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *rindex (char *__s, int __c)
- __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-extern const char *rindex (const char *__s, int __c)
- __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRINGS_H_PROTO
-__extern_always_inline char *
-rindex (char *__s, int __c) __THROW
-{
- return __builtin_rindex (__s, __c);
-}
-
-__extern_always_inline const char *
-rindex (const char *__s, int __c) __THROW
-{
- return __builtin_rindex (__s, __c);
-}
-#endif
-}
-# else
-extern char *rindex (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
-
-/* Return the position of the first bit set in I, or 0 if none are set.
- The least-significant bit is position 1, the most-significant 32. */
-extern int ffs (int __i) __THROW __attribute__ ((__const__));
-
-/* The following two functions are non-standard but necessary for non-32 bit
- platforms. */
-# ifdef __USE_GNU
-extern int ffsl (long int __l) __THROW __attribute__ ((__const__));
-__extension__ extern int ffsll (long long int __ll)
- __THROW __attribute__ ((__const__));
-# endif
-
-/* Compare S1 and S2, ignoring case. */
-extern int strcasecmp (const char *__s1, const char *__s2)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-
-/* Compare no more than N chars of S1 and S2, ignoring case. */
-extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-#endif /* Use misc. */
-
-#ifdef __USE_GNU
-/* Again versions of a few functions which use the given locale instead
- of the global one. */
-extern int strcasecmp_l (const char *__s1, const char *__s2,
- __locale_t __loc)
- __THROW __attribute_pure__ __nonnull ((1, 2, 3));
-
-extern int strncasecmp_l (const char *__s1, const char *__s2,
- size_t __n, __locale_t __loc)
- __THROW __attribute_pure__ __nonnull ((1, 2, 4));
-#endif
-
-#ifdef __USE_MISC
/* Return the next DELIM-delimited token from *STRINGP,
terminating it with a '\0', and update *STRINGP to point past it. */
extern char *strsep (char **__restrict __stringp,
@@ -601,57 +488,10 @@ extern char *basename (const char *__filename) __THROW __nonnull ((1));
# endif
#endif
-
-#if defined __GNUC__ && __GNUC__ >= 2
-# if defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ \
- && !defined __NO_INLINE__ && !defined __cplusplus
-/* When using GNU CC we provide some optimized versions of selected
- functions from this header. There are two kinds of optimizations:
-
- - machine-dependent optimizations, most probably using inline
- assembler code; these might be quite expensive since the code
- size can increase significantly.
- These optimizations are not used unless the symbol
- __USE_STRING_INLINES
- is defined before including this header.
-
- - machine-independent optimizations which do not increase the
- code size significantly and which optimize mainly situations
- where one or more arguments are compile-time constants.
- These optimizations are used always when the compiler is
- taught to optimize.
-
- One can inhibit all optimizations by defining __NO_STRING_INLINES. */
-
-/* Get the machine-dependent optimizations (if any). */
-# include <bits/string.h>
-
-/* These are generic optimizations which do not add too much inline code. */
-# include <bits/string2.h>
-# endif
-
+#if __GNUC_PREREQ (3,4)
# if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
/* Functions with security checks. */
-# include <bits/string3.h>
-# endif
-#endif
-
-#if defined __USE_GNU && defined __OPTIMIZE__ \
- && defined __extern_always_inline && __GNUC_PREREQ (3,2)
-# if !defined _FORCE_INLINES && !defined _HAVE_STRING_ARCH_mempcpy
-
-#undef mempcpy
-#undef __mempcpy
-#define mempcpy(dest, src, n) __mempcpy_inline (dest, src, n)
-#define __mempcpy(dest, src, n) __mempcpy_inline (dest, src, n)
-
-__extern_always_inline void *
-__mempcpy_inline (void *__restrict __dest,
- const void *__restrict __src, size_t __n)
-{
- return (char *) memcpy (__dest, __src, __n) + __n;
-}
-
+# include <bits/string_fortified.h>
# endif
#endif
diff --git a/string/strings.h b/string/strings.h
index e372a331b3..f00d638fe0 100644
--- a/string/strings.h
+++ b/string/strings.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -18,35 +18,31 @@
#ifndef _STRINGS_H
#define _STRINGS_H 1
-/* We don't need and should not read this file if <string.h> was already
- read. The one exception being that if __USE_MISC isn't defined, then
- these aren't defined in string.h, so we need to define them here. */
-#if !defined _STRING_H || !defined __USE_MISC
-
-# include <features.h>
-# define __need_size_t
-# include <stddef.h>
+#include <features.h>
+#define __need_size_t
+#include <stddef.h>
/* Tell the caller that we provide correct C++ prototypes. */
-# if defined __cplusplus && __GNUC_PREREQ (4, 4)
-# define __CORRECT_ISO_CPP_STRINGS_H_PROTO
-# endif
+#if defined __cplusplus && __GNUC_PREREQ (4, 4)
+# define __CORRECT_ISO_CPP_STRINGS_H_PROTO
+#endif
__BEGIN_DECLS
-# if defined __USE_MISC || !defined __USE_XOPEN2K8
+#if defined __USE_MISC || !defined __USE_XOPEN2K8
/* Compare N bytes of S1 and S2 (same as memcmp). */
extern int bcmp (const void *__s1, const void *__s2, size_t __n)
- __THROW __attribute_pure__;
+ __THROW __attribute_pure__ __nonnull ((1, 2));
/* Copy N bytes of SRC to DEST (like memmove, but args reversed). */
-extern void bcopy (const void *__src, void *__dest, size_t __n) __THROW;
+extern void bcopy (const void *__src, void *__dest, size_t __n)
+ __THROW __nonnull ((1, 2));
/* Set N bytes of S to 0. */
-extern void bzero (void *__s, size_t __n) __THROW;
+extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1));
/* Find the first occurrence of C in S (same as strchr). */
-# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
+# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
extern "C++"
{
extern char *index (char *__s, int __c)
@@ -54,7 +50,7 @@ extern char *index (char *__s, int __c)
extern const char *index (const char *__s, int __c)
__THROW __asm ("index") __attribute_pure__ __nonnull ((1));
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRING_H_PROTO
+# if defined __OPTIMIZE__
__extern_always_inline char *
index (char *__s, int __c) __THROW
{
@@ -66,15 +62,15 @@ index (const char *__s, int __c) __THROW
{
return __builtin_index (__s, __c);
}
-# endif
+# endif
}
-# else
+# else
extern char *index (const char *__s, int __c)
__THROW __attribute_pure__ __nonnull ((1));
-# endif
+# endif
/* Find the last occurrence of C in S (same as strrchr). */
-# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
+# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
extern "C++"
{
extern char *rindex (char *__s, int __c)
@@ -82,7 +78,7 @@ extern char *rindex (char *__s, int __c)
extern const char *rindex (const char *__s, int __c)
__THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRING_H_PROTO
+# if defined __OPTIMIZE__
__extern_always_inline char *
rindex (char *__s, int __c) __THROW
{
@@ -94,46 +90,59 @@ rindex (const char *__s, int __c) __THROW
{
return __builtin_rindex (__s, __c);
}
-# endif
+# endif
}
-# else
+# else
extern char *rindex (const char *__s, int __c)
__THROW __attribute_pure__ __nonnull ((1));
-# endif
# endif
+#endif
#if defined __USE_MISC || !defined __USE_XOPEN2K8 || defined __USE_XOPEN2K8XSI
/* Return the position of the first bit set in I, or 0 if none are set.
The least-significant bit is position 1, the most-significant 32. */
-extern int ffs (int __i) __THROW __attribute__ ((const));
+extern int ffs (int __i) __THROW __attribute_const__;
#endif
+/* The following two functions are non-standard but necessary for non-32 bit
+ platforms. */
+# ifdef __USE_MISC
+extern int ffsl (long int __l) __THROW __attribute_const__;
+__extension__ extern int ffsll (long long int __ll)
+ __THROW __attribute_const__;
+# endif
+
/* Compare S1 and S2, ignoring case. */
extern int strcasecmp (const char *__s1, const char *__s2)
- __THROW __attribute_pure__;
+ __THROW __attribute_pure__ __nonnull ((1, 2));
/* Compare no more than N chars of S1 and S2, ignoring case. */
extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
- __THROW __attribute_pure__;
+ __THROW __attribute_pure__ __nonnull ((1, 2));
#ifdef __USE_XOPEN2K8
-/* The following functions are equivalent to the both above but they
- take the locale they use for the collation as an extra argument.
- This is not standardsized but something like will come. */
-# include <xlocale.h>
-
-/* Again versions of a few functions which use the given locale instead
- of the global one. */
-extern int strcasecmp_l (const char *__s1, const char *__s2, __locale_t __loc)
+/* POSIX.1-2008 extended locale interface (see locale.h). */
+# include <bits/types/locale_t.h>
+
+/* Compare S1 and S2, ignoring case, using collation rules from LOC. */
+extern int strcasecmp_l (const char *__s1, const char *__s2, locale_t __loc)
__THROW __attribute_pure__ __nonnull ((1, 2, 3));
+/* Compare no more than N chars of S1 and S2, ignoring case, using
+ collation rules from LOC. */
extern int strncasecmp_l (const char *__s1, const char *__s2,
- size_t __n, __locale_t __loc)
+ size_t __n, locale_t __loc)
__THROW __attribute_pure__ __nonnull ((1, 2, 4));
#endif
__END_DECLS
-#endif /* string.h */
+#if __GNUC_PREREQ (3,4) && __USE_FORTIFY_LEVEL > 0 \
+ && defined __fortify_function
+/* Functions with security checks. */
+# if defined __USE_MISC || !defined __USE_XOPEN2K8
+# include <bits/strings_fortified.h>
+# endif
+#endif
#endif /* strings.h */
diff --git a/string/strlen.c b/string/strlen.c
index 4943ce2ce3..8ce1318487 100644
--- a/string/strlen.c
+++ b/string/strlen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se);
diff --git a/string/strncase.c b/string/strncase.c
index e0aad264fa..2558d2969f 100644
--- a/string/strncase.c
+++ b/string/strncase.c
@@ -1,6 +1,6 @@
/* Compare at most N characters of two strings without taking care for
the case.
- Copyright (C) 1992-2016 Free Software Foundation, Inc.
+ Copyright (C) 1992-2018 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
@@ -36,7 +36,7 @@
#endif
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
-# define LOCALE_PARAM , __locale_t loc
+# define LOCALE_PARAM , locale_t loc
#else
# define LOCALE_PARAM
#endif
@@ -49,7 +49,7 @@ int
__strncasecmp (const char *s1, const char *s2, size_t n LOCALE_PARAM)
{
#if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL
- __locale_t loc = _NL_CURRENT_LOCALE;
+ locale_t loc = _NL_CURRENT_LOCALE;
#endif
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
diff --git a/string/strncase_l.c b/string/strncase_l.c
index 8de6acbdef..85245c3585 100644
--- a/string/strncase_l.c
+++ b/string/strncase_l.c
@@ -1,6 +1,6 @@
/* Compare at most N characters of two strings without taking care for
the case using given locale.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 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
diff --git a/string/strncat.c b/string/strncat.c
index 8b00a10d93..5d48a58632 100644
--- a/string/strncat.c
+++ b/string/strncat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -20,6 +20,7 @@
#ifndef STRNCAT
# undef strncat
# define STRNCAT strncat
+# define STRNCAT_PRIMARY
#endif
char *
@@ -37,3 +38,7 @@ STRNCAT (char *s1, const char *s2, size_t n)
return s;
}
+#ifdef STRNCAT_PRIMARY
+strong_alias (STRNCAT, __strncat)
+libc_hidden_def (__strncat)
+#endif
diff --git a/string/strncmp.c b/string/strncmp.c
index b77a33452b..801d9e11f7 100644
--- a/string/strncmp.c
+++ b/string/strncmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strncpy.c b/string/strncpy.c
index cbd85e1a4c..bb2abe30e5 100644
--- a/string/strncpy.c
+++ b/string/strncpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strndup.c b/string/strndup.c
index 51a1969146..d73925315d 100644
--- a/string/strndup.c
+++ b/string/strndup.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 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
diff --git a/string/strnlen.c b/string/strnlen.c
index b2b0664391..c2ce1eb95a 100644
--- a/string/strnlen.c
+++ b/string/strnlen.c
@@ -1,5 +1,5 @@
/* Find the length of STRING, but scan at most MAXLEN characters.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
Based on strlen written by Torbjorn Granlund (tege@sics.se),
diff --git a/string/strpbrk.c b/string/strpbrk.c
index fddd473ad7..adb10afb48 100644
--- a/string/strpbrk.c
+++ b/string/strpbrk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -27,15 +27,7 @@
char *
STRPBRK (const char *s, const char *accept)
{
- while (*s != '\0')
- {
- const char *a = accept;
- while (*a != '\0')
- if (*a++ == *s)
- return (char *) s;
- ++s;
- }
-
- return NULL;
+ s += strcspn (s, accept);
+ return *s ? (char *)s : NULL;
}
libc_hidden_builtin_def (strpbrk)
diff --git a/string/strrchr.c b/string/strrchr.c
index a07457e21b..3eff914cc0 100644
--- a/string/strrchr.c
+++ b/string/strrchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strsep.c b/string/strsep.c
index 1054774048..cbd670bee3 100644
--- a/string/strsep.c
+++ b/string/strsep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 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
@@ -29,30 +29,10 @@ __strsep (char **stringp, const char *delim)
if (begin == NULL)
return NULL;
- /* A frequent case is when the delimiter string contains only one
- character. Here we don't need to call the expensive `strpbrk'
- function and instead work using `strchr'. */
- if (delim[0] == '\0' || delim[1] == '\0')
- {
- char ch = delim[0];
-
- if (ch == '\0')
- end = NULL;
- else
- {
- if (*begin == ch)
- end = begin;
- else if (*begin == '\0')
- end = NULL;
- else
- end = strchr (begin + 1, ch);
- }
- }
- else
- /* Find the end of the token. */
- end = strpbrk (begin, delim);
+ /* Find the end of the token. */
+ end = begin + strcspn (begin, delim);
- if (end)
+ if (*end)
{
/* Terminate the token and set *STRINGP past NUL character. */
*end++ = '\0';
@@ -66,4 +46,5 @@ __strsep (char **stringp, const char *delim)
}
weak_alias (__strsep, strsep)
strong_alias (__strsep, __strsep_g)
+libc_hidden_def (__strsep)
libc_hidden_def (__strsep_g)
diff --git a/string/strsignal.c b/string/strsignal.c
index 706d6d30dc..b3305aecb7 100644
--- a/string/strsignal.c
+++ b/string/strsignal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/string/strspn.c b/string/strspn.c
index f0635c156a..3984cc8d2d 100644
--- a/string/strspn.c
+++ b/string/strspn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -16,32 +16,61 @@
<http://www.gnu.org/licenses/>. */
#include <string.h>
+#include <stdint.h>
+#include <libc-pointer-arith.h>
#undef strspn
#ifndef STRSPN
-#define STRSPN strspn
+# define STRSPN strspn
#endif
/* Return the length of the maximum initial segment
of S which contains only characters in ACCEPT. */
size_t
-STRSPN (const char *s, const char *accept)
+STRSPN (const char *str, const char *accept)
{
- const char *p;
- const char *a;
- size_t count = 0;
-
- for (p = s; *p != '\0'; ++p)
+ if (accept[0] == '\0')
+ return 0;
+ if (__glibc_unlikely (accept[1] == '\0'))
{
- for (a = accept; *a != '\0'; ++a)
- if (*p == *a)
- break;
- if (*a == '\0')
- return count;
- else
- ++count;
+ const char *a = str;
+ for (; *str == *accept; str++);
+ return str - a;
}
- return count;
+ /* Use multiple small memsets to enable inlining on most targets. */
+ unsigned char table[256];
+ unsigned char *p = memset (table, 0, 64);
+ memset (p + 64, 0, 64);
+ memset (p + 128, 0, 64);
+ memset (p + 192, 0, 64);
+
+ unsigned char *s = (unsigned char*) accept;
+ /* Different from strcspn it does not add the NULL on the table
+ so can avoid check if str[i] is NULL, since table['\0'] will
+ be 0 and thus stopping the loop check. */
+ do
+ p[*s++] = 1;
+ while (*s);
+
+ s = (unsigned char*) str;
+ if (!p[s[0]]) return 0;
+ if (!p[s[1]]) return 1;
+ if (!p[s[2]]) return 2;
+ if (!p[s[3]]) return 3;
+
+ s = (unsigned char *) PTR_ALIGN_DOWN (s, 4);
+
+ unsigned int c0, c1, c2, c3;
+ do {
+ s += 4;
+ c0 = p[s[0]];
+ c1 = p[s[1]];
+ c2 = p[s[2]];
+ c3 = p[s[3]];
+ } while ((c0 & c1 & c2 & c3) != 0);
+
+ size_t count = s - (unsigned char *) str;
+ return (c0 & c1) == 0 ? count + c0 : count + c2 + 2;
}
libc_hidden_builtin_def (strspn)
diff --git a/string/strstr.c b/string/strstr.c
index 4bf3e1aa73..265e9f310c 100644
--- a/string/strstr.c
+++ b/string/strstr.c
@@ -1,5 +1,5 @@
/* Return the offset of one string within another.
- Copyright (C) 1994-2016 Free Software Foundation, Inc.
+ Copyright (C) 1994-2018 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
@@ -33,10 +33,11 @@
#define RETURN_TYPE char *
#define AVAILABLE(h, h_l, j, n_l) \
- (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
- && ((h_l) = (j) + (n_l)))
+ (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
+ (j) + (n_l) <= (h_l)))
#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
+#define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C))
#include "str-two-way.h"
#undef strstr
diff --git a/string/strtok.c b/string/strtok.c
index 7a4574db5c..725249f3f4 100644
--- a/string/strtok.c
+++ b/string/strtok.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -18,14 +18,6 @@
#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:
@@ -36,32 +28,8 @@ static char *olds;
// 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);
}
diff --git a/string/strtok_r.c b/string/strtok_r.c
index f351304766..d0feadff47 100644
--- a/string/strtok_r.c
+++ b/string/strtok_r.c
@@ -1,5 +1,5 @@
/* Reentrant string tokenizer. Generic version.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 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
@@ -22,14 +22,10 @@
#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.
@@ -45,11 +41,17 @@
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')
@@ -59,18 +61,17 @@ __strtok_r (char *s, const char *delim, char **save_ptr)
}
/* 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)
diff --git a/string/strverscmp.c b/string/strverscmp.c
index 96d4227cd5..fc6265c817 100644
--- a/string/strverscmp.c
+++ b/string/strverscmp.c
@@ -1,5 +1,5 @@
/* Compare strings while treating digits characters numerically.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
diff --git a/string/strxfrm.c b/string/strxfrm.c
index 7a315cf87d..e898d32a59 100644
--- a/string/strxfrm.c
+++ b/string/strxfrm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c
index 22e24d37d8..5bda9a4b32 100644
--- a/string/strxfrm_l.c
+++ b/string/strxfrm_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@gnu.org>, 1995.
@@ -665,7 +665,7 @@ do_xfrm_cached (STRING_TYPE *dest, size_t n, const locale_data_t *l_data,
}
size_t
-STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, locale_t l)
{
locale_data_t l_data;
struct __locale_data *current = l->__locales[LC_COLLATE];
diff --git a/string/swab.c b/string/swab.c
index cbd8d570d1..28fe2a1ef3 100644
--- a/string/swab.c
+++ b/string/swab.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 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
diff --git a/string/test-bcopy.c b/string/test-bcopy.c
index d71e76e5c6..5e06fd5b77 100644
--- a/string/test-bcopy.c
+++ b/string/test-bcopy.c
@@ -1,5 +1,5 @@
/* Test and measure bcopy functions.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 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
diff --git a/string/test-bzero.c b/string/test-bzero.c
index 47b88a5ecd..9ca9bb6ecf 100644
--- a/string/test-bzero.c
+++ b/string/test-bzero.c
@@ -1,5 +1,5 @@
/* Test and measure bzero functions.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 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
diff --git a/string/test-endian-file-scope.c b/string/test-endian-file-scope.c
new file mode 100644
index 0000000000..e03063cfbb
--- /dev/null
+++ b/string/test-endian-file-scope.c
@@ -0,0 +1,44 @@
+/* Test endian.h endian-conversion macros accepted at file scope.
+ Copyright (C) 2018 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 <endian.h>
+#include <stddef.h>
+
+int i;
+
+size_t s0 = sizeof (htobe16 (i));
+size_t s1 = sizeof (htole16 (i));
+size_t s2 = sizeof (be16toh (i));
+size_t s3 = sizeof (le16toh (i));
+size_t s4 = sizeof (htobe32 (i));
+size_t s5 = sizeof (htole32 (i));
+size_t s6 = sizeof (be32toh (i));
+size_t s7 = sizeof (le32toh (i));
+size_t s8 = sizeof (htobe64 (i));
+size_t s9 = sizeof (htole64 (i));
+size_t s10 = sizeof (be64toh (i));
+size_t s11 = sizeof (le64toh (i));
+
+static int
+do_test (void)
+{
+ /* This is a compilation test. */
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/string/test-endian-sign-conversion.c b/string/test-endian-sign-conversion.c
new file mode 100644
index 0000000000..cc6b5168b6
--- /dev/null
+++ b/string/test-endian-sign-conversion.c
@@ -0,0 +1,48 @@
+/* Test endian.h endian-conversion macros work with -Wsign-conversion.
+ Copyright (C) 2018 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 <endian.h>
+#include <stdint.h>
+
+uint16_t u16;
+uint32_t u32;
+uint64_t u64;
+
+static int
+do_test (void)
+{
+ /* This is a compilation test. */
+ u16 = (htobe16 (u16));
+ u16 = (htole16 (u16));
+ u16 = (be16toh (u16));
+ u16 = (le16toh (u16));
+ u32 = (htobe32 (u32));
+ u32 = (htole32 (u32));
+ u32 = (be32toh (u32));
+ u32 = (le32toh (u32));
+ u64 = (htobe64 (u64));
+ u64 = (htole64 (u64));
+ u64 = (be64toh (u64));
+ u64 = (le64toh (u64));
+ (void) u16;
+ (void) u32;
+ (void) u64;
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/string/test-endian-types.c b/string/test-endian-types.c
new file mode 100644
index 0000000000..85872252ff
--- /dev/null
+++ b/string/test-endian-types.c
@@ -0,0 +1,49 @@
+/* Test endian.h endian-conversion macros always return the correct type.
+ Copyright (C) 2017-2018 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 <endian.h>
+#include <stdint.h>
+
+int i;
+uint16_t u16;
+uint32_t u32;
+uint64_t u64;
+
+int
+do_test (void)
+{
+ /* This is a compilation test. */
+ extern __typeof (htobe16 (i)) u16;
+ extern __typeof (htole16 (i)) u16;
+ extern __typeof (be16toh (i)) u16;
+ extern __typeof (le16toh (i)) u16;
+ extern __typeof (htobe32 (i)) u32;
+ extern __typeof (htole32 (i)) u32;
+ extern __typeof (be32toh (i)) u32;
+ extern __typeof (le32toh (i)) u32;
+ extern __typeof (htobe64 (i)) u64;
+ extern __typeof (htole64 (i)) u64;
+ extern __typeof (be64toh (i)) u64;
+ extern __typeof (le64toh (i)) u64;
+ (void) u16;
+ (void) u32;
+ (void) u64;
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/string/test-explicit_bzero.c b/string/test-explicit_bzero.c
new file mode 100644
index 0000000000..6ec00256e2
--- /dev/null
+++ b/string/test-explicit_bzero.c
@@ -0,0 +1,20 @@
+/* Test and measure explicit_bzero.
+ Copyright (C) 2016-2018 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/>. */
+#define TEST_EXPLICIT_BZERO
+#define TEST_BZERO
+#include "test-memset.c"
diff --git a/string/test-ffs.c b/string/test-ffs.c
index 035b63db2a..e5e7579a33 100644
--- a/string/test-ffs.c
+++ b/string/test-ffs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
On-Line Applications Research Corporation.
@@ -21,7 +21,7 @@
#include <stdio.h>
#include <string.h>
-static int
+int
do_test (void)
{
int failures = 0;
@@ -62,5 +62,4 @@ do_test (void)
return failures;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-memccpy.c b/string/test-memccpy.c
index 9884c80b0a..c70eff403f 100644
--- a/string/test-memccpy.c
+++ b/string/test-memccpy.c
@@ -1,5 +1,5 @@
/* Test and measure memccpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -266,4 +266,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-memchr.c b/string/test-memchr.c
index 449a19ae59..546dee5edf 100644
--- a/string/test-memchr.c
+++ b/string/test-memchr.c
@@ -1,5 +1,5 @@
/* Test memchr functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -23,7 +23,9 @@
#else
# define TEST_NAME "wmemchr"
#endif /* WIDE */
+
#include "test-string.h"
+#include <stdint.h>
#ifndef WIDE
# define MEMCHR memchr
@@ -71,12 +73,11 @@ do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res)
}
static void
-do_test (size_t align, size_t pos, size_t len, int seek_char)
+do_test (size_t align, size_t pos, size_t len, size_t n, int seek_char)
{
size_t i;
CHAR *result;
- align &= 7;
if ((align + len) * sizeof (CHAR) >= page_size)
return;
@@ -103,7 +104,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char)
}
FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result);
+ do_one_test (impl, (CHAR *) (buf + align), seek_char, n, result);
}
static void
@@ -167,7 +168,7 @@ do_random_tests (void)
int
test_main (void)
{
- size_t i;
+ size_t i, j;
test_init ();
@@ -178,19 +179,49 @@ test_main (void)
for (i = 1; i < 8; ++i)
{
- do_test (0, 16 << i, 2048, 23);
- do_test (i, 64, 256, 23);
- do_test (0, 16 << i, 2048, 0);
- do_test (i, 64, 256, 0);
+ /* Test n == 0. */
+ do_test (i, i, 0, 0, 23);
+ do_test (i, i, 0, 0, 0);
+
+ do_test (0, 16 << i, 2048, 2048, 23);
+ do_test (i, 64, 256, 256, 23);
+ do_test (0, 16 << i, 2048, 2048, 0);
+ do_test (i, 64, 256, 256, 0);
+
+ /* Check for large input sizes and for these cases we need to
+ make sure the byte is within the size range (that's why
+ 7 << i must be smaller than 2048). */
+ do_test (0, 7 << i, 2048, SIZE_MAX, 23);
+ do_test (0, 2048 - i, 2048, SIZE_MAX, 23);
+ do_test (i, 64, 256, SIZE_MAX, 23);
+ do_test (0, 7 << i, 2048, SIZE_MAX, 0);
+ do_test (0, 2048 - i, 2048, SIZE_MAX, 0);
+ do_test (i, 64, 256, SIZE_MAX, 0);
}
+
+ for (i = 1; i < 64; ++i)
+ {
+ for (j = 1; j < 64; j++)
+ {
+ do_test (0, 64 - j, 64, SIZE_MAX, 23);
+ do_test (i, 64 - j, 64, SIZE_MAX, 23);
+ }
+ }
+
for (i = 1; i < 32; ++i)
{
- do_test (0, i, i + 1, 23);
- do_test (0, i, i + 1, 0);
+ do_test (0, i, i + 1, i + 1, 23);
+ do_test (0, i, i + 1, i + 1, 0);
}
+ /* BZ#21182 - wrong overflow calculation for i686 implementation
+ with address near end of the page. */
+ for (i = 2; i < 16; ++i)
+ /* page_size is in fact getpagesize() * 2. */
+ do_test (page_size / 2 - i, i, i, 1, 0x9B);
+
do_random_tests ();
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-memcmp.c b/string/test-memcmp.c
index fa1bcefc0e..8bb928b04c 100644
--- a/string/test-memcmp.c
+++ b/string/test-memcmp.c
@@ -1,5 +1,5 @@
/* Test and measure memcmp functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wmemcmp support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011.
@@ -441,11 +441,12 @@ check1 (void)
n = 116;
for (size_t i = 0; i < n; i++)
- {
- exp_result = SIMPLE_MEMCMP (s1 + i, s2 + i, n - i);
- FOR_EACH_IMPL (impl, 0)
- check_result (impl, s1 + i, s2 + i, n - i, exp_result);
- }
+ for (size_t len = 0; len <= n - i; ++len)
+ {
+ exp_result = SIMPLE_MEMCMP (s1 + i, s2 + i, len);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1 + i, s2 + i, len, exp_result);
+ }
}
/* This test checks that memcmp doesn't overrun buffers. */
@@ -521,4 +522,5 @@ test_main (void)
do_random_tests ();
return ret;
}
-#include "../test-skeleton.c"
+
+#include <support/test-driver.c>
diff --git a/string/test-memcpy.c b/string/test-memcpy.c
index 2a0994ca98..3c8066da52 100644
--- a/string/test-memcpy.c
+++ b/string/test-memcpy.c
@@ -1,5 +1,5 @@
/* Test and measure memcpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -53,6 +53,12 @@ static void
do_one_test (impl_t *impl, char *dst, const char *src,
size_t len)
{
+ size_t i;
+
+ /* Must clear the destination buffer set by the previous run. */
+ for (i = 0; i < len; i++)
+ dst[i] = 0;
+
if (CALL (impl, dst, src, len) != MEMCPY_RESULT (dst, len))
{
error (0, 0, "Wrong result in function %s %p %p", impl->name,
@@ -206,6 +212,50 @@ do_random_tests (void)
}
}
+static void
+do_test1 (void)
+{
+ size_t size = 0x100000;
+ void *large_buf;
+
+ large_buf = mmap (NULL, size * 2 + page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (large_buf == MAP_FAILED)
+ {
+ puts ("Failed to allocat large_buf, skipping do_test1");
+ return;
+ }
+
+ if (mprotect (large_buf + size, page_size, PROT_NONE))
+ error (EXIT_FAILURE, errno, "mprotect failed");
+
+ size_t arrary_size = size / sizeof (uint32_t);
+ uint32_t *dest = large_buf;
+ uint32_t *src = large_buf + size + page_size;
+ size_t i;
+
+ for (i = 0; i < arrary_size; i++)
+ src[i] = (uint32_t) i;
+
+ FOR_EACH_IMPL (impl, 0)
+ {
+ memset (dest, -1, size);
+ CALL (impl, (char *) dest, (char *) src, size);
+ for (i = 0; i < arrary_size; i++)
+ if (dest[i] != src[i])
+ {
+ error (0, 0,
+ "Wrong result in function %s dst \"%p\" src \"%p\" offset \"%zd\"",
+ impl->name, dest, src, i);
+ ret = 1;
+ break;
+ }
+ }
+
+ munmap ((void *) dest, size);
+ munmap ((void *) src, size);
+}
+
int
test_main (void)
{
@@ -247,7 +297,10 @@ test_main (void)
do_test (0, 0, getpagesize ());
do_random_tests ();
+
+ do_test1 ();
+
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-memmem.c b/string/test-memmem.c
index e8ce80b608..51f58d1eda 100644
--- a/string/test-memmem.c
+++ b/string/test-memmem.c
@@ -1,5 +1,5 @@
/* Test and measure memmem functions.
- Copyright (C) 2008-2016 Free Software Foundation, Inc.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@redhat.com>, 2008.
@@ -181,4 +181,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-memmove.c b/string/test-memmove.c
index d2ab3f3c8d..64e3651ba4 100644
--- a/string/test-memmove.c
+++ b/string/test-memmove.c
@@ -1,5 +1,5 @@
/* Test and measure memmove functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -24,6 +24,7 @@
# define TEST_NAME "memmove"
#endif
#include "test-string.h"
+#include <support/test-driver.h>
char *simple_memmove (char *, const char *, size_t);
@@ -68,6 +69,7 @@ static void
do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
size_t len)
{
+ /* This also clears the destination buffer set by the previous run. */
memcpy (src, orig_src, len);
#ifdef TEST_BCOPY
CALL (impl, src, dst, len);
@@ -244,6 +246,60 @@ do_random_tests (void)
}
}
+static void
+do_test2 (void)
+{
+ size_t size = 0x20000000;
+ uint32_t * large_buf;
+
+ large_buf = mmap ((void*) 0x70000000, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+
+ if (large_buf == MAP_FAILED)
+ error (EXIT_UNSUPPORTED, errno, "Large mmap failed");
+
+ if ((uintptr_t) large_buf > 0x80000000 - 128
+ || 0x80000000 - (uintptr_t) large_buf > 0x20000000)
+ {
+ error (0, 0, "Large mmap allocated improperly");
+ ret = EXIT_UNSUPPORTED;
+ munmap ((void *) large_buf, size);
+ return;
+ }
+
+ size_t bytes_move = 0x80000000 - (uintptr_t) large_buf;
+ size_t arr_size = bytes_move / sizeof (uint32_t);
+ size_t i;
+
+ FOR_EACH_IMPL (impl, 0)
+ {
+ for (i = 0; i < arr_size; i++)
+ large_buf[i] = (uint32_t) i;
+
+ uint32_t * dst = &large_buf[33];
+
+#ifdef TEST_BCOPY
+ CALL (impl, (char *) large_buf, (char *) dst, bytes_move);
+#else
+ CALL (impl, (char *) dst, (char *) large_buf, bytes_move);
+#endif
+
+ for (i = 0; i < arr_size; i++)
+ {
+ if (dst[i] != (uint32_t) i)
+ {
+ error (0, 0,
+ "Wrong result in function %s dst \"%p\" src \"%p\" offset \"%zd\"",
+ impl->name, dst, large_buf, i);
+ ret = 1;
+ break;
+ }
+ }
+ }
+
+ munmap ((void *) large_buf, size);
+}
+
int
test_main (void)
{
@@ -283,7 +339,10 @@ test_main (void)
}
do_random_tests ();
+
+ do_test2 ();
+
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-mempcpy.c b/string/test-mempcpy.c
index f4969c24a5..d98ecdd2d9 100644
--- a/string/test-mempcpy.c
+++ b/string/test-mempcpy.c
@@ -1,5 +1,5 @@
/* Test and measure mempcpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -18,6 +18,7 @@
<http://www.gnu.org/licenses/>. */
#define MEMCPY_RESULT(dst, len) (dst) + (len)
+#define MIN_PAGE_SIZE 131072
#define TEST_MAIN
#define TEST_NAME "mempcpy"
#include "test-string.h"
diff --git a/string/test-memrchr.c b/string/test-memrchr.c
index 4d2e35b062..23ed762312 100644
--- a/string/test-memrchr.c
+++ b/string/test-memrchr.c
@@ -1,5 +1,5 @@
/* Test and measure memrchr functions.
- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+ Copyright (C) 2013-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -151,19 +151,36 @@ test_main (void)
for (i = 1; i < 8; ++i)
{
+ /* Test len == 0. */
+ do_test (i, i, 0, 0);
+ do_test (i, i, 0, 23);
+
do_test (0, 16 << i, 2048, 23);
do_test (i, 64, 256, 23);
do_test (0, 16 << i, 2048, 0);
do_test (i, 64, 256, 0);
+
+ do_test (0, i, 256, 23);
+ do_test (0, i, 256, 0);
+ do_test (i, i, 256, 23);
+ do_test (i, i, 256, 0);
+
}
for (i = 1; i < 32; ++i)
{
do_test (0, i, i + 1, 23);
do_test (0, i, i + 1, 0);
+ do_test (i, i, i + 1, 23);
+ do_test (i, i, i + 1, 0);
+
+ do_test (0, 1, i + 1, 23);
+ do_test (0, 2, i + 1, 0);
+ do_test (i, 1, i + 1, 23);
+ do_test (i, 2, i + 1, 0);
}
do_random_tests ();
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-memset.c b/string/test-memset.c
index fee3bdf37f..60c99f0002 100644
--- a/string/test-memset.c
+++ b/string/test-memset.c
@@ -1,5 +1,5 @@
/* Test memset functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -19,7 +19,11 @@
#define TEST_MAIN
#ifdef TEST_BZERO
-# define TEST_NAME "bzero"
+# ifdef TEST_EXPLICIT_BZERO
+# define TEST_NAME "explicit_bzero"
+# else
+# define TEST_NAME "bzero"
+# endif
#else
# ifndef WIDE
# define TEST_NAME "memset"
@@ -56,7 +60,11 @@ void builtin_bzero (char *, size_t);
IMPL (simple_bzero, 0)
IMPL (builtin_bzero, 0)
+#ifdef TEST_EXPLICIT_BZERO
+IMPL (explicit_bzero, 1)
+#else
IMPL (bzero, 1)
+#endif
void
simple_bzero (char *s, size_t n)
@@ -256,4 +264,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-rawmemchr.c b/string/test-rawmemchr.c
index f53c89786b..9161df52c8 100644
--- a/string/test-rawmemchr.c
+++ b/string/test-rawmemchr.c
@@ -1,5 +1,5 @@
/* Test and measure memchr functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -162,4 +162,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-stpcpy.c b/string/test-stpcpy.c
index ce325e67b7..73a9d1f971 100644
--- a/string/test-stpcpy.c
+++ b/string/test-stpcpy.c
@@ -1,5 +1,5 @@
/* Test stpcpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
diff --git a/string/test-stpncpy.c b/string/test-stpncpy.c
index af8f5000e7..ec891f9ec7 100644
--- a/string/test-stpncpy.c
+++ b/string/test-stpncpy.c
@@ -1,5 +1,5 @@
/* Test and measure stpncpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
diff --git a/string/test-strcasecmp.c b/string/test-strcasecmp.c
index 63ae2a2ef5..6f4e7bee6f 100644
--- a/string/test-strcasecmp.c
+++ b/string/test-strcasecmp.c
@@ -1,5 +1,5 @@
/* Test and measure strcasecmp functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -267,4 +267,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strcasestr.c b/string/test-strcasestr.c
index dea89471f9..9b1088df54 100644
--- a/string/test-strcasestr.c
+++ b/string/test-strcasestr.c
@@ -1,5 +1,5 @@
/* Test and measure strcasestr functions.
- Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ Copyright (C) 2010-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@redhat.com>, 2010.
@@ -25,6 +25,7 @@
#define STRCASESTR simple_strcasestr
#define NO_ALIAS
#define __strncasecmp strncasecmp
+#define __strnlen strnlen
#include "strcasestr.c"
@@ -191,4 +192,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strcat.c b/string/test-strcat.c
index 1dda0215b8..c9735c5521 100644
--- a/string/test-strcat.c
+++ b/string/test-strcat.c
@@ -1,5 +1,5 @@
/* Test strcat functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -269,4 +269,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strchr.c b/string/test-strchr.c
index 27e403d257..8d5068cbef 100644
--- a/string/test-strchr.c
+++ b/string/test-strchr.c
@@ -1,5 +1,5 @@
/* Test STRCHR functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wcschr support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
@@ -293,4 +293,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strchrnul.c b/string/test-strchrnul.c
index f635b82a28..d632d51a76 100644
--- a/string/test-strchrnul.c
+++ b/string/test-strchrnul.c
@@ -1,6 +1,6 @@
/* Test and measure strchrnul function.
- Copyright (C) 2011-2016 Free Software Foundation, Inc.
+ Copyright (C) 2011-2018 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
diff --git a/string/test-strcmp.c b/string/test-strcmp.c
index 8d4772a658..9bc4a80a28 100644
--- a/string/test-strcmp.c
+++ b/string/test-strcmp.c
@@ -1,5 +1,5 @@
/* Test and measure strcmp and wcscmp functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wcscmp support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011.
@@ -406,4 +406,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strcpy.c b/string/test-strcpy.c
index 4e925b1e95..2a1bf93da1 100644
--- a/string/test-strcpy.c
+++ b/string/test-strcpy.c
@@ -1,5 +1,5 @@
/* Test and measure strcpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wcscpy support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
@@ -242,4 +242,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strcspn.c b/string/test-strcspn.c
index d0a731569c..3e219644e6 100644
--- a/string/test-strcspn.c
+++ b/string/test-strcspn.c
@@ -1,5 +1,5 @@
/* Test strcspn functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
diff --git a/string/test-string.h b/string/test-string.h
index 728a7c226a..883878b2e9 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -1,5 +1,5 @@
/* Test and measure string and memory functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -40,6 +40,18 @@ extern impl_t __start_impls[], __stop_impls[];
#undef __USE_STRING_INLINES
+/* We are compiled under _ISOMAC, so libc-symbols.h does not do this
+ for us. */
+#include "config.h"
+#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
+# define inhibit_loop_to_libcall \
+ __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
+#else
+# define inhibit_loop_to_libcall
+#endif
+
+#include <getopt.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -55,7 +67,7 @@ extern impl_t __start_impls[], __stop_impls[];
#define GLRO(x) _##x
-# define TEST_FUNCTION test_main ()
+# define TEST_FUNCTION test_main
# define TIMEOUT (4 * 60)
# define OPT_ITERATIONS 10000
# define OPT_RANDOM 10001
@@ -83,23 +95,31 @@ size_t iterations = 100000;
# define CMDLINE_OPTIONS ITERATIONS_OPTIONS \
{ "random", no_argument, NULL, OPT_RANDOM }, \
{ "seed", required_argument, NULL, OPT_SEED },
-# define CMDLINE_PROCESS ITERATIONS_PROCESS \
- case OPT_RANDOM: \
- { \
- int fdr = open ("/dev/urandom", O_RDONLY); \
- \
- if (fdr < 0 || read (fdr, &seed, sizeof(seed)) != sizeof (seed)) \
- seed = time (NULL); \
- if (fdr >= 0) \
- close (fdr); \
- do_srandom = 1; \
- break; \
- } \
- \
- case OPT_SEED: \
- seed = strtoul (optarg, NULL, 0); \
- do_srandom = 1; \
- break;
+
+static void __attribute__ ((used))
+cmdline_process_function (int c)
+{
+ switch (c)
+ {
+ ITERATIONS_PROCESS
+ case OPT_RANDOM:
+ {
+ int fdr = open ("/dev/urandom", O_RDONLY);
+ if (fdr < 0 || read (fdr, &seed, sizeof (seed)) != sizeof (seed))
+ seed = time (NULL);
+ if (fdr >= 0)
+ close (fdr);
+ do_srandom = 1;
+ break;
+ }
+
+ case OPT_SEED:
+ seed = strtoul (optarg, NULL, 0);
+ do_srandom = 1;
+ break;
+ }
+}
+# define CMDLINE_PROCESS cmdline_process_function
#define CALL(impl, ...) \
(* (proto_t) (impl)->fn) (__VA_ARGS__)
diff --git a/string/test-strlen.c b/string/test-strlen.c
index 1838b12d51..4c21147f6d 100644
--- a/string/test-strlen.c
+++ b/string/test-strlen.c
@@ -1,5 +1,5 @@
/* Test and measure STRLEN functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wcslen support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
@@ -164,4 +164,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c
index 08f7a492fb..c117dd3662 100644
--- a/string/test-strncasecmp.c
+++ b/string/test-strncasecmp.c
@@ -1,5 +1,5 @@
/* Test and measure strncasecmp functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -350,4 +350,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strncat.c b/string/test-strncat.c
index 0e9db236ef..0ddd94ea66 100644
--- a/string/test-strncat.c
+++ b/string/test-strncat.c
@@ -1,5 +1,5 @@
/* Test strncat functions.
- Copyright (C) 2011-2016 Free Software Foundation, Inc.
+ Copyright (C) 2011-2018 Free Software Foundation, Inc.
Contributed by Intel Corporation.
The GNU C Library is free software; you can redistribute it and/or
@@ -284,12 +284,23 @@ test_main (void)
do_test (0, 0, 8, 8, n, SMALL_CHAR);
do_test (0, 8, 8, 8, n, SMALL_CHAR);
+ do_test (0, 2, 2, 2, SIZE_MAX, SMALL_CHAR);
+ do_test (0, 0, 4, 4, SIZE_MAX, SMALL_CHAR);
+ do_test (4, 0, 4, 4, SIZE_MAX, BIG_CHAR);
+ do_test (0, 0, 8, 8, SIZE_MAX, SMALL_CHAR);
+ do_test (0, 8, 8, 8, SIZE_MAX, SMALL_CHAR);
+
for (i = 1; i < 8; ++i)
{
do_test (0, 0, 8 << i, 8 << i, n, SMALL_CHAR);
do_test (8 - i, 2 * i, 8 << i, 8 << i, n, SMALL_CHAR);
do_test (0, 0, 8 << i, 2 << i, n, SMALL_CHAR);
do_test (8 - i, 2 * i, 8 << i, 2 << i, n, SMALL_CHAR);
+
+ do_test (0, 0, 8 << i, 8 << i, SIZE_MAX, SMALL_CHAR);
+ do_test (8 - i, 2 * i, 8 << i, 8 << i, SIZE_MAX, SMALL_CHAR);
+ do_test (0, 0, 8 << i, 2 << i, SIZE_MAX, SMALL_CHAR);
+ do_test (8 - i, 2 * i, 8 << i, 2 << i, SIZE_MAX, SMALL_CHAR);
}
for (i = 1; i < 8; ++i)
@@ -297,6 +308,10 @@ test_main (void)
do_test (i, 2 * i, 8 << i, 1, n, SMALL_CHAR);
do_test (2 * i, i, 8 << i, 1, n, BIG_CHAR);
do_test (i, i, 8 << i, 10, n, SMALL_CHAR);
+
+ do_test (i, 2 * i, 8 << i, 1, SIZE_MAX, SMALL_CHAR);
+ do_test (2 * i, i, 8 << i, 1, SIZE_MAX, BIG_CHAR);
+ do_test (i, i, 8 << i, 10, SIZE_MAX, SMALL_CHAR);
}
}
@@ -304,4 +319,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strncmp.c b/string/test-strncmp.c
index 8c0a331fc8..ff2ac3e4c6 100644
--- a/string/test-strncmp.c
+++ b/string/test-strncmp.c
@@ -1,5 +1,5 @@
/* Test strncmp and wcsncmp functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -156,6 +156,9 @@ do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char,
size_t i, align_n;
CHAR *s1, *s2;
+ align1 &= ~(CHARBYTES - 1);
+ align2 &= ~(CHARBYTES - 1);
+
if (n == 0)
{
s1 = (CHAR *) (buf1 + page_size);
@@ -204,6 +207,9 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
size_t i;
CHAR *s1, *s2;
+ align1 &= ~(CHARBYTES - 1);
+ align2 &= ~(CHARBYTES - 1);
+
if (n == 0)
return;
@@ -470,4 +476,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strncpy.c b/string/test-strncpy.c
index 75b4170e90..ff4240cf5c 100644
--- a/string/test-strncpy.c
+++ b/string/test-strncpy.c
@@ -1,5 +1,5 @@
/* Test strncpy functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -320,4 +320,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strnlen.c b/string/test-strnlen.c
index 5149820ab3..1eec1ba83a 100644
--- a/string/test-strnlen.c
+++ b/string/test-strnlen.c
@@ -1,5 +1,5 @@
/* Test strlen functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -143,6 +143,59 @@ do_random_tests (void)
}
}
+/* Tests meant to unveil fail on implementation that does not access bytes
+ around the page boundary accordingly. */
+static void
+do_page_tests (void)
+{
+ size_t i, exp_len, start_offset, offset;
+ /* Calculate the null character offset. */
+ size_t last_offset = (page_size / sizeof (CHAR)) - 1;
+
+ CHAR *s = (CHAR *) buf2;
+ memset (s, 65, (last_offset - 1));
+ s[last_offset] = 0;
+
+ /* Place short strings ending at page boundary. */
+ offset = last_offset;
+ for (i = 0; i < 128; i++)
+ {
+ /* Decrease offset to stress several sizes and alignments. */
+ offset--;
+ exp_len = last_offset - offset;
+ FOR_EACH_IMPL (impl, 0)
+ {
+ /* Varies maxlen value to cover the cases where it is:
+ - larger than length;
+ - slightly greater than length;
+ - equal to length;
+ - slightly less than length. */
+ do_one_test (impl, (CHAR *) (s + offset), page_size, exp_len);
+ do_one_test (impl, (CHAR *) (s + offset), exp_len + 1, exp_len);
+ do_one_test (impl, (CHAR *) (s + offset), exp_len, exp_len);
+ if (exp_len > 0)
+ do_one_test (impl, (CHAR *) (s + offset), exp_len - 1, exp_len - 1);
+ }
+ }
+
+ /* Place long strings ending at page boundary. */
+ start_offset = (last_offset + 1) / 2;
+ for (i = 0; i < 64; ++i)
+ {
+ /* Increase offset to stress several alignments. */
+ offset = start_offset + i;
+ if (offset >= (last_offset + 1))
+ break;
+ exp_len = last_offset - offset;
+ FOR_EACH_IMPL (impl, 0)
+ {
+ /* Checks only for maxlen much larger than length because smaller
+ values are already covered in do_random_tests function. */
+ do_one_test (impl, (CHAR *) (s + offset), page_size, exp_len);
+ }
+ }
+}
+
int
test_main (void)
{
@@ -188,7 +241,8 @@ test_main (void)
}
do_random_tests ();
+ do_page_tests ();
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strpbrk.c b/string/test-strpbrk.c
index 0cd643c042..bc373063aa 100644
--- a/string/test-strpbrk.c
+++ b/string/test-strpbrk.c
@@ -1,5 +1,5 @@
/* Test and measure strpbrk functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -264,4 +264,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strrchr.c b/string/test-strrchr.c
index 9a102959bd..e73fa01a3c 100644
--- a/string/test-strrchr.c
+++ b/string/test-strrchr.c
@@ -1,5 +1,5 @@
/* Test and measure STRCHR functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
Added wcsrrchr support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>,
@@ -244,4 +244,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strspn.c b/string/test-strspn.c
index 98b51dab0e..533c3e9528 100644
--- a/string/test-strspn.c
+++ b/string/test-strspn.c
@@ -1,5 +1,5 @@
/* Test and measure strspn functions.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -242,4 +242,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/test-strstr.c b/string/test-strstr.c
index 763edab20b..8d99716ff3 100644
--- a/string/test-strstr.c
+++ b/string/test-strstr.c
@@ -1,5 +1,5 @@
/* Test and measure strstr functions.
- Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ Copyright (C) 2010-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@redhat.com>, 2010.
@@ -23,6 +23,8 @@
#define STRSTR simple_strstr
+#define libc_hidden_builtin_def(arg) /* nothing */
+#define __strnlen strnlen
#include "strstr.c"
@@ -208,4 +210,4 @@ test_main (void)
return ret;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/testcopy.c b/string/testcopy.c
index 1c9d22b5fb..f14917befe 100644
--- a/string/testcopy.c
+++ b/string/testcopy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1990-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
@@ -19,10 +19,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <malloc.h>
+#include <support/support.h>
-int
-main (void)
+static int
+do_test (void)
{
char *mem, *memp;
char *rand_mem;
@@ -34,10 +34,10 @@ main (void)
max_size = 256;
- mem = malloc (max_size + 2 * max_size + 2 * space_around);
- rand_mem = malloc (max_size);
- lo_around = malloc (space_around);
- hi_around = malloc (space_around);
+ mem = xmalloc (max_size + 2 * max_size + 2 * space_around);
+ rand_mem = xmalloc (max_size);
+ lo_around = xmalloc (space_around);
+ hi_around = xmalloc (space_around);
memp = mem + space_around;
/* Fill RAND_MEM with random bytes, each non-zero. */
@@ -105,3 +105,5 @@ main (void)
return 0;
}
+
+#include <support/test-driver.c>
diff --git a/string/tester.c b/string/tester.c
index 7c36591d8d..601eb01b55 100644
--- a/string/tester.c
+++ b/string/tester.c
@@ -1,5 +1,5 @@
/* Tester for string functions.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 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
@@ -32,7 +32,7 @@
#include <string.h>
#include <strings.h>
#include <fcntl.h>
-#include <libc-internal.h>
+#include <libc-diag.h>
#define STREQ(a, b) (strcmp((a), (b)) == 0)
@@ -264,8 +264,15 @@ test_stpncpy (void)
{
it = "stpncpy";
memset (one, 'x', sizeof (one));
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (8, 0)
+ /* GCC 8 warns about stpncpy truncating output; this is deliberately
+ tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+#endif
check (stpncpy (one, "abc", 2) == one + 2, 1);
check (stpncpy (one, "abc", 3) == one + 3, 2);
+ DIAG_POP_NEEDS_COMMENT;
check (stpncpy (one, "abc", 4) == one + 3, 3);
check (one[3] == '\0' && one[4] == 'x', 4);
check (stpncpy (one, "abcd", 5) == one + 4, 5);
@@ -353,41 +360,106 @@ test_strncat (void)
mechanism. */
it = "strncat";
(void) strcpy (one, "ijk");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here.. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "ijklmn", 2); /* Basic test. */
(void) strcpy (one, "x");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here.. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
(void) strncat (one, "yz", 99);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "xyz", 3); /* Writeover. */
equal (one+4, "mn", 4); /* Wrote too much? */
(void) strcpy (one, "gh");
(void) strcpy (two, "ef");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here; GCC 8
+ gives a -Warray-bounds warning about this. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
(void) strncat (one, two, 99);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "ghef", 5); /* Basic test encore. */
equal (two, "ef", 6); /* Stomped on source? */
(void) strcpy (one, "");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here.. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
(void) strncat (one, "", 99);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "", 7); /* Boundary conditions. */
(void) strcpy (one, "ab");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here.. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
(void) strncat (one, "", 99);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "ab", 8);
(void) strcpy (one, "");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here.. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
(void) strncat (one, "cd", 99);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "cd", 9);
(void) strcpy (one, "ab");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (8, 0)
+ /* GCC 8 warns about strncat truncating output; this is deliberately
+ tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+#endif
(void) strncat (one, "cdef", 2);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "abcd", 10); /* Count-limited. */
(void) strncat (one, "gh", 0);
equal (one, "abcd", 11); /* Zero count. */
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 8 warns about strncat bound equal to source length; this is
+ deliberately tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
+#endif
(void) strncat (one, "gh", 2);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "abcdgh", 12); /* Count and length equal. */
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being larger than
+ the size of the buffer; this is deliberately tested here.. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+#endif
(void) strncat (one, "ij", (size_t)-1); /* set sign bit in count */
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "abcdghij", 13);
int ntest = 14;
@@ -406,8 +478,22 @@ test_strncat (void)
buf1[n2 + n3] = '\0';
strcpy (buf2 + n1, "123");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about the size passed to strncat being
+ larger than the size of the buffer; this is
+ deliberately tested here; GCC 8 gives a -Warray-bounds
+ warning about this. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
+ /* GCC 9 as of 2018-06-14 warns that the size passed is
+ large enough that, if it were the actual object size,
+ the objects would have to overlap. */
+ DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
+#endif
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
check (strncat (buf1 + n2, buf2 + n1, ~((size_t) 0) - n4)
== buf1 + n2, ntest);
+ DIAG_POP_NEEDS_COMMENT;
if (errors == olderrors)
for (size_t i = 0; i < sizeof (buf1); ++i)
{
@@ -466,11 +552,25 @@ test_strncpy (void)
equal (one, "abc", 2); /* Did the copy go right? */
(void) strcpy (one, "abcdefgh");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (8, 0)
+ /* GCC 8 warns about strncpy truncating output; this is deliberately
+ tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+#endif
(void) strncpy (one, "xyz", 2);
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "xycdefgh", 3); /* Copy cut by count. */
(void) strcpy (one, "abcdefgh");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (8, 0)
+ /* GCC 8 warns about strncpy truncating output; this is deliberately
+ tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+#endif
(void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "xyzdefgh", 4);
(void) strcpy (one, "abcdefgh");
@@ -485,7 +585,14 @@ test_strncpy (void)
equal (one+5, "fgh", 9);
(void) strcpy (one, "abc");
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (8, 0)
+ /* GCC 8 warns about strncpy truncating output; this is deliberately
+ tested here. */
+ DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
+#endif
(void) strncpy (one, "xyz", 0); /* Zero-length copy. */
+ DIAG_POP_NEEDS_COMMENT;
equal (one, "abc", 10);
(void) strncpy (one, "", 2); /* Zero-length source. */
@@ -1094,8 +1201,8 @@ test_memcmp (void)
{
char *a = one + i;
char *b = two + i;
- strncpy(a, "--------11112222", 16);
- strncpy(b, "--------33334444", 16);
+ memcpy(a, "--------11112222", 16);
+ memcpy(b, "--------33334444", 16);
check(memcmp(b, a, 16) > 0, cnt++);
check(memcmp(a, b, 16) < 0, cnt++);
}
diff --git a/string/tst-bswap.c b/string/tst-bswap.c
index fdab5fc816..7b8ce4a3fc 100644
--- a/string/tst-bswap.c
+++ b/string/tst-bswap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>.
@@ -21,7 +21,7 @@
extern unsigned long long int wash (unsigned long long int a);
-static int
+int
do_test (void)
{
int result = 0;
@@ -72,5 +72,4 @@ wash (unsigned long long int a)
return a + 0;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-cmp.c b/string/tst-cmp.c
new file mode 100644
index 0000000000..3b9f7b2506
--- /dev/null
+++ b/string/tst-cmp.c
@@ -0,0 +1,227 @@
+/* Alignment/padding coverage test for string comparison.
+ Copyright (C) 2016-2018 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/>. */
+
+/* This performs test comparisons with various (mis)alignments and
+ characters in the padding. It is partly a regression test for bug
+ 20327. */
+
+#include <limits.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libc-diag.h>
+
+static int
+signum (int val)
+{
+ if (val < 0)
+ return -1;
+ if (val > 0)
+ return 1;
+ else
+ return 0;
+}
+
+static size_t
+max_size_t (size_t left, size_t right)
+{
+ if (left > right)
+ return left;
+ else
+ return right;
+}
+
+/* Wrappers for strncmp and strncasecmp which determine the maximum
+ string length in some, either based on the input string length, or
+ using fixed constants. */
+
+static int
+strncmp_no_terminator (const char *left, const char *right)
+{
+ size_t left_len = strlen (left);
+ size_t right_len = strlen (right);
+ return strncmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncasecmp_no_terminator (const char *left, const char *right)
+{
+ size_t left_len = strlen (left);
+ size_t right_len = strlen (right);
+ return strncasecmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncmp_terminator (const char *left, const char *right)
+{
+ size_t left_len = strlen (left);
+ size_t right_len = strlen (right);
+ return strncmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncasecmp_terminator (const char *left, const char *right)
+{
+ size_t left_len = strlen (left);
+ size_t right_len = strlen (right);
+ return strncasecmp (left, right, max_size_t (left_len, right_len));
+}
+
+static int
+strncmp_64 (const char *left, const char *right)
+{
+ return strncmp (left, right, 64);
+}
+
+static int
+strncasecmp_64 (const char *left, const char *right)
+{
+ return strncasecmp (left, right, 64);
+}
+
+static int
+strncmp_max (const char *left, const char *right)
+{
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 9 warns about the size passed to strncmp being larger than
+ PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
+ DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
+#endif
+ return strncmp (left, right, SIZE_MAX);
+ DIAG_POP_NEEDS_COMMENT;
+}
+
+static int
+strncasecmp_max (const char *left, const char *right)
+{
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 9 warns about the size passed to strncasecmp being larger
+ than PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
+ DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
+#endif
+ return strncasecmp (left, right, SIZE_MAX);
+ DIAG_POP_NEEDS_COMMENT;
+}
+
+int
+do_test (void)
+{
+ enum {
+ max_align = 64,
+ max_string_length = 33
+ };
+ size_t blob_size = max_align + max_string_length + 1;
+ char *left = memalign (max_align, blob_size);
+ char *right = memalign (max_align, blob_size);
+ if (left == NULL || right == NULL)
+ {
+ printf ("error: out of memory\n");
+ return 1;
+ }
+
+ const struct
+ {
+ const char *name;
+ int (*implementation) (const char *, const char *);
+ } functions[] =
+ {
+ { "strcmp", strcmp },
+ { "strcasecmp", strcasecmp },
+ { "strncmp (without NUL)", strncmp_no_terminator},
+ { "strncasecmp (without NUL)", strncasecmp_no_terminator},
+ { "strncmp (with NUL)", strncmp_terminator},
+ { "strncasecmp (with NUL)", strncasecmp_terminator},
+ { "strncmp (length 64)", strncmp_64},
+ { "strncasecmp (length 64)", strncasecmp_64},
+ { "strncmp (length SIZE_MAX)", strncmp_max},
+ { "strncasecmp (length SIZE_MAX)", strncasecmp_max},
+ { NULL, NULL }
+ };
+ const char *const strings[] =
+ {
+ "",
+ "0",
+ "01",
+ "01234567",
+ "0123456789abcde",
+ "0123456789abcdef",
+ "0123456789abcdefg",
+ "1",
+ "10",
+ "123456789abcdef",
+ "123456789abcdefg",
+ "23456789abcdef",
+ "23456789abcdefg",
+ "abcdefghijklmnopqrstuvwxyzABCDEF",
+ NULL
+ };
+ const unsigned char pads[] =
+ { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
+
+ bool errors = false;
+ for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx)
+ for (int left_align = 0; left_align < max_align; ++left_align)
+ for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left)
+ {
+ memset (left, pads[pad_left], blob_size);
+ strcpy (left + left_align, strings[left_idx]);
+
+ for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx)
+ for (unsigned pad_right = 0; pad_right < sizeof (pads);
+ ++pad_right)
+ for (int right_align = 0; right_align < max_align;
+ ++right_align)
+ {
+ memset (right, pads[pad_right], blob_size);
+ strcpy (right + right_align, strings[right_idx]);
+
+ for (int func = 0; functions[func].name != NULL; ++func)
+ {
+ int expected = left_idx - right_idx;
+ int actual = functions[func].implementation
+ (left + left_align, right + right_align);
+ if (signum (actual) != signum (expected))
+ {
+ printf ("error: mismatch for %s: %d\n"
+ " left: \"%s\"\n"
+ " right: \"%s\"\n"
+ " pad_left = %u, pad_right = %u,\n"
+ " left_align = %d, right_align = %d\n",
+ functions[func].name, actual,
+ strings[left_idx], strings[right_idx],
+ pad_left, pad_right,
+ left_align, right_align);
+ errors = true;
+ }
+ }
+ }
+ }
+ free (right);
+ free (left);
+ return errors;
+}
+
+/* The nested loops need a long time to complete on slower
+ machines. */
+#define TIMEOUT 600
+
+#include <support/test-driver.c>
diff --git a/string/tst-endian.c b/string/tst-endian.c
index 7d39131a68..b156ede199 100644
--- a/string/tst-endian.c
+++ b/string/tst-endian.c
@@ -3,7 +3,7 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
-#include <libc-internal.h>
+#include <libc-diag.h>
#if __GNUC_PREREQ (6, 0)
/* GCC 6.0 warns on big endian systems about:
@@ -18,7 +18,7 @@
# define DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE()
#endif
-static int
+int
do_test (void)
{
int result = 0;
@@ -131,5 +131,4 @@ do_test (void)
return result;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-inlcall.c b/string/tst-inlcall.c
index 9769263677..9b355aa997 100644
--- a/string/tst-inlcall.c
+++ b/string/tst-inlcall.c
@@ -1,5 +1,5 @@
/* Tester for calling inline string functions.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 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
@@ -31,7 +31,7 @@
#include <fcntl.h>
-static int
+int
do_test (void)
{
int status;
@@ -81,5 +81,4 @@ do_test (void)
return status;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strcoll-overflow.c b/string/tst-strcoll-overflow.c
index 9b130ab90f..4b83e6cba5 100644
--- a/string/tst-strcoll-overflow.c
+++ b/string/tst-strcoll-overflow.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2018 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
@@ -21,42 +21,34 @@
#include <stdlib.h>
#include <string.h>
-/* Verify that strcoll does not crash for large strings for which it cannot
- cache weight lookup results. The size is large enough to cause integer
- overflows on 32-bit as well as buffer overflows on 64-bit. The test should
- work reasonably reliably when overcommit is disabled, but it obviously
- depends on how much memory the system has. There's a limitation to this
- test in that it does not run to completion. Actually collating such a
- large string can take days and we can't have xcheck running that long. For
- that reason, we run the test for about 5 minutes and then assume that
- everything is fine if there are no crashes. */
+#include <support/check.h>
+#include <support/test-driver.h>
+
+/* Verify that strcoll does not crash for large strings for which it
+ cannot cache weight lookup results. The size is large enough to
+ cause integer overflows on 32-bit as well as buffer overflows on
+ 64-bit. */
#define SIZE 0x40000000ul
int
do_test (void)
{
- if (setlocale (LC_COLLATE, "en_GB.UTF-8") == NULL)
- {
- puts ("setlocale failed, cannot test for overflow");
- return 0;
- }
+ TEST_VERIFY_EXIT (setlocale (LC_COLLATE, "en_GB.UTF-8") != NULL);
char *p = malloc (SIZE);
-
if (p == NULL)
{
- puts ("could not allocate memory");
- return 1;
+ puts ("info: could not allocate memory, cannot run test");
+ return EXIT_UNSUPPORTED;
}
memset (p, 'x', SIZE - 1);
p[SIZE - 1] = 0;
- printf ("%d\n", strcoll (p, p));
+ printf ("info: strcoll result: %d\n", strcoll (p, p));
return 0;
}
+/* This test can rung for a long time, but it should complete within
+ this time on reasonably current hardware. */
#define TIMEOUT 300
-#define EXPECTED_SIGNAL SIGALRM
-#define EXPECTED_STATUS 0
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strfry.c b/string/tst-strfry.c
index 2b40a39b13..e4e9018c5b 100644
--- a/string/tst-strfry.c
+++ b/string/tst-strfry.c
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <string.h>
-static int
+int
do_test (void)
{
char str[] = "this is a test";
@@ -11,5 +11,4 @@ do_test (void)
return 0;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strlen.c b/string/tst-strlen.c
index 8376831de5..15fbc8bd7b 100644
--- a/string/tst-strlen.c
+++ b/string/tst-strlen.c
@@ -5,7 +5,7 @@
#include <stdio.h>
#include <string.h>
-static int
+int
do_test (void)
{
static const size_t lens[] = { 0, 1, 0, 2, 0, 1, 0, 3,
@@ -54,5 +54,4 @@ strnlen failed for base=%Zu, words=%Zu, and last=%Zu (is %zd, expected %zd)\n",
return 0;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strtok.c b/string/tst-strtok.c
index 6fbef9f33e..628e106a46 100644
--- a/string/tst-strtok.c
+++ b/string/tst-strtok.c
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <string.h>
-static int
+int
do_test (void)
{
char buf[1] = { 0 };
@@ -22,5 +22,4 @@ do_test (void)
return result;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strtok_r.c b/string/tst-strtok_r.c
index 8bd20220c6..463b2ef765 100644
--- a/string/tst-strtok_r.c
+++ b/string/tst-strtok_r.c
@@ -1,5 +1,5 @@
/* Test strtok_r regression for BZ #14229.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 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
@@ -35,4 +35,4 @@ test_main (void)
return strcmp (tok, "udf") != 0;
}
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strxfrm.c b/string/tst-strxfrm.c
index f48cfc0da4..ffe191c60d 100644
--- a/string/tst-strxfrm.c
+++ b/string/tst-strxfrm.c
@@ -58,7 +58,7 @@ test (const char *locale)
}
-static int
+int
do_test (void)
{
int result = 0;
@@ -70,5 +70,4 @@ do_test (void)
return result;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-strxfrm2.c b/string/tst-strxfrm2.c
index bea5aa2cea..12117e80d6 100644
--- a/string/tst-strxfrm2.c
+++ b/string/tst-strxfrm2.c
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <string.h>
-static int
+int
do_test (void)
{
static const char test_locale[] = "de_DE.UTF-8";
@@ -81,5 +81,4 @@ do_test (void)
return res;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-svc.c b/string/tst-svc.c
index 1b0da3efe5..d5cf2c19c9 100644
--- a/string/tst-svc.c
+++ b/string/tst-svc.c
@@ -13,7 +13,7 @@ compare (const void *p1, const void *p2)
return strverscmp (*((char **) p1), *((char **) p2));
}
-static int
+int
do_test (void)
{
char line[MAX_LINE_SIZE + 1];
@@ -44,5 +44,4 @@ do_test (void)
return EXIT_SUCCESS;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-svc2.c b/string/tst-svc2.c
index 12c88aa2b8..c0aa03dc18 100644
--- a/string/tst-svc2.c
+++ b/string/tst-svc2.c
@@ -26,7 +26,7 @@ compare (const char *str1, const char *str2, int exp)
}
-static int
+int
do_test (void)
{
int res = 0;
@@ -58,5 +58,4 @@ do_test (void)
return res;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c
new file mode 100644
index 0000000000..898345b288
--- /dev/null
+++ b/string/tst-xbzero-opt.c
@@ -0,0 +1,321 @@
+/* Test that explicit_bzero block clears are not optimized out.
+ Copyright (C) 2016-2018 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/>. */
+
+/* This test is conceptually based on a test designed by Matthew
+ Dempsky for the OpenBSD regression suite:
+ <openbsd>/src/regress/lib/libc/explicit_bzero/explicit_bzero.c.
+ The basic idea is, we have a function that contains a
+ block-clearing operation (not necessarily explicit_bzero), after
+ which the block is dead, in the compiler-jargon sense. Execute
+ that function while running on a user-allocated alternative
+ stack. Then we have another pointer to the memory region affected
+ by the block clear -- namely, the original allocation for the
+ alternative stack -- and can find out whether it actually happened.
+
+ The OpenBSD test uses sigaltstack and SIGUSR1 to get onto an
+ alternative stack. This causes a number of awkward problems; some
+ operating systems (e.g. Solaris and OSX) wipe the signal stack upon
+ returning to the normal stack, there's no way to be sure that other
+ processes running on the same system will not interfere, and the
+ signal stack is very small so it's not safe to call printf there.
+ This implementation instead uses the <ucontext.h> coroutine
+ interface. The coroutine stack is still too small to safely use
+ printf, but we know the OS won't erase it, so we can do all the
+ checks and printing from the normal stack. */
+
+#define _GNU_SOURCE 1
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+/* A byte pattern that is unlikely to occur by chance: the first 16
+ prime numbers (OEIS A000040). */
+static const unsigned char test_pattern[16] =
+{
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53
+};
+
+/* Immediately after each subtest returns, we call swapcontext to get
+ back onto the main stack. That call might itself overwrite the
+ test pattern, so we fill a modest-sized buffer with copies of it
+ and check whether any of them survived. */
+
+#define PATTERN_SIZE (sizeof test_pattern)
+#define PATTERN_REPS 32
+#define TEST_BUFFER_SIZE (PATTERN_SIZE * PATTERN_REPS)
+
+/* There are three subtests, two of which are sanity checks.
+ Each test follows this sequence:
+
+ main coroutine
+ ---- --------
+ advance cur_subtest
+ swap
+ call setup function
+ prepare test buffer
+ swap
+ verify that buffer
+ was filled in
+ swap
+ possibly clear buffer
+ return
+ swap
+ check buffer again,
+ according to test
+ expectation
+
+ In the "no_clear" case, we don't do anything to the test buffer
+ between preparing it and letting it go out of scope, and we expect
+ to find it. This confirms that the test buffer does get filled in
+ and we can find it from the stack buffer. In the "ordinary_clear"
+ case, we clear it using memset. Depending on the target, the
+ compiler may not be able to apply dead store elimination to the
+ memset call, so the test does not fail if the memset is not
+ eliminated. Finally, the "explicit_clear" case uses explicit_bzero
+ and expects _not_ to find the test buffer, which is the real
+ test. */
+
+static ucontext_t uc_main, uc_co;
+
+static __attribute__ ((noinline, noclone)) int
+use_test_buffer (unsigned char *buf)
+{
+ unsigned int sum = 0;
+
+ for (unsigned int i = 0; i < PATTERN_REPS; i++)
+ sum += buf[i * PATTERN_SIZE];
+
+ return (sum == 2 * PATTERN_REPS) ? 0 : 1;
+}
+
+/* Always check the test buffer immediately after filling it; this
+ makes externally visible side effects depend on the buffer existing
+ and having been filled in. */
+#if defined __CET__ && !__glibc_has_attribute (__indirect_return__)
+/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
+ Without indirect_return attribute, swapcontext is marked with
+ returns_twice attribute, which prevents always_inline to work. */
+# define ALWAYS_INLINE
+#else
+# define ALWAYS_INLINE __attribute__ ((always_inline))
+#endif
+static inline ALWAYS_INLINE void
+prepare_test_buffer (unsigned char *buf)
+{
+ for (unsigned int i = 0; i < PATTERN_REPS; i++)
+ memcpy (buf + i*PATTERN_SIZE, test_pattern, PATTERN_SIZE);
+
+ if (swapcontext (&uc_co, &uc_main))
+ abort ();
+
+ /* Force the compiler to really copy the pattern to buf. */
+ if (use_test_buffer (buf))
+ abort ();
+}
+
+static void
+setup_no_clear (void)
+{
+ unsigned char buf[TEST_BUFFER_SIZE];
+ prepare_test_buffer (buf);
+}
+
+static void
+setup_ordinary_clear (void)
+{
+ unsigned char buf[TEST_BUFFER_SIZE];
+ prepare_test_buffer (buf);
+ memset (buf, 0, TEST_BUFFER_SIZE);
+}
+
+static void
+setup_explicit_clear (void)
+{
+ unsigned char buf[TEST_BUFFER_SIZE];
+ prepare_test_buffer (buf);
+ explicit_bzero (buf, TEST_BUFFER_SIZE);
+}
+
+enum test_expectation
+ {
+ EXPECT_NONE, EXPECT_SOME, EXPECT_ALL, NO_EXPECTATIONS
+ };
+struct subtest
+{
+ void (*setup_subtest) (void);
+ const char *label;
+ enum test_expectation expected;
+};
+static const struct subtest *cur_subtest;
+
+static const struct subtest subtests[] =
+{
+ { setup_no_clear, "no clear", EXPECT_SOME },
+ /* The memset may happen or not, depending on compiler
+ optimizations. */
+ { setup_ordinary_clear, "ordinary clear", NO_EXPECTATIONS },
+ { setup_explicit_clear, "explicit clear", EXPECT_NONE },
+ { 0, 0, -1 }
+};
+
+static void
+test_coroutine (void)
+{
+ while (cur_subtest->setup_subtest)
+ {
+ cur_subtest->setup_subtest ();
+ if (swapcontext (&uc_co, &uc_main))
+ abort ();
+ }
+}
+
+/* All the code above this point runs on the coroutine stack.
+ All the code below this point runs on the main stack. */
+
+static int test_status;
+static unsigned char *co_stack_buffer;
+static size_t co_stack_size;
+
+static unsigned int
+count_test_patterns (unsigned char *buf, size_t bufsiz)
+{
+ unsigned char *first = memmem (buf, bufsiz, test_pattern, PATTERN_SIZE);
+ if (!first)
+ return 0;
+ unsigned int cnt = 0;
+ for (unsigned int i = 0; i < PATTERN_REPS; i++)
+ {
+ unsigned char *p = first + i*PATTERN_SIZE;
+ if (p + PATTERN_SIZE - buf > bufsiz)
+ break;
+ if (memcmp (p, test_pattern, PATTERN_SIZE) == 0)
+ cnt++;
+ }
+ return cnt;
+}
+
+static void
+check_test_buffer (enum test_expectation expected,
+ const char *label, const char *stage)
+{
+ unsigned int cnt = count_test_patterns (co_stack_buffer, co_stack_size);
+ switch (expected)
+ {
+ case EXPECT_NONE:
+ if (cnt == 0)
+ printf ("PASS: %s/%s: expected 0 got %d\n", label, stage, cnt);
+ else
+ {
+ printf ("FAIL: %s/%s: expected 0 got %d\n", label, stage, cnt);
+ test_status = 1;
+ }
+ break;
+
+ case EXPECT_SOME:
+ if (cnt > 0)
+ printf ("PASS: %s/%s: expected some got %d\n", label, stage, cnt);
+ else
+ {
+ printf ("FAIL: %s/%s: expected some got 0\n", label, stage);
+ test_status = 1;
+ }
+ break;
+
+ case EXPECT_ALL:
+ if (cnt == PATTERN_REPS)
+ printf ("PASS: %s/%s: expected %d got %d\n", label, stage,
+ PATTERN_REPS, cnt);
+ else
+ {
+ printf ("FAIL: %s/%s: expected %d got %d\n", label, stage,
+ PATTERN_REPS, cnt);
+ test_status = 1;
+ }
+ break;
+
+ case NO_EXPECTATIONS:
+ printf ("INFO: %s/%s: found %d patterns%s\n", label, stage, cnt,
+ cnt == 0 ? " (memset not eliminated)" : "");
+ break;
+
+ default:
+ printf ("ERROR: %s/%s: invalid value for 'expected' = %d\n",
+ label, stage, (int)expected);
+ test_status = 1;
+ }
+}
+
+static void
+test_loop (void)
+{
+ cur_subtest = subtests;
+ while (cur_subtest->setup_subtest)
+ {
+ if (swapcontext (&uc_main, &uc_co))
+ abort ();
+ check_test_buffer (EXPECT_ALL, cur_subtest->label, "prepare");
+ if (swapcontext (&uc_main, &uc_co))
+ abort ();
+ check_test_buffer (cur_subtest->expected, cur_subtest->label, "test");
+ cur_subtest++;
+ }
+ /* Terminate the coroutine. */
+ if (swapcontext (&uc_main, &uc_co))
+ abort ();
+}
+
+int
+do_test (void)
+{
+ size_t page_alignment = sysconf (_SC_PAGESIZE);
+ if (page_alignment < sizeof (void *))
+ page_alignment = sizeof (void *);
+
+ co_stack_size = SIGSTKSZ + TEST_BUFFER_SIZE;
+ if (co_stack_size < page_alignment * 4)
+ co_stack_size = page_alignment * 4;
+
+ void *p;
+ int err = posix_memalign (&p, page_alignment, co_stack_size);
+ if (err || !p)
+ {
+ printf ("ERROR: allocating alt stack: %s\n", strerror (err));
+ return 2;
+ }
+ co_stack_buffer = p;
+
+ if (getcontext (&uc_co))
+ {
+ printf ("ERROR: allocating coroutine context: %s\n", strerror (err));
+ return 2;
+ }
+ uc_co.uc_stack.ss_sp = co_stack_buffer;
+ uc_co.uc_stack.ss_size = co_stack_size;
+ uc_co.uc_link = &uc_main;
+ makecontext (&uc_co, test_coroutine, 0);
+
+ test_loop ();
+ return test_status;
+}
+
+#include <support/test-driver.c>
diff --git a/string/wordcopy.c b/string/wordcopy.c
index 87eb1a6f3c..ceaec858c1 100644
--- a/string/wordcopy.c
+++ b/string/wordcopy.c
@@ -1,5 +1,5 @@
/* _memcopy.c -- subroutines for memory copy functions.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
diff --git a/string/xpg-strerror.c b/string/xpg-strerror.c
index d34d5031a8..6ea786c226 100644
--- a/string/xpg-strerror.c
+++ b/string/xpg-strerror.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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