📄 string2.h
字号:
/* Machine-independant string function optimizations. Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library 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. */#ifndef _STRING_H# error "Never use <bits/string2.h> directly; include <string.h> instead."#endif#ifndef __NO_STRING_INLINES/* Unlike the definitions in the header <bits/string.h> the definitions contained here are not optimized down to assembler level. Those optimizations are not always a good idea since this means the code size increases a lot. Instead the definitions here optimize some functions in a way which do not dramatically increase the code size and which do not use assembler. The main trick is to use GNU CC's `__builtin_constant_p' function. Every function XXX which has a defined version in <bits/string.h> must be accompanied by a symbol _HAVE_STRING_ARCH_XXX to make sure we don't get redefinitions. We must use here macros instead of inline functions since the trick won't work with the latter. */#ifndef __STRING_INLINE# ifdef __cplusplus# define __STRING_INLINE inline# else# define __STRING_INLINE extern __inline# endif#endif#if _STRING_ARCH_unaligned/* If we can do unaligned memory accesses we must know the endianess. */# include <endian.h># include <bits/types.h># if __BYTE_ORDER == __LITTLE_ENDIAN# define __STRING2_SMALL_GET16(src, idx) \ (((__const unsigned char *) (__const char *) (src))[idx + 1] << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx])# define __STRING2_SMALL_GET32(src, idx) \ (((((__const unsigned char *) (__const char *) (src))[idx + 3] << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx + 2]) << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx + 1]) << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx])# else# define __STRING2_SMALL_GET16(src, idx) \ (((__const unsigned char *) (__const char *) (src))[idx] << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx + 1])# define __STRING2_SMALL_GET32(src, idx) \ (((((__const unsigned char *) (__const char *) (src))[idx] << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx + 1]) << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx + 2]) << 8 \ | ((__const unsigned char *) (__const char *) (src))[idx + 3])# endif#else/* These are a few types we need for the optimizations if we cannot use unaligned memory accesses. */# define __STRING2_COPY_TYPE(N) \ typedef struct { unsigned char __arr[N]; } \ __STRING2_COPY_ARR##N __attribute__ ((packed))__STRING2_COPY_TYPE (2);__STRING2_COPY_TYPE (3);__STRING2_COPY_TYPE (4);__STRING2_COPY_TYPE (5);__STRING2_COPY_TYPE (6);__STRING2_COPY_TYPE (7);__STRING2_COPY_TYPE (8);# undef __STRING2_COPY_TYPE#endif/* Dereferencing a pointer arg to run sizeof on it fails for the void pointer case, so we use this instead. Note that __x is evaluated twice. */#define __string2_1bptr_p(__x) \ ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)/* Set N bytes of S to C. */#ifndef _HAVE_STRING_ARCH_memset# if _STRING_ARCH_unaligned# define memset(s, c, n) \ (__extension__ (__builtin_constant_p (n) && (n) <= 16 \ ? ((n) == 1 \ ? __memset_1 (s, c) \ : __memset_gc (s, c, n)) \ : (__builtin_constant_p (c) && (c) == '\0' \ ? ({ void *__s = (s); __bzero (__s, n); __s; }) \ : memset (s, c, n))))# define __memset_1(s, c) ({ void *__s = (s); \ *((__uint8_t *) __s) = (__uint8_t) c; __s; })# define __memset_gc(s, c, n) \ ({ void *__s = (s); \ union { \ unsigned int __ui; \ unsigned short int __usi; \ unsigned char __uc; \ } *__u = __s; \ __uint8_t __c = (__uint8_t) (c); \ \ /* This `switch' statement will be removed at compile-time. */ \ switch ((unsigned int) (n)) \ { \ case 15: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 11: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 7: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 3: \ __u->__usi = (unsigned short int) __c * 0x0101; \ __u = __extension__ ((void *) __u + 2); \ __u->__uc = (unsigned char) __c; \ break; \ \ case 14: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 10: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 6: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 2: \ __u->__usi = (unsigned short int) __c * 0x0101; \ break; \ \ case 13: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 9: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 5: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 1: \ __u->__uc = (unsigned char) __c; \ break; \ \ case 16: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 12: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 8: \ __u->__ui = __c * 0x01010101; \ __u = __extension__ ((void *) __u + 4); \ case 4: \ __u->__ui = __c * 0x01010101; \ case 0: \ break; \ } \ \ __s; })# else# define memset(s, c, n) \ (__extension__ (__builtin_constant_p (c) && (c) == '\0' \ ? ({ void *__s = (s); __bzero (__s, n); __s; }) \ : memset (s, c, n)))# endif/* GCC optimizes memset(s, 0, n) but not bzero(s, n). The optimization is broken before EGCS 1.1. */# if defined __GNUC__ \ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 90))# define __bzero(s, n) __builtin_memset (s, '\0', n)# endif#endif/* Copy N bytes from SRC to DEST, returning pointer to byte following the last copied. */#ifdef __USE_GNU# ifndef _HAVE_STRING_ARCH_mempcpy# define __mempcpy(dest, src, n) \ (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \ && __string2_1bptr_p (src) && n <= 8 \ ? __mempcpy_small (dest, __mempcpy_args (src), n) \ : __mempcpy (dest, src, n)))/* In glibc we use this function frequently but for namespace reasons we have to use the name `__mempcpy'. */# define mempcpy(dest, src, n) __mempcpy (dest, src, n)# if _STRING_ARCH_unaligned# define __mempcpy_args(src) \ ((char *) (src))[0], ((char *) (src))[2], ((char *) (src))[4], \ ((char *) (src))[6], \ __extension__ __STRING2_SMALL_GET16 (src, 0), \ __extension__ __STRING2_SMALL_GET16 (src, 4), \ __extension__ __STRING2_SMALL_GET32 (src, 0), \ __extension__ __STRING2_SMALL_GET32 (src, 4)__STRING_INLINE void *__mempcpy_small (void *, char, char, char, char, __uint16_t, __uint16_t, __uint32_t, __uint32_t, size_t);__STRING_INLINE void *__mempcpy_small (void *__dest1, char __src0_1, char __src2_1, char __src4_1, char __src6_1, __uint16_t __src0_2, __uint16_t __src4_2, __uint32_t __src0_4, __uint32_t __src4_4, size_t __srclen){ union { __uint32_t __ui; __uint16_t __usi; unsigned char __uc; unsigned char __c; } *__u = __dest1; switch ((unsigned int) __srclen) { case 1: __u->__c = __src0_1; __u = __extension__ ((void *) __u + 1); break; case 2: __u->__usi = __src0_2; __u = __extension__ ((void *) __u + 2); break; case 3: __u->__usi = __src0_2; __u = __extension__ ((void *) __u + 2); __u->__c = __src2_1; __u = __extension__ ((void *) __u + 1); break; case 4: __u->__ui = __src0_4; __u = __extension__ ((void *) __u + 4); break; case 5: __u->__ui = __src0_4; __u = __extension__ ((void *) __u + 4); __u->__c = __src4_1; __u = __extension__ ((void *) __u + 1); break; case 6: __u->__ui = __src0_4; __u = __extension__ ((void *) __u + 4); __u->__usi = __src4_2; __u = __extension__ ((void *) __u + 2); break; case 7: __u->__ui = __src0_4; __u = __extension__ ((void *) __u + 4); __u->__usi = __src4_2; __u = __extension__ ((void *) __u + 2); __u->__c = __src6_1; __u = __extension__ ((void *) __u + 1); break; case 8: __u->__ui = __src0_4; __u = __extension__ ((void *) __u + 4); __u->__ui = __src4_4; __u = __extension__ ((void *) __u + 4); break; } return (void *) __u;}# else# define __mempcpy_args(src) \ ((__const char *) (src))[0], \ __extension__ ((__STRING2_COPY_ARR2) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1] } }), \ __extension__ ((__STRING2_COPY_ARR3) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ ((__const char *) (src))[2] } }), \ __extension__ ((__STRING2_COPY_ARR4) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ ((__const char *) (src))[2], ((__const char *) (src))[3] } }), \ __extension__ ((__STRING2_COPY_ARR5) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ ((__const char *) (src))[2], ((__const char *) (src))[3], \ ((__const char *) (src))[4] } }), \ __extension__ ((__STRING2_COPY_ARR6) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ ((__const char *) (src))[2], ((__const char *) (src))[3], \ ((__const char *) (src))[4], ((__const char *) (src))[5] } }), \ __extension__ ((__STRING2_COPY_ARR7) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ ((__const char *) (src))[2], ((__const char *) (src))[3], \ ((__const char *) (src))[4], ((__const char *) (src))[5], \ ((__const char *) (src))[6] } }), \ __extension__ ((__STRING2_COPY_ARR8) \ { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ ((__const char *) (src))[2], ((__const char *) (src))[3], \ ((__const char *) (src))[4], ((__const char *) (src))[5], \ ((__const char *) (src))[6], ((__const char *) (src))[7] } })__STRING_INLINE void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2, __STRING2_COPY_ARR3, __STRING2_COPY_ARR4, __STRING2_COPY_ARR5, __STRING2_COPY_ARR6, __STRING2_COPY_ARR7, __STRING2_COPY_ARR8, size_t);__STRING_INLINE void *__mempcpy_small (void *__dest, char __src1, __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, __STRING2_COPY_ARR8 __src8, size_t __srclen){ union { char __c; __STRING2_COPY_ARR2 __sca2; __STRING2_COPY_ARR3 __sca3; __STRING2_COPY_ARR4 __sca4; __STRING2_COPY_ARR5 __sca5; __STRING2_COPY_ARR6 __sca6; __STRING2_COPY_ARR7 __sca7; __STRING2_COPY_ARR8 __sca8; } *__u = __dest; switch ((unsigned int) __srclen) { case 1: __u->__c = __src1; break; case 2: __extension__ __u->__sca2 = __src2; break; case 3: __extension__ __u->__sca3 = __src3; break; case 4: __extension__ __u->__sca4 = __src4; break; case 5: __extension__ __u->__sca5 = __src5; break; case 6: __extension__ __u->__sca6 = __src6; break; case 7: __extension__ __u->__sca7 = __src7; break; case 8: __extension__ __u->__sca8 = __src8; break; } return __extension__ ((void *) __u + __srclen);}# endif# endif#endif/* Return pointer to C in S. */#ifndef _HAVE_STRING_ARCH_strchrextern __ptr_t __rawmemchr (const __ptr_t __s, int __c);# define strchr(s, c) \ (__extension__ (__builtin_constant_p (c) && (c) == '\0' \ ? (char *) __rawmemchr (s, c) \ : strchr (s, c)))#endif/* Copy SRC to DEST. */#ifndef _HAVE_STRING_ARCH_strcpy# define strcpy(dest, src) \ (__extension__ (__builtin_constant_p (src) \ ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \ ? __strcpy_small (dest, __strcpy_args (src), \ strlen (src) + 1) \ : (char *) memcpy (dest, src, strlen (src) + 1)) \ : strcpy (dest, src)))# if _STRING_ARCH_unaligned# define __strcpy_args(src) \ __extension__ __STRING2_SMALL_GET16 (src, 0), \ __extension__ __STRING2_SMALL_GET16 (src, 4), \ __extension__ __STRING2_SMALL_GET32 (src, 0), \ __extension__ __STRING2_SMALL_GET32 (src, 4)__STRING_INLINE char *__strcpy_small (char *, __uint16_t, __uint16_t, __uint32_t, __uint32_t, size_t);__STRING_INLINE char *__strcpy_small (char *__dest, __uint16_t __src0_2, __uint16_t __src4_2, __uint32_t __src0_4, __uint32_t __src4_4, size_t __srclen){ union { __uint32_t __ui;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -