2009-03-19 Roland McGrath <roland@redhat.com>
[glibc.git] / string / bits / string2.h
blobd298bed9f8480abe91bb2f5ab7d5f4ca2e4efcf4
1 /* Machine-independant string function optimizations.
2 Copyright (C) 1997-2003, 2004, 2007, 2008 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
19 02111-1307 USA. */
21 #ifndef _STRING_H
22 # error "Never use <bits/string2.h> directly; include <string.h> instead."
23 #endif
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 GCC'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
43 # ifdef __cplusplus
44 # define __STRING_INLINE inline
45 # else
46 # define __STRING_INLINE __extern_inline
47 # endif
48 #endif
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>
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])
64 # else
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])
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) \
78 typedef struct { unsigned char __arr[N]; } \
79 __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
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
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 #if !defined _HAVE_STRING_ARCH_memset
98 # if !__GNUC_PREREQ (3, 0)
99 # if _STRING_ARCH_unaligned
100 # define memset(s, c, n) \
101 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
102 ? ((n) == 1 \
103 ? __memset_1 (s, c) \
104 : __memset_gc (s, c, n)) \
105 : (__builtin_constant_p (c) && (c) == '\0' \
106 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
107 : memset (s, c, n))))
109 # define __memset_1(s, c) ({ void *__s = (s); \
110 *((__uint8_t *) __s) = (__uint8_t) c; __s; })
112 # define __memset_gc(s, c, n) \
113 ({ void *__s = (s); \
114 union { \
115 unsigned int __ui; \
116 unsigned short int __usi; \
117 unsigned char __uc; \
118 } *__u = __s; \
119 __uint8_t __c = (__uint8_t) (c); \
121 /* This `switch' statement will be removed at compile-time. */ \
122 switch ((unsigned int) (n)) \
124 case 15: \
125 __u->__ui = __c * 0x01010101; \
126 __u = __extension__ ((void *) __u + 4); \
127 case 11: \
128 __u->__ui = __c * 0x01010101; \
129 __u = __extension__ ((void *) __u + 4); \
130 case 7: \
131 __u->__ui = __c * 0x01010101; \
132 __u = __extension__ ((void *) __u + 4); \
133 case 3: \
134 __u->__usi = (unsigned short int) __c * 0x0101; \
135 __u = __extension__ ((void *) __u + 2); \
136 __u->__uc = (unsigned char) __c; \
137 break; \
139 case 14: \
140 __u->__ui = __c * 0x01010101; \
141 __u = __extension__ ((void *) __u + 4); \
142 case 10: \
143 __u->__ui = __c * 0x01010101; \
144 __u = __extension__ ((void *) __u + 4); \
145 case 6: \
146 __u->__ui = __c * 0x01010101; \
147 __u = __extension__ ((void *) __u + 4); \
148 case 2: \
149 __u->__usi = (unsigned short int) __c * 0x0101; \
150 break; \
152 case 13: \
153 __u->__ui = __c * 0x01010101; \
154 __u = __extension__ ((void *) __u + 4); \
155 case 9: \
156 __u->__ui = __c * 0x01010101; \
157 __u = __extension__ ((void *) __u + 4); \
158 case 5: \
159 __u->__ui = __c * 0x01010101; \
160 __u = __extension__ ((void *) __u + 4); \
161 case 1: \
162 __u->__uc = (unsigned char) __c; \
163 break; \
165 case 16: \
166 __u->__ui = __c * 0x01010101; \
167 __u = __extension__ ((void *) __u + 4); \
168 case 12: \
169 __u->__ui = __c * 0x01010101; \
170 __u = __extension__ ((void *) __u + 4); \
171 case 8: \
172 __u->__ui = __c * 0x01010101; \
173 __u = __extension__ ((void *) __u + 4); \
174 case 4: \
175 __u->__ui = __c * 0x01010101; \
176 case 0: \
177 break; \
180 __s; })
181 # else
182 # define memset(s, c, n) \
183 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
184 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
185 : memset (s, c, n)))
186 # endif
187 # endif
189 /* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
190 The optimization is broken before EGCS 1.1.
191 GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
192 if it decides to call the library function, it calls memset
193 and not bzero. */
194 # if __GNUC_PREREQ (2, 91)
195 # define __bzero(s, n) __builtin_memset (s, '\0', n)
196 # endif
198 #endif
201 /* Copy N bytes from SRC to DEST, returning pointer to byte following the
202 last copied. */
203 #ifdef __USE_GNU
204 # if !defined _HAVE_STRING_ARCH_mempcpy || defined _FORCE_INLINES
205 # ifndef _HAVE_STRING_ARCH_mempcpy
206 # if __GNUC_PREREQ (3, 4)
207 # define __mempcpy(dest, src, n) __builtin_mempcpy (dest, src, n)
208 # elif __GNUC_PREREQ (3, 0)
209 # define __mempcpy(dest, src, n) \
210 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
211 && __string2_1bptr_p (src) && n <= 8 \
212 ? __builtin_memcpy (dest, src, n) + (n) \
213 : __mempcpy (dest, src, n)))
214 # else
215 # define __mempcpy(dest, src, n) \
216 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
217 && __string2_1bptr_p (src) && n <= 8 \
218 ? __mempcpy_small (dest, __mempcpy_args (src), n) \
219 : __mempcpy (dest, src, n)))
220 # endif
221 /* In glibc we use this function frequently but for namespace reasons
222 we have to use the name `__mempcpy'. */
223 # define mempcpy(dest, src, n) __mempcpy (dest, src, n)
224 # endif
226 # if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
227 # if _STRING_ARCH_unaligned
228 # ifndef _FORCE_INLINES
229 # define __mempcpy_args(src) \
230 ((__const char *) (src))[0], ((__const char *) (src))[2], \
231 ((__const char *) (src))[4], ((__const char *) (src))[6], \
232 __extension__ __STRING2_SMALL_GET16 (src, 0), \
233 __extension__ __STRING2_SMALL_GET16 (src, 4), \
234 __extension__ __STRING2_SMALL_GET32 (src, 0), \
235 __extension__ __STRING2_SMALL_GET32 (src, 4)
236 # endif
237 __STRING_INLINE void *__mempcpy_small (void *, char, char, char, char,
238 __uint16_t, __uint16_t, __uint32_t,
239 __uint32_t, size_t);
240 __STRING_INLINE void *
241 __mempcpy_small (void *__dest1,
242 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
243 __uint16_t __src0_2, __uint16_t __src4_2,
244 __uint32_t __src0_4, __uint32_t __src4_4,
245 size_t __srclen)
247 union {
248 __uint32_t __ui;
249 __uint16_t __usi;
250 unsigned char __uc;
251 unsigned char __c;
252 } *__u = __dest1;
253 switch ((unsigned int) __srclen)
255 case 1:
256 __u->__c = __src0_1;
257 __u = __extension__ ((void *) __u + 1);
258 break;
259 case 2:
260 __u->__usi = __src0_2;
261 __u = __extension__ ((void *) __u + 2);
262 break;
263 case 3:
264 __u->__usi = __src0_2;
265 __u = __extension__ ((void *) __u + 2);
266 __u->__c = __src2_1;
267 __u = __extension__ ((void *) __u + 1);
268 break;
269 case 4:
270 __u->__ui = __src0_4;
271 __u = __extension__ ((void *) __u + 4);
272 break;
273 case 5:
274 __u->__ui = __src0_4;
275 __u = __extension__ ((void *) __u + 4);
276 __u->__c = __src4_1;
277 __u = __extension__ ((void *) __u + 1);
278 break;
279 case 6:
280 __u->__ui = __src0_4;
281 __u = __extension__ ((void *) __u + 4);
282 __u->__usi = __src4_2;
283 __u = __extension__ ((void *) __u + 2);
284 break;
285 case 7:
286 __u->__ui = __src0_4;
287 __u = __extension__ ((void *) __u + 4);
288 __u->__usi = __src4_2;
289 __u = __extension__ ((void *) __u + 2);
290 __u->__c = __src6_1;
291 __u = __extension__ ((void *) __u + 1);
292 break;
293 case 8:
294 __u->__ui = __src0_4;
295 __u = __extension__ ((void *) __u + 4);
296 __u->__ui = __src4_4;
297 __u = __extension__ ((void *) __u + 4);
298 break;
300 return (void *) __u;
302 # else
303 # ifndef _FORCE_INLINES
304 # define __mempcpy_args(src) \
305 ((__const char *) (src))[0], \
306 __extension__ ((__STRING2_COPY_ARR2) \
307 { { ((__const char *) (src))[0], ((__const char *) (src))[1] } }), \
308 __extension__ ((__STRING2_COPY_ARR3) \
309 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
310 ((__const char *) (src))[2] } }), \
311 __extension__ ((__STRING2_COPY_ARR4) \
312 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
313 ((__const char *) (src))[2], ((__const char *) (src))[3] } }), \
314 __extension__ ((__STRING2_COPY_ARR5) \
315 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
316 ((__const char *) (src))[2], ((__const char *) (src))[3], \
317 ((__const char *) (src))[4] } }), \
318 __extension__ ((__STRING2_COPY_ARR6) \
319 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
320 ((__const char *) (src))[2], ((__const char *) (src))[3], \
321 ((__const char *) (src))[4], ((__const char *) (src))[5] } }), \
322 __extension__ ((__STRING2_COPY_ARR7) \
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] } }), \
327 __extension__ ((__STRING2_COPY_ARR8) \
328 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
329 ((__const char *) (src))[2], ((__const char *) (src))[3], \
330 ((__const char *) (src))[4], ((__const char *) (src))[5], \
331 ((__const char *) (src))[6], ((__const char *) (src))[7] } })
332 # endif
333 __STRING_INLINE void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2,
334 __STRING2_COPY_ARR3,
335 __STRING2_COPY_ARR4,
336 __STRING2_COPY_ARR5,
337 __STRING2_COPY_ARR6,
338 __STRING2_COPY_ARR7,
339 __STRING2_COPY_ARR8, size_t);
340 __STRING_INLINE void *
341 __mempcpy_small (void *__dest, char __src1,
342 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
343 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
344 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
345 __STRING2_COPY_ARR8 __src8, size_t __srclen)
347 union {
348 char __c;
349 __STRING2_COPY_ARR2 __sca2;
350 __STRING2_COPY_ARR3 __sca3;
351 __STRING2_COPY_ARR4 __sca4;
352 __STRING2_COPY_ARR5 __sca5;
353 __STRING2_COPY_ARR6 __sca6;
354 __STRING2_COPY_ARR7 __sca7;
355 __STRING2_COPY_ARR8 __sca8;
356 } *__u = __dest;
357 switch ((unsigned int) __srclen)
359 case 1:
360 __u->__c = __src1;
361 break;
362 case 2:
363 __extension__ __u->__sca2 = __src2;
364 break;
365 case 3:
366 __extension__ __u->__sca3 = __src3;
367 break;
368 case 4:
369 __extension__ __u->__sca4 = __src4;
370 break;
371 case 5:
372 __extension__ __u->__sca5 = __src5;
373 break;
374 case 6:
375 __extension__ __u->__sca6 = __src6;
376 break;
377 case 7:
378 __extension__ __u->__sca7 = __src7;
379 break;
380 case 8:
381 __extension__ __u->__sca8 = __src8;
382 break;
384 return __extension__ ((void *) __u + __srclen);
386 # endif
387 # endif
388 # endif
389 #endif
392 /* Return pointer to C in S. */
393 #ifndef _HAVE_STRING_ARCH_strchr
394 extern void *__rawmemchr (const void *__s, int __c);
395 # if __GNUC_PREREQ (3, 2)
396 # define strchr(s, c) \
397 (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \
398 && (c) == '\0' \
399 ? (char *) __rawmemchr (s, c) \
400 : __builtin_strchr (s, c)))
401 # else
402 # define strchr(s, c) \
403 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
404 ? (char *) __rawmemchr (s, c) \
405 : strchr (s, c)))
406 # endif
407 #endif
410 /* Copy SRC to DEST. */
411 #if (!defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)) \
412 || defined _FORCE_INLINES
413 # if !defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)
414 # define strcpy(dest, src) \
415 (__extension__ (__builtin_constant_p (src) \
416 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
417 ? __strcpy_small (dest, __strcpy_args (src), \
418 strlen (src) + 1) \
419 : (char *) memcpy (dest, src, strlen (src) + 1)) \
420 : strcpy (dest, src)))
421 # endif
423 # if _STRING_ARCH_unaligned
424 # ifndef _FORCE_INLINES
425 # define __strcpy_args(src) \
426 __extension__ __STRING2_SMALL_GET16 (src, 0), \
427 __extension__ __STRING2_SMALL_GET16 (src, 4), \
428 __extension__ __STRING2_SMALL_GET32 (src, 0), \
429 __extension__ __STRING2_SMALL_GET32 (src, 4)
430 # endif
431 __STRING_INLINE char *__strcpy_small (char *, __uint16_t, __uint16_t,
432 __uint32_t, __uint32_t, size_t);
433 __STRING_INLINE char *
434 __strcpy_small (char *__dest,
435 __uint16_t __src0_2, __uint16_t __src4_2,
436 __uint32_t __src0_4, __uint32_t __src4_4,
437 size_t __srclen)
439 union {
440 __uint32_t __ui;
441 __uint16_t __usi;
442 unsigned char __uc;
443 } *__u = (void *) __dest;
444 switch ((unsigned int) __srclen)
446 case 1:
447 __u->__uc = '\0';
448 break;
449 case 2:
450 __u->__usi = __src0_2;
451 break;
452 case 3:
453 __u->__usi = __src0_2;
454 __u = __extension__ ((void *) __u + 2);
455 __u->__uc = '\0';
456 break;
457 case 4:
458 __u->__ui = __src0_4;
459 break;
460 case 5:
461 __u->__ui = __src0_4;
462 __u = __extension__ ((void *) __u + 4);
463 __u->__uc = '\0';
464 break;
465 case 6:
466 __u->__ui = __src0_4;
467 __u = __extension__ ((void *) __u + 4);
468 __u->__usi = __src4_2;
469 break;
470 case 7:
471 __u->__ui = __src0_4;
472 __u = __extension__ ((void *) __u + 4);
473 __u->__usi = __src4_2;
474 __u = __extension__ ((void *) __u + 2);
475 __u->__uc = '\0';
476 break;
477 case 8:
478 __u->__ui = __src0_4;
479 __u = __extension__ ((void *) __u + 4);
480 __u->__ui = __src4_4;
481 break;
483 return __dest;
485 # else
486 # ifndef _FORCE_INLINES
487 # define __strcpy_args(src) \
488 __extension__ ((__STRING2_COPY_ARR2) \
489 { { ((__const char *) (src))[0], '\0' } }), \
490 __extension__ ((__STRING2_COPY_ARR3) \
491 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
492 '\0' } }), \
493 __extension__ ((__STRING2_COPY_ARR4) \
494 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
495 ((__const char *) (src))[2], '\0' } }), \
496 __extension__ ((__STRING2_COPY_ARR5) \
497 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
498 ((__const char *) (src))[2], ((__const char *) (src))[3], \
499 '\0' } }), \
500 __extension__ ((__STRING2_COPY_ARR6) \
501 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
502 ((__const char *) (src))[2], ((__const char *) (src))[3], \
503 ((__const char *) (src))[4], '\0' } }), \
504 __extension__ ((__STRING2_COPY_ARR7) \
505 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
506 ((__const char *) (src))[2], ((__const char *) (src))[3], \
507 ((__const char *) (src))[4], ((__const char *) (src))[5], \
508 '\0' } }), \
509 __extension__ ((__STRING2_COPY_ARR8) \
510 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
511 ((__const char *) (src))[2], ((__const char *) (src))[3], \
512 ((__const char *) (src))[4], ((__const char *) (src))[5], \
513 ((__const char *) (src))[6], '\0' } })
514 # endif
515 __STRING_INLINE char *__strcpy_small (char *, __STRING2_COPY_ARR2,
516 __STRING2_COPY_ARR3,
517 __STRING2_COPY_ARR4,
518 __STRING2_COPY_ARR5,
519 __STRING2_COPY_ARR6,
520 __STRING2_COPY_ARR7,
521 __STRING2_COPY_ARR8, size_t);
522 __STRING_INLINE char *
523 __strcpy_small (char *__dest,
524 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
525 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
526 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
527 __STRING2_COPY_ARR8 __src8, size_t __srclen)
529 union {
530 char __c;
531 __STRING2_COPY_ARR2 __sca2;
532 __STRING2_COPY_ARR3 __sca3;
533 __STRING2_COPY_ARR4 __sca4;
534 __STRING2_COPY_ARR5 __sca5;
535 __STRING2_COPY_ARR6 __sca6;
536 __STRING2_COPY_ARR7 __sca7;
537 __STRING2_COPY_ARR8 __sca8;
538 } *__u = (void *) __dest;
539 switch ((unsigned int) __srclen)
541 case 1:
542 __u->__c = '\0';
543 break;
544 case 2:
545 __extension__ __u->__sca2 = __src2;
546 break;
547 case 3:
548 __extension__ __u->__sca3 = __src3;
549 break;
550 case 4:
551 __extension__ __u->__sca4 = __src4;
552 break;
553 case 5:
554 __extension__ __u->__sca5 = __src5;
555 break;
556 case 6:
557 __extension__ __u->__sca6 = __src6;
558 break;
559 case 7:
560 __extension__ __u->__sca7 = __src7;
561 break;
562 case 8:
563 __extension__ __u->__sca8 = __src8;
564 break;
566 return __dest;
568 # endif
569 #endif
572 /* Copy SRC to DEST, returning pointer to final NUL byte. */
573 #ifdef __USE_GNU
574 # if !defined _HAVE_STRING_ARCH_stpcpy || defined _FORCE_INLINES
575 # ifndef _HAVE_STRING_ARCH_stpcpy
576 # if __GNUC_PREREQ (3, 4)
577 # define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
578 # elif __GNUC_PREREQ (3, 0)
579 # define __stpcpy(dest, src) \
580 (__extension__ (__builtin_constant_p (src) \
581 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
582 ? __builtin_strcpy (dest, src) + strlen (src) \
583 : ((char *) (__mempcpy) (dest, src, strlen (src) + 1) \
584 - 1)) \
585 : __stpcpy (dest, src)))
586 # else
587 # define __stpcpy(dest, src) \
588 (__extension__ (__builtin_constant_p (src) \
589 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
590 ? __stpcpy_small (dest, __stpcpy_args (src), \
591 strlen (src) + 1) \
592 : ((char *) (__mempcpy) (dest, src, strlen (src) + 1) \
593 - 1)) \
594 : __stpcpy (dest, src)))
595 # endif
596 /* In glibc we use this function frequently but for namespace reasons
597 we have to use the name `__stpcpy'. */
598 # define stpcpy(dest, src) __stpcpy (dest, src)
599 # endif
601 # if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
602 # if _STRING_ARCH_unaligned
603 # ifndef _FORCE_INLINES
604 # define __stpcpy_args(src) \
605 __extension__ __STRING2_SMALL_GET16 (src, 0), \
606 __extension__ __STRING2_SMALL_GET16 (src, 4), \
607 __extension__ __STRING2_SMALL_GET32 (src, 0), \
608 __extension__ __STRING2_SMALL_GET32 (src, 4)
609 # endif
610 __STRING_INLINE char *__stpcpy_small (char *, __uint16_t, __uint16_t,
611 __uint32_t, __uint32_t, size_t);
612 __STRING_INLINE char *
613 __stpcpy_small (char *__dest,
614 __uint16_t __src0_2, __uint16_t __src4_2,
615 __uint32_t __src0_4, __uint32_t __src4_4,
616 size_t __srclen)
618 union {
619 unsigned int __ui;
620 unsigned short int __usi;
621 unsigned char __uc;
622 char __c;
623 } *__u = (void *) __dest;
624 switch ((unsigned int) __srclen)
626 case 1:
627 __u->__uc = '\0';
628 break;
629 case 2:
630 __u->__usi = __src0_2;
631 __u = __extension__ ((void *) __u + 1);
632 break;
633 case 3:
634 __u->__usi = __src0_2;
635 __u = __extension__ ((void *) __u + 2);
636 __u->__uc = '\0';
637 break;
638 case 4:
639 __u->__ui = __src0_4;
640 __u = __extension__ ((void *) __u + 3);
641 break;
642 case 5:
643 __u->__ui = __src0_4;
644 __u = __extension__ ((void *) __u + 4);
645 __u->__uc = '\0';
646 break;
647 case 6:
648 __u->__ui = __src0_4;
649 __u = __extension__ ((void *) __u + 4);
650 __u->__usi = __src4_2;
651 __u = __extension__ ((void *) __u + 1);
652 break;
653 case 7:
654 __u->__ui = __src0_4;
655 __u = __extension__ ((void *) __u + 4);
656 __u->__usi = __src4_2;
657 __u = __extension__ ((void *) __u + 2);
658 __u->__uc = '\0';
659 break;
660 case 8:
661 __u->__ui = __src0_4;
662 __u = __extension__ ((void *) __u + 4);
663 __u->__ui = __src4_4;
664 __u = __extension__ ((void *) __u + 3);
665 break;
667 return &__u->__c;
669 # else
670 # ifndef _FORCE_INLINES
671 # define __stpcpy_args(src) \
672 __extension__ ((__STRING2_COPY_ARR2) \
673 { { ((__const char *) (src))[0], '\0' } }), \
674 __extension__ ((__STRING2_COPY_ARR3) \
675 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
676 '\0' } }), \
677 __extension__ ((__STRING2_COPY_ARR4) \
678 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
679 ((__const char *) (src))[2], '\0' } }), \
680 __extension__ ((__STRING2_COPY_ARR5) \
681 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
682 ((__const char *) (src))[2], ((__const char *) (src))[3], \
683 '\0' } }), \
684 __extension__ ((__STRING2_COPY_ARR6) \
685 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
686 ((__const char *) (src))[2], ((__const char *) (src))[3], \
687 ((__const char *) (src))[4], '\0' } }), \
688 __extension__ ((__STRING2_COPY_ARR7) \
689 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
690 ((__const char *) (src))[2], ((__const char *) (src))[3], \
691 ((__const char *) (src))[4], ((__const char *) (src))[5], \
692 '\0' } }), \
693 __extension__ ((__STRING2_COPY_ARR8) \
694 { { ((__const char *) (src))[0], ((__const char *) (src))[1], \
695 ((__const char *) (src))[2], ((__const char *) (src))[3], \
696 ((__const char *) (src))[4], ((__const char *) (src))[5], \
697 ((__const char *) (src))[6], '\0' } })
698 # endif
699 __STRING_INLINE char *__stpcpy_small (char *, __STRING2_COPY_ARR2,
700 __STRING2_COPY_ARR3,
701 __STRING2_COPY_ARR4,
702 __STRING2_COPY_ARR5,
703 __STRING2_COPY_ARR6,
704 __STRING2_COPY_ARR7,
705 __STRING2_COPY_ARR8, size_t);
706 __STRING_INLINE char *
707 __stpcpy_small (char *__dest,
708 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
709 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
710 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
711 __STRING2_COPY_ARR8 __src8, size_t __srclen)
713 union {
714 char __c;
715 __STRING2_COPY_ARR2 __sca2;
716 __STRING2_COPY_ARR3 __sca3;
717 __STRING2_COPY_ARR4 __sca4;
718 __STRING2_COPY_ARR5 __sca5;
719 __STRING2_COPY_ARR6 __sca6;
720 __STRING2_COPY_ARR7 __sca7;
721 __STRING2_COPY_ARR8 __sca8;
722 } *__u = (void *) __dest;
723 switch ((unsigned int) __srclen)
725 case 1:
726 __u->__c = '\0';
727 break;
728 case 2:
729 __extension__ __u->__sca2 = __src2;
730 break;
731 case 3:
732 __extension__ __u->__sca3 = __src3;
733 break;
734 case 4:
735 __extension__ __u->__sca4 = __src4;
736 break;
737 case 5:
738 __extension__ __u->__sca5 = __src5;
739 break;
740 case 6:
741 __extension__ __u->__sca6 = __src6;
742 break;
743 case 7:
744 __extension__ __u->__sca7 = __src7;
745 break;
746 case 8:
747 __extension__ __u->__sca8 = __src8;
748 break;
750 return __dest + __srclen - 1;
752 # endif
753 # endif
754 # endif
755 #endif
758 /* Copy no more than N characters of SRC to DEST. */
759 #ifndef _HAVE_STRING_ARCH_strncpy
760 # if __GNUC_PREREQ (3, 2)
761 # define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)
762 # else
763 # define strncpy(dest, src, n) \
764 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
765 ? (strlen (src) + 1 >= ((size_t) (n)) \
766 ? (char *) memcpy (dest, src, n) \
767 : strncpy (dest, src, n)) \
768 : strncpy (dest, src, n)))
769 # endif
770 #endif
773 /* Append no more than N characters from SRC onto DEST. */
774 #ifndef _HAVE_STRING_ARCH_strncat
775 # ifdef _USE_STRING_ARCH_strchr
776 # define strncat(dest, src, n) \
777 (__extension__ ({ char *__dest = (dest); \
778 __builtin_constant_p (src) && __builtin_constant_p (n) \
779 ? (strlen (src) < ((size_t) (n)) \
780 ? strcat (__dest, src) \
781 : (*((char *) __mempcpy (strchr (__dest, '\0'), \
782 src, n)) = '\0', __dest)) \
783 : strncat (dest, src, n); }))
784 # elif __GNUC_PREREQ (3, 2)
785 # define strncat(dest, src, n) __builtin_strncat (dest, src, n)
786 # else
787 # define strncat(dest, src, n) \
788 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
789 ? (strlen (src) < ((size_t) (n)) \
790 ? strcat (dest, src) \
791 : strncat (dest, src, n)) \
792 : strncat (dest, src, n)))
793 # endif
794 #endif
797 /* Compare characters of S1 and S2. */
798 #ifndef _HAVE_STRING_ARCH_strcmp
799 # if __GNUC_PREREQ (3, 2)
800 # define strcmp(s1, s2) \
801 __extension__ \
802 ({ size_t __s1_len, __s2_len; \
803 (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
804 && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
805 (!__string2_1bptr_p (s1) || __s1_len >= 4) \
806 && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
807 ? __builtin_strcmp (s1, s2) \
808 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
809 && (__s1_len = strlen (s1), __s1_len < 4) \
810 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
811 ? __builtin_strcmp (s1, s2) \
812 : __strcmp_cg (s1, s2, __s1_len)) \
813 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
814 && (__s2_len = strlen (s2), __s2_len < 4) \
815 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
816 ? __builtin_strcmp (s1, s2) \
817 : __strcmp_gc (s1, s2, __s2_len)) \
818 : __builtin_strcmp (s1, s2)))); })
819 # else
820 # define strcmp(s1, s2) \
821 __extension__ \
822 ({ size_t __s1_len, __s2_len; \
823 (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
824 && (__s1_len = strlen (s1), __s2_len = strlen (s2), \
825 (!__string2_1bptr_p (s1) || __s1_len >= 4) \
826 && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \
827 ? memcmp ((__const char *) (s1), (__const char *) (s2), \
828 (__s1_len < __s2_len ? __s1_len : __s2_len) + 1) \
829 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
830 && (__s1_len = strlen (s1), __s1_len < 4) \
831 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
832 ? __strcmp_cc (s1, s2, __s1_len) \
833 : __strcmp_cg (s1, s2, __s1_len)) \
834 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
835 && (__s2_len = strlen (s2), __s2_len < 4) \
836 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
837 ? __strcmp_cc (s1, s2, __s2_len) \
838 : __strcmp_gc (s1, s2, __s2_len)) \
839 : strcmp (s1, s2)))); })
840 # endif
842 # define __strcmp_cc(s1, s2, l) \
843 (__extension__ ({ register int __result = \
844 (((__const unsigned char *) (__const char *) (s1))[0] \
845 - ((__const unsigned char *) (__const char *)(s2))[0]);\
846 if (l > 0 && __result == 0) \
848 __result = (((__const unsigned char *) \
849 (__const char *) (s1))[1] \
850 - ((__const unsigned char *) \
851 (__const char *) (s2))[1]); \
852 if (l > 1 && __result == 0) \
854 __result = \
855 (((__const unsigned char *) \
856 (__const char *) (s1))[2] \
857 - ((__const unsigned char *) \
858 (__const char *) (s2))[2]); \
859 if (l > 2 && __result == 0) \
860 __result = \
861 (((__const unsigned char *) \
862 (__const char *) (s1))[3] \
863 - ((__const unsigned char *) \
864 (__const char *) (s2))[3]); \
867 __result; }))
869 # define __strcmp_cg(s1, s2, l1) \
870 (__extension__ ({ __const unsigned char *__s2 = \
871 (__const unsigned char *) (__const char *) (s2); \
872 register int __result = \
873 (((__const unsigned char *) (__const char *) (s1))[0] \
874 - __s2[0]); \
875 if (l1 > 0 && __result == 0) \
877 __result = (((__const unsigned char *) \
878 (__const char *) (s1))[1] - __s2[1]); \
879 if (l1 > 1 && __result == 0) \
881 __result = (((__const unsigned char *) \
882 (__const char *) (s1))[2] - __s2[2]);\
883 if (l1 > 2 && __result == 0) \
884 __result = (((__const unsigned char *) \
885 (__const char *) (s1))[3] \
886 - __s2[3]); \
889 __result; }))
891 # define __strcmp_gc(s1, s2, l2) \
892 (__extension__ ({ __const unsigned char *__s1 = \
893 (__const unsigned char *) (__const char *) (s1); \
894 register int __result = \
895 __s1[0] - ((__const unsigned char *) \
896 (__const char *) (s2))[0]; \
897 if (l2 > 0 && __result == 0) \
899 __result = (__s1[1] \
900 - ((__const unsigned char *) \
901 (__const char *) (s2))[1]); \
902 if (l2 > 1 && __result == 0) \
904 __result = \
905 (__s1[2] - ((__const unsigned char *) \
906 (__const char *) (s2))[2]); \
907 if (l2 > 2 && __result == 0) \
908 __result = \
909 (__s1[3] \
910 - ((__const unsigned char *) \
911 (__const char *) (s2))[3]); \
914 __result; }))
915 #endif
918 /* Compare N characters of S1 and S2. */
919 #ifndef _HAVE_STRING_ARCH_strncmp
920 # define strncmp(s1, s2, n) \
921 (__extension__ (__builtin_constant_p (n) \
922 && ((__builtin_constant_p (s1) \
923 && strlen (s1) < ((size_t) (n))) \
924 || (__builtin_constant_p (s2) \
925 && strlen (s2) < ((size_t) (n)))) \
926 ? strcmp (s1, s2) : strncmp (s1, s2, n)))
927 #endif
930 /* Return the length of the initial segment of S which
931 consists entirely of characters not in REJECT. */
932 #if !defined _HAVE_STRING_ARCH_strcspn || defined _FORCE_INLINES
933 # ifndef _HAVE_STRING_ARCH_strcspn
934 # if __GNUC_PREREQ (3, 2)
935 # define strcspn(s, reject) \
936 __extension__ \
937 ({ char __r0, __r1, __r2; \
938 (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
939 ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
940 ? __builtin_strcspn (s, reject) \
941 : ((__r0 = ((__const char *) (reject))[0], __r0 == '\0') \
942 ? strlen (s) \
943 : ((__r1 = ((__const char *) (reject))[1], __r1 == '\0') \
944 ? __strcspn_c1 (s, __r0) \
945 : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \
946 ? __strcspn_c2 (s, __r0, __r1) \
947 : (((__const char *) (reject))[3] == '\0' \
948 ? __strcspn_c3 (s, __r0, __r1, __r2) \
949 : __builtin_strcspn (s, reject)))))) \
950 : __builtin_strcspn (s, reject)); })
951 # else
952 # define strcspn(s, reject) \
953 __extension__ \
954 ({ char __r0, __r1, __r2; \
955 (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
956 ? ((__r0 = ((__const char *) (reject))[0], __r0 == '\0') \
957 ? strlen (s) \
958 : ((__r1 = ((__const char *) (reject))[1], __r1 == '\0') \
959 ? __strcspn_c1 (s, __r0) \
960 : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \
961 ? __strcspn_c2 (s, __r0, __r1) \
962 : (((__const char *) (reject))[3] == '\0' \
963 ? __strcspn_c3 (s, __r0, __r1, __r2) \
964 : strcspn (s, reject))))) \
965 : strcspn (s, reject)); })
966 # endif
967 # endif
969 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
970 __STRING_INLINE size_t
971 __strcspn_c1 (__const char *__s, int __reject)
973 register size_t __result = 0;
974 while (__s[__result] != '\0' && __s[__result] != __reject)
975 ++__result;
976 return __result;
979 __STRING_INLINE size_t __strcspn_c2 (__const char *__s, int __reject1,
980 int __reject2);
981 __STRING_INLINE size_t
982 __strcspn_c2 (__const char *__s, int __reject1, int __reject2)
984 register size_t __result = 0;
985 while (__s[__result] != '\0' && __s[__result] != __reject1
986 && __s[__result] != __reject2)
987 ++__result;
988 return __result;
991 __STRING_INLINE size_t __strcspn_c3 (__const char *__s, int __reject1,
992 int __reject2, int __reject3);
993 __STRING_INLINE size_t
994 __strcspn_c3 (__const char *__s, int __reject1, int __reject2,
995 int __reject3)
997 register size_t __result = 0;
998 while (__s[__result] != '\0' && __s[__result] != __reject1
999 && __s[__result] != __reject2 && __s[__result] != __reject3)
1000 ++__result;
1001 return __result;
1003 #endif
1006 /* Return the length of the initial segment of S which
1007 consists entirely of characters in ACCEPT. */
1008 #if !defined _HAVE_STRING_ARCH_strspn || defined _FORCE_INLINES
1009 # ifndef _HAVE_STRING_ARCH_strspn
1010 # if __GNUC_PREREQ (3, 2)
1011 # define strspn(s, accept) \
1012 __extension__ \
1013 ({ char __a0, __a1, __a2; \
1014 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
1015 ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
1016 ? __builtin_strspn (s, accept) \
1017 : ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \
1018 ? ((void) (s), 0) \
1019 : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \
1020 ? __strspn_c1 (s, __a0) \
1021 : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \
1022 ? __strspn_c2 (s, __a0, __a1) \
1023 : (((__const char *) (accept))[3] == '\0' \
1024 ? __strspn_c3 (s, __a0, __a1, __a2) \
1025 : __builtin_strspn (s, accept)))))) \
1026 : __builtin_strspn (s, accept)); })
1027 # else
1028 # define strspn(s, accept) \
1029 __extension__ \
1030 ({ char __a0, __a1, __a2; \
1031 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
1032 ? ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \
1033 ? ((void) (s), 0) \
1034 : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \
1035 ? __strspn_c1 (s, __a0) \
1036 : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \
1037 ? __strspn_c2 (s, __a0, __a1) \
1038 : (((__const char *) (accept))[3] == '\0' \
1039 ? __strspn_c3 (s, __a0, __a1, __a2) \
1040 : strspn (s, accept))))) \
1041 : strspn (s, accept)); })
1042 # endif
1043 # endif
1045 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1046 __STRING_INLINE size_t
1047 __strspn_c1 (__const char *__s, int __accept)
1049 register size_t __result = 0;
1050 /* Please note that __accept never can be '\0'. */
1051 while (__s[__result] == __accept)
1052 ++__result;
1053 return __result;
1056 __STRING_INLINE size_t __strspn_c2 (__const char *__s, int __accept1,
1057 int __accept2);
1058 __STRING_INLINE size_t
1059 __strspn_c2 (__const char *__s, int __accept1, int __accept2)
1061 register size_t __result = 0;
1062 /* Please note that __accept1 and __accept2 never can be '\0'. */
1063 while (__s[__result] == __accept1 || __s[__result] == __accept2)
1064 ++__result;
1065 return __result;
1068 __STRING_INLINE size_t __strspn_c3 (__const char *__s, int __accept1,
1069 int __accept2, int __accept3);
1070 __STRING_INLINE size_t
1071 __strspn_c3 (__const char *__s, int __accept1, int __accept2, int __accept3)
1073 register size_t __result = 0;
1074 /* Please note that __accept1 to __accept3 never can be '\0'. */
1075 while (__s[__result] == __accept1 || __s[__result] == __accept2
1076 || __s[__result] == __accept3)
1077 ++__result;
1078 return __result;
1080 #endif
1083 /* Find the first occurrence in S of any character in ACCEPT. */
1084 #if !defined _HAVE_STRING_ARCH_strpbrk || defined _FORCE_INLINES
1085 # ifndef _HAVE_STRING_ARCH_strpbrk
1086 # if __GNUC_PREREQ (3, 2)
1087 # define strpbrk(s, accept) \
1088 __extension__ \
1089 ({ char __a0, __a1, __a2; \
1090 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
1091 ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
1092 ? __builtin_strpbrk (s, accept) \
1093 : ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \
1094 ? ((void) (s), (char *) NULL) \
1095 : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \
1096 ? __builtin_strchr (s, __a0) \
1097 : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \
1098 ? __strpbrk_c2 (s, __a0, __a1) \
1099 : (((__const char *) (accept))[3] == '\0' \
1100 ? __strpbrk_c3 (s, __a0, __a1, __a2) \
1101 : __builtin_strpbrk (s, accept)))))) \
1102 : __builtin_strpbrk (s, accept)); })
1103 # else
1104 # define strpbrk(s, accept) \
1105 __extension__ \
1106 ({ char __a0, __a1, __a2; \
1107 (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
1108 ? ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \
1109 ? ((void) (s), (char *) NULL) \
1110 : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \
1111 ? strchr (s, __a0) \
1112 : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \
1113 ? __strpbrk_c2 (s, __a0, __a1) \
1114 : (((__const char *) (accept))[3] == '\0' \
1115 ? __strpbrk_c3 (s, __a0, __a1, __a2) \
1116 : strpbrk (s, accept))))) \
1117 : strpbrk (s, accept)); })
1118 # endif
1119 # endif
1121 __STRING_INLINE char *__strpbrk_c2 (__const char *__s, int __accept1,
1122 int __accept2);
1123 __STRING_INLINE char *
1124 __strpbrk_c2 (__const char *__s, int __accept1, int __accept2)
1126 /* Please note that __accept1 and __accept2 never can be '\0'. */
1127 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
1128 ++__s;
1129 return *__s == '\0' ? NULL : (char *) (size_t) __s;
1132 __STRING_INLINE char *__strpbrk_c3 (__const char *__s, int __accept1,
1133 int __accept2, int __accept3);
1134 __STRING_INLINE char *
1135 __strpbrk_c3 (__const char *__s, int __accept1, int __accept2,
1136 int __accept3)
1138 /* Please note that __accept1 to __accept3 never can be '\0'. */
1139 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
1140 && *__s != __accept3)
1141 ++__s;
1142 return *__s == '\0' ? NULL : (char *) (size_t) __s;
1144 #endif
1147 /* Find the first occurrence of NEEDLE in HAYSTACK. Newer gcc versions
1148 do this itself. */
1149 #if !defined _HAVE_STRING_ARCH_strstr && !__GNUC_PREREQ (2, 97)
1150 # define strstr(haystack, needle) \
1151 (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
1152 ? (((__const char *) (needle))[0] == '\0' \
1153 ? (char *) (size_t) (haystack) \
1154 : (((__const char *) (needle))[1] == '\0' \
1155 ? strchr (haystack, \
1156 ((__const char *) (needle))[0]) \
1157 : strstr (haystack, needle))) \
1158 : strstr (haystack, needle)))
1159 #endif
1162 #if !defined _HAVE_STRING_ARCH_strtok_r || defined _FORCE_INLINES
1163 # ifndef _HAVE_STRING_ARCH_strtok_r
1164 # define __strtok_r(s, sep, nextp) \
1165 (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \
1166 && ((__const char *) (sep))[0] != '\0' \
1167 && ((__const char *) (sep))[1] == '\0' \
1168 ? __strtok_r_1c (s, ((__const char *) (sep))[0], nextp) \
1169 : __strtok_r (s, sep, nextp)))
1170 # endif
1172 __STRING_INLINE char *__strtok_r_1c (char *__s, char __sep, char **__nextp);
1173 __STRING_INLINE char *
1174 __strtok_r_1c (char *__s, char __sep, char **__nextp)
1176 char *__result;
1177 if (__s == NULL)
1178 __s = *__nextp;
1179 while (*__s == __sep)
1180 ++__s;
1181 __result = NULL;
1182 if (*__s != '\0')
1184 __result = __s++;
1185 while (*__s != '\0')
1186 if (*__s++ == __sep)
1188 __s[-1] = '\0';
1189 break;
1192 *__nextp = __s;
1193 return __result;
1195 # if defined __USE_POSIX || defined __USE_MISC
1196 # define strtok_r(s, sep, nextp) __strtok_r (s, sep, nextp)
1197 # endif
1198 #endif
1201 #if !defined _HAVE_STRING_ARCH_strsep || defined _FORCE_INLINES
1202 # ifndef _HAVE_STRING_ARCH_strsep
1204 extern char *__strsep_g (char **__stringp, __const char *__delim);
1205 # define __strsep(s, reject) \
1206 __extension__ \
1207 ({ char __r0, __r1, __r2; \
1208 (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
1209 && (__r0 = ((__const char *) (reject))[0], \
1210 ((__const char *) (reject))[0] != '\0') \
1211 ? ((__r1 = ((__const char *) (reject))[1], \
1212 ((__const char *) (reject))[1] == '\0') \
1213 ? __strsep_1c (s, __r0) \
1214 : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \
1215 ? __strsep_2c (s, __r0, __r1) \
1216 : (((__const char *) (reject))[3] == '\0' \
1217 ? __strsep_3c (s, __r0, __r1, __r2) \
1218 : __strsep_g (s, reject)))) \
1219 : __strsep_g (s, reject)); })
1220 # endif
1222 __STRING_INLINE char *__strsep_1c (char **__s, char __reject);
1223 __STRING_INLINE char *
1224 __strsep_1c (char **__s, char __reject)
1226 register char *__retval = *__s;
1227 if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
1228 *(*__s)++ = '\0';
1229 return __retval;
1232 __STRING_INLINE char *__strsep_2c (char **__s, char __reject1, char __reject2);
1233 __STRING_INLINE char *
1234 __strsep_2c (char **__s, char __reject1, char __reject2)
1236 register char *__retval = *__s;
1237 if (__retval != NULL)
1239 register char *__cp = __retval;
1240 while (1)
1242 if (*__cp == '\0')
1244 __cp = NULL;
1245 break;
1247 if (*__cp == __reject1 || *__cp == __reject2)
1249 *__cp++ = '\0';
1250 break;
1252 ++__cp;
1254 *__s = __cp;
1256 return __retval;
1259 __STRING_INLINE char *__strsep_3c (char **__s, char __reject1, char __reject2,
1260 char __reject3);
1261 __STRING_INLINE char *
1262 __strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
1264 register char *__retval = *__s;
1265 if (__retval != NULL)
1267 register char *__cp = __retval;
1268 while (1)
1270 if (*__cp == '\0')
1272 __cp = NULL;
1273 break;
1275 if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
1277 *__cp++ = '\0';
1278 break;
1280 ++__cp;
1282 *__s = __cp;
1284 return __retval;
1286 # ifdef __USE_BSD
1287 # define strsep(s, reject) __strsep (s, reject)
1288 # endif
1289 #endif
1291 /* We need the memory allocation functions for inline strdup().
1292 Referring to stdlib.h (even minimally) is not allowed
1293 in any of the tight standards compliant modes. */
1294 #ifdef __USE_MISC
1296 # if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup
1297 # define __need_malloc_and_calloc
1298 # include <stdlib.h>
1299 # endif
1301 # ifndef _HAVE_STRING_ARCH_strdup
1303 extern char *__strdup (__const char *__string) __THROW __attribute_malloc__;
1304 # define __strdup(s) \
1305 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
1306 ? (((__const char *) (s))[0] == '\0' \
1307 ? (char *) calloc ((size_t) 1, (size_t) 1) \
1308 : ({ size_t __len = strlen (s) + 1; \
1309 char *__retval = (char *) malloc (__len); \
1310 if (__retval != NULL) \
1311 __retval = (char *) memcpy (__retval, s, __len); \
1312 __retval; })) \
1313 : __strdup (s)))
1315 # if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1316 # define strdup(s) __strdup (s)
1317 # endif
1318 # endif
1320 # ifndef _HAVE_STRING_ARCH_strndup
1322 extern char *__strndup (__const char *__string, size_t __n)
1323 __THROW __attribute_malloc__;
1324 # define __strndup(s, n) \
1325 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
1326 ? (((__const char *) (s))[0] == '\0' \
1327 ? (char *) calloc ((size_t) 1, (size_t) 1) \
1328 : ({ size_t __len = strlen (s) + 1; \
1329 size_t __n = (n); \
1330 char *__retval; \
1331 if (__n < __len) \
1332 __len = __n + 1; \
1333 __retval = (char *) malloc (__len); \
1334 if (__retval != NULL) \
1336 __retval[__len - 1] = '\0'; \
1337 __retval = (char *) memcpy (__retval, s, \
1338 __len - 1); \
1340 __retval; })) \
1341 : __strndup (s, n)))
1343 # ifdef __USE_GNU
1344 # define strndup(s, n) __strndup (s, n)
1345 # endif
1346 # endif
1348 #endif /* Use misc. or use GNU. */
1350 #ifndef _FORCE_INLINES
1351 # undef __STRING_INLINE
1352 #endif
1354 #endif /* No string inlines. */