mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
2.5-18.1
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1991-1999,2000,2001,2002 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1991-2002, 2005, 2006, 2007 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
|
||||
@ -52,8 +52,9 @@ strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
|
||||
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 \
|
||||
$(addprefix test-,$(strop-tests))
|
||||
tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
|
||||
bug-strtok1 $(addprefix test-,$(strop-tests)) \
|
||||
bug-envz1 tst-strxfrm2
|
||||
distribute := memcopy.h pagecopy.h tst-svc.expect test-string.h
|
||||
|
||||
|
||||
@ -63,11 +64,14 @@ tester-ENV = LANGUAGE=C
|
||||
inl-tester-ENV = LANGUAGE=C
|
||||
noinl-tester-ENV = LANGUAGE=C
|
||||
tst-strxfrm-ENV = LOCPATH=$(common-objpfx)localedata
|
||||
tst-strxfrm2-ENV = LOCPATH=$(common-objpfx)localedata
|
||||
bug-strcoll1-ENV = LOCPATH=$(common-objpfx)localedata
|
||||
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
|
||||
|
||||
ifeq ($(cross-compiling),no)
|
||||
tests: $(objpfx)tst-svc.out
|
||||
|
68
string/_strerror.c
Normal file
68
string/_strerror.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 1991,93,95,96,97,98,2000,2002,2006
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <libintl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio-common/_itoa.h>
|
||||
|
||||
/* It is critical here that we always use the `dcgettext' function for
|
||||
the message translation. Since <libintl.h> only defines the macro
|
||||
`dgettext' to use `dcgettext' for optimizing programs this is not
|
||||
always guaranteed. */
|
||||
#ifndef dgettext
|
||||
# include <locale.h> /* We need LC_MESSAGES. */
|
||||
# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
|
||||
#endif
|
||||
|
||||
/* Return a string describing the errno code in ERRNUM. */
|
||||
char *
|
||||
__strerror_r (int errnum, char *buf, size_t buflen)
|
||||
{
|
||||
if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
|
||||
|| _sys_errlist_internal[errnum] == NULL, 0))
|
||||
{
|
||||
/* Buffer we use to print the number in. For a maximum size for
|
||||
`int' of 8 bytes we never need more than 20 digits. */
|
||||
char numbuf[21];
|
||||
const char *unk = _("Unknown error ");
|
||||
const size_t unklen = strlen (unk);
|
||||
char *p, *q;
|
||||
|
||||
numbuf[20] = '\0';
|
||||
p = _itoa_word (errnum, &numbuf[20], 10, 0);
|
||||
|
||||
/* Now construct the result while taking care for the destination
|
||||
buffer size. */
|
||||
q = __mempcpy (buf, unk, MIN (unklen, buflen));
|
||||
if (unklen < buflen)
|
||||
memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen));
|
||||
|
||||
/* Terminate the string in any case. */
|
||||
if (buflen > 0)
|
||||
buf[buflen - 1] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
return (char *) _(_sys_errlist_internal[errnum]);
|
||||
}
|
||||
weak_alias (__strerror_r, strerror_r)
|
||||
libc_hidden_def (__strerror_r)
|
@ -1,5 +1,5 @@
|
||||
/* String replacement in an argz vector
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>
|
||||
|
||||
@ -121,8 +121,7 @@ __argz_replace (char **argz, size_t *argz_len, const char *str, const char *with
|
||||
if (! delayed_copy)
|
||||
/* We never found any instances of str. */
|
||||
{
|
||||
if (src)
|
||||
free (src);
|
||||
free (src);
|
||||
*argz = dst;
|
||||
*argz_len = dst_len;
|
||||
}
|
||||
|
29
string/bcopy.c
Normal file
29
string/bcopy.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (C) 1991, 1992, 1997 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define memmove bcopy
|
||||
#define rettype void
|
||||
#define RETURN(s) return
|
||||
#define a1 src
|
||||
#define a1const const
|
||||
#define a2 dest
|
||||
#define a2const
|
||||
|
||||
#include <memmove.c>
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2004, 2005 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
|
||||
@ -44,10 +44,9 @@
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memcpy_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __memcpy_ichk (dest, src, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__memcpy_ichk (void *__restrict __dest, const void *__restrict __src,
|
||||
size_t __len)
|
||||
static __always_inline void *
|
||||
__NTH (__memcpy_ichk (void *__restrict __dest, __const void *__restrict __src,
|
||||
size_t __len))
|
||||
{
|
||||
return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
|
||||
}
|
||||
@ -57,9 +56,8 @@ __memcpy_ichk (void *__restrict __dest, const void *__restrict __src,
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memmove_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __memmove_ichk (dest, src, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__memmove_ichk (void *__dest, const void *__src, size_t __len)
|
||||
static __always_inline void *
|
||||
__NTH (__memmove_ichk (void *__dest, __const void *__src, size_t __len))
|
||||
{
|
||||
return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
|
||||
}
|
||||
@ -70,23 +68,30 @@ __memmove_ichk (void *__dest, const void *__src, size_t __len)
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___mempcpy_chk (dest, src, len, __bos0 (dest)) \
|
||||
: __mempcpy_ichk (dest, src, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__mempcpy_ichk (void *__restrict __dest, const void *__restrict __src,
|
||||
size_t __len)
|
||||
static __always_inline void *
|
||||
__NTH (__mempcpy_ichk (void *__restrict __dest,
|
||||
__const void *__restrict __src, size_t __len))
|
||||
{
|
||||
return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* The first two tests here help to catch a somewhat common problem
|
||||
where the second and third parameter are transposed. This is
|
||||
especially problematic if the intended fill value is zero. In this
|
||||
case no work is done at all. We detect these problems by referring
|
||||
non-existing functions. */
|
||||
__warndecl (__warn_memset_zero_len,
|
||||
"memset used with constant zero length parameter; this could be due to transposed parameters");
|
||||
#define memset(dest, ch, len) \
|
||||
((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memset_chk (dest, ch, len, __bos0 (dest)) \
|
||||
: __memset_ichk (dest, ch, len))
|
||||
static __inline__ void *
|
||||
__attribute__ ((__always_inline__))
|
||||
__memset_ichk (void *__dest, int __ch, size_t __len)
|
||||
(__builtin_constant_p (len) && (len) == 0 \
|
||||
? (__warn_memset_zero_len (), (void) (ch), (void) (len), (void *) (dest)) \
|
||||
: ((__bos0 (dest) != (size_t) -1) \
|
||||
? __builtin___memset_chk (dest, ch, len, __bos0 (dest)) \
|
||||
: __memset_ichk (dest, ch, len)))
|
||||
static __always_inline void *
|
||||
__NTH (__memset_ichk (void *__dest, int __ch, size_t __len))
|
||||
{
|
||||
return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
|
||||
}
|
||||
@ -107,9 +112,8 @@ __memset_ichk (void *__dest, int __ch, size_t __len)
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strcpy_chk (dest, src, __bos (dest)) \
|
||||
: __strcpy_ichk (dest, src))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strcpy_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
static __always_inline char *
|
||||
__NTH (__strcpy_ichk (char *__restrict __dest, __const char *__restrict __src))
|
||||
{
|
||||
return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
|
||||
}
|
||||
@ -120,9 +124,8 @@ __strcpy_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___stpcpy_chk (dest, src, __bos (dest)) \
|
||||
: __stpcpy_ichk (dest, src))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__stpcpy_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
static __always_inline char *
|
||||
__NTH (__stpcpy_ichk (char *__restrict __dest, __const char *__restrict __src))
|
||||
{
|
||||
return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
|
||||
}
|
||||
@ -133,22 +136,37 @@ __stpcpy_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strncpy_chk (dest, src, len, __bos (dest)) \
|
||||
: __strncpy_ichk (dest, src, len))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strncpy_ichk (char *__restrict __dest, const char *__restrict __src,
|
||||
size_t __len)
|
||||
static __always_inline char *
|
||||
__NTH (__strncpy_ichk (char *__restrict __dest, __const char *__restrict __src,
|
||||
size_t __len))
|
||||
{
|
||||
return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
|
||||
}
|
||||
|
||||
|
||||
// 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,
|
||||
size_t __n), stpncpy);
|
||||
|
||||
extern __always_inline char *
|
||||
__NTH (stpncpy (char *__dest, __const char *__src, size_t __n))
|
||||
{
|
||||
if (__bos (__dest) != (size_t) -1
|
||||
&& (!__builtin_constant_p (__n) || __n <= __bos (__dest)))
|
||||
return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||
return __stpncpy_alias (__dest, __src, __n);
|
||||
}
|
||||
|
||||
|
||||
#define strcat(dest, src) \
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strcat_chk (dest, src, __bos (dest)) \
|
||||
: __strcat_ichk (dest, src))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strcat_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
static __always_inline char *
|
||||
__NTH (__strcat_ichk (char *__restrict __dest, __const char *__restrict __src))
|
||||
{
|
||||
return __builtin___strcat_chk (__dest, __src, __bos (__dest));
|
||||
}
|
||||
@ -158,10 +176,9 @@ __strcat_ichk (char *__restrict __dest, const char *__restrict __src)
|
||||
((__bos (dest) != (size_t) -1) \
|
||||
? __builtin___strncat_chk (dest, src, len, __bos (dest)) \
|
||||
: __strncat_ichk (dest, src, len))
|
||||
static __inline__ char *
|
||||
__attribute__ ((__always_inline__))
|
||||
__strncat_ichk (char *__restrict __dest, const char *__restrict __src,
|
||||
size_t __len)
|
||||
static __always_inline char *
|
||||
__NTH (__strncat_ichk (char *__restrict __dest, __const char *__restrict __src,
|
||||
size_t __len))
|
||||
{
|
||||
return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
|
||||
}
|
||||
|
76
string/bug-envz1.c
Normal file
76
string/bug-envz1.c
Normal file
@ -0,0 +1,76 @@
|
||||
/* Test for bug BZ #2703. */
|
||||
#include <stdio.h>
|
||||
#include <envz.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *s;
|
||||
int in_result;
|
||||
} strs[] =
|
||||
{
|
||||
{ "a=1", 1 },
|
||||
{ "b=2", 1 },
|
||||
{ "(*)", 0 },
|
||||
{ "(*)", 0 },
|
||||
{ "e=5", 1 },
|
||||
{ "f=", 1 },
|
||||
{ "(*)", 0 },
|
||||
{ "h=8", 1 },
|
||||
{ "i=9", 1 },
|
||||
{ "j", 0 }
|
||||
};
|
||||
|
||||
#define nstrs (sizeof (strs) / sizeof (strs[0]))
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
|
||||
size_t size = 0;
|
||||
char *str = malloc (100);
|
||||
if (str == NULL)
|
||||
{
|
||||
puts ("out of memory");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char **argz = &str;
|
||||
|
||||
for (int i = 0; i < nstrs; ++i)
|
||||
argz_add_sep (argz, &size, strs[i].s, '\0');
|
||||
|
||||
printf ("calling envz_strip with size=%zu\n", size);
|
||||
envz_strip (argz, &size);
|
||||
|
||||
int result = 0;
|
||||
printf ("new size=%zu\n", size);
|
||||
for (int i = 0; i < nstrs; ++i)
|
||||
if (strs[i].in_result)
|
||||
{
|
||||
char name[2];
|
||||
name[0] = strs[i].s[0];
|
||||
name[1] = '\0';
|
||||
|
||||
char *e = envz_entry (*argz, size, name);
|
||||
if (e == NULL)
|
||||
{
|
||||
printf ("entry '%s' not found\n", name);
|
||||
result = 1;
|
||||
}
|
||||
else if (strcmp (e, strs[i].s) != 0)
|
||||
{
|
||||
printf ("entry '%s' does not match: is '%s', expected '%s'\n",
|
||||
name, e, strs[i].s);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
free (*argz);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
45
string/bug-strtok1.c
Normal file
45
string/bug-strtok1.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* See BZ #2126. */
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
const char str[] = "axaaba";
|
||||
char *token;
|
||||
char *cp;
|
||||
char *l;
|
||||
int result = 0;
|
||||
|
||||
puts ("test strtok");
|
||||
cp = strdupa (str);
|
||||
printf ("cp = %p, len = %zu\n", cp, strlen (cp));
|
||||
token = strtok (cp, "ab");
|
||||
result |= token == NULL || strcmp (token, "x");
|
||||
printf ("token: %s (%d)\n", token ? token : "NULL", result);
|
||||
token = strtok(0, "ab");
|
||||
result |= token != NULL;
|
||||
printf ("token: %s (%d)\n", token ? token : "NULL", result);
|
||||
token = strtok(0, "a");
|
||||
result |= token != NULL;
|
||||
printf ("token: %s (%d)\n", token ? token : "NULL", result);
|
||||
|
||||
puts ("test strtok_r");
|
||||
cp = strdupa (str);
|
||||
size_t len = strlen (cp);
|
||||
printf ("cp = %p, len = %zu\n", cp, len);
|
||||
token = strtok_r (cp, "ab", &l);
|
||||
result |= token == NULL || strcmp (token, "x");
|
||||
printf ("token: %s, next = %p (%d)\n", token ? token : "NULL", l, result);
|
||||
token = strtok_r(0, "ab", &l);
|
||||
result |= token != NULL || l != cp + len;
|
||||
printf ("token: %s, next = %p (%d)\n", token ? token : "NULL", l, result);
|
||||
token = strtok_r(0, "a", &l);
|
||||
result |= token != NULL || l != cp + len;
|
||||
printf ("token: %s, next = %p (%d)\n", token ? token : "NULL", l, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
83
string/bzero.c
Normal file
83
string/bzero.c
Normal file
@ -0,0 +1,83 @@
|
||||
/* Copyright (C) 1991, 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
#undef __bzero
|
||||
|
||||
/* Set N bytes of S to 0. */
|
||||
void
|
||||
__bzero (s, len)
|
||||
void *s;
|
||||
size_t len;
|
||||
{
|
||||
long int dstp = (long int) s;
|
||||
const op_t zero = 0;
|
||||
|
||||
if (len >= 8)
|
||||
{
|
||||
size_t xlen;
|
||||
|
||||
/* There are at least some bytes to zero. No need to test
|
||||
for LEN == 0 in this alignment loop. */
|
||||
while (dstp % OPSIZ != 0)
|
||||
{
|
||||
((byte *) dstp)[0] = 0;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* Write 8 op_t per iteration until less than 8 op_t remain. */
|
||||
xlen = len / (OPSIZ * 8);
|
||||
while (xlen != 0)
|
||||
{
|
||||
((op_t *) dstp)[0] = zero;
|
||||
((op_t *) dstp)[1] = zero;
|
||||
((op_t *) dstp)[2] = zero;
|
||||
((op_t *) dstp)[3] = zero;
|
||||
((op_t *) dstp)[4] = zero;
|
||||
((op_t *) dstp)[5] = zero;
|
||||
((op_t *) dstp)[6] = zero;
|
||||
((op_t *) dstp)[7] = zero;
|
||||
dstp += 8 * OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ * 8;
|
||||
|
||||
/* Write 1 op_t per iteration until less than op_t remain. */
|
||||
xlen = len / OPSIZ;
|
||||
while (xlen != 0)
|
||||
{
|
||||
((op_t *) dstp)[0] = zero;
|
||||
dstp += OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* Write the last few bytes. */
|
||||
while (len != 0)
|
||||
{
|
||||
((byte *) dstp)[0] = 0;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
}
|
||||
weak_alias (__bzero, bzero)
|
@ -1,5 +1,5 @@
|
||||
/* Routines for dealing with '\0' separated environment vectors
|
||||
Copyright (C) 1995,96,97,98,2001,02 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1998,2001,2002,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.org>
|
||||
|
||||
@ -165,7 +165,7 @@ envz_strip (char **envz, size_t *envz_len)
|
||||
left -= entry_len;
|
||||
if (! strchr (entry, SEP))
|
||||
/* Null entry. */
|
||||
memmove (entry + entry_len, entry, left);
|
||||
memmove (entry, entry + entry_len, left);
|
||||
else
|
||||
entry += entry_len;
|
||||
}
|
||||
|
55
string/ffs.c
Normal file
55
string/ffs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1991, 1992, 1997, 1998, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <limits.h>
|
||||
#define ffsl __something_else
|
||||
#include <string.h>
|
||||
|
||||
#undef ffs
|
||||
|
||||
/* Find the first bit set in I. */
|
||||
int
|
||||
__ffs (i)
|
||||
int i;
|
||||
{
|
||||
static const unsigned char table[] =
|
||||
{
|
||||
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
|
||||
};
|
||||
unsigned int a;
|
||||
unsigned int x = i & -i;
|
||||
|
||||
a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
|
||||
|
||||
return table[x >> a] + a;
|
||||
}
|
||||
weak_alias (__ffs, ffs)
|
||||
libc_hidden_builtin_def (ffs)
|
||||
|
||||
#if ULONG_MAX == UINT_MAX
|
||||
#undef ffsl
|
||||
weak_alias (__ffs, ffsl)
|
||||
#endif
|
42
string/ffsll.c
Normal file
42
string/ffsll.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 1991, 1992, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <limits.h>
|
||||
#define ffsl __something_else
|
||||
#include <string.h>
|
||||
|
||||
#undef ffsll
|
||||
|
||||
/* Find the first bit set in I. */
|
||||
int
|
||||
ffsll (i)
|
||||
long long int i;
|
||||
{
|
||||
unsigned long long int x = i & -i;
|
||||
|
||||
if (x <= 0xffffffff)
|
||||
return ffs (i);
|
||||
else
|
||||
return 32 + ffs (i >> 32);
|
||||
}
|
||||
|
||||
#if ULONG_MAX != UINT_MAX
|
||||
#undef ffsl
|
||||
weak_alias (ffsll, ffsl)
|
||||
#endif
|
46
string/memccpy.c
Normal file
46
string/memccpy.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 1991, 1995, 1997, 1999, 2000 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef __memccpy
|
||||
#undef memccpy
|
||||
|
||||
/* 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, or
|
||||
NULL if C was not found in the first N bytes of SRC. */
|
||||
void *
|
||||
__memccpy (dest, src, c, n)
|
||||
void *dest;
|
||||
const void *src;
|
||||
int c;
|
||||
size_t n;
|
||||
{
|
||||
register const char *s = src;
|
||||
register char *d = dest;
|
||||
register const char x = c;
|
||||
register size_t i = n;
|
||||
|
||||
while (i-- > 0)
|
||||
if ((*d++ = *s++) == x)
|
||||
return d;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
weak_alias (__memccpy, memccpy)
|
215
string/memchr.c
Normal file
215
string/memchr.c
Normal file
@ -0,0 +1,215 @@
|
||||
/* Copyright (C) 1991,93,96,97,99,2000,2003 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
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
# define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#if defined _LIBC
|
||||
# include <string.h>
|
||||
# include <memcopy.h>
|
||||
#else
|
||||
# define reg_char char
|
||||
#endif
|
||||
|
||||
#if HAVE_STDLIB_H || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if 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>
|
||||
#if HAVE_BP_SYM_H || defined _LIBC
|
||||
#include <bp-sym.h>
|
||||
#else
|
||||
# define BP_SYM(sym) sym
|
||||
#endif
|
||||
|
||||
#undef memchr
|
||||
#undef __memchr
|
||||
|
||||
/* Search no more than N bytes of S for C. */
|
||||
__ptr_t
|
||||
__memchr (s, c_in, n)
|
||||
const __ptr_t s;
|
||||
int c_in;
|
||||
size_t n;
|
||||
{
|
||||
const unsigned char *char_ptr;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, charmask;
|
||||
unsigned reg_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;
|
||||
n > 0 && ((unsigned long int) char_ptr
|
||||
& (sizeof (longword) - 1)) != 0;
|
||||
--n, ++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. */
|
||||
|
||||
if (sizeof (longword) != 4 && sizeof (longword) != 8)
|
||||
abort ();
|
||||
|
||||
#if LONG_MAX <= LONG_MAX_32_BITS
|
||||
magic_bits = 0x7efefeff;
|
||||
#else
|
||||
magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
|
||||
#endif
|
||||
|
||||
/* 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 (n >= sizeof (longword))
|
||||
{
|
||||
/* 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];
|
||||
#endif
|
||||
}
|
||||
|
||||
n -= sizeof (longword);
|
||||
}
|
||||
|
||||
char_ptr = (const unsigned char *) longword_ptr;
|
||||
|
||||
while (n-- > 0)
|
||||
{
|
||||
if (*char_ptr == c)
|
||||
return (__ptr_t) char_ptr;
|
||||
else
|
||||
++char_ptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__memchr, BP_SYM (memchr))
|
||||
#endif
|
||||
libc_hidden_builtin_def (memchr)
|
381
string/memcmp.c
Normal file
381
string/memcmp.c
Normal file
@ -0,0 +1,381 @@
|
||||
/* Copyright (C) 1991,1993,1995,1997,1998,2003,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__)
|
||||
# define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef const
|
||||
# define const
|
||||
# define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#if defined HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#undef memcmp
|
||||
|
||||
#ifdef _LIBC
|
||||
|
||||
# include <memcopy.h>
|
||||
# include <endian.h>
|
||||
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define WORDS_BIGENDIAN
|
||||
# endif
|
||||
|
||||
#else /* Not in the GNU C library. */
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
/* Type to use for aligned memory operations.
|
||||
This should normally be the biggest type supported by a single load
|
||||
and store. Must be an unsigned type. */
|
||||
# define op_t unsigned long int
|
||||
# define OPSIZ (sizeof(op_t))
|
||||
|
||||
/* Threshold value for when to enter the unrolled loops. */
|
||||
# define OP_T_THRES 16
|
||||
|
||||
/* Type to use for unaligned operations. */
|
||||
typedef unsigned char byte;
|
||||
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
|
||||
# else
|
||||
# define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
|
||||
# endif
|
||||
|
||||
#endif /* In the GNU C library. */
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
|
||||
#else
|
||||
# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
|
||||
#endif
|
||||
|
||||
/* BE VERY CAREFUL IF YOU CHANGE THIS CODE! */
|
||||
|
||||
/* The strategy of this memcmp is:
|
||||
|
||||
1. Compare bytes until one of the block pointers is aligned.
|
||||
|
||||
2. Compare using memcmp_common_alignment or
|
||||
memcmp_not_common_alignment, regarding the alignment of the other
|
||||
block after the initial byte operations. The maximum number of
|
||||
full words (of type op_t) are compared in this way.
|
||||
|
||||
3. Compare the few remaining bytes. */
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
|
||||
A and B are known to be different.
|
||||
This is needed only on little-endian machines. */
|
||||
|
||||
static int memcmp_bytes (op_t, op_t) __THROW;
|
||||
|
||||
# ifdef __GNUC__
|
||||
__inline
|
||||
# endif
|
||||
static int
|
||||
memcmp_bytes (a, b)
|
||||
op_t a, b;
|
||||
{
|
||||
long int srcp1 = (long int) &a;
|
||||
long int srcp2 = (long int) &b;
|
||||
op_t a0, b0;
|
||||
|
||||
do
|
||||
{
|
||||
a0 = ((byte *) srcp1)[0];
|
||||
b0 = ((byte *) srcp2)[0];
|
||||
srcp1 += 1;
|
||||
srcp2 += 1;
|
||||
}
|
||||
while (a0 == b0);
|
||||
return a0 - b0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int memcmp_common_alignment (long, long, size_t) __THROW;
|
||||
|
||||
/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
|
||||
objects (not LEN bytes!). Both SRCP1 and SRCP2 should be aligned for
|
||||
memory operations on `op_t's. */
|
||||
static int
|
||||
memcmp_common_alignment (srcp1, srcp2, len)
|
||||
long int srcp1;
|
||||
long int srcp2;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1;
|
||||
op_t b0, b1;
|
||||
|
||||
switch (len % 4)
|
||||
{
|
||||
default: /* Avoid warning about uninitialized local variables. */
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
srcp1 -= 2 * OPSIZ;
|
||||
srcp2 -= 2 * OPSIZ;
|
||||
len += 2;
|
||||
goto do1;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp1)[0];
|
||||
b1 = ((op_t *) srcp2)[0];
|
||||
srcp1 -= OPSIZ;
|
||||
srcp2 -= OPSIZ;
|
||||
len += 1;
|
||||
goto do2;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return 0;
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
goto do3;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp1)[0];
|
||||
b1 = ((op_t *) srcp2)[0];
|
||||
srcp1 += OPSIZ;
|
||||
srcp2 += OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
/* Fall through. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
if (a1 != b1)
|
||||
return CMP_LT_OR_GT (a1, b1);
|
||||
|
||||
do3:
|
||||
a1 = ((op_t *) srcp1)[1];
|
||||
b1 = ((op_t *) srcp2)[1];
|
||||
if (a0 != b0)
|
||||
return CMP_LT_OR_GT (a0, b0);
|
||||
|
||||
do2:
|
||||
a0 = ((op_t *) srcp1)[2];
|
||||
b0 = ((op_t *) srcp2)[2];
|
||||
if (a1 != b1)
|
||||
return CMP_LT_OR_GT (a1, b1);
|
||||
|
||||
do1:
|
||||
a1 = ((op_t *) srcp1)[3];
|
||||
b1 = ((op_t *) srcp2)[3];
|
||||
if (a0 != b0)
|
||||
return CMP_LT_OR_GT (a0, b0);
|
||||
|
||||
srcp1 += 4 * OPSIZ;
|
||||
srcp2 += 4 * OPSIZ;
|
||||
len -= 4;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
if (a1 != b1)
|
||||
return CMP_LT_OR_GT (a1, b1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memcmp_not_common_alignment (long, long, size_t) __THROW;
|
||||
|
||||
/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
|
||||
`op_t' objects (not LEN bytes!). SRCP2 should be aligned for memory
|
||||
operations on `op_t', but SRCP1 *should be unaligned*. */
|
||||
static int
|
||||
memcmp_not_common_alignment (srcp1, srcp2, len)
|
||||
long int srcp1;
|
||||
long int srcp2;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1, a2, a3;
|
||||
op_t b0, b1, b2, b3;
|
||||
op_t x;
|
||||
int shl, shr;
|
||||
|
||||
/* Calculate how to shift a word read at the memory operation
|
||||
aligned srcp1 to make it aligned for comparison. */
|
||||
|
||||
shl = 8 * (srcp1 % OPSIZ);
|
||||
shr = 8 * OPSIZ - shl;
|
||||
|
||||
/* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
|
||||
it points in the middle of. */
|
||||
srcp1 &= -OPSIZ;
|
||||
|
||||
switch (len % 4)
|
||||
{
|
||||
default: /* Avoid warning about uninitialized local variables. */
|
||||
case 2:
|
||||
a1 = ((op_t *) srcp1)[0];
|
||||
a2 = ((op_t *) srcp1)[1];
|
||||
b2 = ((op_t *) srcp2)[0];
|
||||
srcp1 -= 1 * OPSIZ;
|
||||
srcp2 -= 2 * OPSIZ;
|
||||
len += 2;
|
||||
goto do1;
|
||||
case 3:
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
a1 = ((op_t *) srcp1)[1];
|
||||
b1 = ((op_t *) srcp2)[0];
|
||||
srcp2 -= 1 * OPSIZ;
|
||||
len += 1;
|
||||
goto do2;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return 0;
|
||||
a3 = ((op_t *) srcp1)[0];
|
||||
a0 = ((op_t *) srcp1)[1];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
srcp1 += 1 * OPSIZ;
|
||||
goto do3;
|
||||
case 1:
|
||||
a2 = ((op_t *) srcp1)[0];
|
||||
a3 = ((op_t *) srcp1)[1];
|
||||
b3 = ((op_t *) srcp2)[0];
|
||||
srcp1 += 2 * OPSIZ;
|
||||
srcp2 += 1 * OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
/* Fall through. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
x = MERGE(a2, shl, a3, shr);
|
||||
if (x != b3)
|
||||
return CMP_LT_OR_GT (x, b3);
|
||||
|
||||
do3:
|
||||
a1 = ((op_t *) srcp1)[1];
|
||||
b1 = ((op_t *) srcp2)[1];
|
||||
x = MERGE(a3, shl, a0, shr);
|
||||
if (x != b0)
|
||||
return CMP_LT_OR_GT (x, b0);
|
||||
|
||||
do2:
|
||||
a2 = ((op_t *) srcp1)[2];
|
||||
b2 = ((op_t *) srcp2)[2];
|
||||
x = MERGE(a0, shl, a1, shr);
|
||||
if (x != b1)
|
||||
return CMP_LT_OR_GT (x, b1);
|
||||
|
||||
do1:
|
||||
a3 = ((op_t *) srcp1)[3];
|
||||
b3 = ((op_t *) srcp2)[3];
|
||||
x = MERGE(a1, shl, a2, shr);
|
||||
if (x != b2)
|
||||
return CMP_LT_OR_GT (x, b2);
|
||||
|
||||
srcp1 += 4 * OPSIZ;
|
||||
srcp2 += 4 * OPSIZ;
|
||||
len -= 4;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
x = MERGE(a2, shl, a3, shr);
|
||||
if (x != b3)
|
||||
return CMP_LT_OR_GT (x, b3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
memcmp (s1, s2, len)
|
||||
const __ptr_t s1;
|
||||
const __ptr_t s2;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0;
|
||||
op_t b0;
|
||||
long int srcp1 = (long int) s1;
|
||||
long int srcp2 = (long int) s2;
|
||||
op_t res;
|
||||
|
||||
if (len >= OP_T_THRES)
|
||||
{
|
||||
/* There are at least some bytes to compare. No need to test
|
||||
for LEN == 0 in this alignment loop. */
|
||||
while (srcp2 % OPSIZ != 0)
|
||||
{
|
||||
a0 = ((byte *) srcp1)[0];
|
||||
b0 = ((byte *) srcp2)[0];
|
||||
srcp1 += 1;
|
||||
srcp2 += 1;
|
||||
res = a0 - b0;
|
||||
if (res != 0)
|
||||
return res;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* SRCP2 is now aligned for memory operations on `op_t'.
|
||||
SRCP1 alignment determines if we can do a simple,
|
||||
aligned compare or need to shuffle bits. */
|
||||
|
||||
if (srcp1 % OPSIZ == 0)
|
||||
res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
|
||||
else
|
||||
res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
/* Number of bytes remaining in the interval [0..OPSIZ-1]. */
|
||||
srcp1 += len & -OPSIZ;
|
||||
srcp2 += len & -OPSIZ;
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* There are just a few bytes to compare. Use byte memory operations. */
|
||||
while (len != 0)
|
||||
{
|
||||
a0 = ((byte *) srcp1)[0];
|
||||
b0 = ((byte *) srcp2)[0];
|
||||
srcp1 += 1;
|
||||
srcp2 += 1;
|
||||
res = a0 - b0;
|
||||
if (res != 0)
|
||||
return res;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
libc_hidden_builtin_def(memcmp)
|
||||
#ifdef weak_alias
|
||||
# undef bcmp
|
||||
weak_alias (memcmp, bcmp)
|
||||
#endif
|
65
string/memcpy.c
Normal file
65
string/memcpy.c
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is NOT handled correctly.
|
||||
Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
#include <pagecopy.h>
|
||||
|
||||
#undef memcpy
|
||||
|
||||
void *
|
||||
memcpy (dstpp, srcpp, len)
|
||||
void *dstpp;
|
||||
const void *srcpp;
|
||||
size_t len;
|
||||
{
|
||||
unsigned long int dstp = (long int) dstpp;
|
||||
unsigned long int srcp = (long int) srcpp;
|
||||
|
||||
/* Copy from the beginning to the end. */
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if (len >= OP_T_THRES)
|
||||
{
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= (-dstp) % OPSIZ;
|
||||
BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
|
||||
|
||||
/* Copy whole pages from SRCP to DSTP by virtual address manipulation,
|
||||
as much as possible. */
|
||||
|
||||
PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known alignment of
|
||||
DSTP. Number of bytes remaining is put in the third argument,
|
||||
i.e. in LEN. This number may vary from machine to machine. */
|
||||
|
||||
WORD_COPY_FWD (dstp, srcp, len, len);
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
BYTE_COPY_FWD (dstp, srcp, len);
|
||||
|
||||
return dstpp;
|
||||
}
|
||||
libc_hidden_builtin_def (memcpy)
|
58
string/memmem.c
Normal file
58
string/memmem.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 1991,92,93,94,96,97,98,2000,2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _LIBC
|
||||
# define __builtin_expect(expr, val) (expr)
|
||||
#endif
|
||||
|
||||
#undef memmem
|
||||
|
||||
/* Return the first occurrence of NEEDLE in HAYSTACK. */
|
||||
void *
|
||||
memmem (haystack, haystack_len, needle, needle_len)
|
||||
const void *haystack;
|
||||
size_t haystack_len;
|
||||
const void *needle;
|
||||
size_t needle_len;
|
||||
{
|
||||
const char *begin;
|
||||
const char *const last_possible
|
||||
= (const char *) haystack + haystack_len - needle_len;
|
||||
|
||||
if (needle_len == 0)
|
||||
/* The first occurrence of the empty string is deemed to occur at
|
||||
the beginning of the string. */
|
||||
return (void *) haystack;
|
||||
|
||||
/* Sanity check, otherwise the loop might search through the whole
|
||||
memory. */
|
||||
if (__builtin_expect (haystack_len < needle_len, 0))
|
||||
return NULL;
|
||||
|
||||
for (begin = (const char *) haystack; begin <= last_possible; ++begin)
|
||||
if (begin[0] == ((const char *) needle)[0] &&
|
||||
!memcmp ((const void *) &begin[1],
|
||||
(const void *) ((const char *) needle + 1),
|
||||
needle_len - 1))
|
||||
return (void *) begin;
|
||||
|
||||
return NULL;
|
||||
}
|
112
string/memmove.c
Normal file
112
string/memmove.c
Normal file
@ -0,0 +1,112 @@
|
||||
/* Copy memory to memory until the specified number of bytes
|
||||
has been copied. Overlap is handled correctly.
|
||||
Copyright (C) 1991, 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
#include <pagecopy.h>
|
||||
|
||||
/* All this is so that bcopy.c can #include
|
||||
this file after defining some things. */
|
||||
#ifndef a1
|
||||
#define a1 dest /* First arg is DEST. */
|
||||
#define a1const
|
||||
#define a2 src /* Second arg is SRC. */
|
||||
#define a2const const
|
||||
#undef memmove
|
||||
#endif
|
||||
#if !defined(RETURN) || !defined(rettype)
|
||||
#define RETURN(s) return (s) /* Return DEST. */
|
||||
#define rettype void *
|
||||
#endif
|
||||
|
||||
|
||||
rettype
|
||||
memmove (a1, a2, len)
|
||||
a1const void *a1;
|
||||
a2const void *a2;
|
||||
size_t len;
|
||||
{
|
||||
unsigned long int dstp = (long int) dest;
|
||||
unsigned long int srcp = (long int) src;
|
||||
|
||||
/* This test makes the forward copying code be used whenever possible.
|
||||
Reduces the working set. */
|
||||
if (dstp - srcp >= len) /* *Unsigned* compare! */
|
||||
{
|
||||
/* Copy from the beginning to the end. */
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if (len >= OP_T_THRES)
|
||||
{
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= (-dstp) % OPSIZ;
|
||||
BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
|
||||
|
||||
/* Copy whole pages from SRCP to DSTP by virtual address
|
||||
manipulation, as much as possible. */
|
||||
|
||||
PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known
|
||||
alignment of DSTP. Number of bytes remaining is put
|
||||
in the third argument, i.e. in LEN. This number may
|
||||
vary from machine to machine. */
|
||||
|
||||
WORD_COPY_FWD (dstp, srcp, len, len);
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
BYTE_COPY_FWD (dstp, srcp, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy from the end to the beginning. */
|
||||
srcp += len;
|
||||
dstp += len;
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if (len >= OP_T_THRES)
|
||||
{
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= dstp % OPSIZ;
|
||||
BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known
|
||||
alignment of DSTP. Number of bytes remaining is put
|
||||
in the third argument, i.e. in LEN. This number may
|
||||
vary from machine to machine. */
|
||||
|
||||
WORD_COPY_BWD (dstp, srcp, len, len);
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
BYTE_COPY_BWD (dstp, srcp, len);
|
||||
}
|
||||
|
||||
RETURN (dest);
|
||||
}
|
||||
#ifndef memmove
|
||||
libc_hidden_builtin_def (memmove)
|
||||
#endif
|
69
string/mempcpy.c
Normal file
69
string/mempcpy.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* 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, 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
#include <pagecopy.h>
|
||||
|
||||
#undef mempcpy
|
||||
#undef __mempcpy
|
||||
|
||||
void *
|
||||
__mempcpy (dstpp, srcpp, len)
|
||||
void *dstpp;
|
||||
const void *srcpp;
|
||||
size_t len;
|
||||
{
|
||||
unsigned long int dstp = (long int) dstpp;
|
||||
unsigned long int srcp = (long int) srcpp;
|
||||
|
||||
/* Copy from the beginning to the end. */
|
||||
|
||||
/* If there not too few bytes to copy, use word copy. */
|
||||
if (len >= OP_T_THRES)
|
||||
{
|
||||
/* Copy just a few bytes to make DSTP aligned. */
|
||||
len -= (-dstp) % OPSIZ;
|
||||
BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
|
||||
|
||||
/* Copy whole pages from SRCP to DSTP by virtual address manipulation,
|
||||
as much as possible. */
|
||||
|
||||
PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
|
||||
|
||||
/* Copy from SRCP to DSTP taking advantage of the known alignment of
|
||||
DSTP. Number of bytes remaining is put in the third argument,
|
||||
i.e. in LEN. This number may vary from machine to machine. */
|
||||
|
||||
WORD_COPY_FWD (dstp, srcp, len, len);
|
||||
|
||||
/* Fall out and copy the tail. */
|
||||
}
|
||||
|
||||
/* There are just a few bytes to copy. Use byte memory operations. */
|
||||
BYTE_COPY_FWD (dstp, srcp, len);
|
||||
|
||||
return (void *) dstp;
|
||||
}
|
||||
libc_hidden_def (__mempcpy)
|
||||
weak_alias (__mempcpy, mempcpy)
|
||||
libc_hidden_builtin_def (mempcpy)
|
210
string/memrchr.c
Normal file
210
string/memrchr.c
Normal file
@ -0,0 +1,210 @@
|
||||
/* memrchr -- find the last occurrence of a byte in a memory block
|
||||
Copyright (C) 1991, 93, 96, 97, 99, 2000 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
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__)
|
||||
# define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#if defined _LIBC
|
||||
# include <string.h>
|
||||
# include <memcopy.h>
|
||||
#else
|
||||
# define reg_char char
|
||||
#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 __memrchr
|
||||
#undef memrchr
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __memrchr memrchr
|
||||
#endif
|
||||
|
||||
/* Search no more than N bytes of S for C. */
|
||||
__ptr_t
|
||||
__memrchr (s, c_in, n)
|
||||
const __ptr_t s;
|
||||
int c_in;
|
||||
size_t n;
|
||||
{
|
||||
const unsigned char *char_ptr;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, charmask;
|
||||
unsigned reg_char c;
|
||||
|
||||
c = (unsigned char) c_in;
|
||||
|
||||
/* Handle the last 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 + n;
|
||||
n > 0 && ((unsigned long int) char_ptr
|
||||
& (sizeof (longword) - 1)) != 0;
|
||||
--n)
|
||||
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 = (const 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. */
|
||||
|
||||
if (sizeof (longword) != 4 && sizeof (longword) != 8)
|
||||
abort ();
|
||||
|
||||
#if LONG_MAX <= LONG_MAX_32_BITS
|
||||
magic_bits = 0x7efefeff;
|
||||
#else
|
||||
magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
|
||||
#endif
|
||||
|
||||
/* 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 (n >= sizeof (longword))
|
||||
{
|
||||
/* 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;
|
||||
|
||||
#if LONG_MAX > 2147483647
|
||||
if (cp[7] == c)
|
||||
return (__ptr_t) &cp[7];
|
||||
if (cp[6] == c)
|
||||
return (__ptr_t) &cp[6];
|
||||
if (cp[5] == c)
|
||||
return (__ptr_t) &cp[5];
|
||||
if (cp[4] == c)
|
||||
return (__ptr_t) &cp[4];
|
||||
#endif
|
||||
if (cp[3] == c)
|
||||
return (__ptr_t) &cp[3];
|
||||
if (cp[2] == c)
|
||||
return (__ptr_t) &cp[2];
|
||||
if (cp[1] == c)
|
||||
return (__ptr_t) &cp[1];
|
||||
if (cp[0] == c)
|
||||
return (__ptr_t) cp;
|
||||
}
|
||||
|
||||
n -= sizeof (longword);
|
||||
}
|
||||
|
||||
char_ptr = (const unsigned char *) longword_ptr;
|
||||
|
||||
while (n-- > 0)
|
||||
{
|
||||
if (*--char_ptr == c)
|
||||
return (__ptr_t) char_ptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__memrchr, memrchr)
|
||||
#endif
|
91
string/memset.c
Normal file
91
string/memset.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* Copyright (C) 1991, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
#undef memset
|
||||
|
||||
void *
|
||||
memset (dstpp, c, len)
|
||||
void *dstpp;
|
||||
int c;
|
||||
size_t len;
|
||||
{
|
||||
long int dstp = (long int) dstpp;
|
||||
|
||||
if (len >= 8)
|
||||
{
|
||||
size_t xlen;
|
||||
op_t cccc;
|
||||
|
||||
cccc = (unsigned char) c;
|
||||
cccc |= cccc << 8;
|
||||
cccc |= cccc << 16;
|
||||
if (OPSIZ > 4)
|
||||
/* Do the shift in two steps to avoid warning if long has 32 bits. */
|
||||
cccc |= (cccc << 16) << 16;
|
||||
|
||||
/* There are at least some bytes to set.
|
||||
No need to test for LEN == 0 in this alignment loop. */
|
||||
while (dstp % OPSIZ != 0)
|
||||
{
|
||||
((byte *) dstp)[0] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
|
||||
xlen = len / (OPSIZ * 8);
|
||||
while (xlen > 0)
|
||||
{
|
||||
((op_t *) dstp)[0] = cccc;
|
||||
((op_t *) dstp)[1] = cccc;
|
||||
((op_t *) dstp)[2] = cccc;
|
||||
((op_t *) dstp)[3] = cccc;
|
||||
((op_t *) dstp)[4] = cccc;
|
||||
((op_t *) dstp)[5] = cccc;
|
||||
((op_t *) dstp)[6] = cccc;
|
||||
((op_t *) dstp)[7] = cccc;
|
||||
dstp += 8 * OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ * 8;
|
||||
|
||||
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
|
||||
xlen = len / OPSIZ;
|
||||
while (xlen > 0)
|
||||
{
|
||||
((op_t *) dstp)[0] = cccc;
|
||||
dstp += OPSIZ;
|
||||
xlen -= 1;
|
||||
}
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* Write the last few bytes. */
|
||||
while (len > 0)
|
||||
{
|
||||
((byte *) dstp)[0] = c;
|
||||
dstp += 1;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
return dstpp;
|
||||
}
|
||||
libc_hidden_builtin_def (memset)
|
189
string/rawmemchr.c
Normal file
189
string/rawmemchr.c
Normal file
@ -0,0 +1,189 @@
|
||||
/* Copyright (C) 1991,93,96,97,99,2000,2002 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
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
# define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#if defined (_LIBC)
|
||||
# include <string.h>
|
||||
# include <memcopy.h>
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# define reg_char char
|
||||
#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
|
||||
|
||||
|
||||
/* Find the first occurrence of C in S. */
|
||||
__ptr_t
|
||||
__rawmemchr (s, c_in)
|
||||
const __ptr_t s;
|
||||
int c_in;
|
||||
{
|
||||
const unsigned char *char_ptr;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, charmask;
|
||||
unsigned reg_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. */
|
||||
|
||||
if (sizeof (longword) != 4 && sizeof (longword) != 8)
|
||||
abort ();
|
||||
|
||||
#if LONG_MAX <= LONG_MAX_32_BITS
|
||||
magic_bits = 0x7efefeff;
|
||||
#else
|
||||
magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
|
||||
#endif
|
||||
|
||||
/* 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];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
libc_hidden_def (__rawmemchr)
|
||||
weak_alias (__rawmemchr, rawmemchr)
|
55
string/stpcpy.c
Normal file
55
string/stpcpy.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1992, 1995, 1997, 2002, 2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef __stpcpy
|
||||
#undef stpcpy
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __stpcpy stpcpy
|
||||
#endif
|
||||
|
||||
/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
|
||||
char *
|
||||
__stpcpy (dest, src)
|
||||
char *dest;
|
||||
const char *src;
|
||||
{
|
||||
register char *d = dest;
|
||||
register const char *s = src;
|
||||
|
||||
do
|
||||
*d++ = *s;
|
||||
while (*s++ != '\0');
|
||||
|
||||
return d - 1;
|
||||
}
|
||||
#ifdef libc_hidden_def
|
||||
libc_hidden_def (__stpcpy)
|
||||
#endif
|
||||
#ifdef weak_alias
|
||||
weak_alias (__stpcpy, stpcpy)
|
||||
#endif
|
||||
#ifdef libc_hidden_builtin_def
|
||||
libc_hidden_builtin_def (stpcpy)
|
||||
#endif
|
100
string/stpncpy.c
Normal file
100
string/stpncpy.c
Normal file
@ -0,0 +1,100 @@
|
||||
/* Copyright (C) 1993, 1995, 1996, 1997, 2002 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __stpncpy stpncpy
|
||||
#endif
|
||||
|
||||
/* Copy no more than N characters of SRC to DEST, returning the address of
|
||||
the terminating '\0' in DEST, if any, or else DEST + N. */
|
||||
char *
|
||||
__stpncpy (dest, src, n)
|
||||
char *dest;
|
||||
const char *src;
|
||||
size_t n;
|
||||
{
|
||||
char c;
|
||||
char *s = dest;
|
||||
|
||||
if (n >= 4)
|
||||
{
|
||||
size_t n4 = n >> 2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = *src++;
|
||||
*dest++ = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
c = *src++;
|
||||
*dest++ = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
c = *src++;
|
||||
*dest++ = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
c = *src++;
|
||||
*dest++ = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
if (--n4 == 0)
|
||||
goto last_chars;
|
||||
}
|
||||
n -= dest - s;
|
||||
goto zero_fill;
|
||||
}
|
||||
|
||||
last_chars:
|
||||
n &= 3;
|
||||
if (n == 0)
|
||||
return dest;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = *src++;
|
||||
--n;
|
||||
*dest++ = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
if (n == 0)
|
||||
return dest;
|
||||
}
|
||||
|
||||
zero_fill:
|
||||
while (n-- > 0)
|
||||
dest[n] = '\0';
|
||||
|
||||
return dest - 1;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
libc_hidden_def (__stpncpy)
|
||||
weak_alias (__stpncpy, stpncpy)
|
||||
#endif
|
74
string/strcasecmp.c
Normal file
74
string/strcasecmp.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright (C) 1991,1992,1995,1996,1997,2001,2002, 2004
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _LIBC
|
||||
# define __strcasecmp strcasecmp
|
||||
# define TOLOWER(Ch) tolower (Ch)
|
||||
#else
|
||||
# include <locale/localeinfo.h>
|
||||
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define __strcasecmp __strcasecmp_l
|
||||
# endif
|
||||
# define TOLOWER(Ch) __tolower_l ((Ch), loc)
|
||||
#endif
|
||||
|
||||
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define LOCALE_PARAM , loc
|
||||
# define LOCALE_PARAM_DECL __locale_t loc;
|
||||
#else
|
||||
# define LOCALE_PARAM
|
||||
# define LOCALE_PARAM_DECL
|
||||
#endif
|
||||
|
||||
/* Compare S1 and S2, ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than,
|
||||
equal to or greater than S2. */
|
||||
int
|
||||
__strcasecmp (s1, s2 LOCALE_PARAM)
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
LOCALE_PARAM_DECL
|
||||
{
|
||||
#if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL
|
||||
__locale_t loc = _NL_CURRENT_LOCALE;
|
||||
#endif
|
||||
const unsigned char *p1 = (const unsigned char *) s1;
|
||||
const unsigned char *p2 = (const unsigned char *) s2;
|
||||
int result;
|
||||
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
|
||||
while ((result = TOLOWER (*p1) - TOLOWER (*p2++)) == 0)
|
||||
if (*p1++ == '\0')
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
#ifndef __strcasecmp
|
||||
libc_hidden_def (__strcasecmp)
|
||||
weak_alias (__strcasecmp, strcasecmp)
|
||||
#endif
|
23
string/strcasecmp_l.c
Normal file
23
string/strcasecmp_l.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* Copyright (C) 1997, 2002, 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define USE_IN_EXTENDED_LOCALE_MODEL 1
|
||||
#include "strcasecmp.c"
|
||||
|
||||
libc_hidden_def (__strcasecmp_l)
|
||||
weak_alias (__strcasecmp_l, strcasecmp_l)
|
142
string/strcasestr.c
Normal file
142
string/strcasestr.c
Normal file
@ -0,0 +1,142 @@
|
||||
/* Return the offset of one string within another.
|
||||
Copyright (C) 1994, 1996-2000, 2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/*
|
||||
* My personal strstr() implementation that beats most other algorithms.
|
||||
* Until someone tells me otherwise, I assume that this is the
|
||||
* fastest implementation of strstr() in C.
|
||||
* I deliberately chose not to comment it. You should have at least
|
||||
* as much fun trying to understand it, as I had to write it :-).
|
||||
*
|
||||
* Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined _LIBC || defined HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <locale/localeinfo.h>
|
||||
# define TOLOWER(c) __tolower_l ((unsigned char) c, loc)
|
||||
#else
|
||||
# define TOLOWER(c) _tolower (c)
|
||||
#endif
|
||||
|
||||
typedef unsigned chartype;
|
||||
|
||||
#undef strcasestr
|
||||
#undef __strcasestr
|
||||
|
||||
char *
|
||||
__strcasestr (phaystack, pneedle)
|
||||
const char *phaystack;
|
||||
const char *pneedle;
|
||||
{
|
||||
register const unsigned char *haystack, *needle;
|
||||
register chartype b, c;
|
||||
#ifdef _LIBC
|
||||
__locale_t loc = _NL_CURRENT_LOCALE;
|
||||
#endif
|
||||
|
||||
haystack = (const unsigned char *) phaystack;
|
||||
needle = (const unsigned char *) pneedle;
|
||||
|
||||
b = TOLOWER (*needle);
|
||||
if (b != '\0')
|
||||
{
|
||||
haystack--; /* possible ANSI violation */
|
||||
do
|
||||
{
|
||||
c = *++haystack;
|
||||
if (c == '\0')
|
||||
goto ret0;
|
||||
}
|
||||
while (TOLOWER (c) != (int) b);
|
||||
|
||||
c = TOLOWER (*++needle);
|
||||
if (c == '\0')
|
||||
goto foundneedle;
|
||||
++needle;
|
||||
goto jin;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
register chartype a;
|
||||
register const unsigned char *rhaystack, *rneedle;
|
||||
|
||||
do
|
||||
{
|
||||
a = *++haystack;
|
||||
if (a == '\0')
|
||||
goto ret0;
|
||||
if (TOLOWER (a) == (int) b)
|
||||
break;
|
||||
a = *++haystack;
|
||||
if (a == '\0')
|
||||
goto ret0;
|
||||
shloop:
|
||||
;
|
||||
}
|
||||
while (TOLOWER (a) != (int) b);
|
||||
|
||||
jin: a = *++haystack;
|
||||
if (a == '\0')
|
||||
goto ret0;
|
||||
|
||||
if (TOLOWER (a) != (int) c)
|
||||
goto shloop;
|
||||
|
||||
rhaystack = haystack-- + 1;
|
||||
rneedle = needle;
|
||||
a = TOLOWER (*rneedle);
|
||||
|
||||
if (TOLOWER (*rhaystack) == (int) a)
|
||||
do
|
||||
{
|
||||
if (a == '\0')
|
||||
goto foundneedle;
|
||||
++rhaystack;
|
||||
a = TOLOWER (*++needle);
|
||||
if (TOLOWER (*rhaystack) != (int) a)
|
||||
break;
|
||||
if (a == '\0')
|
||||
goto foundneedle;
|
||||
++rhaystack;
|
||||
a = TOLOWER (*++needle);
|
||||
}
|
||||
while (TOLOWER (*rhaystack) == (int) a);
|
||||
|
||||
needle = rneedle; /* took the register-poor approach */
|
||||
|
||||
if (a == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
foundneedle:
|
||||
return (char*) haystack;
|
||||
ret0:
|
||||
return 0;
|
||||
}
|
||||
|
||||
weak_alias (__strcasestr, strcasestr)
|
52
string/strcat.c
Normal file
52
string/strcat.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 1991, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
#undef strcat
|
||||
|
||||
/* Append SRC on the end of DEST. */
|
||||
char *
|
||||
strcat (dest, src)
|
||||
char *dest;
|
||||
const char *src;
|
||||
{
|
||||
char *s1 = dest;
|
||||
const char *s2 = src;
|
||||
reg_char c;
|
||||
|
||||
/* Find the end of the string. */
|
||||
do
|
||||
c = *s1++;
|
||||
while (c != '\0');
|
||||
|
||||
/* Make S1 point before the next character, so we can increment
|
||||
it while memory is read (wins on pipelined cpus). */
|
||||
s1 -= 2;
|
||||
|
||||
do
|
||||
{
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
}
|
||||
while (c != '\0');
|
||||
|
||||
return dest;
|
||||
}
|
||||
libc_hidden_builtin_def (strcat)
|
191
string/strchr.c
Normal file
191
string/strchr.c
Normal file
@ -0,0 +1,191 @@
|
||||
/* Copyright (C) 1991,1993-1997,1999,2000,2003,2006
|
||||
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
|
||||
bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
|
||||
adaptation to strchr 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
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef strchr
|
||||
|
||||
/* Find the first occurrence of C in S. */
|
||||
char *
|
||||
strchr (s, c_in)
|
||||
const char *s;
|
||||
int c_in;
|
||||
{
|
||||
const unsigned char *char_ptr;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, charmask;
|
||||
unsigned reg_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 (void *) char_ptr;
|
||||
else if (*char_ptr == '\0')
|
||||
return NULL;
|
||||
|
||||
/* 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. */
|
||||
switch (sizeof (longword))
|
||||
{
|
||||
case 4: magic_bits = 0x7efefeffL; break;
|
||||
case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Set up a longword, each of whose bytes is C. */
|
||||
charmask = c | (c << 8);
|
||||
charmask |= charmask << 16;
|
||||
if (sizeof (longword) > 4)
|
||||
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
|
||||
charmask |= (charmask << 16) << 16;
|
||||
if (sizeof (longword) > 8)
|
||||
abort ();
|
||||
|
||||
/* 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. */
|
||||
for (;;)
|
||||
{
|
||||
/* 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 as well as 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++;
|
||||
|
||||
/* 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 ||
|
||||
|
||||
/* That caught zeroes. Now test for C. */
|
||||
((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
|
||||
& ~magic_bits) != 0)
|
||||
{
|
||||
/* Which of the bytes was C or zero?
|
||||
If none of them were, it was a misfire; continue the search. */
|
||||
|
||||
const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
|
||||
|
||||
if (*cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (sizeof (longword) > 4)
|
||||
{
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
if (*++cp == c)
|
||||
return (char *) cp;
|
||||
else if (*cp == '\0')
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef weak_alias
|
||||
#undef index
|
||||
weak_alias (strchr, index)
|
||||
#endif
|
||||
libc_hidden_builtin_def (strchr)
|
170
string/strchrnul.c
Normal file
170
string/strchrnul.c
Normal file
@ -0,0 +1,170 @@
|
||||
/* Copyright (C) 1991,1993-1997,99,2000,2005 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
|
||||
bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
|
||||
adaptation to strchr 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
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef __strchrnul
|
||||
#undef strchrnul
|
||||
|
||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
||||
char *
|
||||
__strchrnul (s, c_in)
|
||||
const char *s;
|
||||
int c_in;
|
||||
{
|
||||
const unsigned char *char_ptr;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, charmask;
|
||||
unsigned reg_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 || *char_ptr == '\0')
|
||||
return (void *) 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. */
|
||||
switch (sizeof (longword))
|
||||
{
|
||||
case 4: magic_bits = 0x7efefeffL; break;
|
||||
case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Set up a longword, each of whose bytes is C. */
|
||||
charmask = c | (c << 8);
|
||||
charmask |= charmask << 16;
|
||||
if (sizeof (longword) > 4)
|
||||
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
|
||||
charmask |= (charmask << 16) << 16;
|
||||
if (sizeof (longword) > 8)
|
||||
abort ();
|
||||
|
||||
/* 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. */
|
||||
for (;;)
|
||||
{
|
||||
/* 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 as well as 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++;
|
||||
|
||||
/* 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 ||
|
||||
|
||||
/* That caught zeroes. Now test for C. */
|
||||
((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
|
||||
& ~magic_bits) != 0)
|
||||
{
|
||||
/* Which of the bytes was C or zero?
|
||||
If none of them were, it was a misfire; continue the search. */
|
||||
|
||||
const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
|
||||
|
||||
if (*cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (sizeof (longword) > 4)
|
||||
{
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
if (*++cp == c || *cp == '\0')
|
||||
return (char *) cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This should never happen. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
weak_alias (__strchrnul, strchrnul)
|
47
string/strcmp.c
Normal file
47
string/strcmp.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 1991, 1996, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
#undef strcmp
|
||||
|
||||
/* Compare S1 and S2, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than,
|
||||
equal to or greater than S2. */
|
||||
int
|
||||
strcmp (p1, p2)
|
||||
const char *p1;
|
||||
const char *p2;
|
||||
{
|
||||
register const unsigned char *s1 = (const unsigned char *) p1;
|
||||
register const unsigned char *s2 = (const unsigned char *) p2;
|
||||
unsigned reg_char c1, c2;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0')
|
||||
return c1 - c2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
return c1 - c2;
|
||||
}
|
||||
libc_hidden_builtin_def (strcmp)
|
@ -23,6 +23,7 @@
|
||||
# define STRING_TYPE char
|
||||
# define STRCOLL strcoll
|
||||
# define STRCOLL_L __strcoll_l
|
||||
# define USE_HIDDEN_DEF
|
||||
#endif
|
||||
|
||||
#include "../locale/localeinfo.h"
|
||||
@ -35,6 +36,7 @@ STRCOLL (s1, s2)
|
||||
{
|
||||
return STRCOLL_L (s1, s2, _NL_CURRENT_LOCALE);
|
||||
}
|
||||
#if !defined WIDE_CHAR_VERSION
|
||||
libc_hidden_def (strcoll)
|
||||
|
||||
#ifdef USE_HIDDEN_DEF
|
||||
libc_hidden_def (STRCOLL)
|
||||
#endif
|
||||
|
50
string/strcpy.c
Normal file
50
string/strcpy.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 1991, 1997, 2000, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#undef strcpy
|
||||
|
||||
/* Copy SRC to DEST. */
|
||||
char *
|
||||
strcpy (dest, src)
|
||||
char *dest;
|
||||
const char *src;
|
||||
{
|
||||
reg_char c;
|
||||
char *__unbounded s = (char *__unbounded) CHECK_BOUNDS_LOW (src);
|
||||
const ptrdiff_t off = CHECK_BOUNDS_LOW (dest) - s - 1;
|
||||
size_t n;
|
||||
|
||||
do
|
||||
{
|
||||
c = *s++;
|
||||
s[off] = c;
|
||||
}
|
||||
while (c != '\0');
|
||||
|
||||
n = s - src;
|
||||
(void) CHECK_BOUNDS_HIGH (src + n);
|
||||
(void) CHECK_BOUNDS_HIGH (dest + n);
|
||||
|
||||
return dest;
|
||||
}
|
||||
libc_hidden_builtin_def (strcpy)
|
51
string/strcspn.c
Normal file
51
string/strcspn.c
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright (C) 1991, 1994, 1996, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
# ifndef strchr
|
||||
# define strchr index
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef strcspn
|
||||
|
||||
/* Return the length of the maximum initial segment of S
|
||||
which contains no characters from REJECT. */
|
||||
size_t
|
||||
strcspn (s, reject)
|
||||
const char *s;
|
||||
const char *reject;
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
while (*s != '\0')
|
||||
if (strchr (reject, *s++) == NULL)
|
||||
++count;
|
||||
else
|
||||
return count;
|
||||
|
||||
return count;
|
||||
}
|
||||
libc_hidden_builtin_def (strcspn)
|
35
string/string-inlines.c
Normal file
35
string/string-inlines.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 1999, 2002, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* <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__
|
||||
|
||||
#include <string.h>
|
||||
#undef index
|
||||
#undef rindex
|
||||
|
||||
#undef __NO_INLINE__
|
||||
#include <bits/string.h>
|
||||
#include <bits/string2.h>
|
153
string/strlen.c
Normal file
153
string/strlen.c
Normal file
@ -0,0 +1,153 @@
|
||||
/* Copyright (C) 1991, 1993, 1997, 2000, 2003 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);
|
||||
commentary by Jim Blandy (jimb@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
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef strlen
|
||||
|
||||
/* Return the length of the null-terminated string STR. Scan for
|
||||
the null terminator quickly by testing four bytes at a time. */
|
||||
size_t
|
||||
strlen (str)
|
||||
const char *str;
|
||||
{
|
||||
const char *char_ptr;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, himagic, lomagic;
|
||||
|
||||
/* 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 = str; ((unsigned long int) char_ptr
|
||||
& (sizeof (longword) - 1)) != 0;
|
||||
++char_ptr)
|
||||
if (*char_ptr == '\0')
|
||||
return char_ptr - str;
|
||||
|
||||
/* 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 = 0x7efefeffL;
|
||||
himagic = 0x80808080L;
|
||||
lomagic = 0x01010101L;
|
||||
if (sizeof (longword) > 4)
|
||||
{
|
||||
/* 64-bit version of the magic. */
|
||||
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
|
||||
magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
|
||||
himagic = ((himagic << 16) << 16) | himagic;
|
||||
lomagic = ((lomagic << 16) << 16) | lomagic;
|
||||
}
|
||||
if (sizeof (longword) > 8)
|
||||
abort ();
|
||||
|
||||
/* 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. */
|
||||
for (;;)
|
||||
{
|
||||
/* 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. */
|
||||
|
||||
longword = *longword_ptr++;
|
||||
|
||||
if (
|
||||
#if 0
|
||||
/* Add MAGIC_BITS to LONGWORD. */
|
||||
(((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)
|
||||
#else
|
||||
((longword - lomagic) & himagic)
|
||||
#endif
|
||||
!= 0)
|
||||
{
|
||||
/* Which of the bytes was the zero? If none of them were, it was
|
||||
a misfire; continue the search. */
|
||||
|
||||
const char *cp = (const char *) (longword_ptr - 1);
|
||||
|
||||
if (cp[0] == 0)
|
||||
return cp - str;
|
||||
if (cp[1] == 0)
|
||||
return cp - str + 1;
|
||||
if (cp[2] == 0)
|
||||
return cp - str + 2;
|
||||
if (cp[3] == 0)
|
||||
return cp - str + 3;
|
||||
if (sizeof (longword) > 4)
|
||||
{
|
||||
if (cp[4] == 0)
|
||||
return cp - str + 4;
|
||||
if (cp[5] == 0)
|
||||
return cp - str + 5;
|
||||
if (cp[6] == 0)
|
||||
return cp - str + 6;
|
||||
if (cp[7] == 0)
|
||||
return cp - str + 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
libc_hidden_builtin_def (strlen)
|
76
string/strncase.c
Normal file
76
string/strncase.c
Normal file
@ -0,0 +1,76 @@
|
||||
/* Compare at most N characters of two strings without taking care for
|
||||
the case.
|
||||
Copyright (C) 1992, 1996, 1997, 2001, 2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __strncasecmp strncasecmp
|
||||
# define TOLOWER(Ch) tolower (Ch)
|
||||
#else
|
||||
# include <locale/localeinfo.h>
|
||||
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define __strncasecmp __strncasecmp_l
|
||||
# endif
|
||||
# define TOLOWER(Ch) __tolower_l ((Ch), loc)
|
||||
#endif
|
||||
|
||||
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define LOCALE_PARAM , loc
|
||||
# define LOCALE_PARAM_DECL __locale_t loc;
|
||||
#else
|
||||
# define LOCALE_PARAM
|
||||
# define LOCALE_PARAM_DECL
|
||||
#endif
|
||||
|
||||
/* Compare no more than N characters of S1 and S2,
|
||||
ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less
|
||||
than, equal to or greater than S2. */
|
||||
int
|
||||
__strncasecmp (s1, s2, n LOCALE_PARAM)
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
size_t n;
|
||||
LOCALE_PARAM_DECL
|
||||
{
|
||||
#if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL
|
||||
__locale_t loc = _NL_CURRENT_LOCALE;
|
||||
#endif
|
||||
const unsigned char *p1 = (const unsigned char *) s1;
|
||||
const unsigned char *p2 = (const unsigned char *) s2;
|
||||
int result;
|
||||
|
||||
if (p1 == p2 || n == 0)
|
||||
return 0;
|
||||
|
||||
while ((result = TOLOWER (*p1) - TOLOWER (*p2++)) == 0)
|
||||
if (*p1++ == '\0' || --n == 0)
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
#ifndef __strncasecmp
|
||||
weak_alias (__strncasecmp, strncasecmp)
|
||||
#endif
|
25
string/strncase_l.c
Normal file
25
string/strncase_l.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* Compare at most N characters of two strings without taking care for
|
||||
the case using given locale.
|
||||
Copyright (C) 1997, 2002, 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define USE_IN_EXTENDED_LOCALE_MODEL 1
|
||||
#include "strncase.c"
|
||||
|
||||
libc_hidden_def (__strncasecmp_l)
|
||||
weak_alias (__strncasecmp_l, strncasecmp_l)
|
85
string/strncat.c
Normal file
85
string/strncat.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 1991, 1997 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <memcopy.h>
|
||||
#else
|
||||
typedef char reg_char;
|
||||
#endif
|
||||
|
||||
#undef strncat
|
||||
|
||||
char *
|
||||
strncat (s1, s2, n)
|
||||
char *s1;
|
||||
const char *s2;
|
||||
size_t n;
|
||||
{
|
||||
reg_char c;
|
||||
char *s = s1;
|
||||
|
||||
/* Find the end of S1. */
|
||||
do
|
||||
c = *s1++;
|
||||
while (c != '\0');
|
||||
|
||||
/* Make S1 point before next character, so we can increment
|
||||
it while memory is read (wins on pipelined cpus). */
|
||||
s1 -= 2;
|
||||
|
||||
if (n >= 4)
|
||||
{
|
||||
size_t n4 = n >> 2;
|
||||
do
|
||||
{
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
return s;
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
return s;
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
return s;
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
return s;
|
||||
} while (--n4 > 0);
|
||||
n &= 3;
|
||||
}
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
return s;
|
||||
n--;
|
||||
}
|
||||
|
||||
if (c != '\0')
|
||||
*++s1 = '\0';
|
||||
|
||||
return s;
|
||||
}
|
73
string/strncmp.c
Normal file
73
string/strncmp.c
Normal file
@ -0,0 +1,73 @@
|
||||
/* Copyright (C) 1991, 1996, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
#undef strncmp
|
||||
|
||||
/* Compare no more than N characters of S1 and S2,
|
||||
returning less than, equal to or greater than zero
|
||||
if S1 is lexicographically less than, equal to or
|
||||
greater than S2. */
|
||||
int
|
||||
strncmp (s1, s2, n)
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
size_t n;
|
||||
{
|
||||
unsigned reg_char c1 = '\0';
|
||||
unsigned reg_char c2 = '\0';
|
||||
|
||||
if (n >= 4)
|
||||
{
|
||||
size_t n4 = n >> 2;
|
||||
do
|
||||
{
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0' || c1 != c2)
|
||||
return c1 - c2;
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0' || c1 != c2)
|
||||
return c1 - c2;
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0' || c1 != c2)
|
||||
return c1 - c2;
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0' || c1 != c2)
|
||||
return c1 - c2;
|
||||
} while (--n4 > 0);
|
||||
n &= 3;
|
||||
}
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0' || c1 != c2)
|
||||
return c1 - c2;
|
||||
n--;
|
||||
}
|
||||
|
||||
return c1 - c2;
|
||||
}
|
||||
libc_hidden_builtin_def (strncmp)
|
87
string/strncpy.c
Normal file
87
string/strncpy.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* Copyright (C) 1991, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
#undef strncpy
|
||||
|
||||
char *
|
||||
strncpy (s1, s2, n)
|
||||
char *s1;
|
||||
const char *s2;
|
||||
size_t n;
|
||||
{
|
||||
reg_char c;
|
||||
char *s = s1;
|
||||
|
||||
--s1;
|
||||
|
||||
if (n >= 4)
|
||||
{
|
||||
size_t n4 = n >> 2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (c == '\0')
|
||||
break;
|
||||
if (--n4 == 0)
|
||||
goto last_chars;
|
||||
}
|
||||
n = n - (s1 - s) - 1;
|
||||
if (n == 0)
|
||||
return s;
|
||||
goto zero_fill;
|
||||
}
|
||||
|
||||
last_chars:
|
||||
n &= 3;
|
||||
if (n == 0)
|
||||
return s;
|
||||
|
||||
do
|
||||
{
|
||||
c = *s2++;
|
||||
*++s1 = c;
|
||||
if (--n == 0)
|
||||
return s;
|
||||
}
|
||||
while (c != '\0');
|
||||
|
||||
zero_fill:
|
||||
do
|
||||
*++s1 = '\0';
|
||||
while (--n > 0);
|
||||
|
||||
return s;
|
||||
}
|
||||
libc_hidden_builtin_def (strncpy)
|
161
string/strnlen.c
Normal file
161
string/strnlen.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* Find the length of STRING, but scan at most MAXLEN characters.
|
||||
Copyright (C) 1991,1993,1997,2000,2001,2005 Free Software Foundation, Inc.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
Based on strlen written by Torbjorn Granlund (tege@sics.se),
|
||||
with help from Dan Sahlin (dan@sics.se);
|
||||
commentary by Jim Blandy (jimb@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 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; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Find the length of S, but scan at most MAXLEN characters. If no
|
||||
'\0' terminator is found in that many characters, return MAXLEN. */
|
||||
size_t
|
||||
__strnlen (const char *str, size_t maxlen)
|
||||
{
|
||||
const char *char_ptr, *end_ptr = str + maxlen;
|
||||
const unsigned long int *longword_ptr;
|
||||
unsigned long int longword, magic_bits, himagic, lomagic;
|
||||
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
|
||||
if (__builtin_expect (end_ptr < str, 0))
|
||||
end_ptr = (const char *) ~0UL;
|
||||
|
||||
/* 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 = str; ((unsigned long int) char_ptr
|
||||
& (sizeof (longword) - 1)) != 0;
|
||||
++char_ptr)
|
||||
if (*char_ptr == '\0')
|
||||
{
|
||||
if (char_ptr > end_ptr)
|
||||
char_ptr = end_ptr;
|
||||
return char_ptr - str;
|
||||
}
|
||||
|
||||
/* 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 = 0x7efefeffL;
|
||||
himagic = 0x80808080L;
|
||||
lomagic = 0x01010101L;
|
||||
if (sizeof (longword) > 4)
|
||||
{
|
||||
/* 64-bit version of the magic. */
|
||||
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
|
||||
magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
|
||||
himagic = ((himagic << 16) << 16) | himagic;
|
||||
lomagic = ((lomagic << 16) << 16) | lomagic;
|
||||
}
|
||||
if (sizeof (longword) > 8)
|
||||
abort ();
|
||||
|
||||
/* 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 (longword_ptr < (unsigned long int *) end_ptr)
|
||||
{
|
||||
/* 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. */
|
||||
|
||||
longword = *longword_ptr++;
|
||||
|
||||
if ((longword - lomagic) & himagic)
|
||||
{
|
||||
/* Which of the bytes was the zero? If none of them were, it was
|
||||
a misfire; continue the search. */
|
||||
|
||||
const char *cp = (const char *) (longword_ptr - 1);
|
||||
|
||||
char_ptr = cp;
|
||||
if (cp[0] == 0)
|
||||
break;
|
||||
char_ptr = cp + 1;
|
||||
if (cp[1] == 0)
|
||||
break;
|
||||
char_ptr = cp + 2;
|
||||
if (cp[2] == 0)
|
||||
break;
|
||||
char_ptr = cp + 3;
|
||||
if (cp[3] == 0)
|
||||
break;
|
||||
if (sizeof (longword) > 4)
|
||||
{
|
||||
char_ptr = cp + 4;
|
||||
if (cp[4] == 0)
|
||||
break;
|
||||
char_ptr = cp + 5;
|
||||
if (cp[5] == 0)
|
||||
break;
|
||||
char_ptr = cp + 6;
|
||||
if (cp[6] == 0)
|
||||
break;
|
||||
char_ptr = cp + 7;
|
||||
if (cp[7] == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
char_ptr = end_ptr;
|
||||
}
|
||||
|
||||
if (char_ptr > end_ptr)
|
||||
char_ptr = end_ptr;
|
||||
return char_ptr - str;
|
||||
}
|
||||
weak_alias (__strnlen, strnlen)
|
||||
libc_hidden_def (strnlen)
|
46
string/strpbrk.c
Normal file
46
string/strpbrk.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 1991, 1994, 1996, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || defined HAVE_CONFIG_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#undef strpbrk
|
||||
|
||||
/* Find the first occurrence in S of any character in ACCEPT. */
|
||||
char *
|
||||
strpbrk (s, accept)
|
||||
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;
|
||||
}
|
||||
libc_hidden_builtin_def (strpbrk)
|
50
string/strrchr.c
Normal file
50
string/strrchr.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 1991, 1995, 1996, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef strrchr
|
||||
|
||||
/* Find the last occurrence of C in S. */
|
||||
char *
|
||||
strrchr (const char *s, int c)
|
||||
{
|
||||
register const char *found, *p;
|
||||
|
||||
c = (unsigned char) c;
|
||||
|
||||
/* Since strchr is fast, we use it rather than the obvious loop. */
|
||||
|
||||
if (c == '\0')
|
||||
return strchr (s, '\0');
|
||||
|
||||
found = NULL;
|
||||
while ((p = strchr (s, c)) != NULL)
|
||||
{
|
||||
found = p;
|
||||
s = p + 1;
|
||||
}
|
||||
|
||||
return (char *) found;
|
||||
}
|
||||
|
||||
#ifdef weak_alias
|
||||
#undef rindex
|
||||
weak_alias (strrchr, rindex)
|
||||
#endif
|
||||
libc_hidden_builtin_def (strrchr)
|
70
string/strsep.c
Normal file
70
string/strsep.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef __strsep
|
||||
#undef strsep
|
||||
|
||||
char *
|
||||
__strsep (char **stringp, const char *delim)
|
||||
{
|
||||
char *begin, *end;
|
||||
|
||||
begin = *stringp;
|
||||
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);
|
||||
|
||||
if (end)
|
||||
{
|
||||
/* Terminate the token and set *STRINGP past NUL character. */
|
||||
*end++ = '\0';
|
||||
*stringp = end;
|
||||
}
|
||||
else
|
||||
/* No more delimiters; this is the last token. */
|
||||
*stringp = NULL;
|
||||
|
||||
return begin;
|
||||
}
|
||||
weak_alias (__strsep, strsep)
|
||||
strong_alias (__strsep, __strsep_g)
|
||||
libc_hidden_def (__strsep_g)
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1994-2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1994-2002, 2005 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
|
||||
@ -24,10 +24,6 @@
|
||||
#include <bits/libc-lock.h>
|
||||
|
||||
|
||||
#ifndef HAVE_GNU_LD
|
||||
#define _sys_siglist sys_siglist
|
||||
#endif
|
||||
|
||||
/* Defined in siglist.c. */
|
||||
extern const char *const _sys_siglist[];
|
||||
extern const char *const _sys_siglist_internal[] attribute_hidden;
|
||||
|
47
string/strspn.c
Normal file
47
string/strspn.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 1991, 1997, 2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef strspn
|
||||
|
||||
/* Return the length of the maximum initial segment
|
||||
of S which contains only characters in ACCEPT. */
|
||||
size_t
|
||||
strspn (s, accept)
|
||||
const char *s;
|
||||
const char *accept;
|
||||
{
|
||||
const char *p;
|
||||
const char *a;
|
||||
size_t count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p)
|
||||
{
|
||||
for (a = accept; *a != '\0'; ++a)
|
||||
if (*p == *a)
|
||||
break;
|
||||
if (*a == '\0')
|
||||
return count;
|
||||
else
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
libc_hidden_builtin_def (strspn)
|
123
string/strstr.c
Normal file
123
string/strstr.c
Normal file
@ -0,0 +1,123 @@
|
||||
/* Return the offset of one string within another.
|
||||
Copyright (C) 1994,1996,1997,2000,2001,2003 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/*
|
||||
* My personal strstr() implementation that beats most other algorithms.
|
||||
* Until someone tells me otherwise, I assume that this is the
|
||||
* fastest implementation of strstr() in C.
|
||||
* I deliberately chose not to comment it. You should have at least
|
||||
* as much fun trying to understand it, as I had to write it :-).
|
||||
*
|
||||
* Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || defined HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
typedef unsigned chartype;
|
||||
|
||||
#undef strstr
|
||||
|
||||
char *
|
||||
strstr (phaystack, pneedle)
|
||||
const char *phaystack;
|
||||
const char *pneedle;
|
||||
{
|
||||
const unsigned char *haystack, *needle;
|
||||
chartype b;
|
||||
const unsigned char *rneedle;
|
||||
|
||||
haystack = (const unsigned char *) phaystack;
|
||||
|
||||
if ((b = *(needle = (const unsigned char *) pneedle)))
|
||||
{
|
||||
chartype c;
|
||||
haystack--; /* possible ANSI violation */
|
||||
|
||||
{
|
||||
chartype a;
|
||||
do
|
||||
if (!(a = *++haystack))
|
||||
goto ret0;
|
||||
while (a != b);
|
||||
}
|
||||
|
||||
if (!(c = *++needle))
|
||||
goto foundneedle;
|
||||
++needle;
|
||||
goto jin;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
{
|
||||
chartype a;
|
||||
if (0)
|
||||
jin:{
|
||||
if ((a = *++haystack) == c)
|
||||
goto crest;
|
||||
}
|
||||
else
|
||||
a = *++haystack;
|
||||
do
|
||||
{
|
||||
for (; a != b; a = *++haystack)
|
||||
{
|
||||
if (!a)
|
||||
goto ret0;
|
||||
if ((a = *++haystack) == b)
|
||||
break;
|
||||
if (!a)
|
||||
goto ret0;
|
||||
}
|
||||
}
|
||||
while ((a = *++haystack) != c);
|
||||
}
|
||||
crest:
|
||||
{
|
||||
chartype a;
|
||||
{
|
||||
const unsigned char *rhaystack;
|
||||
if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))
|
||||
do
|
||||
{
|
||||
if (!a)
|
||||
goto foundneedle;
|
||||
if (*++rhaystack != (a = *++needle))
|
||||
break;
|
||||
if (!a)
|
||||
goto foundneedle;
|
||||
}
|
||||
while (*++rhaystack == (a = *++needle));
|
||||
needle = rneedle; /* took the register-poor aproach */
|
||||
}
|
||||
if (!a)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
foundneedle:
|
||||
return (char *) haystack;
|
||||
ret0:
|
||||
return 0;
|
||||
}
|
||||
libc_hidden_builtin_def (strstr)
|
66
string/strtok.c
Normal file
66
string/strtok.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* Copyright (C) 1991,1996,1997,1999,2000,2001 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static char *olds;
|
||||
|
||||
#undef strtok
|
||||
|
||||
/* Parse S into tokens separated by characters in DELIM.
|
||||
If S is NULL, the last string strtok() was called with is
|
||||
used. For example:
|
||||
char s[] = "-abc-=-def";
|
||||
x = strtok(s, "-"); // x = "abc"
|
||||
x = strtok(NULL, "-="); // x = "def"
|
||||
x = strtok(NULL, "="); // x = NULL
|
||||
// s = "abc\0-def\0"
|
||||
*/
|
||||
char *
|
||||
strtok (s, delim)
|
||||
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;
|
||||
}
|
79
string/strtok_r.c
Normal file
79
string/strtok_r.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* Reentrant string tokenizer. Generic version.
|
||||
Copyright (C) 1991,1996-1999,2001,2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#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.
|
||||
If S is NULL, the saved pointer in SAVE_PTR is used as
|
||||
the next starting point. For example:
|
||||
char s[] = "-abc-=-def";
|
||||
char *sp;
|
||||
x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
|
||||
x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
|
||||
x = strtok_r(NULL, "=", &sp); // x = NULL
|
||||
// s = "abc\0-def\0"
|
||||
*/
|
||||
char *
|
||||
__strtok_r (char *s, const char *delim, char **save_ptr)
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (s == NULL)
|
||||
s = *save_ptr;
|
||||
|
||||
/* Scan leading delimiters. */
|
||||
s += strspn (s, delim);
|
||||
if (*s == '\0')
|
||||
{
|
||||
*save_ptr = s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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
|
||||
{
|
||||
/* Terminate the token and make *SAVE_PTR point past it. */
|
||||
*s = '\0';
|
||||
*save_ptr = s + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
libc_hidden_def (__strtok_r)
|
||||
weak_alias (__strtok_r, strtok_r)
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1995,96,97,2002, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995, 1996, 1997, 2002, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Ulrich Drepper <drepper@gnu.org>, 1995.
|
||||
|
||||
@ -96,6 +97,7 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
|
||||
const int32_t *indirect;
|
||||
uint_fast32_t pass;
|
||||
size_t needed;
|
||||
size_t last_needed;
|
||||
const USTRING_TYPE *usrc;
|
||||
size_t srclen = STRLEN (src);
|
||||
int32_t *idxarr;
|
||||
@ -197,6 +199,7 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
|
||||
this is true for all of them. */
|
||||
int position = rule & sort_position;
|
||||
|
||||
last_needed = needed;
|
||||
if (position == 0)
|
||||
{
|
||||
for (idxcnt = 0; idxcnt < idxmax; ++idxcnt)
|
||||
@ -210,8 +213,9 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
|
||||
/* Handle the pushed elements now. */
|
||||
size_t backw;
|
||||
|
||||
for (backw = idxcnt - 1; backw >= backw_stop; --backw)
|
||||
for (backw = idxcnt; backw > backw_stop; )
|
||||
{
|
||||
--backw;
|
||||
len = weights[idxarr[backw]++];
|
||||
|
||||
if (needed + len < n)
|
||||
@ -293,8 +297,9 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
|
||||
/* Handle the pushed elements now. */
|
||||
size_t backw;
|
||||
|
||||
for (backw = idxcnt - 1; backw >= backw_stop; --backw)
|
||||
for (backw = idxcnt; backw > backw_stop; )
|
||||
{
|
||||
--backw;
|
||||
len = weights[idxarr[backw]++];
|
||||
if (len != 0)
|
||||
{
|
||||
@ -424,11 +429,11 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
|
||||
a `position' rule at the end and if no non-ignored character
|
||||
is found the last \1 byte is immediately followed by a \0 byte
|
||||
signalling this. We can avoid the \1 byte(s). */
|
||||
if (needed <= n && needed > 2 && dest[needed - 2] == L('\1'))
|
||||
if (needed > 2 && needed == last_needed + 1)
|
||||
{
|
||||
/* Remove the \1 byte. */
|
||||
--needed;
|
||||
dest[needed - 1] = L('\0');
|
||||
if (--needed <= n)
|
||||
dest[needed - 1] = L('\0');
|
||||
}
|
||||
|
||||
/* Free the memory if needed. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure memccpy functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -109,8 +109,8 @@ do_test (size_t align1, size_t align2, int c, size_t len, size_t n,
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len - 1; ++i)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure memchr functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -89,7 +89,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char)
|
||||
{
|
||||
buf1[align + pos] = seek_char;
|
||||
buf1[align + len] = -seek_char;
|
||||
result = buf1 + align + pos;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -101,7 +101,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1 + align, seek_char, len, result);
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -144,16 +144,17 @@ do_random_tests (void)
|
||||
}
|
||||
|
||||
if (pos < len)
|
||||
result = p + pos + align;
|
||||
result = (char *) (p + pos + align);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
if (CALL (impl, p + align, seek_char, len) != result)
|
||||
if (CALL (impl, (char *) (p + align), seek_char, len) != result)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
|
||||
n, impl->name, align, seek_char, len, pos,
|
||||
CALL (impl, p + align, seek_char, len), result, p);
|
||||
CALL (impl, (char *) (p + align), seek_char, len),
|
||||
result, p);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure memcmp functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -88,8 +88,8 @@ do_test (size_t align1, size_t align2, size_t len, int exp_result)
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = s2[i] = 1 + 23 * i % 255;
|
||||
@ -161,7 +161,7 @@ do_random_tests (void)
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
r = CALL (impl, p1 + align1, p2 + align2, len);
|
||||
r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2), len);
|
||||
/* Test whether on 64-bit architectures where ABI requires
|
||||
callee to promote has the promotion been done. */
|
||||
asm ("" : "=g" (r) : "0" (r));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure memcpy functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -102,8 +102,8 @@ do_test (size_t align1, size_t align2, size_t len)
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0, j = 1; i < len; i++, j += 23)
|
||||
s1[i] = j;
|
||||
@ -190,7 +190,9 @@ do_random_tests (void)
|
||||
if (j > size2)
|
||||
j = size2;
|
||||
memset (p2, c, j);
|
||||
res = CALL (impl, p2 + align2, p1 + align1, len);
|
||||
res = (unsigned char *) CALL (impl,
|
||||
(char *) (p2 + align2),
|
||||
(char *) (p1 + align1), len);
|
||||
if (res != MEMCPY_RESULT (p2 + align2, len))
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
|
||||
|
@ -101,8 +101,8 @@ do_test (size_t align1, size_t align2, size_t len)
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0, j = 1; i < len; i++, j += 23)
|
||||
s1[i] = j;
|
||||
@ -111,7 +111,7 @@ do_test (size_t align1, size_t align2, size_t len)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, buf2 + align1, s1, len);
|
||||
do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -179,7 +179,9 @@ do_random_tests (void)
|
||||
{
|
||||
memset (p2 + dststart, c, dstend - dststart);
|
||||
memcpy (p2 + srcstart, p1 + srcstart, srcend - srcstart);
|
||||
res = CALL (impl, p2 + align2, p2 + align1, len);
|
||||
res = (unsigned char *) CALL (impl,
|
||||
(char *) (p2 + align2),
|
||||
(char *) (p2 + align1), len);
|
||||
if (res != p2 + align2)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure memset functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -49,10 +49,12 @@ static void
|
||||
do_one_test (impl_t *impl, char *s, int c, size_t n)
|
||||
{
|
||||
char *res = CALL (impl, s, c, n);
|
||||
if (res != s)
|
||||
char tstbuf[n];
|
||||
if (res != s
|
||||
|| simple_memset (tstbuf, c, n) != tstbuf
|
||||
|| memcmp (s, tstbuf, n) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p != %p", impl->name,
|
||||
res, s);
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
@ -87,7 +89,7 @@ do_test (size_t align, int c, size_t len)
|
||||
printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1 + align, c, len);
|
||||
do_one_test (impl, (char *) buf1 + align, c, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -143,7 +145,7 @@ do_random_tests (void)
|
||||
if (p[i + align] == c)
|
||||
p[i + align] = o;
|
||||
}
|
||||
res = CALL (impl, p + align, c, len);
|
||||
res = (unsigned char *) CALL (impl, (char *) p + align, c, len);
|
||||
if (res != p + align)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd) %p != %p",
|
||||
@ -191,7 +193,7 @@ test_main (void)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (c = 0; c <= 65; c += 65)
|
||||
for (c = -65; c <= 130; c += 65)
|
||||
{
|
||||
for (i = 0; i < 18; ++i)
|
||||
do_test (0, c, 1 << i);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strcat functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -91,8 +91,8 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char)
|
||||
if (align2 + len1 + len2 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len1; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
@ -175,7 +175,8 @@ do_random_tests (void)
|
||||
memset (p2 - 64, '\1', align2 + 64);
|
||||
memset (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1);
|
||||
memcpy (p2 + align2, buf1, len2 + 1);
|
||||
res = CALL (impl, p2 + align2, p1 + align1);
|
||||
res = (unsigned char *) CALL (impl, (char *) (p2 + align2),
|
||||
(char *) (p1 + align1));
|
||||
if (res != p2 + align2)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd %zd) %p != %p",
|
||||
|
@ -101,10 +101,10 @@ do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
if (pos < len)
|
||||
{
|
||||
buf1[align + pos] = seek_char;
|
||||
result = buf1 + align + pos;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
}
|
||||
else if (seek_char == 0)
|
||||
result = buf1 + align + len;
|
||||
result = (char *) (buf1 + align + len);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
@ -112,7 +112,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1 + align, seek_char, result);
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -166,18 +166,18 @@ do_random_tests (void)
|
||||
}
|
||||
|
||||
if (pos <= len)
|
||||
result = p + pos + align;
|
||||
result = (char *) (p + pos + align);
|
||||
else if (seek_char == 0)
|
||||
result = p + len + align;
|
||||
result = (char *) (p + len + align);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
if (CALL (impl, p + align, seek_char) != result)
|
||||
if (CALL (impl, (char *) (p + align), seek_char) != result)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
|
||||
n, impl->name, align, seek_char, len, pos,
|
||||
CALL (impl, p + align, seek_char), result, p);
|
||||
CALL (impl, (char *) (p + align), seek_char), result, p);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strcmp functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -103,8 +103,8 @@ do_test (size_t align1, size_t align2, size_t len, int max_char,
|
||||
if (align2 + len + 1 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = s2[i] = 1 + 23 * i % max_char;
|
||||
@ -198,7 +198,7 @@ do_random_tests (void)
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
r = CALL (impl, p1 + align1, p2 + align2);
|
||||
r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2));
|
||||
/* Test whether on 64-bit architectures where ABI requires
|
||||
callee to promote has the promotion been done. */
|
||||
asm ("" : "=g" (r) : "0" (r));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strcpy functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -92,8 +92,8 @@ do_test (size_t align1, size_t align2, size_t len, int max_char)
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
@ -148,7 +148,8 @@ do_random_tests (void)
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
memset (p2 - 64, '\1', 512 + 64);
|
||||
res = CALL (impl, p2 + align2, p1 + align1);
|
||||
res = (unsigned char *) CALL (impl, (char *) (p2 + align2),
|
||||
(char *) (p1 + align1));
|
||||
if (res != STRCPY_RESULT (p2 + align2, len))
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strlen functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -92,7 +92,7 @@ do_test (size_t align, size_t len, int max_char)
|
||||
printf ("Length %4zd, alignment %2zd:", len, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1 + align, len);
|
||||
do_one_test (impl, (char *) (buf1 + align), len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -127,10 +127,11 @@ do_random_tests (void)
|
||||
}
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
if (CALL (impl, p + align) != len)
|
||||
if (CALL (impl, (char *) (p + align)) != len)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd) %zd != %zd, p %p",
|
||||
n, impl->name, align, CALL (impl, p + align), len, p);
|
||||
n, impl->name, align, CALL (impl, (char *) (p + align)),
|
||||
len, p);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,65 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char,
|
||||
int exp_result)
|
||||
{
|
||||
size_t i, align_n;
|
||||
char *s1, *s2;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
s1 = (char*)(buf1 + page_size);
|
||||
s2 = (char*)(buf2 + page_size);
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd:", len, n);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, 0);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
align1 &= 15;
|
||||
align2 &= 15;
|
||||
align_n = (page_size - n) & 15;
|
||||
|
||||
s1 = (char*)(buf1 + page_size - n);
|
||||
s2 = (char*)(buf2 + page_size - n);
|
||||
|
||||
if (align1 < align_n)
|
||||
s1 -= (align_n - align1);
|
||||
|
||||
if (align2 < align_n)
|
||||
s2 -= (align_n - align2);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
s1[i] = s2[i] = 1 + 23 * i % max_char;
|
||||
|
||||
if (len < n)
|
||||
{
|
||||
s1[len] = 0;
|
||||
s2[len] = 0;
|
||||
if (exp_result < 0)
|
||||
s2[len] = 32;
|
||||
else if (exp_result > 0)
|
||||
s1[len] = 64;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
|
||||
int exp_result)
|
||||
@ -103,8 +162,8 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
|
||||
if (align2 + n + 1 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char*)(buf1 + align1);
|
||||
s2 = (char*)(buf2 + align2);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
s1[i] = s2[i] = 1 + 23 * i % max_char;
|
||||
@ -124,7 +183,7 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, exp_result);
|
||||
do_one_test (impl, (char*)s1, (char*)s2, n, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -208,7 +267,7 @@ do_random_tests (void)
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
r = CALL (impl, p1 + align1, p2 + align2, size);
|
||||
r = CALL (impl, (char*)(p1 + align1), (char*)(p2 + align2), size);
|
||||
/* Test whether on 64-bit architectures where ABI requires
|
||||
callee to promote has the promotion been done. */
|
||||
asm ("" : "=g" (r) : "0" (r));
|
||||
@ -271,6 +330,24 @@ test_main (void)
|
||||
do_test (2 * i, i, 8 << i, 16 << i, 255, 0);
|
||||
do_test (2 * i, i, 8 << i, 16 << i, 255, 1);
|
||||
}
|
||||
|
||||
do_test_limit (0, 0, 0, 0, 127, 0);
|
||||
do_test_limit (4, 0, 21, 20, 127, 0);
|
||||
do_test_limit (0, 4, 21, 20, 127, 0);
|
||||
do_test_limit (8, 0, 25, 24, 127, 0);
|
||||
do_test_limit (0, 8, 25, 24, 127, 0);
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
do_test_limit (0, 0, 17 - i, 16 - i, 127, 0);
|
||||
do_test_limit (0, 0, 17 - i, 16 - i, 255, 0);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 127, 0);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 127, 1);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 127, -1);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 255, 0);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 255, 1);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 255, -1);
|
||||
}
|
||||
|
||||
do_random_tests ();
|
||||
return ret;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strncpy functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -124,8 +124,8 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = buf1 + align1;
|
||||
s2 = buf2 + align2;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
@ -215,7 +215,9 @@ do_random_tests (void)
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
{
|
||||
memset (p2 - 64, '\1', 512 + 64);
|
||||
res = CALL (impl, p2 + align2, p1 + align1, size);
|
||||
res = (unsigned char *) CALL (impl,
|
||||
(char *) (p2 + align2),
|
||||
(char *) (p1 + align1), size);
|
||||
if (res != STRNCPY_RESULT (p2 + align2, len, size))
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strpbrk functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -102,8 +102,8 @@ do_test (size_t align, size_t pos, size_t len)
|
||||
if (align + pos + 10 >= page_size || len > 240)
|
||||
return;
|
||||
|
||||
rej = buf2 + (random () & 255);
|
||||
s = buf1 + align;
|
||||
rej = (char *) (buf2 + (random () & 255));
|
||||
s = (char *) (buf1 + align);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
@ -182,7 +182,7 @@ do_random_tests (void)
|
||||
}
|
||||
rej[i] = '\0';
|
||||
for (c = 1; c <= 255; ++c)
|
||||
if (strchr (rej, c) == NULL)
|
||||
if (strchr ((char *) rej, c) == NULL)
|
||||
break;
|
||||
j = (pos > len ? pos : len) + align + 64;
|
||||
if (j > 512)
|
||||
@ -199,23 +199,24 @@ do_random_tests (void)
|
||||
else
|
||||
{
|
||||
p[i] = random () & 255;
|
||||
if (strchr (rej, p[i]))
|
||||
if (strchr ((char *) rej, p[i]))
|
||||
{
|
||||
p[i] = random () & 255;
|
||||
if (strchr (rej, p[i]))
|
||||
if (strchr ((char *) rej, p[i]))
|
||||
p[i] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = STRPBRK_RESULT (p + align, pos < len ? pos : len);
|
||||
result = STRPBRK_RESULT ((char *) (p + align), pos < len ? pos : len);
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
if (CALL (impl, p + align, rej) != result)
|
||||
if (CALL (impl, (char *) (p + align), (char *) rej) != result)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %p, %zd, %zd, %zd) %p != %p",
|
||||
n, impl->name, align, rej, rlen, pos, len,
|
||||
(void *) CALL (impl, p + align, rej), (void *) result);
|
||||
(void *) CALL (impl, (char *) (p + align), (char *) rej),
|
||||
(void *) result);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strrchr functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -95,10 +95,10 @@ do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
if (pos < len)
|
||||
{
|
||||
buf1[align + pos] = seek_char;
|
||||
result = buf1 + align + pos;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
}
|
||||
else if (seek_char == 0)
|
||||
result = buf1 + align + len;
|
||||
result = (char *) (buf1 + align + len);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
@ -106,7 +106,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1 + align, seek_char, result);
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
@ -165,18 +165,18 @@ do_random_tests (void)
|
||||
}
|
||||
|
||||
if (pos <= len)
|
||||
result = p + pos + align;
|
||||
result = (char *) (p + pos + align);
|
||||
else if (seek_char == 0)
|
||||
result = p + len + align;
|
||||
result = (char *) (p + len + align);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
if (CALL (impl, p + align, seek_char) != result)
|
||||
if (CALL (impl, (char *) (p + align), seek_char) != result)
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
|
||||
n, impl->name, align, seek_char, len, pos,
|
||||
CALL (impl, p + align, seek_char), result, p);
|
||||
CALL (impl, (char *) (p + align), seek_char), result, p);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Test and measure strspn functions.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999,2002,2003,2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
|
||||
|
||||
@ -104,8 +104,8 @@ do_test (size_t align, size_t pos, size_t len)
|
||||
if (align + pos + 10 >= page_size || len > 240 || ! len)
|
||||
return;
|
||||
|
||||
acc = buf2 + (random () & 255);
|
||||
s = buf1 + align;
|
||||
acc = (char *) (buf2 + (random () & 255));
|
||||
s = (char *) (buf1 + align);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
@ -183,7 +183,7 @@ do_random_tests (void)
|
||||
else if (i == pos + align)
|
||||
{
|
||||
p[i] = random () & 255;
|
||||
if (strchr (acc, p[i]))
|
||||
if (strchr ((char *) acc, p[i]))
|
||||
p[i] = '\0';
|
||||
}
|
||||
else if (i < align || i > pos + align)
|
||||
@ -193,11 +193,13 @@ do_random_tests (void)
|
||||
}
|
||||
|
||||
FOR_EACH_IMPL (impl, 1)
|
||||
if (CALL (impl, p + align, acc) != (pos < len ? pos : len))
|
||||
if (CALL (impl, (char *) (p + align),
|
||||
(char *) acc) != (pos < len ? pos : len))
|
||||
{
|
||||
error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %p, %zd, %zd, %zd) %zd != %zd",
|
||||
n, impl->name, align, acc, alen, pos, len,
|
||||
CALL (impl, p + align, acc), (pos < len ? pos : len));
|
||||
CALL (impl, (char *) (p + align), (char *) acc),
|
||||
(pos < len ? pos : len));
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Tester for string functions.
|
||||
Copyright (C) 1995-2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2001, 2003, 2005 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,10 +34,6 @@
|
||||
#include <strings.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef HAVE_GNU_LD
|
||||
#define _sys_nerr sys_nerr
|
||||
#define _sys_errlist sys_errlist
|
||||
#endif
|
||||
|
||||
#define STREQ(a, b) (strcmp((a), (b)) == 0)
|
||||
|
||||
@ -348,6 +344,9 @@ test_strncat (void)
|
||||
|
||||
(void) strncat (one, "gh", 2);
|
||||
equal (one, "abcdgh", 12); /* Count and length equal. */
|
||||
|
||||
(void) strncat (one, "ij", (size_t)-1); /* set sign bit in count */
|
||||
equal (one, "abcdghij", 13);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -368,6 +367,8 @@ test_strncmp (void)
|
||||
check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
|
||||
check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
|
||||
check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
|
||||
check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
|
||||
check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -433,6 +434,29 @@ test_strlen (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_strnlen (void)
|
||||
{
|
||||
it = "strnlen";
|
||||
check (strnlen ("", 10) == 0, 1); /* Empty. */
|
||||
check (strnlen ("a", 10) == 1, 2); /* Single char. */
|
||||
check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
|
||||
check (strnlen ("foo", (size_t)-1) == 3, 4); /* limits of n. */
|
||||
|
||||
{
|
||||
char buf[4096];
|
||||
int i;
|
||||
char *p;
|
||||
for (i=0; i < 0x100; i++)
|
||||
{
|
||||
p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
|
||||
strcpy (p, "OK");
|
||||
strcpy (p+3, "BAD/WRONG");
|
||||
check (strnlen (p, 100) == 2, 5+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_strchr (void)
|
||||
{
|
||||
@ -1386,6 +1410,9 @@ main (void)
|
||||
/* strlen. */
|
||||
test_strlen ();
|
||||
|
||||
/* strnlen. */
|
||||
test_strnlen ();
|
||||
|
||||
/* strchr. */
|
||||
test_strchr ();
|
||||
|
||||
|
15
string/tst-strfry.c
Normal file
15
string/tst-strfry.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
char str[] = "this is a test";
|
||||
|
||||
strfry (str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
83
string/tst-strxfrm2.c
Normal file
83
string/tst-strxfrm2.c
Normal file
@ -0,0 +1,83 @@
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
char buf[20];
|
||||
size_t l1 = strxfrm (NULL, "ab", 0);
|
||||
size_t l2 = strxfrm (buf, "ab", 1);
|
||||
size_t l3 = strxfrm (buf, "ab", sizeof (buf));
|
||||
if (l3 < sizeof (buf) && strlen (buf) != l3)
|
||||
{
|
||||
puts ("C locale l3 test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
size_t l4 = strxfrm (buf, "ab", l1 + 1);
|
||||
if (l4 < l1 + 1 && strlen (buf) != l4)
|
||||
{
|
||||
puts ("C locale l4 test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
buf[l1] = 'Z';
|
||||
size_t l5 = strxfrm (buf, "ab", l1);
|
||||
if (buf[l1] != 'Z')
|
||||
{
|
||||
puts ("C locale l5 test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
if (l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5)
|
||||
{
|
||||
puts ("C locale retval test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
|
||||
{
|
||||
puts ("setlocale failed");
|
||||
res = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l1 = strxfrm (NULL, "ab", 0);
|
||||
l2 = strxfrm (buf, "ab", 1);
|
||||
l3 = strxfrm (buf, "ab", sizeof (buf));
|
||||
if (l3 < sizeof (buf) && strlen (buf) != l3)
|
||||
{
|
||||
puts ("UTF-8 locale l3 test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
l4 = strxfrm (buf, "ab", l1 + 1);
|
||||
if (l4 < l1 + 1 && strlen (buf) != l4)
|
||||
{
|
||||
puts ("UTF-8 locale l4 test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
buf[l1] = 'Z';
|
||||
l5 = strxfrm (buf, "ab", l1);
|
||||
if (buf[l1] != 'Z')
|
||||
{
|
||||
puts ("UTF-8 locale l5 test failed");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
if (l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5)
|
||||
{
|
||||
puts ("UTF-8 locale retval test failed");
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
413
string/wordcopy.c
Normal file
413
string/wordcopy.c
Normal file
@ -0,0 +1,413 @@
|
||||
/* _memcopy.c -- subroutines for memory copy functions.
|
||||
Copyright (C) 1991, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <memcopy.h>
|
||||
|
||||
/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
Both SRCP and DSTP should be aligned for memory operations on `op_t's. */
|
||||
|
||||
void
|
||||
_wordcopy_fwd_aligned (dstp, srcp, len)
|
||||
long int dstp;
|
||||
long int srcp;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1;
|
||||
|
||||
switch (len % 8)
|
||||
{
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 6 * OPSIZ;
|
||||
dstp -= 7 * OPSIZ;
|
||||
len += 6;
|
||||
goto do1;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 5 * OPSIZ;
|
||||
dstp -= 6 * OPSIZ;
|
||||
len += 5;
|
||||
goto do2;
|
||||
case 4:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 5 * OPSIZ;
|
||||
len += 4;
|
||||
goto do3;
|
||||
case 5:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 3 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
len += 3;
|
||||
goto do4;
|
||||
case 6:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 2 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
len += 2;
|
||||
goto do5;
|
||||
case 7:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -= 1 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
len += 1;
|
||||
goto do6;
|
||||
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return;
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
srcp -= 0 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
goto do7;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
srcp -=-1 * OPSIZ;
|
||||
dstp -= 0 * OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
goto do8; /* No-op. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
do8:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
((op_t *) dstp)[0] = a1;
|
||||
do7:
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
((op_t *) dstp)[1] = a0;
|
||||
do6:
|
||||
a0 = ((op_t *) srcp)[2];
|
||||
((op_t *) dstp)[2] = a1;
|
||||
do5:
|
||||
a1 = ((op_t *) srcp)[3];
|
||||
((op_t *) dstp)[3] = a0;
|
||||
do4:
|
||||
a0 = ((op_t *) srcp)[4];
|
||||
((op_t *) dstp)[4] = a1;
|
||||
do3:
|
||||
a1 = ((op_t *) srcp)[5];
|
||||
((op_t *) dstp)[5] = a0;
|
||||
do2:
|
||||
a0 = ((op_t *) srcp)[6];
|
||||
((op_t *) dstp)[6] = a1;
|
||||
do1:
|
||||
a1 = ((op_t *) srcp)[7];
|
||||
((op_t *) dstp)[7] = a0;
|
||||
|
||||
srcp += 8 * OPSIZ;
|
||||
dstp += 8 * OPSIZ;
|
||||
len -= 8;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
((op_t *) dstp)[0] = a1;
|
||||
}
|
||||
|
||||
/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
|
||||
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
|
||||
DSTP should be aligned for memory operations on `op_t's, but SRCP must
|
||||
*not* be aligned. */
|
||||
|
||||
void
|
||||
_wordcopy_fwd_dest_aligned (dstp, srcp, len)
|
||||
long int dstp;
|
||||
long int srcp;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1, a2, a3;
|
||||
int sh_1, sh_2;
|
||||
|
||||
/* Calculate how to shift a word read at the memory operation
|
||||
aligned srcp to make it aligned for copy. */
|
||||
|
||||
sh_1 = 8 * (srcp % OPSIZ);
|
||||
sh_2 = 8 * OPSIZ - sh_1;
|
||||
|
||||
/* Make SRCP aligned by rounding it down to the beginning of the `op_t'
|
||||
it points in the middle of. */
|
||||
srcp &= -OPSIZ;
|
||||
|
||||
switch (len % 4)
|
||||
{
|
||||
case 2:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
a2 = ((op_t *) srcp)[1];
|
||||
srcp -= 1 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
len += 2;
|
||||
goto do1;
|
||||
case 3:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
srcp -= 0 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
len += 1;
|
||||
goto do2;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return;
|
||||
a3 = ((op_t *) srcp)[0];
|
||||
a0 = ((op_t *) srcp)[1];
|
||||
srcp -=-1 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
len += 0;
|
||||
goto do3;
|
||||
case 1:
|
||||
a2 = ((op_t *) srcp)[0];
|
||||
a3 = ((op_t *) srcp)[1];
|
||||
srcp -=-2 * OPSIZ;
|
||||
dstp -= 0 * OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
goto do4; /* No-op. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
do4:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
|
||||
do3:
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
|
||||
do2:
|
||||
a2 = ((op_t *) srcp)[2];
|
||||
((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
|
||||
do1:
|
||||
a3 = ((op_t *) srcp)[3];
|
||||
((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
|
||||
|
||||
srcp += 4 * OPSIZ;
|
||||
dstp += 4 * OPSIZ;
|
||||
len -= 4;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
|
||||
}
|
||||
|
||||
/* _wordcopy_bwd_aligned -- Copy block finishing right before
|
||||
SRCP to block finishing right before DSTP with LEN `op_t' words
|
||||
(not LEN bytes!). Both SRCP and DSTP should be aligned for memory
|
||||
operations on `op_t's. */
|
||||
|
||||
void
|
||||
_wordcopy_bwd_aligned (dstp, srcp, len)
|
||||
long int dstp;
|
||||
long int srcp;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1;
|
||||
|
||||
switch (len % 8)
|
||||
{
|
||||
case 2:
|
||||
srcp -= 2 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
a0 = ((op_t *) srcp)[1];
|
||||
len += 6;
|
||||
goto do1;
|
||||
case 3:
|
||||
srcp -= 3 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
a1 = ((op_t *) srcp)[2];
|
||||
len += 5;
|
||||
goto do2;
|
||||
case 4:
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
a0 = ((op_t *) srcp)[3];
|
||||
len += 4;
|
||||
goto do3;
|
||||
case 5:
|
||||
srcp -= 5 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
a1 = ((op_t *) srcp)[4];
|
||||
len += 3;
|
||||
goto do4;
|
||||
case 6:
|
||||
srcp -= 6 * OPSIZ;
|
||||
dstp -= 5 * OPSIZ;
|
||||
a0 = ((op_t *) srcp)[5];
|
||||
len += 2;
|
||||
goto do5;
|
||||
case 7:
|
||||
srcp -= 7 * OPSIZ;
|
||||
dstp -= 6 * OPSIZ;
|
||||
a1 = ((op_t *) srcp)[6];
|
||||
len += 1;
|
||||
goto do6;
|
||||
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return;
|
||||
srcp -= 8 * OPSIZ;
|
||||
dstp -= 7 * OPSIZ;
|
||||
a0 = ((op_t *) srcp)[7];
|
||||
goto do7;
|
||||
case 1:
|
||||
srcp -= 9 * OPSIZ;
|
||||
dstp -= 8 * OPSIZ;
|
||||
a1 = ((op_t *) srcp)[8];
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
goto do8; /* No-op. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
do8:
|
||||
a0 = ((op_t *) srcp)[7];
|
||||
((op_t *) dstp)[7] = a1;
|
||||
do7:
|
||||
a1 = ((op_t *) srcp)[6];
|
||||
((op_t *) dstp)[6] = a0;
|
||||
do6:
|
||||
a0 = ((op_t *) srcp)[5];
|
||||
((op_t *) dstp)[5] = a1;
|
||||
do5:
|
||||
a1 = ((op_t *) srcp)[4];
|
||||
((op_t *) dstp)[4] = a0;
|
||||
do4:
|
||||
a0 = ((op_t *) srcp)[3];
|
||||
((op_t *) dstp)[3] = a1;
|
||||
do3:
|
||||
a1 = ((op_t *) srcp)[2];
|
||||
((op_t *) dstp)[2] = a0;
|
||||
do2:
|
||||
a0 = ((op_t *) srcp)[1];
|
||||
((op_t *) dstp)[1] = a1;
|
||||
do1:
|
||||
a1 = ((op_t *) srcp)[0];
|
||||
((op_t *) dstp)[0] = a0;
|
||||
|
||||
srcp -= 8 * OPSIZ;
|
||||
dstp -= 8 * OPSIZ;
|
||||
len -= 8;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
((op_t *) dstp)[7] = a1;
|
||||
}
|
||||
|
||||
/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
|
||||
before SRCP to block finishing right before DSTP with LEN `op_t'
|
||||
words (not LEN bytes!). DSTP should be aligned for memory
|
||||
operations on `op_t', but SRCP must *not* be aligned. */
|
||||
|
||||
void
|
||||
_wordcopy_bwd_dest_aligned (dstp, srcp, len)
|
||||
long int dstp;
|
||||
long int srcp;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1, a2, a3;
|
||||
int sh_1, sh_2;
|
||||
|
||||
/* Calculate how to shift a word read at the memory operation
|
||||
aligned srcp to make it aligned for copy. */
|
||||
|
||||
sh_1 = 8 * (srcp % OPSIZ);
|
||||
sh_2 = 8 * OPSIZ - sh_1;
|
||||
|
||||
/* Make srcp aligned by rounding it down to the beginning of the op_t
|
||||
it points in the middle of. */
|
||||
srcp &= -OPSIZ;
|
||||
srcp += OPSIZ;
|
||||
|
||||
switch (len % 4)
|
||||
{
|
||||
case 2:
|
||||
srcp -= 3 * OPSIZ;
|
||||
dstp -= 1 * OPSIZ;
|
||||
a2 = ((op_t *) srcp)[2];
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
len += 2;
|
||||
goto do1;
|
||||
case 3:
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 2 * OPSIZ;
|
||||
a3 = ((op_t *) srcp)[3];
|
||||
a2 = ((op_t *) srcp)[2];
|
||||
len += 1;
|
||||
goto do2;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return;
|
||||
srcp -= 5 * OPSIZ;
|
||||
dstp -= 3 * OPSIZ;
|
||||
a0 = ((op_t *) srcp)[4];
|
||||
a3 = ((op_t *) srcp)[3];
|
||||
goto do3;
|
||||
case 1:
|
||||
srcp -= 6 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
a1 = ((op_t *) srcp)[5];
|
||||
a0 = ((op_t *) srcp)[4];
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
goto do4; /* No-op. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
do4:
|
||||
a3 = ((op_t *) srcp)[3];
|
||||
((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
|
||||
do3:
|
||||
a2 = ((op_t *) srcp)[2];
|
||||
((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
|
||||
do2:
|
||||
a1 = ((op_t *) srcp)[1];
|
||||
((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
|
||||
do1:
|
||||
a0 = ((op_t *) srcp)[0];
|
||||
((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
|
||||
|
||||
srcp -= 4 * OPSIZ;
|
||||
dstp -= 4 * OPSIZ;
|
||||
len -= 4;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
|
||||
}
|
57
string/xpg-strerror.c
Normal file
57
string/xpg-strerror.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio-common/_itoa.h>
|
||||
|
||||
/* It is critical here that we always use the `dcgettext' function for
|
||||
the message translation. Since <libintl.h> only defines the macro
|
||||
`dgettext' to use `dcgettext' for optimizing programs this is not
|
||||
always guaranteed. */
|
||||
#ifndef dgettext
|
||||
# include <locale.h> /* We need LC_MESSAGES. */
|
||||
# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
|
||||
#endif
|
||||
|
||||
/* Fill buf with a string describing the errno code in ERRNUM. */
|
||||
int
|
||||
__xpg_strerror_r (int errnum, char *buf, size_t buflen)
|
||||
{
|
||||
if (errnum < 0 || errnum >= _sys_nerr_internal
|
||||
|| _sys_errlist_internal[errnum] == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
const char *estr = (const char *) _(_sys_errlist_internal[errnum]);
|
||||
size_t estrlen = strlen (estr) + 1;
|
||||
|
||||
if (buflen < estrlen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy (buf, estr, estrlen);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user