]> git.ipfire.org Git - thirdparty/glibc.git/blame - string/bits/string2.h
Improve generic strspn performance
[thirdparty/glibc.git] / string / bits / string2.h
CommitLineData
9a0a462c 1/* Machine-independant string function optimizations.
f7a9f785 2 Copyright (C) 1997-2016 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
16396c41 49#if _STRING_INLINE_unaligned
61eb22d3
UD
50/* If we can do unaligned memory accesses we must know the endianess. */
51# include <endian.h>
52# include <bits/types.h>
53
54# if __BYTE_ORDER == __LITTLE_ENDIAN
55# define __STRING2_SMALL_GET16(src, idx) \
a784e502
UD
56 (((const unsigned char *) (const char *) (src))[idx + 1] << 8 \
57 | ((const unsigned char *) (const char *) (src))[idx])
61eb22d3 58# define __STRING2_SMALL_GET32(src, idx) \
a784e502
UD
59 (((((const unsigned char *) (const char *) (src))[idx + 3] << 8 \
60 | ((const unsigned char *) (const char *) (src))[idx + 2]) << 8 \
61 | ((const unsigned char *) (const char *) (src))[idx + 1]) << 8 \
62 | ((const unsigned char *) (const char *) (src))[idx])
61eb22d3
UD
63# else
64# define __STRING2_SMALL_GET16(src, idx) \
a784e502
UD
65 (((const unsigned char *) (const char *) (src))[idx] << 8 \
66 | ((const unsigned char *) (const char *) (src))[idx + 1])
61eb22d3 67# define __STRING2_SMALL_GET32(src, idx) \
a784e502
UD
68 (((((const unsigned char *) (const char *) (src))[idx] << 8 \
69 | ((const unsigned char *) (const char *) (src))[idx + 1]) << 8 \
70 | ((const unsigned char *) (const char *) (src))[idx + 2]) << 8 \
71 | ((const unsigned char *) (const char *) (src))[idx + 3])
61eb22d3
UD
72# endif
73#else
74/* These are a few types we need for the optimizations if we cannot
75 use unaligned memory accesses. */
76# define __STRING2_COPY_TYPE(N) \
fab6d621 77 typedef struct { unsigned char __arr[N]; } \
87865838 78 __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
61eb22d3
UD
79__STRING2_COPY_TYPE (2);
80__STRING2_COPY_TYPE (3);
81__STRING2_COPY_TYPE (4);
82__STRING2_COPY_TYPE (5);
83__STRING2_COPY_TYPE (6);
84__STRING2_COPY_TYPE (7);
85__STRING2_COPY_TYPE (8);
86# undef __STRING2_COPY_TYPE
87#endif
88
7ef90c15
UD
89/* Dereferencing a pointer arg to run sizeof on it fails for the void
90 pointer case, so we use this instead.
91 Note that __x is evaluated twice. */
92#define __string2_1bptr_p(__x) \
36ab45e1 93 ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)
61eb22d3
UD
94
95/* Set N bytes of S to C. */
3dbfd811
UD
96#if !defined _HAVE_STRING_ARCH_memset
97# if !__GNUC_PREREQ (3, 0)
16396c41 98# if _STRING_INLINE_unaligned
3dbfd811 99# define memset(s, c, n) \
99434729 100 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
c1d226e7
UD
101 ? ((n) == 1 \
102 ? __memset_1 (s, c) \
6c8f9de3 103 : __memset_gc (s, c, n)) \
99434729
UD
104 : (__builtin_constant_p (c) && (c) == '\0' \
105 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
106 : memset (s, c, n))))
107
3dbfd811 108# define __memset_1(s, c) ({ void *__s = (s); \
6c8f9de3 109 *((__uint8_t *) __s) = (__uint8_t) c; __s; })
c1d226e7 110
3dbfd811 111# define __memset_gc(s, c, n) \
99434729 112 ({ void *__s = (s); \
722c33bb
UD
113 union { \
114 unsigned int __ui; \
115 unsigned short int __usi; \
116 unsigned char __uc; \
117 } *__u = __s; \
6c8f9de3 118 __uint8_t __c = (__uint8_t) (c); \
722c33bb 119 \
99434729 120 /* This `switch' statement will be removed at compile-time. */ \
b85697f6 121 switch ((unsigned int) (n)) \
99434729
UD
122 { \
123 case 15: \
722c33bb 124 __u->__ui = __c * 0x01010101; \
87843f15 125 __u = __extension__ ((void *) __u + 4); \
99434729 126 case 11: \
722c33bb 127 __u->__ui = __c * 0x01010101; \
87843f15 128 __u = __extension__ ((void *) __u + 4); \
99434729 129 case 7: \
722c33bb 130 __u->__ui = __c * 0x01010101; \
87843f15 131 __u = __extension__ ((void *) __u + 4); \
99434729 132 case 3: \
722c33bb 133 __u->__usi = (unsigned short int) __c * 0x0101; \
87843f15 134 __u = __extension__ ((void *) __u + 2); \
722c33bb 135 __u->__uc = (unsigned char) __c; \
99434729
UD
136 break; \
137 \
138 case 14: \
722c33bb 139 __u->__ui = __c * 0x01010101; \
87843f15 140 __u = __extension__ ((void *) __u + 4); \
99434729 141 case 10: \
722c33bb 142 __u->__ui = __c * 0x01010101; \
87843f15 143 __u = __extension__ ((void *) __u + 4); \
99434729 144 case 6: \
722c33bb 145 __u->__ui = __c * 0x01010101; \
87843f15 146 __u = __extension__ ((void *) __u + 4); \
99434729 147 case 2: \
722c33bb 148 __u->__usi = (unsigned short int) __c * 0x0101; \
99434729
UD
149 break; \
150 \
151 case 13: \
722c33bb 152 __u->__ui = __c * 0x01010101; \
87843f15 153 __u = __extension__ ((void *) __u + 4); \
99434729 154 case 9: \
722c33bb 155 __u->__ui = __c * 0x01010101; \
87843f15 156 __u = __extension__ ((void *) __u + 4); \
99434729 157 case 5: \
722c33bb 158 __u->__ui = __c * 0x01010101; \
87843f15 159 __u = __extension__ ((void *) __u + 4); \
99434729 160 case 1: \
722c33bb 161 __u->__uc = (unsigned char) __c; \
99434729
UD
162 break; \
163 \
164 case 16: \
722c33bb 165 __u->__ui = __c * 0x01010101; \
87843f15 166 __u = __extension__ ((void *) __u + 4); \
99434729 167 case 12: \
722c33bb 168 __u->__ui = __c * 0x01010101; \
87843f15 169 __u = __extension__ ((void *) __u + 4); \
99434729 170 case 8: \
722c33bb 171 __u->__ui = __c * 0x01010101; \
87843f15 172 __u = __extension__ ((void *) __u + 4); \
99434729 173 case 4: \
722c33bb 174 __u->__ui = __c * 0x01010101; \
99434729
UD
175 case 0: \
176 break; \
177 } \
178 \
179 __s; })
3dbfd811
UD
180# else
181# define memset(s, c, n) \
23f5f62d
UD
182 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
183 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
184 : memset (s, c, n)))
3dbfd811 185# endif
23f5f62d
UD
186# endif
187
3dbfd811
UD
188/* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
189 The optimization is broken before EGCS 1.1.
190 GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
191 if it decides to call the library function, it calls memset
192 and not bzero. */
722c33bb 193# if __GNUC_PREREQ (2, 91)
a97d1494 194# define __bzero(s, n) __builtin_memset (s, '\0', n)
23f5f62d 195# endif
c1d226e7 196
61eb22d3 197#endif
9a0a462c
UD
198
199
e7c5513d
UD
200/* Copy N bytes from SRC to DEST, returning pointer to byte following the
201 last copied. */
202#ifdef __USE_GNU
61423e13
UD
203# if !defined _HAVE_STRING_ARCH_mempcpy || defined _FORCE_INLINES
204# ifndef _HAVE_STRING_ARCH_mempcpy
4a691b06
UD
205# if __GNUC_PREREQ (3, 4)
206# define __mempcpy(dest, src, n) __builtin_mempcpy (dest, src, n)
207# elif __GNUC_PREREQ (3, 0)
0295d266
UD
208# define __mempcpy(dest, src, n) \
209 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
210 && __string2_1bptr_p (src) && n <= 8 \
9d7810d8 211 ? __builtin_memcpy (dest, src, n) + (n) \
0295d266
UD
212 : __mempcpy (dest, src, n)))
213# else
214# define __mempcpy(dest, src, n) \
e7c5513d
UD
215 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
216 && __string2_1bptr_p (src) && n <= 8 \
36ab45e1 217 ? __mempcpy_small (dest, __mempcpy_args (src), n) \
e7c5513d 218 : __mempcpy (dest, src, n)))
0295d266 219# endif
e7c5513d
UD
220/* In glibc we use this function frequently but for namespace reasons
221 we have to use the name `__mempcpy'. */
61423e13
UD
222# define mempcpy(dest, src, n) __mempcpy (dest, src, n)
223# endif
e7c5513d 224
0295d266 225# if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
16396c41 226# if _STRING_INLINE_unaligned
0295d266
UD
227# ifndef _FORCE_INLINES
228# define __mempcpy_args(src) \
a784e502
UD
229 ((const char *) (src))[0], ((const char *) (src))[2], \
230 ((const char *) (src))[4], ((const char *) (src))[6], \
36ab45e1
UD
231 __extension__ __STRING2_SMALL_GET16 (src, 0), \
232 __extension__ __STRING2_SMALL_GET16 (src, 4), \
233 __extension__ __STRING2_SMALL_GET32 (src, 0), \
234 __extension__ __STRING2_SMALL_GET32 (src, 4)
0295d266 235# endif
fcab9698
UD
236__STRING_INLINE void *__mempcpy_small (void *, char, char, char, char,
237 __uint16_t, __uint16_t, __uint32_t,
238 __uint32_t, size_t);
36ab45e1
UD
239__STRING_INLINE void *
240__mempcpy_small (void *__dest1,
241 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
242 __uint16_t __src0_2, __uint16_t __src4_2,
243 __uint32_t __src0_4, __uint32_t __src4_4,
244 size_t __srclen)
245{
722c33bb
UD
246 union {
247 __uint32_t __ui;
248 __uint16_t __usi;
249 unsigned char __uc;
250 unsigned char __c;
251 } *__u = __dest1;
7eda722d 252 switch ((unsigned int) __srclen)
36ab45e1
UD
253 {
254 case 1:
722c33bb 255 __u->__c = __src0_1;
87843f15 256 __u = __extension__ ((void *) __u + 1);
36ab45e1
UD
257 break;
258 case 2:
722c33bb 259 __u->__usi = __src0_2;
87843f15 260 __u = __extension__ ((void *) __u + 2);
36ab45e1
UD
261 break;
262 case 3:
722c33bb 263 __u->__usi = __src0_2;
87843f15 264 __u = __extension__ ((void *) __u + 2);
722c33bb 265 __u->__c = __src2_1;
87843f15 266 __u = __extension__ ((void *) __u + 1);
36ab45e1
UD
267 break;
268 case 4:
722c33bb 269 __u->__ui = __src0_4;
87843f15 270 __u = __extension__ ((void *) __u + 4);
36ab45e1
UD
271 break;
272 case 5:
722c33bb 273 __u->__ui = __src0_4;
87843f15 274 __u = __extension__ ((void *) __u + 4);
722c33bb 275 __u->__c = __src4_1;
87843f15 276 __u = __extension__ ((void *) __u + 1);
36ab45e1
UD
277 break;
278 case 6:
722c33bb 279 __u->__ui = __src0_4;
87843f15 280 __u = __extension__ ((void *) __u + 4);
722c33bb 281 __u->__usi = __src4_2;
87843f15 282 __u = __extension__ ((void *) __u + 2);
36ab45e1
UD
283 break;
284 case 7:
722c33bb 285 __u->__ui = __src0_4;
87843f15 286 __u = __extension__ ((void *) __u + 4);
722c33bb 287 __u->__usi = __src4_2;
87843f15 288 __u = __extension__ ((void *) __u + 2);
722c33bb 289 __u->__c = __src6_1;
87843f15 290 __u = __extension__ ((void *) __u + 1);
36ab45e1
UD
291 break;
292 case 8:
722c33bb 293 __u->__ui = __src0_4;
87843f15 294 __u = __extension__ ((void *) __u + 4);
722c33bb 295 __u->__ui = __src4_4;
87843f15 296 __u = __extension__ ((void *) __u + 4);
36ab45e1
UD
297 break;
298 }
722c33bb 299 return (void *) __u;
36ab45e1 300}
0295d266
UD
301# else
302# ifndef _FORCE_INLINES
303# define __mempcpy_args(src) \
a784e502 304 ((const char *) (src))[0], \
36ab45e1 305 __extension__ ((__STRING2_COPY_ARR2) \
a784e502 306 { { ((const char *) (src))[0], ((const char *) (src))[1] } }), \
36ab45e1 307 __extension__ ((__STRING2_COPY_ARR3) \
a784e502
UD
308 { { ((const char *) (src))[0], ((const char *) (src))[1], \
309 ((const char *) (src))[2] } }), \
36ab45e1 310 __extension__ ((__STRING2_COPY_ARR4) \
a784e502
UD
311 { { ((const char *) (src))[0], ((const char *) (src))[1], \
312 ((const char *) (src))[2], ((const char *) (src))[3] } }), \
36ab45e1 313 __extension__ ((__STRING2_COPY_ARR5) \
a784e502
UD
314 { { ((const char *) (src))[0], ((const char *) (src))[1], \
315 ((const char *) (src))[2], ((const char *) (src))[3], \
316 ((const char *) (src))[4] } }), \
36ab45e1 317 __extension__ ((__STRING2_COPY_ARR6) \
a784e502
UD
318 { { ((const char *) (src))[0], ((const char *) (src))[1], \
319 ((const char *) (src))[2], ((const char *) (src))[3], \
320 ((const char *) (src))[4], ((const char *) (src))[5] } }), \
36ab45e1 321 __extension__ ((__STRING2_COPY_ARR7) \
a784e502
UD
322 { { ((const char *) (src))[0], ((const char *) (src))[1], \
323 ((const char *) (src))[2], ((const char *) (src))[3], \
324 ((const char *) (src))[4], ((const char *) (src))[5], \
325 ((const char *) (src))[6] } }), \
36ab45e1 326 __extension__ ((__STRING2_COPY_ARR8) \
a784e502
UD
327 { { ((const char *) (src))[0], ((const char *) (src))[1], \
328 ((const char *) (src))[2], ((const char *) (src))[3], \
329 ((const char *) (src))[4], ((const char *) (src))[5], \
330 ((const char *) (src))[6], ((const char *) (src))[7] } })
0295d266 331# endif
fcab9698
UD
332__STRING_INLINE void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2,
333 __STRING2_COPY_ARR3,
334 __STRING2_COPY_ARR4,
335 __STRING2_COPY_ARR5,
336 __STRING2_COPY_ARR6,
337 __STRING2_COPY_ARR7,
338 __STRING2_COPY_ARR8, size_t);
36ab45e1 339__STRING_INLINE void *
722c33bb 340__mempcpy_small (void *__dest, char __src1,
36ab45e1
UD
341 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
342 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
343 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
344 __STRING2_COPY_ARR8 __src8, size_t __srclen)
345{
722c33bb
UD
346 union {
347 char __c;
348 __STRING2_COPY_ARR2 __sca2;
349 __STRING2_COPY_ARR3 __sca3;
350 __STRING2_COPY_ARR4 __sca4;
351 __STRING2_COPY_ARR5 __sca5;
352 __STRING2_COPY_ARR6 __sca6;
353 __STRING2_COPY_ARR7 __sca7;
354 __STRING2_COPY_ARR8 __sca8;
355 } *__u = __dest;
7eda722d 356 switch ((unsigned int) __srclen)
36ab45e1
UD
357 {
358 case 1:
722c33bb 359 __u->__c = __src1;
36ab45e1
UD
360 break;
361 case 2:
722c33bb 362 __extension__ __u->__sca2 = __src2;
36ab45e1
UD
363 break;
364 case 3:
722c33bb 365 __extension__ __u->__sca3 = __src3;
36ab45e1
UD
366 break;
367 case 4:
722c33bb 368 __extension__ __u->__sca4 = __src4;
36ab45e1
UD
369 break;
370 case 5:
722c33bb 371 __extension__ __u->__sca5 = __src5;
36ab45e1
UD
372 break;
373 case 6:
722c33bb 374 __extension__ __u->__sca6 = __src6;
36ab45e1
UD
375 break;
376 case 7:
722c33bb 377 __extension__ __u->__sca7 = __src7;
36ab45e1
UD
378 break;
379 case 8:
722c33bb 380 __extension__ __u->__sca8 = __src8;
36ab45e1
UD
381 break;
382 }
722c33bb 383 return __extension__ ((void *) __u + __srclen);
36ab45e1 384}
0295d266 385# endif
e7c5513d
UD
386# endif
387# endif
388#endif
389
390
482eec0d
UD
391/* Return pointer to C in S. */
392#ifndef _HAVE_STRING_ARCH_strchr
c1422e5b 393extern void *__rawmemchr (const void *__s, int __c);
4a691b06
UD
394# if __GNUC_PREREQ (3, 2)
395# define strchr(s, c) \
396 (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \
397 && (c) == '\0' \
398 ? (char *) __rawmemchr (s, c) \
399 : __builtin_strchr (s, c)))
400# else
401# define strchr(s, c) \
482eec0d
UD
402 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
403 ? (char *) __rawmemchr (s, c) \
404 : strchr (s, c)))
4a691b06 405# endif
482eec0d
UD
406#endif
407
408
9a0a462c 409/* Copy SRC to DEST. */
0295d266
UD
410#if (!defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)) \
411 || defined _FORCE_INLINES
412# if !defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)
61423e13 413# define strcpy(dest, src) \
9a0a462c 414 (__extension__ (__builtin_constant_p (src) \
dfd2257a 415 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
36ab45e1
UD
416 ? __strcpy_small (dest, __strcpy_args (src), \
417 strlen (src) + 1) \
9a0a462c
UD
418 : (char *) memcpy (dest, src, strlen (src) + 1)) \
419 : strcpy (dest, src)))
61423e13 420# endif
9a0a462c 421
16396c41 422# if _STRING_INLINE_unaligned
61423e13
UD
423# ifndef _FORCE_INLINES
424# define __strcpy_args(src) \
36ab45e1
UD
425 __extension__ __STRING2_SMALL_GET16 (src, 0), \
426 __extension__ __STRING2_SMALL_GET16 (src, 4), \
427 __extension__ __STRING2_SMALL_GET32 (src, 0), \
428 __extension__ __STRING2_SMALL_GET32 (src, 4)
61423e13 429# endif
fcab9698
UD
430__STRING_INLINE char *__strcpy_small (char *, __uint16_t, __uint16_t,
431 __uint32_t, __uint32_t, size_t);
36ab45e1
UD
432__STRING_INLINE char *
433__strcpy_small (char *__dest,
434 __uint16_t __src0_2, __uint16_t __src4_2,
435 __uint32_t __src0_4, __uint32_t __src4_4,
436 size_t __srclen)
437{
722c33bb
UD
438 union {
439 __uint32_t __ui;
440 __uint16_t __usi;
441 unsigned char __uc;
442 } *__u = (void *) __dest;
7eda722d 443 switch ((unsigned int) __srclen)
36ab45e1
UD
444 {
445 case 1:
722c33bb 446 __u->__uc = '\0';
36ab45e1
UD
447 break;
448 case 2:
722c33bb 449 __u->__usi = __src0_2;
36ab45e1
UD
450 break;
451 case 3:
722c33bb 452 __u->__usi = __src0_2;
87843f15 453 __u = __extension__ ((void *) __u + 2);
722c33bb 454 __u->__uc = '\0';
36ab45e1
UD
455 break;
456 case 4:
722c33bb 457 __u->__ui = __src0_4;
36ab45e1
UD
458 break;
459 case 5:
722c33bb 460 __u->__ui = __src0_4;
87843f15 461 __u = __extension__ ((void *) __u + 4);
722c33bb 462 __u->__uc = '\0';
36ab45e1
UD
463 break;
464 case 6:
722c33bb 465 __u->__ui = __src0_4;
87843f15 466 __u = __extension__ ((void *) __u + 4);
722c33bb 467 __u->__usi = __src4_2;
36ab45e1
UD
468 break;
469 case 7:
722c33bb 470 __u->__ui = __src0_4;
87843f15 471 __u = __extension__ ((void *) __u + 4);
722c33bb 472 __u->__usi = __src4_2;
87843f15 473 __u = __extension__ ((void *) __u + 2);
722c33bb 474 __u->__uc = '\0';
36ab45e1
UD
475 break;
476 case 8:
722c33bb 477 __u->__ui = __src0_4;
87843f15 478 __u = __extension__ ((void *) __u + 4);
83f6a990 479 __u->__ui = __src4_4;
36ab45e1
UD
480 break;
481 }
482 return __dest;
483}
61eb22d3 484# else
61423e13
UD
485# ifndef _FORCE_INLINES
486# define __strcpy_args(src) \
36ab45e1 487 __extension__ ((__STRING2_COPY_ARR2) \
a784e502 488 { { ((const char *) (src))[0], '\0' } }), \
36ab45e1 489 __extension__ ((__STRING2_COPY_ARR3) \
a784e502 490 { { ((const char *) (src))[0], ((const char *) (src))[1], \
36ab45e1
UD
491 '\0' } }), \
492 __extension__ ((__STRING2_COPY_ARR4) \
a784e502
UD
493 { { ((const char *) (src))[0], ((const char *) (src))[1], \
494 ((const char *) (src))[2], '\0' } }), \
36ab45e1 495 __extension__ ((__STRING2_COPY_ARR5) \
a784e502
UD
496 { { ((const char *) (src))[0], ((const char *) (src))[1], \
497 ((const char *) (src))[2], ((const char *) (src))[3], \
36ab45e1
UD
498 '\0' } }), \
499 __extension__ ((__STRING2_COPY_ARR6) \
a784e502
UD
500 { { ((const char *) (src))[0], ((const char *) (src))[1], \
501 ((const char *) (src))[2], ((const char *) (src))[3], \
502 ((const char *) (src))[4], '\0' } }), \
36ab45e1 503 __extension__ ((__STRING2_COPY_ARR7) \
a784e502
UD
504 { { ((const char *) (src))[0], ((const char *) (src))[1], \
505 ((const char *) (src))[2], ((const char *) (src))[3], \
506 ((const char *) (src))[4], ((const char *) (src))[5], \
36ab45e1
UD
507 '\0' } }), \
508 __extension__ ((__STRING2_COPY_ARR8) \
a784e502
UD
509 { { ((const char *) (src))[0], ((const char *) (src))[1], \
510 ((const char *) (src))[2], ((const char *) (src))[3], \
511 ((const char *) (src))[4], ((const char *) (src))[5], \
512 ((const char *) (src))[6], '\0' } })
61423e13 513# endif
fcab9698
UD
514__STRING_INLINE char *__strcpy_small (char *, __STRING2_COPY_ARR2,
515 __STRING2_COPY_ARR3,
516 __STRING2_COPY_ARR4,
517 __STRING2_COPY_ARR5,
518 __STRING2_COPY_ARR6,
519 __STRING2_COPY_ARR7,
520 __STRING2_COPY_ARR8, size_t);
36ab45e1
UD
521__STRING_INLINE char *
522__strcpy_small (char *__dest,
523 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
524 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
525 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
526 __STRING2_COPY_ARR8 __src8, size_t __srclen)
527{
722c33bb
UD
528 union {
529 char __c;
530 __STRING2_COPY_ARR2 __sca2;
531 __STRING2_COPY_ARR3 __sca3;
532 __STRING2_COPY_ARR4 __sca4;
533 __STRING2_COPY_ARR5 __sca5;
534 __STRING2_COPY_ARR6 __sca6;
535 __STRING2_COPY_ARR7 __sca7;
536 __STRING2_COPY_ARR8 __sca8;
b18ac18e 537 } *__u = (void *) __dest;
7eda722d 538 switch ((unsigned int) __srclen)
36ab45e1
UD
539 {
540 case 1:
722c33bb 541 __u->__c = '\0';
36ab45e1
UD
542 break;
543 case 2:
722c33bb 544 __extension__ __u->__sca2 = __src2;
36ab45e1
UD
545 break;
546 case 3:
722c33bb 547 __extension__ __u->__sca3 = __src3;
36ab45e1
UD
548 break;
549 case 4:
722c33bb 550 __extension__ __u->__sca4 = __src4;
36ab45e1
UD
551 break;
552 case 5:
722c33bb 553 __extension__ __u->__sca5 = __src5;
36ab45e1
UD
554 break;
555 case 6:
722c33bb 556 __extension__ __u->__sca6 = __src6;
36ab45e1
UD
557 break;
558 case 7:
722c33bb 559 __extension__ __u->__sca7 = __src7;
36ab45e1
UD
560 break;
561 case 8:
722c33bb 562 __extension__ __u->__sca8 = __src8;
36ab45e1
UD
563 break;
564 }
565 return __dest;
566}
61eb22d3 567# endif
9a0a462c
UD
568#endif
569
570
571/* Copy SRC to DEST, returning pointer to final NUL byte. */
572#ifdef __USE_GNU
61423e13
UD
573# if !defined _HAVE_STRING_ARCH_stpcpy || defined _FORCE_INLINES
574# ifndef _HAVE_STRING_ARCH_stpcpy
4a691b06
UD
575# if __GNUC_PREREQ (3, 4)
576# define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
577# elif __GNUC_PREREQ (3, 0)
0295d266
UD
578# define __stpcpy(dest, src) \
579 (__extension__ (__builtin_constant_p (src) \
580 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
581 ? __builtin_strcpy (dest, src) + strlen (src) \
582 : ((char *) (__mempcpy) (dest, src, strlen (src) + 1) \
583 - 1)) \
584 : __stpcpy (dest, src)))
585# else
586# define __stpcpy(dest, src) \
9a0a462c 587 (__extension__ (__builtin_constant_p (src) \
dfd2257a 588 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
36ab45e1
UD
589 ? __stpcpy_small (dest, __stpcpy_args (src), \
590 strlen (src) + 1) \
0295d266
UD
591 : ((char *) (__mempcpy) (dest, src, strlen (src) + 1) \
592 - 1)) \
9a0a462c 593 : __stpcpy (dest, src)))
0295d266 594# endif
9a0a462c
UD
595/* In glibc we use this function frequently but for namespace reasons
596 we have to use the name `__stpcpy'. */
61423e13
UD
597# define stpcpy(dest, src) __stpcpy (dest, src)
598# endif
9a0a462c 599
b45b9457 600# if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
16396c41 601# if _STRING_INLINE_unaligned
0295d266
UD
602# ifndef _FORCE_INLINES
603# define __stpcpy_args(src) \
36ab45e1
UD
604 __extension__ __STRING2_SMALL_GET16 (src, 0), \
605 __extension__ __STRING2_SMALL_GET16 (src, 4), \
606 __extension__ __STRING2_SMALL_GET32 (src, 0), \
607 __extension__ __STRING2_SMALL_GET32 (src, 4)
0295d266 608# endif
fcab9698
UD
609__STRING_INLINE char *__stpcpy_small (char *, __uint16_t, __uint16_t,
610 __uint32_t, __uint32_t, size_t);
36ab45e1
UD
611__STRING_INLINE char *
612__stpcpy_small (char *__dest,
613 __uint16_t __src0_2, __uint16_t __src4_2,
614 __uint32_t __src0_4, __uint32_t __src4_4,
615 size_t __srclen)
616{
722c33bb
UD
617 union {
618 unsigned int __ui;
619 unsigned short int __usi;
620 unsigned char __uc;
3e1e749e 621 char __c;
722c33bb 622 } *__u = (void *) __dest;
7eda722d 623 switch ((unsigned int) __srclen)
36ab45e1
UD
624 {
625 case 1:
722c33bb 626 __u->__uc = '\0';
36ab45e1
UD
627 break;
628 case 2:
722c33bb 629 __u->__usi = __src0_2;
87843f15 630 __u = __extension__ ((void *) __u + 1);
36ab45e1
UD
631 break;
632 case 3:
722c33bb 633 __u->__usi = __src0_2;
87843f15 634 __u = __extension__ ((void *) __u + 2);
722c33bb 635 __u->__uc = '\0';
36ab45e1
UD
636 break;
637 case 4:
722c33bb 638 __u->__ui = __src0_4;
87843f15 639 __u = __extension__ ((void *) __u + 3);
36ab45e1
UD
640 break;
641 case 5:
722c33bb 642 __u->__ui = __src0_4;
87843f15 643 __u = __extension__ ((void *) __u + 4);
722c33bb 644 __u->__uc = '\0';
36ab45e1
UD
645 break;
646 case 6:
722c33bb 647 __u->__ui = __src0_4;
87843f15 648 __u = __extension__ ((void *) __u + 4);
722c33bb 649 __u->__usi = __src4_2;
87843f15 650 __u = __extension__ ((void *) __u + 1);
36ab45e1
UD
651 break;
652 case 7:
722c33bb 653 __u->__ui = __src0_4;
87843f15 654 __u = __extension__ ((void *) __u + 4);
722c33bb 655 __u->__usi = __src4_2;
87843f15 656 __u = __extension__ ((void *) __u + 2);
722c33bb 657 __u->__uc = '\0';
36ab45e1
UD
658 break;
659 case 8:
722c33bb 660 __u->__ui = __src0_4;
87843f15 661 __u = __extension__ ((void *) __u + 4);
722c33bb 662 __u->__ui = __src4_4;
87843f15 663 __u = __extension__ ((void *) __u + 3);
36ab45e1
UD
664 break;
665 }
3e1e749e 666 return &__u->__c;
36ab45e1 667}
0295d266
UD
668# else
669# ifndef _FORCE_INLINES
670# define __stpcpy_args(src) \
36ab45e1 671 __extension__ ((__STRING2_COPY_ARR2) \
a784e502 672 { { ((const char *) (src))[0], '\0' } }), \
36ab45e1 673 __extension__ ((__STRING2_COPY_ARR3) \
a784e502 674 { { ((const char *) (src))[0], ((const char *) (src))[1], \
36ab45e1
UD
675 '\0' } }), \
676 __extension__ ((__STRING2_COPY_ARR4) \
a784e502
UD
677 { { ((const char *) (src))[0], ((const char *) (src))[1], \
678 ((const char *) (src))[2], '\0' } }), \
36ab45e1 679 __extension__ ((__STRING2_COPY_ARR5) \
a784e502
UD
680 { { ((const char *) (src))[0], ((const char *) (src))[1], \
681 ((const char *) (src))[2], ((const char *) (src))[3], \
36ab45e1
UD
682 '\0' } }), \
683 __extension__ ((__STRING2_COPY_ARR6) \
a784e502
UD
684 { { ((const char *) (src))[0], ((const char *) (src))[1], \
685 ((const char *) (src))[2], ((const char *) (src))[3], \
686 ((const char *) (src))[4], '\0' } }), \
36ab45e1 687 __extension__ ((__STRING2_COPY_ARR7) \
a784e502
UD
688 { { ((const char *) (src))[0], ((const char *) (src))[1], \
689 ((const char *) (src))[2], ((const char *) (src))[3], \
690 ((const char *) (src))[4], ((const char *) (src))[5], \
36ab45e1
UD
691 '\0' } }), \
692 __extension__ ((__STRING2_COPY_ARR8) \
a784e502
UD
693 { { ((const char *) (src))[0], ((const char *) (src))[1], \
694 ((const char *) (src))[2], ((const char *) (src))[3], \
695 ((const char *) (src))[4], ((const char *) (src))[5], \
696 ((const char *) (src))[6], '\0' } })
0295d266 697# endif
fcab9698
UD
698__STRING_INLINE char *__stpcpy_small (char *, __STRING2_COPY_ARR2,
699 __STRING2_COPY_ARR3,
700 __STRING2_COPY_ARR4,
701 __STRING2_COPY_ARR5,
702 __STRING2_COPY_ARR6,
703 __STRING2_COPY_ARR7,
704 __STRING2_COPY_ARR8, size_t);
36ab45e1
UD
705__STRING_INLINE char *
706__stpcpy_small (char *__dest,
707 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
708 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
709 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
710 __STRING2_COPY_ARR8 __src8, size_t __srclen)
711{
722c33bb
UD
712 union {
713 char __c;
714 __STRING2_COPY_ARR2 __sca2;
715 __STRING2_COPY_ARR3 __sca3;
716 __STRING2_COPY_ARR4 __sca4;
717 __STRING2_COPY_ARR5 __sca5;
718 __STRING2_COPY_ARR6 __sca6;
719 __STRING2_COPY_ARR7 __sca7;
720 __STRING2_COPY_ARR8 __sca8;
b18ac18e 721 } *__u = (void *) __dest;
7eda722d 722 switch ((unsigned int) __srclen)
36ab45e1
UD
723 {
724 case 1:
b18ac18e 725 __u->__c = '\0';
36ab45e1
UD
726 break;
727 case 2:
722c33bb 728 __extension__ __u->__sca2 = __src2;
36ab45e1
UD
729 break;
730 case 3:
722c33bb 731 __extension__ __u->__sca3 = __src3;
36ab45e1
UD
732 break;
733 case 4:
722c33bb 734 __extension__ __u->__sca4 = __src4;
36ab45e1
UD
735 break;
736 case 5:
722c33bb 737 __extension__ __u->__sca5 = __src5;
36ab45e1
UD
738 break;
739 case 6:
722c33bb 740 __extension__ __u->__sca6 = __src6;
36ab45e1
UD
741 break;
742 case 7:
722c33bb 743 __extension__ __u->__sca7 = __src7;
36ab45e1
UD
744 break;
745 case 8:
722c33bb 746 __extension__ __u->__sca8 = __src8;
36ab45e1
UD
747 break;
748 }
749 return __dest + __srclen - 1;
750}
0295d266 751# endif
61eb22d3 752# endif
9a0a462c
UD
753# endif
754#endif
755
756
757/* Copy no more than N characters of SRC to DEST. */
758#ifndef _HAVE_STRING_ARCH_strncpy
4a691b06
UD
759# if __GNUC_PREREQ (3, 2)
760# define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)
9a0a462c
UD
761# else
762# define strncpy(dest, src, n) \
763 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
764 ? (strlen (src) + 1 >= ((size_t) (n)) \
765 ? (char *) memcpy (dest, src, n) \
766 : strncpy (dest, src, n)) \
767 : strncpy (dest, src, n)))
768# endif
769#endif
770
771
772/* Append no more than N characters from SRC onto DEST. */
773#ifndef _HAVE_STRING_ARCH_strncat
d3d99893 774# ifdef _USE_STRING_ARCH_strchr
9a0a462c 775# define strncat(dest, src, n) \
650425ce
UD
776 (__extension__ ({ char *__dest = (dest); \
777 __builtin_constant_p (src) && __builtin_constant_p (n) \
778 ? (strlen (src) < ((size_t) (n)) \
779 ? strcat (__dest, src) \
9c3b1ceb
UD
780 : (*((char *) __mempcpy (strchr (__dest, '\0'), \
781 src, n)) = '\0', __dest)) \
650425ce 782 : strncat (dest, src, n); }))
4a691b06
UD
783# elif __GNUC_PREREQ (3, 2)
784# define strncat(dest, src, n) __builtin_strncat (dest, src, n)
9a0a462c
UD
785# else
786# define strncat(dest, src, n) \
787 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
788 ? (strlen (src) < ((size_t) (n)) \
789 ? strcat (dest, src) \
790 : strncat (dest, src, n)) \
791 : strncat (dest, src, n)))
792# endif
793#endif
794
795
650425ce
UD
796/* Compare characters of S1 and S2. */
797#ifndef _HAVE_STRING_ARCH_strcmp
4a691b06
UD
798# if __GNUC_PREREQ (3, 2)
799# define strcmp(s1, s2) \
800 __extension__ \
801 ({ size_t __s1_len, __s2_len; \
802 (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
803 && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
804 (!__string2_1bptr_p (s1) || __s1_len >= 4) \
805 && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
806 ? __builtin_strcmp (s1, s2) \
807 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
808 && (__s1_len = strlen (s1), __s1_len < 4) \
809 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
810 ? __builtin_strcmp (s1, s2) \
811 : __strcmp_cg (s1, s2, __s1_len)) \
812 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
813 && (__s2_len = strlen (s2), __s2_len < 4) \
814 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
815 ? __builtin_strcmp (s1, s2) \
816 : __strcmp_gc (s1, s2, __s2_len)) \
817 : __builtin_strcmp (s1, s2)))); })
818# else
819# define strcmp(s1, s2) \
36ab45e1
UD
820 __extension__ \
821 ({ size_t __s1_len, __s2_len; \
fcab9698 822 (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
36ab45e1
UD
823 && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
824 (!__string2_1bptr_p (s1) || __s1_len >= 4) \
825 && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
a784e502 826 ? memcmp ((const char *) (s1), (const char *) (s2), \
36ab45e1 827 (__s1_len < __s2_len ? __s1_len : __s2_len) + 1) \
fcab9698 828 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
36ab45e1 829 && (__s1_len = strlen (s1), __s1_len < 4) \
fcab9698 830 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
36ab45e1
UD
831 ? __strcmp_cc (s1, s2, __s1_len) \
832 : __strcmp_cg (s1, s2, __s1_len)) \
fcab9698 833 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
36ab45e1 834 && (__s2_len = strlen (s2), __s2_len < 4) \
fcab9698 835 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
36ab45e1
UD
836 ? __strcmp_cc (s1, s2, __s2_len) \
837 : __strcmp_gc (s1, s2, __s2_len)) \
838 : strcmp (s1, s2)))); })
4a691b06 839# endif
650425ce 840
a5a0310d 841# define __strcmp_cc(s1, s2, l) \
2e09a79a 842 (__extension__ ({ int __result = \
a784e502
UD
843 (((const unsigned char *) (const char *) (s1))[0] \
844 - ((const unsigned char *) (const char *)(s2))[0]); \
a5a0310d
UD
845 if (l > 0 && __result == 0) \
846 { \
a784e502
UD
847 __result = (((const unsigned char *) \
848 (const char *) (s1))[1] \
849 - ((const unsigned char *) \
850 (const char *) (s2))[1]); \
a5a0310d
UD
851 if (l > 1 && __result == 0) \
852 { \
af6f3906 853 __result = \
a784e502
UD
854 (((const unsigned char *) \
855 (const char *) (s1))[2] \
856 - ((const unsigned char *) \
857 (const char *) (s2))[2]); \
a5a0310d 858 if (l > 2 && __result == 0) \
af6f3906 859 __result = \
a784e502
UD
860 (((const unsigned char *) \
861 (const char *) (s1))[3] \
862 - ((const unsigned char *) \
863 (const char *) (s2))[3]); \
a5a0310d
UD
864 } \
865 } \
866 __result; }))
867
650425ce 868# define __strcmp_cg(s1, s2, l1) \
a784e502
UD
869 (__extension__ ({ const unsigned char *__s2 = \
870 (const unsigned char *) (const char *) (s2); \
2e09a79a 871 int __result = \
a784e502 872 (((const unsigned char *) (const char *) (s1))[0] \
fab6d621 873 - __s2[0]); \
650425ce
UD
874 if (l1 > 0 && __result == 0) \
875 { \
a784e502
UD
876 __result = (((const unsigned char *) \
877 (const char *) (s1))[1] - __s2[1]); \
650425ce
UD
878 if (l1 > 1 && __result == 0) \
879 { \
a784e502
UD
880 __result = (((const unsigned char *) \
881 (const char *) (s1))[2] - __s2[2]); \
650425ce 882 if (l1 > 2 && __result == 0) \
a784e502
UD
883 __result = (((const unsigned char *) \
884 (const char *) (s1))[3] \
af6f3906 885 - __s2[3]); \
650425ce
UD
886 } \
887 } \
888 __result; }))
889
a07c5731 890# define __strcmp_gc(s1, s2, l2) (- __strcmp_cg (s2, s1, l2))
650425ce
UD
891#endif
892
893
9a0a462c
UD
894/* Compare N characters of S1 and S2. */
895#ifndef _HAVE_STRING_ARCH_strncmp
d30da2a8
UD
896# define strncmp(s1, s2, n) \
897 (__extension__ (__builtin_constant_p (n) \
898 && ((__builtin_constant_p (s1) \
899 && strlen (s1) < ((size_t) (n))) \
900 || (__builtin_constant_p (s2) \
901 && strlen (s2) < ((size_t) (n)))) \
902 ? strcmp (s1, s2) : strncmp (s1, s2, n)))
9a0a462c
UD
903#endif
904
905
906/* Return the length of the initial segment of S which
907 consists entirely of characters not in REJECT. */
d3496c9f
WD
908#ifndef _HAVE_STRING_ARCH_strcspn
909# if __GNUC_PREREQ (3, 2)
910# define strcspn(s, reject) __builtin_strcspn (s, reject)
61423e13 911# endif
9a0a462c
UD
912#endif
913
914
915/* Return the length of the initial segment of S which
916 consists entirely of characters in ACCEPT. */
91f3b75f
AZ
917#ifndef _HAVE_STRING_ARCH_strspn
918# if __GNUC_PREREQ (3, 2)
919# define strspn(s, accept) __builtin_strspn (s, accept)
61423e13 920# endif
9a0a462c
UD
921#endif
922
923
924/* Find the first occurrence in S of any character in ACCEPT. */
61423e13
UD
925#if !defined _HAVE_STRING_ARCH_strpbrk || defined _FORCE_INLINES
926# ifndef _HAVE_STRING_ARCH_strpbrk
4a691b06
UD
927# if __GNUC_PREREQ (3, 2)
928# define strpbrk(s, accept) \
929 __extension__ \
930 ({ char __a0, __a1, __a2; \
931 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
932 ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
933 ? __builtin_strpbrk (s, accept) \
a784e502 934 : ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
4a691b06 935 ? ((void) (s), (char *) NULL) \
a784e502 936 : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
4a691b06 937 ? __builtin_strchr (s, __a0) \
a784e502 938 : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
4a691b06 939 ? __strpbrk_c2 (s, __a0, __a1) \
a784e502 940 : (((const char *) (accept))[3] == '\0' \
4a691b06
UD
941 ? __strpbrk_c3 (s, __a0, __a1, __a2) \
942 : __builtin_strpbrk (s, accept)))))) \
943 : __builtin_strpbrk (s, accept)); })
944# else
945# define strpbrk(s, accept) \
36ab45e1
UD
946 __extension__ \
947 ({ char __a0, __a1, __a2; \
948 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
a784e502 949 ? ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
6f0b2e1f 950 ? ((void) (s), (char *) NULL) \
a784e502 951 : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
36ab45e1 952 ? strchr (s, __a0) \
a784e502 953 : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
36ab45e1 954 ? __strpbrk_c2 (s, __a0, __a1) \
a784e502 955 : (((const char *) (accept))[3] == '\0' \
36ab45e1
UD
956 ? __strpbrk_c3 (s, __a0, __a1, __a2) \
957 : strpbrk (s, accept))))) \
958 : strpbrk (s, accept)); })
4a691b06 959# endif
61423e13 960# endif
14c44e2e 961
a784e502
UD
962__STRING_INLINE char *__strpbrk_c2 (const char *__s, int __accept1,
963 int __accept2);
14c44e2e 964__STRING_INLINE char *
a784e502 965__strpbrk_c2 (const char *__s, int __accept1, int __accept2)
14c44e2e
UD
966{
967 /* Please note that __accept1 and __accept2 never can be '\0'. */
968 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
969 ++__s;
d2537a47 970 return *__s == '\0' ? NULL : (char *) (size_t) __s;
14c44e2e
UD
971}
972
a784e502
UD
973__STRING_INLINE char *__strpbrk_c3 (const char *__s, int __accept1,
974 int __accept2, int __accept3);
14c44e2e 975__STRING_INLINE char *
a784e502 976__strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
14c44e2e
UD
977{
978 /* Please note that __accept1 to __accept3 never can be '\0'. */
979 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
980 && *__s != __accept3)
981 ++__s;
d2537a47 982 return *__s == '\0' ? NULL : (char *) (size_t) __s;
14c44e2e 983}
9a0a462c
UD
984#endif
985
986
e8e24320
UD
987/* Find the first occurrence of NEEDLE in HAYSTACK. Newer gcc versions
988 do this itself. */
989#if !defined _HAVE_STRING_ARCH_strstr && !__GNUC_PREREQ (2, 97)
9a0a462c 990# define strstr(haystack, needle) \
dfd2257a 991 (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
a784e502 992 ? (((const char *) (needle))[0] == '\0' \
d2537a47 993 ? (char *) (size_t) (haystack) \
a784e502 994 : (((const char *) (needle))[1] == '\0' \
af6f3906 995 ? strchr (haystack, \
a784e502 996 ((const char *) (needle))[0]) \
9a0a462c
UD
997 : strstr (haystack, needle))) \
998 : strstr (haystack, needle)))
999#endif
1000
1001
61423e13
UD
1002#if !defined _HAVE_STRING_ARCH_strtok_r || defined _FORCE_INLINES
1003# ifndef _HAVE_STRING_ARCH_strtok_r
1004# define __strtok_r(s, sep, nextp) \
6973fc01 1005 (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \
a784e502
UD
1006 && ((const char *) (sep))[0] != '\0' \
1007 && ((const char *) (sep))[1] == '\0' \
1008 ? __strtok_r_1c (s, ((const char *) (sep))[0], nextp) \
7551a1e5 1009 : __strtok_r (s, sep, nextp)))
61423e13 1010# endif
6973fc01
UD
1011
1012__STRING_INLINE char *__strtok_r_1c (char *__s, char __sep, char **__nextp);
1013__STRING_INLINE char *
1014__strtok_r_1c (char *__s, char __sep, char **__nextp)
1015{
1016 char *__result;
1017 if (__s == NULL)
1018 __s = *__nextp;
1019 while (*__s == __sep)
1020 ++__s;
61423e13
UD
1021 __result = NULL;
1022 if (*__s != '\0')
6973fc01 1023 {
61423e13 1024 __result = __s++;
29215bbd
UD
1025 while (*__s != '\0')
1026 if (*__s++ == __sep)
1027 {
1028 __s[-1] = '\0';
1029 break;
1030 }
6973fc01 1031 }
ebca8f73 1032 *__nextp = __s;
6973fc01
UD
1033 return __result;
1034}
acd7f096 1035# ifdef __USE_POSIX
61423e13 1036# define strtok_r(s, sep, nextp) __strtok_r (s, sep, nextp)
6973fc01
UD
1037# endif
1038#endif
1039
1040
61423e13
UD
1041#if !defined _HAVE_STRING_ARCH_strsep || defined _FORCE_INLINES
1042# ifndef _HAVE_STRING_ARCH_strsep
b61345a1 1043
a784e502 1044extern char *__strsep_g (char **__stringp, const char *__delim);
61423e13 1045# define __strsep(s, reject) \
36ab45e1
UD
1046 __extension__ \
1047 ({ char __r0, __r1, __r2; \
1048 (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
a784e502
UD
1049 && (__r0 = ((const char *) (reject))[0], \
1050 ((const char *) (reject))[0] != '\0') \
1051 ? ((__r1 = ((const char *) (reject))[1], \
1052 ((const char *) (reject))[1] == '\0') \
36ab45e1 1053 ? __strsep_1c (s, __r0) \
a784e502 1054 : ((__r2 = ((const char *) (reject))[2], __r2 == '\0') \
36ab45e1 1055 ? __strsep_2c (s, __r0, __r1) \
a784e502 1056 : (((const char *) (reject))[3] == '\0' \
36ab45e1 1057 ? __strsep_3c (s, __r0, __r1, __r2) \
b61345a1
UD
1058 : __strsep_g (s, reject)))) \
1059 : __strsep_g (s, reject)); })
61423e13 1060# endif
61eb22d3
UD
1061
1062__STRING_INLINE char *__strsep_1c (char **__s, char __reject);
1063__STRING_INLINE char *
1064__strsep_1c (char **__s, char __reject)
1065{
2e09a79a 1066 char *__retval = *__s;
61423e13 1067 if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
61eb22d3 1068 *(*__s)++ = '\0';
14c44e2e
UD
1069 return __retval;
1070}
1071
1072__STRING_INLINE char *__strsep_2c (char **__s, char __reject1, char __reject2);
1073__STRING_INLINE char *
1074__strsep_2c (char **__s, char __reject1, char __reject2)
1075{
2e09a79a 1076 char *__retval = *__s;
61423e13 1077 if (__retval != NULL)
14c44e2e 1078 {
2e09a79a 1079 char *__cp = __retval;
61423e13 1080 while (1)
14c44e2e 1081 {
61423e13
UD
1082 if (*__cp == '\0')
1083 {
1084 __cp = NULL;
1085 break;
1086 }
1087 if (*__cp == __reject1 || *__cp == __reject2)
1088 {
1089 *__cp++ = '\0';
1090 break;
1091 }
1092 ++__cp;
14c44e2e 1093 }
61423e13 1094 *__s = __cp;
14c44e2e
UD
1095 }
1096 return __retval;
1097}
1098
1099__STRING_INLINE char *__strsep_3c (char **__s, char __reject1, char __reject2,
1100 char __reject3);
1101__STRING_INLINE char *
1102__strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
1103{
2e09a79a 1104 char *__retval = *__s;
61423e13 1105 if (__retval != NULL)
14c44e2e 1106 {
2e09a79a 1107 char *__cp = __retval;
61423e13 1108 while (1)
14c44e2e 1109 {
61423e13
UD
1110 if (*__cp == '\0')
1111 {
1112 __cp = NULL;
1113 break;
1114 }
1115 if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
1116 {
1117 *__cp++ = '\0';
1118 break;
1119 }
1120 ++__cp;
14c44e2e 1121 }
61423e13 1122 *__s = __cp;
14c44e2e 1123 }
650425ce 1124 return __retval;
61eb22d3 1125}
498afc54 1126# ifdef __USE_MISC
61423e13 1127# define strsep(s, reject) __strsep (s, reject)
31161268
UD
1128# endif
1129#endif
1130
7ef90c15 1131/* We need the memory allocation functions for inline strdup().
d2537a47 1132 Referring to stdlib.h (even minimally) is not allowed
4a582094 1133 in any of the tight standards compliant modes. */
6e2cc2c1 1134#ifdef __USE_MISC
31161268 1135
4a582094
UD
1136# if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup
1137# define __need_malloc_and_calloc
1138# include <stdlib.h>
1139# endif
7ef90c15 1140
4a582094 1141# ifndef _HAVE_STRING_ARCH_strdup
31161268 1142
a784e502 1143extern char *__strdup (const char *__string) __THROW __attribute_malloc__;
4a582094 1144# define __strdup(s) \
7551a1e5 1145 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
a784e502 1146 ? (((const char *) (s))[0] == '\0' \
a83b5649 1147 ? (char *) calloc ((size_t) 1, (size_t) 1) \
7551a1e5
UD
1148 : ({ size_t __len = strlen (s) + 1; \
1149 char *__retval = (char *) malloc (__len); \
1150 if (__retval != NULL) \
1151 __retval = (char *) memcpy (__retval, s, __len); \
1152 __retval; })) \
1153 : __strdup (s)))
31161268 1154
3d7c00e3 1155# if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
4a582094
UD
1156# define strdup(s) __strdup (s)
1157# endif
61eb22d3 1158# endif
61eb22d3 1159
4a582094 1160# ifndef _HAVE_STRING_ARCH_strndup
7551a1e5 1161
a784e502 1162extern char *__strndup (const char *__string, size_t __n)
160016c9 1163 __THROW __attribute_malloc__;
4a582094 1164# define __strndup(s, n) \
7551a1e5 1165 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
a784e502 1166 ? (((const char *) (s))[0] == '\0' \
a83b5649 1167 ? (char *) calloc ((size_t) 1, (size_t) 1) \
7551a1e5
UD
1168 : ({ size_t __len = strlen (s) + 1; \
1169 size_t __n = (n); \
1170 char *__retval; \
1171 if (__n < __len) \
fb4fb542 1172 __len = __n + 1; \
7551a1e5
UD
1173 __retval = (char *) malloc (__len); \
1174 if (__retval != NULL) \
1175 { \
1176 __retval[__len - 1] = '\0'; \
1177 __retval = (char *) memcpy (__retval, s, \
1178 __len - 1); \
1179 } \
1180 __retval; })) \
61423e13 1181 : __strndup (s, n)))
7551a1e5 1182
3d7c00e3 1183# ifdef __USE_XOPEN2K8
61423e13 1184# define strndup(s, n) __strndup (s, n)
4a582094 1185# endif
7551a1e5 1186# endif
7551a1e5 1187
4a582094 1188#endif /* Use misc. or use GNU. */
7551a1e5 1189
9bbd7837
UD
1190#ifndef _FORCE_INLINES
1191# undef __STRING_INLINE
1192#endif
9a0a462c 1193
61eb22d3 1194#endif /* No string inlines. */