]> git.ipfire.org Git - thirdparty/glibc.git/blame - string/bits/string2.h
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / string / bits / string2.h
CommitLineData
9a0a462c 1/* Machine-independant string function optimizations.
bfff8b1b 2 Copyright (C) 1997-2017 Free Software Foundation, Inc.
9a0a462c
UD
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
9a0a462c
UD
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 14 Lesser General Public License for more details.
9a0a462c 15
41bdb6e2 16 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
9a0a462c 19
61eb22d3
UD
20#ifndef _STRING_H
21# error "Never use <bits/string2.h> directly; include <string.h> instead."
22#endif
23
2bdd4ca6 24#ifndef __NO_STRING_INLINES
9a0a462c
UD
25
26/* Unlike the definitions in the header <bits/string.h> the
61952351
UD
27 definitions contained here are not optimized down to assembler
28 level. Those optimizations are not always a good idea since this
9a0a462c 29 means the code size increases a lot. Instead the definitions here
61952351
UD
30 optimize some functions in a way which do not dramatically
31 increase the code size and which do not use assembler. The main
4a691b06 32 trick is to use GCC's `__builtin_constant_p' function.
9a0a462c
UD
33
34 Every function XXX which has a defined version in
61eb22d3 35 <bits/string.h> must be accompanied by a symbol _HAVE_STRING_ARCH_XXX
9a0a462c
UD
36 to make sure we don't get redefinitions.
37
38 We must use here macros instead of inline functions since the
49c091e5 39 trick won't work with the latter. */
9a0a462c 40
9bbd7837
UD
41#ifndef __STRING_INLINE
42# ifdef __cplusplus
43# define __STRING_INLINE inline
44# else
b037a293 45# define __STRING_INLINE __extern_inline
9bbd7837 46# endif
9a0a462c
UD
47#endif
48
7ef90c15
UD
49/* Dereferencing a pointer arg to run sizeof on it fails for the void
50 pointer case, so we use this instead.
51 Note that __x is evaluated twice. */
52#define __string2_1bptr_p(__x) \
36ab45e1 53 ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)
61eb22d3 54
9601d3ad 55/* Set N bytes of S to 0. */
3dbfd811 56#if !defined _HAVE_STRING_ARCH_memset
155bc2a5 57# define __bzero(s, n) __builtin_memset (s, '\0', n)
61eb22d3 58#endif
9a0a462c 59
e7c5513d 60
482eec0d 61#ifndef _HAVE_STRING_ARCH_strchr
c1422e5b 62extern void *__rawmemchr (const void *__s, int __c);
4a691b06
UD
63# define strchr(s, c) \
64 (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \
65 && (c) == '\0' \
66 ? (char *) __rawmemchr (s, c) \
67 : __builtin_strchr (s, c)))
482eec0d
UD
68#endif
69
70
9a0a462c
UD
71/* Copy SRC to DEST, returning pointer to final NUL byte. */
72#ifdef __USE_GNU
155bc2a5
WD
73# ifndef _HAVE_STRING_ARCH_stpcpy
74# define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
9a0a462c
UD
75/* In glibc we use this function frequently but for namespace reasons
76 we have to use the name `__stpcpy'. */
155bc2a5
WD
77# define stpcpy(dest, src) __stpcpy (dest, src)
78# endif
9a0a462c
UD
79#endif
80
81
82/* Copy no more than N characters of SRC to DEST. */
83#ifndef _HAVE_STRING_ARCH_strncpy
155bc2a5 84# define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)
9a0a462c
UD
85#endif
86
87
88/* Append no more than N characters from SRC onto DEST. */
89#ifndef _HAVE_STRING_ARCH_strncat
d3d99893 90# ifdef _USE_STRING_ARCH_strchr
9a0a462c 91# define strncat(dest, src, n) \
650425ce
UD
92 (__extension__ ({ char *__dest = (dest); \
93 __builtin_constant_p (src) && __builtin_constant_p (n) \
94 ? (strlen (src) < ((size_t) (n)) \
95 ? strcat (__dest, src) \
9c3b1ceb
UD
96 : (*((char *) __mempcpy (strchr (__dest, '\0'), \
97 src, n)) = '\0', __dest)) \
650425ce 98 : strncat (dest, src, n); }))
9a0a462c 99# else
155bc2a5 100# define strncat(dest, src, n) __builtin_strncat (dest, src, n)
9a0a462c
UD
101# endif
102#endif
103
104
650425ce
UD
105/* Compare characters of S1 and S2. */
106#ifndef _HAVE_STRING_ARCH_strcmp
155bc2a5 107# define strcmp(s1, s2) \
4a691b06
UD
108 __extension__ \
109 ({ size_t __s1_len, __s2_len; \
110 (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
111 && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
112 (!__string2_1bptr_p (s1) || __s1_len >= 4) \
113 && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
114 ? __builtin_strcmp (s1, s2) \
115 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
116 && (__s1_len = strlen (s1), __s1_len < 4) \
117 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
118 ? __builtin_strcmp (s1, s2) \
119 : __strcmp_cg (s1, s2, __s1_len)) \
120 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
121 && (__s2_len = strlen (s2), __s2_len < 4) \
122 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
123 ? __builtin_strcmp (s1, s2) \
155bc2a5
WD
124 : -__strcmp_cg (s2, s1, __s2_len)) \
125 : __builtin_strcmp (s1, s2)))); })
a5a0310d 126
650425ce 127# define __strcmp_cg(s1, s2, l1) \
a784e502
UD
128 (__extension__ ({ const unsigned char *__s2 = \
129 (const unsigned char *) (const char *) (s2); \
2e09a79a 130 int __result = \
a784e502 131 (((const unsigned char *) (const char *) (s1))[0] \
fab6d621 132 - __s2[0]); \
650425ce
UD
133 if (l1 > 0 && __result == 0) \
134 { \
a784e502
UD
135 __result = (((const unsigned char *) \
136 (const char *) (s1))[1] - __s2[1]); \
650425ce
UD
137 if (l1 > 1 && __result == 0) \
138 { \
a784e502
UD
139 __result = (((const unsigned char *) \
140 (const char *) (s1))[2] - __s2[2]); \
650425ce 141 if (l1 > 2 && __result == 0) \
a784e502
UD
142 __result = (((const unsigned char *) \
143 (const char *) (s1))[3] \
af6f3906 144 - __s2[3]); \
650425ce
UD
145 } \
146 } \
147 __result; }))
650425ce
UD
148#endif
149
150
9a0a462c
UD
151/* Compare N characters of S1 and S2. */
152#ifndef _HAVE_STRING_ARCH_strncmp
d30da2a8
UD
153# define strncmp(s1, s2, n) \
154 (__extension__ (__builtin_constant_p (n) \
155 && ((__builtin_constant_p (s1) \
156 && strlen (s1) < ((size_t) (n))) \
157 || (__builtin_constant_p (s2) \
158 && strlen (s2) < ((size_t) (n)))) \
159 ? strcmp (s1, s2) : strncmp (s1, s2, n)))
9a0a462c
UD
160#endif
161
162
163/* Return the length of the initial segment of S which
164 consists entirely of characters not in REJECT. */
d3496c9f 165#ifndef _HAVE_STRING_ARCH_strcspn
155bc2a5 166# define strcspn(s, reject) __builtin_strcspn (s, reject)
9a0a462c
UD
167#endif
168
169
170/* Return the length of the initial segment of S which
171 consists entirely of characters in ACCEPT. */
91f3b75f 172#ifndef _HAVE_STRING_ARCH_strspn
155bc2a5 173# define strspn(s, accept) __builtin_strspn (s, accept)
9a0a462c
UD
174#endif
175
176
177/* Find the first occurrence in S of any character in ACCEPT. */
282b71f0 178#ifndef _HAVE_STRING_ARCH_strpbrk
155bc2a5 179# define strpbrk(s, accept) __builtin_strpbrk (s, accept)
9a0a462c
UD
180#endif
181
182
7ef90c15 183/* We need the memory allocation functions for inline strdup().
d2537a47 184 Referring to stdlib.h (even minimally) is not allowed
4a582094 185 in any of the tight standards compliant modes. */
6e2cc2c1 186#ifdef __USE_MISC
31161268 187
4a582094
UD
188# if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup
189# define __need_malloc_and_calloc
190# include <stdlib.h>
191# endif
7ef90c15 192
4a582094 193# ifndef _HAVE_STRING_ARCH_strdup
31161268 194
a784e502 195extern char *__strdup (const char *__string) __THROW __attribute_malloc__;
4a582094 196# define __strdup(s) \
7551a1e5 197 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
a784e502 198 ? (((const char *) (s))[0] == '\0' \
a83b5649 199 ? (char *) calloc ((size_t) 1, (size_t) 1) \
7551a1e5
UD
200 : ({ size_t __len = strlen (s) + 1; \
201 char *__retval = (char *) malloc (__len); \
202 if (__retval != NULL) \
203 __retval = (char *) memcpy (__retval, s, __len); \
204 __retval; })) \
205 : __strdup (s)))
31161268 206
3d7c00e3 207# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
4a582094
UD
208# define strdup(s) __strdup (s)
209# endif
61eb22d3 210# endif
61eb22d3 211
4a582094 212# ifndef _HAVE_STRING_ARCH_strndup
7551a1e5 213
a784e502 214extern char *__strndup (const char *__string, size_t __n)
160016c9 215 __THROW __attribute_malloc__;
4a582094 216# define __strndup(s, n) \
7551a1e5 217 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
a784e502 218 ? (((const char *) (s))[0] == '\0' \
a83b5649 219 ? (char *) calloc ((size_t) 1, (size_t) 1) \
7551a1e5
UD
220 : ({ size_t __len = strlen (s) + 1; \
221 size_t __n = (n); \
222 char *__retval; \
223 if (__n < __len) \
fb4fb542 224 __len = __n + 1; \
7551a1e5
UD
225 __retval = (char *) malloc (__len); \
226 if (__retval != NULL) \
227 { \
228 __retval[__len - 1] = '\0'; \
229 __retval = (char *) memcpy (__retval, s, \
230 __len - 1); \
231 } \
232 __retval; })) \
61423e13 233 : __strndup (s, n)))
7551a1e5 234
3d7c00e3 235# ifdef __USE_XOPEN2K8
61423e13 236# define strndup(s, n) __strndup (s, n)
4a582094 237# endif
7551a1e5 238# endif
7551a1e5 239
4a582094 240#endif /* Use misc. or use GNU. */
7551a1e5 241
9bbd7837
UD
242#ifndef _FORCE_INLINES
243# undef __STRING_INLINE
244#endif
9a0a462c 245
61eb22d3 246#endif /* No string inlines. */