Update.
[glibc.git] / string / bits / string2.h
blobc2e63b6ebccbb3c845f1ef963a2d13f6d4419885
1 /* Machine-independant string function optimizations.
2 Copyright (C) 1997 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 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.
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.
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. */
21 #ifndef _STRING_H
22 # error "Never use <bits/string2.h> directly; include <string.h> instead."
23 #endif
25 #ifndef __NO_STRING_INLINES
27 /* Unlike the definitions in the header <bits/string.h> the
28 definitions contained here are not optimizing down to assembler
29 level. These 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 does not dramatically
32 increase the code size and which does 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 later. */
42 #ifdef __cplusplus
43 # define __STRING_INLINE inline
44 #else
45 # define __STRING_INLINE extern __inline
46 #endif
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>
53 # if __BYTE_ORDER == __LITTLE_ENDIAN
54 # define __STRING2_SMALL_GET16(src, idx) \
55 (((src)[idx + 1] << 8) | (src)[idx])
56 # define __STRING2_SMALL_GET32(src, idx) \
57 ((((src)[idx + 3] << 8 | (src)[idx + 2]) << 8 \
58 | (src)[idx + 1]) << 8 | (src)[idx])
59 # else
60 # define __STRING2_SMALL_GET16(src, idx) \
61 (((src)[idx] << 8) | (src)[idx + 1])
62 # define __STRING2_SMALL_GET32(src, idx) \
63 ((((src)[idx] << 8 | (src)[idx + 1]) << 8 \
64 | (src)[idx + 2]) << 8 | (src)[idx + 3])
65 # endif
66 #else
67 /* These are a few types we need for the optimizations if we cannot
68 use unaligned memory accesses. */
69 # define __STRING2_COPY_TYPE(N) \
70 typedef struct { char __arr[N]; } \
71 __STRING2_COPY_ARR##N __attribute__ ((packed))
72 __STRING2_COPY_TYPE (2);
73 __STRING2_COPY_TYPE (3);
74 __STRING2_COPY_TYPE (4);
75 __STRING2_COPY_TYPE (5);
76 __STRING2_COPY_TYPE (6);
77 __STRING2_COPY_TYPE (7);
78 __STRING2_COPY_TYPE (8);
79 # undef __STRING2_COPY_TYPE
80 #endif
82 /* Dereferencing a pointer arg to run sizeof on it fails for the
83 void pointer case, so we use this instead. */
84 #define __string2_1bptr_p(x) (((size_t) ((x) + 1) - (size_t) (x)) == 1)
87 /* Set N bytes of S to C. */
88 #ifndef _HAVE_STRING_ARCH_memset
89 # define memset(s, c, n) \
90 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
91 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
92 : memset (s, c, n)))
93 #endif
96 /* Copy SRC to DEST. */
97 #ifndef _HAVE_STRING_ARCH_strcpy
98 # define strcpy(dest, src) \
99 (__extension__ (__builtin_constant_p (src) \
100 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
101 ? __strcpy_small (dest, src, strlen (src) + 1) \
102 : (char *) memcpy (dest, src, strlen (src) + 1)) \
103 : strcpy (dest, src)))
105 # if _STRING_ARCH_unaligned
106 # define __strcpy_small(dest, src, srclen) \
107 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
108 switch (srclen) \
110 case 1: \
111 *__dest = '\0'; \
112 break; \
113 case 2: \
114 *((__uint16_t *) __dest) = \
115 __STRING2_SMALL_GET16 (src, 0); \
116 break; \
117 case 3: \
118 *((__uint16_t *) __dest) = \
119 __STRING2_SMALL_GET16 (src, 0); \
120 *(__dest + 2) = '\0'; \
121 break; \
122 case 4: \
123 *((__uint32_t *) __dest) = \
124 __STRING2_SMALL_GET32 (src, 0); \
125 break; \
126 case 5: \
127 *((__uint32_t *) __dest) = \
128 __STRING2_SMALL_GET32 (src, 0); \
129 *(__dest + 4) = '\0'; \
130 break; \
131 case 6: \
132 *((__uint32_t *) __dest) = \
133 __STRING2_SMALL_GET32 (src, 0); \
134 *((__uint16_t *) (__dest + 4)) = \
135 __STRING2_SMALL_GET16 (src, 4); \
136 break; \
137 case 7: \
138 *((__uint32_t *) __dest) = \
139 __STRING2_SMALL_GET32 (src, 0); \
140 *((__uint16_t *) (__dest + 4)) = \
141 __STRING2_SMALL_GET16 (src, 4); \
142 *(__dest + 6) = '\0'; \
143 break; \
144 case 8: \
145 *((__uint32_t *) __dest) = \
146 __STRING2_SMALL_GET32 (src, 0); \
147 *((__uint32_t *) (__dest + 4)) = \
148 __STRING2_SMALL_GET32 (src, 4); \
149 break; \
151 (char *) __dest; }))
152 # else
153 # define __strcpy_small(dest, src, srclen) \
154 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
155 switch (srclen) \
157 case 1: \
158 *__dest = '\0'; \
159 break; \
160 case 2: \
161 *((__STRING2_COPY_ARR2 *) __dest) = \
162 ((__STRING2_COPY_ARR2) { { (src)[0], '\0' } }); \
163 break; \
164 case 3: \
165 *((__STRING2_COPY_ARR3 *) __dest) = \
166 ((__STRING2_COPY_ARR3) { { (src)[0], (src)[1], \
167 '\0' } }); \
168 break; \
169 case 4: \
170 *((__STRING2_COPY_ARR4 *) __dest) = \
171 ((__STRING2_COPY_ARR4) { { (src)[0], (src)[1], \
172 (src)[2], '\0' } }); \
173 break; \
174 case 5: \
175 *((__STRING2_COPY_ARR5 *) __dest) = \
176 ((__STRING2_COPY_ARR5) { { (src)[0], (src)[1], \
177 (src)[2], (src)[3], \
178 '\0' } }); \
179 break; \
180 case 6: \
181 *((__STRING2_COPY_ARR6 *) __dest) = \
182 ((__STRING2_COPY_ARR6) { { (src)[0], (src)[1], \
183 (src)[2], (src)[3], \
184 (src)[4], '\0' } }); \
185 break; \
186 case 7: \
187 *((__STRING2_COPY_ARR7 *) __dest) = \
188 ((__STRING2_COPY_ARR7) { { (src)[0], (src)[1], \
189 (src)[2], (src)[3], \
190 (src)[4], (src)[5], \
191 '\0' } }); \
192 break; \
193 case 8: \
194 *((__STRING2_COPY_ARR8 *) __dest) = \
195 ((__STRING2_COPY_ARR8) { { (src)[0], (src)[1], \
196 (src)[2], (src)[3], \
197 (src)[4], (src)[5], \
198 (src)[6], '\0' } }); \
199 break; \
201 (char *) __dest; }))
202 # endif
203 #endif
206 /* Copy SRC to DEST, returning pointer to final NUL byte. */
207 #ifdef __USE_GNU
208 # ifndef _HAVE_STRING_ARCH_stpcpy
209 # define __stpcpy(dest, src) \
210 (__extension__ (__builtin_constant_p (src) \
211 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
212 ? __stpcpy_small (dest, src, strlen (src) + 1) \
213 : ((char *) __mempcpy (dest, src, strlen (src) + 1) - 1))\
214 : __stpcpy (dest, src)))
215 /* In glibc we use this function frequently but for namespace reasons
216 we have to use the name `__stpcpy'. */
217 # define stpcpy(dest, src) __stpcpy (dest, src)
219 # if _STRING_ARCH_unaligned
220 # define __stpcpy_small(dest, src, srclen) \
221 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
222 switch (srclen) \
224 case 1: \
225 *__dest = '\0'; \
226 break; \
227 case 2: \
228 *((__uint16_t *) __dest) = \
229 __STRING2_SMALL_GET16 (src, 0); \
230 ++__dest; \
231 break; \
232 case 3: \
233 *((__uint16_t *) __dest) = \
234 __STRING2_SMALL_GET16 (src, 0); \
235 __dest += sizeof (__uint16_t); \
236 *__dest = '\0'; \
237 break; \
238 case 4: \
239 *((__uint32_t *) __dest) = \
240 __STRING2_SMALL_GET32 (src, 0); \
241 __dest += 3; \
242 break; \
243 case 5: \
244 *((__uint32_t *) __dest) = \
245 __STRING2_SMALL_GET32 (src, 0); \
246 __dest += sizeof (__uint32_t); \
247 *__dest = '\0'; \
248 break; \
249 case 6: \
250 *((__uint32_t *) __dest) = \
251 __STRING2_SMALL_GET32 (src, 0); \
252 *((__uint16_t *) (__dest + 4)) = \
253 __STRING2_SMALL_GET16 (src, 4); \
254 __dest += 5; \
255 break; \
256 case 7: \
257 *((__uint32_t *) __dest) = \
258 __STRING2_SMALL_GET32 (src, 0); \
259 *((__uint16_t *) (__dest + 4)) = \
260 __STRING2_SMALL_GET16 (src, 4); \
261 __dest += 6; \
262 *__dest = '\0'; \
263 break; \
264 case 8: \
265 *((__uint32_t *) __dest) = \
266 __STRING2_SMALL_GET32 (src, 0); \
267 *((__uint32_t *) (__dest + 4)) = \
268 __STRING2_SMALL_GET32 (src, 4); \
269 __dest += 7; \
270 break; \
272 (char *) __dest; }))
273 # else
274 # define __stpcpy_small(dest, src, srclen) \
275 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
276 switch (srclen) \
278 case 1: \
279 *__dest = '\0'; \
280 break; \
281 case 2: \
282 *((__STRING2_COPY_ARR2 *) __dest) = \
283 ((__STRING2_COPY_ARR2) { { (src)[0], '\0' } }); \
284 break; \
285 case 3: \
286 *((__STRING2_COPY_ARR3 *) __dest) = \
287 ((__STRING2_COPY_ARR3) { { (src)[0], (src)[1], \
288 '\0' } }); \
289 break; \
290 case 4: \
291 *((__STRING2_COPY_ARR4 *) __dest) = \
292 ((__STRING2_COPY_ARR4) { { (src)[0], (src)[1], \
293 (src)[2], '\0' } }); \
294 break; \
295 case 5: \
296 *((__STRING2_COPY_ARR5 *) __dest) = \
297 ((__STRING2_COPY_ARR5) { { (src)[0], (src)[1], \
298 (src)[2], (src)[3], \
299 '\0' } }); \
300 break; \
301 case 6: \
302 *((__STRING2_COPY_ARR6 *) __dest) = \
303 ((__STRING2_COPY_ARR6) { { (src)[0], (src)[1], \
304 (src)[2], (src)[3], \
305 (src)[4], '\0' } }); \
306 break; \
307 case 7: \
308 *((__STRING2_COPY_ARR7 *) __dest) = \
309 ((__STRING2_COPY_ARR7) { { (src)[0], (src)[1], \
310 (src)[2], (src)[3], \
311 (src)[4], (src)[5], \
312 '\0' } }); \
313 break; \
314 case 8: \
315 *((__STRING2_COPY_ARR8 *) __dest) = \
316 ((__STRING2_COPY_ARR8) { { (src)[0], (src)[1], \
317 (src)[2], (src)[3], \
318 (src)[4], (src)[5], \
319 (src)[6], '\0' } }); \
320 break; \
322 (char *) (__dest + ((srclen) - 1)); }))
323 # endif
324 # endif
325 #endif
328 /* Copy no more than N characters of SRC to DEST. */
329 #ifndef _HAVE_STRING_ARCH_strncpy
330 # if defined _HAVE_STRING_ARCH_memset && defined _HAVE_STRING_ARCH_mempcpy
331 # define strncpy(dest, src, n) \
332 (__extension__ ({ char *__dest = (dest); \
333 __builtin_constant_p (src) && __builtin_constant_p (n) \
334 ? (strlen (src) + 1 >= ((size_t) (n)) \
335 ? (char *) memcpy (__dest, src, n) \
336 : (memset (__mempcpy (__dest, src, strlen (src)), \
337 '\0', n - strlen (src)), \
338 __dest)) \
339 : strncpy (__dest, src, n); }))
340 # else
341 # define strncpy(dest, src, n) \
342 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
343 ? (strlen (src) + 1 >= ((size_t) (n)) \
344 ? (char *) memcpy (dest, src, n) \
345 : strncpy (dest, src, n)) \
346 : strncpy (dest, src, n)))
347 # endif
348 #endif
351 /* Append no more than N characters from SRC onto DEST. */
352 #ifndef _HAVE_STRING_ARCH_strncat
353 # ifdef _HAVE_STRING_ARCH_strchr
354 # define strncat(dest, src, n) \
355 (__extension__ ({ char *__dest = (dest); \
356 __builtin_constant_p (src) && __builtin_constant_p (n) \
357 ? (strlen (src) < ((size_t) (n)) \
358 ? strcat (__dest, src) \
359 : (memcpy (strchr (__dest, '\0'), src, n), __dest)) \
360 : strncat (dest, src, n); }))
361 # else
362 # define strncat(dest, src, n) \
363 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
364 ? (strlen (src) < ((size_t) (n)) \
365 ? strcat (dest, src) \
366 : strncat (dest, src, n)) \
367 : strncat (dest, src, n)))
368 # endif
369 #endif
372 /* Compare characters of S1 and S2. */
373 #ifndef _HAVE_STRING_ARCH_strcmp
374 # define strcmp(s1, s2) \
375 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
376 && (!__string2_1bptr_p (s1) || strlen (s1) >= 4) \
377 && (!__string2_1bptr_p (s2) || strlen (s2) >= 4) \
378 ? memcmp (s1, s2, (strlen (s1) < strlen (s2) \
379 ? strlen (s1) : strlen (s2)) + 1) \
380 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
381 && __string2_1bptr_p (s2) && strlen (s1) < 4 \
382 ? (__builtin_constant_p (s2) \
383 ? __strcmp_cc (s1, s2, strlen (s1)) \
384 : __strcmp_cg (s1, s2, strlen (s1))) \
385 : (__builtin_constant_p (s2) && __string2_1bptr_p (s1) \
386 && __string2_1bptr_p (s2) && strlen (s2) < 4 \
387 ? (__builtin_constant_p (s1) \
388 ? __strcmp_cc (s1, s2, strlen (s2)) \
389 : __strcmp_gc (s1, s2, strlen (s2))) \
390 : strcmp (s1, s2)))))
392 # define __strcmp_cc(s1, s2, l) \
393 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
394 - (unsigned char) (s2)[0]); \
395 if (l > 0 && __result == 0) \
397 __result = ((unsigned char) (s1)[1] \
398 - (unsigned char) (s2)[1]); \
399 if (l > 1 && __result == 0) \
401 __result = ((unsigned char) (s1)[2] \
402 - (unsigned char) (s2)[2]); \
403 if (l > 2 && __result == 0) \
404 __result = ((unsigned char) (s1)[3] \
405 - (unsigned char) (s2)[3]); \
408 __result; }))
410 # define __strcmp_cg(s1, s2, l1) \
411 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
412 register int __result = (unsigned char) (s1)[0] - __s2[0];\
413 if (l1 > 0 && __result == 0) \
415 __result = (unsigned char) (s1)[1] - __s2[1]; \
416 if (l1 > 1 && __result == 0) \
418 __result = (unsigned char) (s1)[2] - __s2[2]; \
419 if (l1 > 2 && __result == 0) \
420 __result = (unsigned char) (s1)[3] - __s2[3]; \
423 __result; }))
425 # define __strcmp_gc(s1, s2, l2) \
426 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
427 register int __result = __s1[0] - (unsigned char) (s2)[0];\
428 if (l2 > 0 && __result == 0) \
430 __result = __s1[1] - (unsigned char) (s2)[1]; \
431 if (l2 > 1 && __result == 0) \
433 __result = __s1[2] - (unsigned char) (s2)[2]; \
434 if (l2 > 2 && __result == 0) \
435 __result = __s1[3] - (unsigned char) (s2)[3]; \
438 __result; }))
439 #endif
442 /* Compare N characters of S1 and S2. */
443 #ifndef _HAVE_STRING_ARCH_strncmp
444 # define strncmp(s1, s2, n) \
445 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
446 ? strcmp (s1, s2) \
447 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
448 ? strcmp (s1, s2) \
449 : strncmp (s1, s2, n))))
450 #endif
453 /* Return the length of the initial segment of S which
454 consists entirely of characters not in REJECT. */
455 #ifndef _HAVE_STRING_ARCH_strcspn
456 # define strcspn(s, reject) \
457 (__extension__ (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
458 ? ((reject)[0] == '\0' \
459 ? strlen (s) \
460 : ((reject)[1] == '\0' \
461 ? __strcspn_c1 (s, (reject)[0]) \
462 : strcspn (s, reject))) \
463 : strcspn (s, reject)))
465 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, char __reject);
466 __STRING_INLINE size_t
467 __strcspn_c1 (__const char *__s, char __reject)
469 register size_t __result = 0;
470 while (__s[__result] != '\0' && __s[__result] != __reject)
471 ++__result;
472 return __result;
474 #endif
477 /* Return the length of the initial segment of S which
478 consists entirely of characters in ACCEPT. */
479 #ifndef _HAVE_STRING_ARCH_strspn
480 # define strspn(s, accept) \
481 (__extension__ (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
482 ? ((accept)[0] == '\0' \
483 ? 0 \
484 : ((accept)[1] == '\0' \
485 ? __strspn_c1 (s, (accept)[0]) \
486 : strspn (s, accept))) \
487 : strspn (s, accept)))
489 __STRING_INLINE size_t __strspn_c1 (__const char *__s, char __accept);
490 __STRING_INLINE size_t
491 __strspn_c1 (__const char *__s, char __accept)
493 register size_t __result = 0;
494 /* Please note that __accept never can be '\0'. */
495 while (__s[__result] == __accept)
496 ++__result;
497 return __result;
499 #endif
502 /* Find the first occurrence in S of any character in ACCEPT. */
503 #ifndef _HAVE_STRING_ARCH_strpbrk
504 # define strpbrk(s, accept) \
505 (__extension__ (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
506 ? ((accept)[0] == '\0' \
507 ? NULL \
508 : ((accept)[1] == '\0' \
509 ? strchr (s, (accept)[0]) \
510 : strpbrk (s, accept))) \
511 : strpbrk (s, accept)))
512 #endif
515 /* Find the first occurrence of NEEDLE in HAYSTACK. */
516 #ifndef _HAVE_STRING_ARCH_strstr
517 # define strstr(haystack, needle) \
518 (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
519 ? ((needle)[0] == '\0' \
520 ? haystack \
521 : ((needle)[1] == '\0' \
522 ? strchr (haystack, (needle)[0]) \
523 : strstr (haystack, needle))) \
524 : strstr (haystack, needle)))
525 #endif
528 #ifdef __USE_GNU
529 # ifndef _HAVE_STRING_ARCH_strnlen
530 __STRING_INLINE size_t strnlen (__const char *__string, size_t __maxlen);
531 __STRING_INLINE size_t
532 strnlen (__const char *__string, size_t __maxlen)
534 __const char *__end = (__const char *) memchr (__string, '\0', __maxlen);
535 return __end ? __end - __string : __maxlen;
537 # endif
538 #endif
541 #ifdef __USE_BSD
542 # ifndef _HAVE_STRING_ARCH_strsep
544 # define strsep(s, reject) \
545 (__extension__ (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
546 ? ((reject)[0] != '\0' && (reject)[1] == '\0' \
547 ? __strsep_1c (s, (reject)[0]) \
548 : __strsep_g (s, reject)) \
549 : __strsep_g (s, reject)))
551 __STRING_INLINE char *__strsep_1c (char **__s, char __reject);
552 __STRING_INLINE char *
553 __strsep_1c (char **__s, char __reject)
555 register char *__retval = *__s;
556 if (__retval == NULL || *__retval == '\0')
557 return NULL;
558 while (*__retval == __reject)
559 ++__retval;
560 if ((*__s = strchr (__retval, __reject)) != NULL)
561 *(*__s)++ = '\0';
562 return __retval;
565 __STRING_INLINE char *__strsep_g (char **__s, __const char *__reject);
566 __STRING_INLINE char *
567 __strsep_g (char **__s, __const char *__reject)
569 register char *__retval = *__s;
570 if (__retval == NULL || *__retval == '\0')
571 return NULL;
572 if ((*__s = strpbrk (__retval, __reject)) != NULL)
573 *(*__s)++ = '\0';
574 return __retval;
576 # endif
577 #endif
580 #undef __STRING_INLINE
582 #endif /* No string inlines. */