1 /* Machine-independant string function optimizations.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6 The GNU C Library is free software; you can redistribute it and/or
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.
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 Lesser General Public License for more details.
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
22 # error "Never use <bits/string2.h> directly; include <string.h> instead."
25 #if !defined __NO_STRING_INLINES && !defined __BOUNDED_POINTERS__
27 /* Unlike the definitions in the header <bits/string.h> the
28 definitions contained here are not optimized down to assembler
29 level. Those optimizations are not always a good idea since this
30 means the code size increases a lot. Instead the definitions here
31 optimize some functions in a way which do not dramatically
32 increase the code size and which do not use assembler. The main
33 trick is to use GNU CC's `__builtin_constant_p' function.
35 Every function XXX which has a defined version in
36 <bits/string.h> must be accompanied by a symbol _HAVE_STRING_ARCH_XXX
37 to make sure we don't get redefinitions.
39 We must use here macros instead of inline functions since the
40 trick won't work with the latter. */
42 #ifndef __STRING_INLINE
44 # define __STRING_INLINE inline
46 # define __STRING_INLINE extern __inline
50 #if _STRING_ARCH_unaligned
51 /* If we can do unaligned memory accesses we must know the endianess. */
53 # include <bits/types.h>
55 # if __BYTE_ORDER == __LITTLE_ENDIAN
56 # define __STRING2_SMALL_GET16(src, idx) \
57 (((__const unsigned char *) (__const char *) (src))[idx + 1] << 8 \
58 | ((__const unsigned char *) (__const char *) (src))[idx])
59 # define __STRING2_SMALL_GET32(src, idx) \
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])
65 # define __STRING2_SMALL_GET16(src, idx) \
66 (((__const unsigned char *) (__const char *) (src))[idx] << 8 \
67 | ((__const unsigned char *) (__const char *) (src))[idx + 1])
68 # define __STRING2_SMALL_GET32(src, idx) \
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])
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) \
78 typedef struct { unsigned char __arr[N]; } \
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
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) \
94 ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)
96 /* Set N bytes of S to C. */
97 #ifndef _HAVE_STRING_ARCH_memset
98 # if _STRING_ARCH_unaligned
99 # define memset(s, c, n) \
100 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
102 ? __memset_1 (s, c) \
103 : __memset_gc (s, c, n)) \
104 : (__builtin_constant_p (c) && (c) == '\0' \
105 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
106 : memset (s, c, n))))
108 # define __memset_1(s, c) ({ void *__s = (s); \
109 *((__uint8_t *) __s) = (__uint8_t) c; __s; })
111 # define __memset_gc(s, c, n) \
112 ({ void *__s = (s); \
115 unsigned short int __usi; \
116 unsigned char __uc; \
118 __uint8_t __c = (__uint8_t) (c); \
120 /* This `switch' statement will be removed at compile-time. */ \
121 switch ((unsigned int) (n)) \
124 __u->__ui = __c * 0x01010101; \
125 __u = __extension__ ((void *) __u + 4); \
127 __u->__ui = __c * 0x01010101; \
128 __u = __extension__ ((void *) __u + 4); \
130 __u->__ui = __c * 0x01010101; \
131 __u = __extension__ ((void *) __u + 4); \
133 __u->__usi = (unsigned short int) __c * 0x0101; \
134 __u = __extension__ ((void *) __u + 2); \
135 __u->__uc = (unsigned char) __c; \
139 __u->__ui = __c * 0x01010101; \
140 __u = __extension__ ((void *) __u + 4); \
142 __u->__ui = __c * 0x01010101; \
143 __u = __extension__ ((void *) __u + 4); \
145 __u->__ui = __c * 0x01010101; \
146 __u = __extension__ ((void *) __u + 4); \
148 __u->__usi = (unsigned short int) __c * 0x0101; \
152 __u->__ui = __c * 0x01010101; \
153 __u = __extension__ ((void *) __u + 4); \
155 __u->__ui = __c * 0x01010101; \
156 __u = __extension__ ((void *) __u + 4); \
158 __u->__ui = __c * 0x01010101; \
159 __u = __extension__ ((void *) __u + 4); \
161 __u->__uc = (unsigned char) __c; \
165 __u->__ui = __c * 0x01010101; \
166 __u = __extension__ ((void *) __u + 4); \
168 __u->__ui = __c * 0x01010101; \
169 __u = __extension__ ((void *) __u + 4); \
171 __u->__ui = __c * 0x01010101; \
172 __u = __extension__ ((void *) __u + 4); \
174 __u->__ui = __c * 0x01010101; \
181 # define memset(s, c, n) \
182 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
183 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
187 /* GCC optimizes memset(s, 0, n) but not bzero(s, n).
188 The optimization is broken before EGCS 1.1. */
189 # if __GNUC_PREREQ (2, 91)
190 # define __bzero(s, n) __builtin_memset (s, '\0', n)
196 /* Copy N bytes from SRC to DEST, returning pointer to byte following the
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 \
203 ? __mempcpy_small (dest, __mempcpy_args (src), n) \
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)
209 # if _STRING_ARCH_unaligned
210 # define __mempcpy_args(src) \
211 ((__const char *) (src))[0], ((__const char *) (src))[2], \
212 ((__const char *) (src))[4], ((__const 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)
217 __STRING_INLINE
void *__mempcpy_small (void *, char, char, char, char,
218 __uint16_t
, __uint16_t
, __uint32_t
,
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
,
233 switch ((unsigned int) __srclen
)
237 __u
= __extension__ ((void *) __u
+ 1);
240 __u
->__usi
= __src0_2
;
241 __u
= __extension__ ((void *) __u
+ 2);
244 __u
->__usi
= __src0_2
;
245 __u
= __extension__ ((void *) __u
+ 2);
247 __u
= __extension__ ((void *) __u
+ 1);
250 __u
->__ui
= __src0_4
;
251 __u
= __extension__ ((void *) __u
+ 4);
254 __u
->__ui
= __src0_4
;
255 __u
= __extension__ ((void *) __u
+ 4);
257 __u
= __extension__ ((void *) __u
+ 1);
260 __u
->__ui
= __src0_4
;
261 __u
= __extension__ ((void *) __u
+ 4);
262 __u
->__usi
= __src4_2
;
263 __u
= __extension__ ((void *) __u
+ 2);
266 __u
->__ui
= __src0_4
;
267 __u
= __extension__ ((void *) __u
+ 4);
268 __u
->__usi
= __src4_2
;
269 __u
= __extension__ ((void *) __u
+ 2);
271 __u
= __extension__ ((void *) __u
+ 1);
274 __u
->__ui
= __src0_4
;
275 __u
= __extension__ ((void *) __u
+ 4);
276 __u
->__ui
= __src4_4
;
277 __u
= __extension__ ((void *) __u
+ 4);
283 # define __mempcpy_args(src) \
284 ((__const char *) (src))[0], \
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] } })
311 __STRING_INLINE
void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2
,
317 __STRING2_COPY_ARR8
, size_t);
318 __STRING_INLINE
void *
319 __mempcpy_small (void *__dest
, char __src1
,
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
)
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
;
335 switch ((unsigned int) __srclen
)
341 __extension__ __u
->__sca2
= __src2
;
344 __extension__ __u
->__sca3
= __src3
;
347 __extension__ __u
->__sca4
= __src4
;
350 __extension__ __u
->__sca5
= __src5
;
353 __extension__ __u
->__sca6
= __src6
;
356 __extension__ __u
->__sca7
= __src7
;
359 __extension__ __u
->__sca8
= __src8
;
362 return __extension__ ((void *) __u
+ __srclen
);
369 /* Return pointer to C in S. */
370 #ifndef _HAVE_STRING_ARCH_strchr
371 extern void *__rawmemchr (const void *__s
, int __c
);
372 # define strchr(s, c) \
373 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
374 ? (char *) __rawmemchr (s, c) \
379 /* Copy SRC to DEST. */
380 #ifndef _HAVE_STRING_ARCH_strcpy
381 # define strcpy(dest, src) \
382 (__extension__ (__builtin_constant_p (src) \
383 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
384 ? __strcpy_small (dest, __strcpy_args (src), \
386 : (char *) memcpy (dest, src, strlen (src) + 1)) \
387 : strcpy (dest, src)))
389 # if _STRING_ARCH_unaligned
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)
395 __STRING_INLINE
char *__strcpy_small (char *, __uint16_t
, __uint16_t
,
396 __uint32_t
, __uint32_t
, size_t);
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
,
407 } *__u
= (void *) __dest
;
408 switch ((unsigned int) __srclen
)
414 __u
->__usi
= __src0_2
;
417 __u
->__usi
= __src0_2
;
418 __u
= __extension__ ((void *) __u
+ 2);
422 __u
->__ui
= __src0_4
;
425 __u
->__ui
= __src0_4
;
426 __u
= __extension__ ((void *) __u
+ 4);
430 __u
->__ui
= __src0_4
;
431 __u
= __extension__ ((void *) __u
+ 4);
432 __u
->__usi
= __src4_2
;
435 __u
->__ui
= __src0_4
;
436 __u
= __extension__ ((void *) __u
+ 4);
437 __u
->__usi
= __src4_2
;
438 __u
= __extension__ ((void *) __u
+ 2);
442 __u
->__ui
= __src0_4
;
443 __u
= __extension__ ((void *) __u
+ 4);
444 __u
->__ui
= __src4_4
;
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], \
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], \
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], \
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' } })
477 __STRING_INLINE
char *__strcpy_small (char *, __STRING2_COPY_ARR2
,
483 __STRING2_COPY_ARR8
, size_t);
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
)
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
;
500 } *__u
= (void *) __dest
;
501 switch ((unsigned int) __srclen
)
507 __extension__ __u
->__sca2
= __src2
;
510 __extension__ __u
->__sca3
= __src3
;
513 __extension__ __u
->__sca4
= __src4
;
516 __extension__ __u
->__sca5
= __src5
;
519 __extension__ __u
->__sca6
= __src6
;
522 __extension__ __u
->__sca7
= __src7
;
525 __extension__ __u
->__sca8
= __src8
;
534 /* Copy SRC to DEST, returning pointer to final NUL byte. */
536 # ifndef _HAVE_STRING_ARCH_stpcpy
537 # define __stpcpy(dest, src) \
538 (__extension__ (__builtin_constant_p (src) \
539 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
540 ? __stpcpy_small (dest, __stpcpy_args (src), \
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)
548 # if _STRING_ARCH_unaligned
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)
554 __STRING_INLINE
char *__stpcpy_small (char *, __uint16_t
, __uint16_t
,
555 __uint32_t
, __uint32_t
, size_t);
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
,
564 unsigned short int __usi
;
567 } *__u
= (void *) __dest
;
568 switch ((unsigned int) __srclen
)
574 __u
->__usi
= __src0_2
;
575 __u
= __extension__ ((void *) __u
+ 1);
578 __u
->__usi
= __src0_2
;
579 __u
= __extension__ ((void *) __u
+ 2);
583 __u
->__ui
= __src0_4
;
584 __u
= __extension__ ((void *) __u
+ 3);
587 __u
->__ui
= __src0_4
;
588 __u
= __extension__ ((void *) __u
+ 4);
592 __u
->__ui
= __src0_4
;
593 __u
= __extension__ ((void *) __u
+ 4);
594 __u
->__usi
= __src4_2
;
595 __u
= __extension__ ((void *) __u
+ 1);
598 __u
->__ui
= __src0_4
;
599 __u
= __extension__ ((void *) __u
+ 4);
600 __u
->__usi
= __src4_2
;
601 __u
= __extension__ ((void *) __u
+ 2);
605 __u
->__ui
= __src0_4
;
606 __u
= __extension__ ((void *) __u
+ 4);
607 __u
->__ui
= __src4_4
;
608 __u
= __extension__ ((void *) __u
+ 3);
614 # define __stpcpy_args(src) \
615 __extension__ ((__STRING2_COPY_ARR2) \
616 { { ((__const char *) (src))[0], '\0' } }), \
617 __extension__ ((__STRING2_COPY_ARR3) \
618 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
620 __extension__ ((__STRING2_COPY_ARR4) \
621 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
622 ((__const char *) (src))[2], '\0' } }), \
623 __extension__ ((__STRING2_COPY_ARR5) \
624 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
625 ((__const char *) (src))[2], ((__const char *) (src))[3], \
627 __extension__ ((__STRING2_COPY_ARR6) \
628 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
629 ((__const char *) (src))[2], ((__const char *) (src))[3], \
630 ((__const char *) (src))[4], '\0' } }), \
631 __extension__ ((__STRING2_COPY_ARR7) \
632 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
633 ((__const char *) (src))[2], ((__const char *) (src))[3], \
634 ((__const char *) (src))[4], ((__const char *) (src))[5], \
636 __extension__ ((__STRING2_COPY_ARR8) \
637 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
638 ((__const char *) (src))[2], ((__const char *) (src))[3], \
639 ((__const char *) (src))[4], ((__const char *) (src))[5], \
640 ((__const char *) (src))[6], '\0' } })
641 __STRING_INLINE
char *__stpcpy_small (char *, __STRING2_COPY_ARR2
,
647 __STRING2_COPY_ARR8
, size_t);
648 __STRING_INLINE
char *
649 __stpcpy_small (char *__dest
,
650 __STRING2_COPY_ARR2 __src2
, __STRING2_COPY_ARR3 __src3
,
651 __STRING2_COPY_ARR4 __src4
, __STRING2_COPY_ARR5 __src5
,
652 __STRING2_COPY_ARR6 __src6
, __STRING2_COPY_ARR7 __src7
,
653 __STRING2_COPY_ARR8 __src8
, size_t __srclen
)
657 __STRING2_COPY_ARR2 __sca2
;
658 __STRING2_COPY_ARR3 __sca3
;
659 __STRING2_COPY_ARR4 __sca4
;
660 __STRING2_COPY_ARR5 __sca5
;
661 __STRING2_COPY_ARR6 __sca6
;
662 __STRING2_COPY_ARR7 __sca7
;
663 __STRING2_COPY_ARR8 __sca8
;
664 } *__u
= (void *) __dest
;
665 switch ((unsigned int) __srclen
)
671 __extension__ __u
->__sca2
= __src2
;
674 __extension__ __u
->__sca3
= __src3
;
677 __extension__ __u
->__sca4
= __src4
;
680 __extension__ __u
->__sca5
= __src5
;
683 __extension__ __u
->__sca6
= __src6
;
686 __extension__ __u
->__sca7
= __src7
;
689 __extension__ __u
->__sca8
= __src8
;
692 return __dest
+ __srclen
- 1;
699 /* Copy no more than N characters of SRC to DEST. */
700 #ifndef _HAVE_STRING_ARCH_strncpy
701 # if defined _USE_STRING_ARCH_memset && defined _USE_STRING_ARCH_mempcpy
702 # define strncpy(dest, src, n) \
703 (__extension__ ({ char *__dest = (dest); \
704 __builtin_constant_p (src) && __builtin_constant_p (n) \
705 ? (strlen (src) + 1 >= ((size_t) (n)) \
706 ? (char *) memcpy (__dest, src, n) \
707 : (memset (__mempcpy (__dest, src, strlen (src)), \
708 '\0', n - strlen (src)), \
710 : strncpy (__dest, src, n); }))
712 # define strncpy(dest, src, n) \
713 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
714 ? (strlen (src) + 1 >= ((size_t) (n)) \
715 ? (char *) memcpy (dest, src, n) \
716 : strncpy (dest, src, n)) \
717 : strncpy (dest, src, n)))
722 /* Append no more than N characters from SRC onto DEST. */
723 #ifndef _HAVE_STRING_ARCH_strncat
724 # ifdef _USE_STRING_ARCH_strchr
725 # define strncat(dest, src, n) \
726 (__extension__ ({ char *__dest = (dest); \
727 __builtin_constant_p (src) && __builtin_constant_p (n) \
728 ? (strlen (src) < ((size_t) (n)) \
729 ? strcat (__dest, src) \
730 : (*((char *) __mempcpy (strchr (__dest, '\0'), \
731 src, n)) = '\0', __dest)) \
732 : strncat (dest, src, n); }))
734 # define strncat(dest, src, n) \
735 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
736 ? (strlen (src) < ((size_t) (n)) \
737 ? strcat (dest, src) \
738 : strncat (dest, src, n)) \
739 : strncat (dest, src, n)))
744 /* Compare characters of S1 and S2. */
745 #ifndef _HAVE_STRING_ARCH_strcmp
746 # define strcmp(s1, s2) \
748 ({ size_t __s1_len, __s2_len; \
749 (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
750 && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
751 (!__string2_1bptr_p (s1) || __s1_len >= 4) \
752 && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
753 ? memcmp ((__const char *) (s1), (__const char *) (s2), \
754 (__s1_len < __s2_len ? __s1_len : __s2_len) + 1) \
755 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
756 && (__s1_len = strlen (s1), __s1_len < 4) \
757 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
758 ? __strcmp_cc (s1, s2, __s1_len) \
759 : __strcmp_cg (s1, s2, __s1_len)) \
760 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
761 && (__s2_len = strlen (s2), __s2_len < 4) \
762 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
763 ? __strcmp_cc (s1, s2, __s2_len) \
764 : __strcmp_gc (s1, s2, __s2_len)) \
765 : strcmp (s1, s2)))); })
767 # define __strcmp_cc(s1, s2, l) \
768 (__extension__ ({ register int __result = \
769 (((__const unsigned char *) (__const char *) (s1))[0] \
770 - ((__const unsigned char *) (__const char *)(s2))[0]);\
771 if (l > 0 && __result == 0) \
773 __result = (((__const unsigned char *) \
774 (__const char *) (s1))[1] \
775 - ((__const unsigned char *) \
776 (__const char *) (s2))[1]); \
777 if (l > 1 && __result == 0) \
780 (((__const unsigned char *) \
781 (__const char *) (s1))[2] \
782 - ((__const unsigned char *) \
783 (__const char *) (s2))[2]); \
784 if (l > 2 && __result == 0) \
786 (((__const unsigned char *) \
787 (__const char *) (s1))[3] \
788 - ((__const unsigned char *) \
789 (__const char *) (s2))[3]); \
794 # define __strcmp_cg(s1, s2, l1) \
795 (__extension__ ({ __const unsigned char *__s2 = \
796 (__const unsigned char *) (__const char *) (s2); \
797 register int __result = \
798 (((__const unsigned char *) (__const char *) (s1))[0] \
800 if (l1 > 0 && __result == 0) \
802 __result = (((__const unsigned char *) \
803 (__const char *) (s1))[1] - __s2[1]); \
804 if (l1 > 1 && __result == 0) \
806 __result = (((__const unsigned char *) \
807 (__const char *) (s1))[2] - __s2[2]);\
808 if (l1 > 2 && __result == 0) \
809 __result = (((__const unsigned char *) \
810 (__const char *) (s1))[3] \
816 # define __strcmp_gc(s1, s2, l2) \
817 (__extension__ ({ __const unsigned char *__s1 = \
818 (__const unsigned char *) (__const char *) (s1); \
819 register int __result = \
820 __s1[0] - ((__const unsigned char *) \
821 (__const char *) (s2))[0]; \
822 if (l2 > 0 && __result == 0) \
824 __result = (__s1[1] \
825 - ((__const unsigned char *) \
826 (__const char *) (s2))[1]); \
827 if (l2 > 1 && __result == 0) \
830 (__s1[2] - ((__const unsigned char *) \
831 (__const char *) (s2))[2]); \
832 if (l2 > 2 && __result == 0) \
835 - ((__const unsigned char *) \
836 (__const char *) (s2))[3]); \
843 /* Compare N characters of S1 and S2. */
844 #ifndef _HAVE_STRING_ARCH_strncmp
845 # define strncmp(s1, s2, n) \
846 (__extension__ (__builtin_constant_p (n) \
847 && ((__builtin_constant_p (s1) \
848 && strlen (s1) < ((size_t) (n))) \
849 || (__builtin_constant_p (s2) \
850 && strlen (s2) < ((size_t) (n)))) \
851 ? strcmp (s1, s2) : strncmp (s1, s2, n)))
855 /* Return the length of the initial segment of S which
856 consists entirely of characters not in REJECT. */
857 #ifndef _HAVE_STRING_ARCH_strcspn
858 # define strcspn(s, reject) \
860 ({ char __r0, __r1, __r2; \
861 (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
862 ? ((__r0 = ((__const char *) (reject))[0], __r0 == '\0') \
864 : ((__r1 = ((__const char *) (reject))[1], __r1 == '\0') \
865 ? __strcspn_c1 (s, __r0) \
866 : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \
867 ? __strcspn_c2 (s, __r0, __r1) \
868 : (((__const char *) (reject))[3] == '\0' \
869 ? __strcspn_c3 (s, __r0, __r1, __r2) \
870 : strcspn (s, reject))))) \
871 : strcspn (s, reject)); })
873 __STRING_INLINE
size_t __strcspn_c1 (__const
char *__s
, char __reject
);
874 __STRING_INLINE
size_t
875 __strcspn_c1 (__const
char *__s
, char __reject
)
877 register size_t __result
= 0;
878 while (__s
[__result
] != '\0' && __s
[__result
] != __reject
)
883 __STRING_INLINE
size_t __strcspn_c2 (__const
char *__s
, char __reject1
,
885 __STRING_INLINE
size_t
886 __strcspn_c2 (__const
char *__s
, char __reject1
, char __reject2
)
888 register size_t __result
= 0;
889 while (__s
[__result
] != '\0' && __s
[__result
] != __reject1
890 && __s
[__result
] != __reject2
)
895 __STRING_INLINE
size_t __strcspn_c3 (__const
char *__s
, char __reject1
,
896 char __reject2
, char __reject3
);
897 __STRING_INLINE
size_t
898 __strcspn_c3 (__const
char *__s
, char __reject1
, char __reject2
,
901 register size_t __result
= 0;
902 while (__s
[__result
] != '\0' && __s
[__result
] != __reject1
903 && __s
[__result
] != __reject2
&& __s
[__result
] != __reject3
)
910 /* Return the length of the initial segment of S which
911 consists entirely of characters in ACCEPT. */
912 #ifndef _HAVE_STRING_ARCH_strspn
913 # define strspn(s, accept) \
915 ({ char __a0, __a1, __a2; \
916 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
917 ? ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \
919 : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \
920 ? __strspn_c1 (s, __a0) \
921 : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \
922 ? __strspn_c2 (s, __a0, __a1) \
923 : (((__const char *) (accept))[3] == '\0' \
924 ? __strspn_c3 (s, __a0, __a1, __a2) \
925 : strspn (s, accept))))) \
926 : strspn (s, accept)); })
928 __STRING_INLINE
size_t __strspn_c1 (__const
char *__s
, char __accept
);
929 __STRING_INLINE
size_t
930 __strspn_c1 (__const
char *__s
, char __accept
)
932 register size_t __result
= 0;
933 /* Please note that __accept never can be '\0'. */
934 while (__s
[__result
] == __accept
)
939 __STRING_INLINE
size_t __strspn_c2 (__const
char *__s
, char __accept1
,
941 __STRING_INLINE
size_t
942 __strspn_c2 (__const
char *__s
, char __accept1
, char __accept2
)
944 register size_t __result
= 0;
945 /* Please note that __accept1 and __accept2 never can be '\0'. */
946 while (__s
[__result
] == __accept1
|| __s
[__result
] == __accept2
)
951 __STRING_INLINE
size_t __strspn_c3 (__const
char *__s
, char __accept1
,
952 char __accept2
, char __accept3
);
953 __STRING_INLINE
size_t
954 __strspn_c3 (__const
char *__s
, char __accept1
, char __accept2
, char __accept3
)
956 register size_t __result
= 0;
957 /* Please note that __accept1 to __accept3 never can be '\0'. */
958 while (__s
[__result
] == __accept1
|| __s
[__result
] == __accept2
959 || __s
[__result
] == __accept3
)
966 /* Find the first occurrence in S of any character in ACCEPT. */
967 #ifndef _HAVE_STRING_ARCH_strpbrk
968 # define strpbrk(s, accept) \
970 ({ char __a0, __a1, __a2; \
971 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
972 ? ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \
973 ? ((void) (s), NULL) \
974 : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \
976 : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \
977 ? __strpbrk_c2 (s, __a0, __a1) \
978 : (((__const char *) (accept))[3] == '\0' \
979 ? __strpbrk_c3 (s, __a0, __a1, __a2) \
980 : strpbrk (s, accept))))) \
981 : strpbrk (s, accept)); })
983 __STRING_INLINE
char *__strpbrk_c2 (__const
char *__s
, int __accept1
,
985 __STRING_INLINE
char *
986 __strpbrk_c2 (__const
char *__s
, int __accept1
, int __accept2
)
988 /* Please note that __accept1 and __accept2 never can be '\0'. */
989 while (*__s
!= '\0' && *__s
!= __accept1
&& *__s
!= __accept2
)
991 return *__s
== '\0' ? NULL
: (char *) (size_t) __s
;
994 __STRING_INLINE
char *__strpbrk_c3 (__const
char *__s
, int __accept1
,
995 int __accept2
, int __accept3
);
996 __STRING_INLINE
char *
997 __strpbrk_c3 (__const
char *__s
, int __accept1
, int __accept2
,
1000 /* Please note that __accept1 to __accept3 never can be '\0'. */
1001 while (*__s
!= '\0' && *__s
!= __accept1
&& *__s
!= __accept2
1002 && *__s
!= __accept3
)
1004 return *__s
== '\0' ? NULL
: (char *) (size_t) __s
;
1009 /* Find the first occurrence of NEEDLE in HAYSTACK. Newer gcc versions
1011 #if !defined _HAVE_STRING_ARCH_strstr && !__GNUC_PREREQ (2, 97)
1012 # define strstr(haystack, needle) \
1013 (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
1014 ? (((__const char *) (needle))[0] == '\0' \
1015 ? (char *) (size_t) (haystack) \
1016 : (((__const char *) (needle))[1] == '\0' \
1017 ? strchr (haystack, \
1018 ((__const char *) (needle))[0]) \
1019 : strstr (haystack, needle))) \
1020 : strstr (haystack, needle)))
1024 #ifndef _HAVE_STRING_ARCH_strtok_r
1025 # define __strtok_r(s, sep, nextp) \
1026 (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \
1027 ? (((__const char *) (sep))[0] != '\0' \
1028 && ((__const char *) (sep))[1] == '\0' \
1029 ? __strtok_r_1c (s, ((__const char *) (sep))[0], nextp) \
1030 : __strtok_r (s, sep, nextp)) \
1031 : __strtok_r (s, sep, nextp)))
1033 __STRING_INLINE
char *__strtok_r_1c (char *__s
, char __sep
, char **__nextp
);
1034 __STRING_INLINE
char *
1035 __strtok_r_1c (char *__s
, char __sep
, char **__nextp
)
1040 while (*__s
== __sep
)
1047 while (*__s
!= '\0')
1048 if (*__s
++ == __sep
)
1057 # if defined __USE_POSIX || defined __USE_MISC
1058 # define strtok_r(s, sep, nextp) __strtok_r ((s), (sep), (nextp))
1063 #ifndef _HAVE_STRING_ARCH_strsep
1065 # define __strsep(s, reject) \
1067 ({ char __r0, __r1, __r2; \
1068 (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
1069 && (__r0 = ((__const char *) (reject))[0], \
1070 ((__const char *) (reject))[0] != '\0') \
1071 ? ((__r1 = ((__const char *) (reject))[1], \
1072 ((__const char *) (reject))[1] == '\0') \
1073 ? __strsep_1c (s, __r0) \
1074 : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \
1075 ? __strsep_2c (s, __r0, __r1) \
1076 : (((__const char *) (reject))[3] == '\0' \
1077 ? __strsep_3c (s, __r0, __r1, __r2) \
1078 : __strsep_g (s, reject)))) \
1079 : __strsep_g (s, reject)); })
1081 __STRING_INLINE
char *__strsep_1c (char **__s
, char __reject
);
1082 __STRING_INLINE
char *
1083 __strsep_1c (char **__s
, char __reject
)
1085 register char *__retval
= *__s
;
1086 if (__retval
== NULL
)
1088 if (*__retval
== __reject
)
1091 if ((*__s
= strchr (__retval
, __reject
)) != NULL
)
1098 __STRING_INLINE
char *__strsep_2c (char **__s
, char __reject1
, char __reject2
);
1099 __STRING_INLINE
char *
1100 __strsep_2c (char **__s
, char __reject1
, char __reject2
)
1102 register char *__retval
= *__s
;
1103 if (__retval
== NULL
)
1105 if (*__retval
== __reject1
|| *__retval
== __reject2
)
1109 register char *__cp
= __retval
;
1110 while (*__cp
!= '\0' && *__cp
!= __reject1
&& *__cp
!= __reject2
)
1123 __STRING_INLINE
char *__strsep_3c (char **__s
, char __reject1
, char __reject2
,
1125 __STRING_INLINE
char *
1126 __strsep_3c (char **__s
, char __reject1
, char __reject2
, char __reject3
)
1128 register char *__retval
= *__s
;
1129 if (__retval
== NULL
)
1131 if (*__retval
== __reject1
|| *__retval
== __reject2
1132 || *__retval
== __reject3
)
1136 register char *__cp
= __retval
;
1137 while (*__cp
!= '\0' && *__cp
!= __reject1
&& *__cp
!= __reject2
1138 && *__cp
!= __reject3
)
1151 __STRING_INLINE
char *__strsep_g (char **__s
, __const
char *__reject
);
1152 __STRING_INLINE
char *
1153 __strsep_g (char **__s
, __const
char *__reject
)
1155 register char *__retval
= *__s
;
1156 if (__retval
== NULL
)
1158 if ((*__s
= strpbrk (__retval
, __reject
)) != NULL
)
1163 # define strsep(s, reject) __strsep ((s), (reject))
1167 /* We need the memory allocation functions for inline strdup().
1168 Referring to stdlib.h (even minimally) is not allowed
1169 in any of the tight standards compliant modes. */
1172 # if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup
1173 # define __need_malloc_and_calloc
1174 # include <stdlib.h>
1177 # ifndef _HAVE_STRING_ARCH_strdup
1179 extern char *__strdup (__const
char *__string
) __THROW __attribute_malloc__
;
1180 # define __strdup(s) \
1181 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
1182 ? (((__const char *) (s))[0] == '\0' \
1183 ? (char *) calloc (1, 1) \
1184 : ({ size_t __len = strlen (s) + 1; \
1185 char *__retval = (char *) malloc (__len); \
1186 if (__retval != NULL) \
1187 __retval = (char *) memcpy (__retval, s, __len); \
1191 # if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1192 # define strdup(s) __strdup (s)
1196 # ifndef _HAVE_STRING_ARCH_strndup
1198 extern char *__strndup (__const
char *__string
, size_t __n
)
1199 __THROW __attribute_malloc__
;
1200 # define __strndup(s, n) \
1201 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
1202 ? (((__const char *) (s))[0] == '\0' \
1203 ? (char *) calloc (1, 1) \
1204 : ({ size_t __len = strlen (s) + 1; \
1209 __retval = (char *) malloc (__len); \
1210 if (__retval != NULL) \
1212 __retval[__len - 1] = '\0'; \
1213 __retval = (char *) memcpy (__retval, s, \
1217 : __strndup ((s), (n))))
1220 # define strndup(s, n) __strndup ((s), (n))
1224 #endif /* Use misc. or use GNU. */
1226 #ifndef _FORCE_INLINES
1227 # undef __STRING_INLINE
1230 #endif /* No string inlines. */