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