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