diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2005-12-14 15:06:39 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2005-12-14 15:06:39 +0000 |
| commit | 9d13fb2413921c713f83efe331e8e4d219c62c6b (patch) | |
| tree | 2d44d7ac45ab2d147eb8361bbff880c365aa8ad5 /string | |
| parent | b6ab06cef4670e02756bcdd4d2c33a49369a4346 (diff) | |
| download | glibc-9d13fb2413921c713f83efe331e8e4d219c62c6b.tar.xz glibc-9d13fb2413921c713f83efe331e8e4d219c62c6b.zip | |
Moved to csu/errno-loc.c.
Diffstat (limited to 'string')
40 files changed, 4133 insertions, 0 deletions
diff --git a/string/ffs.c b/string/ffs.c new file mode 100644 index 0000000000..06a1542bd9 --- /dev/null +++ b/string/ffs.c @@ -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 diff --git a/string/ffsll.c b/string/ffsll.c new file mode 100644 index 0000000000..9dd269afb7 --- /dev/null +++ b/string/ffsll.c @@ -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 diff --git a/string/memccpy.c b/string/memccpy.c new file mode 100644 index 0000000000..9ffdc335d4 --- /dev/null +++ b/string/memccpy.c @@ -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) diff --git a/string/memchr.c b/string/memchr.c new file mode 100644 index 0000000000..f3098c775a --- /dev/null +++ b/string/memchr.c @@ -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) diff --git a/string/memcmp.c b/string/memcmp.c new file mode 100644 index 0000000000..2f8cf344af --- /dev/null +++ b/string/memcmp.c @@ -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. */ + |
