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