]> git.ipfire.org Git - thirdparty/glibc.git/blame - string/bits/string2.h
Update.
[thirdparty/glibc.git] / string / bits / string2.h
CommitLineData
9a0a462c 1/* Machine-independant string function optimizations.
14c44e2e 2 Copyright (C) 1997, 1998 Free Software Foundation, Inc.
9a0a462c
UD
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
61eb22d3
UD
21#ifndef _STRING_H
22# error "Never use <bits/string2.h> directly; include <string.h> instead."
23#endif
24
650425ce 25#ifndef __NO_STRING_INLINES
9a0a462c
UD
26
27/* Unlike the definitions in the header <bits/string.h> the
61952351
UD
28 definitions contained here are not optimized down to assembler
29 level. Those optimizations are not always a good idea since this
9a0a462c 30 means the code size increases a lot. Instead the definitions here
61952351
UD
31 optimize some functions in a way which do not dramatically
32 increase the code size and which do not use assembler. The main
9a0a462c
UD
33 trick is to use GNU CC's `__builtin_constant_p' function.
34
35 Every function XXX which has a defined version in
61eb22d3 36 <bits/string.h> must be accompanied by a symbol _HAVE_STRING_ARCH_XXX
9a0a462c
UD
37 to make sure we don't get redefinitions.
38
39 We must use here macros instead of inline functions since the
40 trick won't work with the later. */
41
42#ifdef __cplusplus
43# define __STRING_INLINE inline
44#else
45# define __STRING_INLINE extern __inline
46#endif
47
61eb22d3
UD
48#if _STRING_ARCH_unaligned
49/* If we can do unaligned memory accesses we must know the endianess. */
50# include <endian.h>
51# include <bits/types.h>
52
53# if __BYTE_ORDER == __LITTLE_ENDIAN
54# define __STRING2_SMALL_GET16(src, idx) \
fab6d621
UD
55 (((__const unsigned char *) (__const char *) (src))[idx + 1] << 8 \
56 | ((__const unsigned char *) (__const char *) (src))[idx])
61eb22d3 57# define __STRING2_SMALL_GET32(src, idx) \
fab6d621
UD
58 (((((__const unsigned char *) (__const char *) (src))[idx + 3] << 8 \
59 | ((__const unsigned char *) (__const char *) (src))[idx + 2]) << 8 \
60 | ((__const unsigned char *) (__const char *) (src))[idx + 1]) << 8 \
61 | ((__const unsigned char *) (__const char *) (src))[idx])
61eb22d3
UD
62# else
63# define __STRING2_SMALL_GET16(src, idx) \
fab6d621
UD
64 (((__const unsigned char *) (__const char *) (src))[idx] << 8 \
65 | ((__const unsigned char *) (__const char *) (src))[idx + 1])
61eb22d3 66# define __STRING2_SMALL_GET32(src, idx) \
fab6d621
UD
67 (((((__const unsigned char *) (__const char *) (src))[idx] << 8 \
68 | ((__const unsigned char *) (__const char *) (src))[idx + 1]) << 8 \
69 | ((__const unsigned char *) (__const char *) (src))[idx + 2]) << 8 \
70 | ((__const unsigned char *) (__const char *) (src))[idx + 3])
61eb22d3
UD
71# endif
72#else
73/* These are a few types we need for the optimizations if we cannot
74 use unaligned memory accesses. */
75# define __STRING2_COPY_TYPE(N) \
fab6d621 76 typedef struct { unsigned char __arr[N]; } \
61eb22d3
UD
77 __STRING2_COPY_ARR##N __attribute__ ((packed))
78__STRING2_COPY_TYPE (2);
79__STRING2_COPY_TYPE (3);
80__STRING2_COPY_TYPE (4);
81__STRING2_COPY_TYPE (5);
82__STRING2_COPY_TYPE (6);
83__STRING2_COPY_TYPE (7);
84__STRING2_COPY_TYPE (8);
85# undef __STRING2_COPY_TYPE
86#endif
87
7ef90c15
UD
88/* Dereferencing a pointer arg to run sizeof on it fails for the void
89 pointer case, so we use this instead.
90 Note that __x is evaluated twice. */
91#define __string2_1bptr_p(__x) \
92 (({ const void *__a, *__b; __a = (__x) + 1; __b = (__x); \
93 (size_t)__a - (size_t)__b; }) == 1)
61eb22d3
UD
94
95/* Set N bytes of S to C. */
96#ifndef _HAVE_STRING_ARCH_memset
97# define memset(s, c, n) \
98 (__extension__ (__builtin_constant_p (c) && (c) == '\0' \
99 ? ({ void *__s = (s); __bzero (__s, n); __s; }) \
100 : memset (s, c, n)))
101#endif
9a0a462c
UD
102
103
104/* Copy SRC to DEST. */
105#ifndef _HAVE_STRING_ARCH_strcpy
106# define strcpy(dest, src) \
107 (__extension__ (__builtin_constant_p (src) \
dfd2257a 108 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
9a0a462c
UD
109 ? __strcpy_small (dest, src, strlen (src) + 1) \
110 : (char *) memcpy (dest, src, strlen (src) + 1)) \
111 : strcpy (dest, src)))
112
61eb22d3
UD
113# if _STRING_ARCH_unaligned
114# define __strcpy_small(dest, src, srclen) \
fab6d621 115 (__extension__ ({ char *__dest = (char *) (dest); \
61eb22d3
UD
116 switch (srclen) \
117 { \
118 case 1: \
650425ce 119 *__dest = '\0'; \
61eb22d3
UD
120 break; \
121 case 2: \
650425ce 122 *((__uint16_t *) __dest) = \
61eb22d3
UD
123 __STRING2_SMALL_GET16 (src, 0); \
124 break; \
125 case 3: \
650425ce 126 *((__uint16_t *) __dest) = \
61eb22d3 127 __STRING2_SMALL_GET16 (src, 0); \
650425ce 128 *(__dest + 2) = '\0'; \
61eb22d3
UD
129 break; \
130 case 4: \
650425ce 131 *((__uint32_t *) __dest) = \
61eb22d3
UD
132 __STRING2_SMALL_GET32 (src, 0); \
133 break; \
134 case 5: \
650425ce 135 *((__uint32_t *) __dest) = \
61eb22d3 136 __STRING2_SMALL_GET32 (src, 0); \
650425ce 137 *(__dest + 4) = '\0'; \
61eb22d3
UD
138 break; \
139 case 6: \
650425ce 140 *((__uint32_t *) __dest) = \
61eb22d3 141 __STRING2_SMALL_GET32 (src, 0); \
650425ce 142 *((__uint16_t *) (__dest + 4)) = \
61eb22d3
UD
143 __STRING2_SMALL_GET16 (src, 4); \
144 break; \
145 case 7: \
650425ce 146 *((__uint32_t *) __dest) = \
61eb22d3 147 __STRING2_SMALL_GET32 (src, 0); \
650425ce 148 *((__uint16_t *) (__dest + 4)) = \
61eb22d3 149 __STRING2_SMALL_GET16 (src, 4); \
650425ce 150 *(__dest + 6) = '\0'; \
61eb22d3
UD
151 break; \
152 case 8: \
650425ce 153 *((__uint32_t *) __dest) = \
61eb22d3 154 __STRING2_SMALL_GET32 (src, 0); \
650425ce 155 *((__uint32_t *) (__dest + 4)) = \
61eb22d3
UD
156 __STRING2_SMALL_GET32 (src, 4); \
157 break; \
158 } \
fab6d621 159 __dest; }))
61eb22d3
UD
160# else
161# define __strcpy_small(dest, src, srclen) \
fab6d621 162 (__extension__ ({ char *__dest = (char *) (dest); \
61eb22d3
UD
163 switch (srclen) \
164 { \
165 case 1: \
650425ce 166 *__dest = '\0'; \
61eb22d3
UD
167 break; \
168 case 2: \
650425ce 169 *((__STRING2_COPY_ARR2 *) __dest) = \
af6f3906 170 ((__STRING2_COPY_ARR2) \
fab6d621 171 { { ((__const char *) (src))[0], \
af6f3906 172 '\0' } }); \
61eb22d3
UD
173 break; \
174 case 3: \
650425ce 175 *((__STRING2_COPY_ARR3 *) __dest) = \
af6f3906 176 ((__STRING2_COPY_ARR3) \
fab6d621
UD
177 { { ((__const char *) (src))[0], \
178 ((__const char *) (src))[1], \
af6f3906 179 '\0' } }); \
61eb22d3
UD
180 break; \
181 case 4: \
650425ce 182 *((__STRING2_COPY_ARR4 *) __dest) = \
af6f3906 183 ((__STRING2_COPY_ARR4) \
fab6d621
UD
184 { { ((__const char *) (src))[0], \
185 ((__const char *) (src))[1], \
186 ((__const char *) (src))[2], \
af6f3906 187 '\0' } }); \
61eb22d3
UD
188 break; \
189 case 5: \
650425ce 190 *((__STRING2_COPY_ARR5 *) __dest) = \
af6f3906 191 ((__STRING2_COPY_ARR5) \
fab6d621
UD
192 { { ((__const char *) (src))[0], \
193 ((__const char *) (src))[1], \
194 ((__const char *) (src))[2], \
195 ((__const char *) (src))[3], \
af6f3906 196 '\0' } }); \
61eb22d3
UD
197 break; \
198 case 6: \
650425ce 199 *((__STRING2_COPY_ARR6 *) __dest) = \
af6f3906 200 ((__STRING2_COPY_ARR6) \
fab6d621
UD
201 { { ((__const char *) (src))[0], \
202 ((__const char *) (src))[1], \
203 ((__const char *) (src))[2], \
204 ((__const char *) (src))[3], \
205 ((__const char *) (src))[4], \
af6f3906 206 '\0' } }); \
61eb22d3
UD
207 break; \
208 case 7: \
650425ce 209 *((__STRING2_COPY_ARR7 *) __dest) = \
af6f3906 210 ((__STRING2_COPY_ARR7) \
fab6d621
UD
211 { { ((__const char *) (src))[0], \
212 ((__const char *) (src))[1], \
213 ((__const char *) (src))[2], \
214 ((__const char *) (src))[3], \
215 ((__const char *) (src))[4], \
216 ((__const char *) (src))[5], \
af6f3906 217 '\0' } }); \
61eb22d3
UD
218 break; \
219 case 8: \
650425ce 220 *((__STRING2_COPY_ARR8 *) __dest) = \
af6f3906 221 ((__STRING2_COPY_ARR8) \
fab6d621
UD
222 { { ((__const char *) (src))[0], \
223 ((__const char *) (src))[1], \
224 ((__const char *) (src))[2], \
225 ((__const char *) (src))[3], \
226 ((__const char *) (src))[4], \
227 ((__const char *) (src))[5], \
228 ((__const char *) (src))[6], \
af6f3906 229 '\0' } }); \
61eb22d3
UD
230 break; \
231 } \
fab6d621 232 __dest; }))
61eb22d3 233# endif
9a0a462c
UD
234#endif
235
236
237/* Copy SRC to DEST, returning pointer to final NUL byte. */
238#ifdef __USE_GNU
239# ifndef _HAVE_STRING_ARCH_stpcpy
240# define __stpcpy(dest, src) \
241 (__extension__ (__builtin_constant_p (src) \
dfd2257a 242 ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \
9a0a462c
UD
243 ? __stpcpy_small (dest, src, strlen (src) + 1) \
244 : ((char *) __mempcpy (dest, src, strlen (src) + 1) - 1))\
245 : __stpcpy (dest, src)))
246/* In glibc we use this function frequently but for namespace reasons
247 we have to use the name `__stpcpy'. */
248# define stpcpy(dest, src) __stpcpy (dest, src)
249
61eb22d3
UD
250# if _STRING_ARCH_unaligned
251# define __stpcpy_small(dest, src, srclen) \
fab6d621 252 (__extension__ ({ char *__dest = (char *) (dest); \
61eb22d3
UD
253 switch (srclen) \
254 { \
255 case 1: \
650425ce 256 *__dest = '\0'; \
61eb22d3
UD
257 break; \
258 case 2: \
650425ce 259 *((__uint16_t *) __dest) = \
61eb22d3 260 __STRING2_SMALL_GET16 (src, 0); \
650425ce 261 ++__dest; \
61eb22d3
UD
262 break; \
263 case 3: \
a2b08ee5 264 *((__uint16_t *) __dest) = \
61eb22d3 265 __STRING2_SMALL_GET16 (src, 0); \
a2b08ee5 266 __dest += sizeof (__uint16_t); \
650425ce 267 *__dest = '\0'; \
61eb22d3
UD
268 break; \
269 case 4: \
650425ce 270 *((__uint32_t *) __dest) = \
61eb22d3 271 __STRING2_SMALL_GET32 (src, 0); \
650425ce 272 __dest += 3; \
61eb22d3
UD
273 break; \
274 case 5: \
a2b08ee5 275 *((__uint32_t *) __dest) = \
61eb22d3 276 __STRING2_SMALL_GET32 (src, 0); \
a2b08ee5 277 __dest += sizeof (__uint32_t); \
650425ce 278 *__dest = '\0'; \
61eb22d3
UD
279 break; \
280 case 6: \
650425ce 281 *((__uint32_t *) __dest) = \
61eb22d3 282 __STRING2_SMALL_GET32 (src, 0); \
650425ce 283 *((__uint16_t *) (__dest + 4)) = \
61eb22d3 284 __STRING2_SMALL_GET16 (src, 4); \
650425ce 285 __dest += 5; \
61eb22d3
UD
286 break; \
287 case 7: \
650425ce 288 *((__uint32_t *) __dest) = \
61eb22d3 289 __STRING2_SMALL_GET32 (src, 0); \
650425ce 290 *((__uint16_t *) (__dest + 4)) = \
61eb22d3 291 __STRING2_SMALL_GET16 (src, 4); \
650425ce
UD
292 __dest += 6; \
293 *__dest = '\0'; \
61eb22d3
UD
294 break; \
295 case 8: \
650425ce 296 *((__uint32_t *) __dest) = \
61eb22d3 297 __STRING2_SMALL_GET32 (src, 0); \
650425ce 298 *((__uint32_t *) (__dest + 4)) = \
61eb22d3 299 __STRING2_SMALL_GET32 (src, 4); \
650425ce 300 __dest += 7; \
61eb22d3
UD
301 break; \
302 } \
fab6d621 303 __dest; }))
61eb22d3
UD
304# else
305# define __stpcpy_small(dest, src, srclen) \
fab6d621 306 (__extension__ ({ char *__dest = (char *) (dest); \
61eb22d3
UD
307 switch (srclen) \
308 { \
309 case 1: \
650425ce 310 *__dest = '\0'; \
61eb22d3
UD
311 break; \
312 case 2: \
650425ce 313 *((__STRING2_COPY_ARR2 *) __dest) = \
af6f3906 314 ((__STRING2_COPY_ARR2) \
fab6d621 315 { { ((__const char *) (src))[0], \
af6f3906 316 '\0' } }); \
61eb22d3
UD
317 break; \
318 case 3: \
650425ce 319 *((__STRING2_COPY_ARR3 *) __dest) = \
af6f3906 320 ((__STRING2_COPY_ARR3) \
fab6d621
UD
321 { { ((__const char *) (src))[0], \
322 ((__const char *) (src))[1], \
af6f3906 323 '\0' } }); \
61eb22d3
UD
324 break; \
325 case 4: \
650425ce 326 *((__STRING2_COPY_ARR4 *) __dest) = \
af6f3906 327 ((__STRING2_COPY_ARR4) \
fab6d621
UD
328 { { ((__const char *) (src))[0], \
329 ((__const char *) (src))[1], \
330 ((__const char *) (src))[2], \
af6f3906 331 '\0' } }); \
61eb22d3
UD
332 break; \
333 case 5: \
650425ce 334 *((__STRING2_COPY_ARR5 *) __dest) = \
af6f3906 335 ((__STRING2_COPY_ARR5) \
fab6d621
UD
336 { { ((__const char *) (src))[0], \
337 ((__const char *) (src))[1], \
338 ((__const char *) (src))[2], \
339 ((__const char *) (src))[3], \
af6f3906 340 '\0' } }); \
61eb22d3
UD
341 break; \
342 case 6: \
650425ce 343 *((__STRING2_COPY_ARR6 *) __dest) = \
af6f3906 344 ((__STRING2_COPY_ARR6) \
fab6d621
UD
345 { { ((__const char *) (src))[0], \
346 ((__const char *) (src))[1], \
347 ((__const char *) (src))[2], \
348 ((__const char *) (src))[3], \
349 ((__const char *) (src))[4], \
af6f3906 350 '\0' } }); \
61eb22d3
UD
351 break; \
352 case 7: \
650425ce 353 *((__STRING2_COPY_ARR7 *) __dest) = \
af6f3906 354 ((__STRING2_COPY_ARR7) \
fab6d621
UD
355 { { ((__const char *) (src))[0], \
356 ((__const char *) (src))[1], \
357 ((__const char *) (src))[2], \
358 ((__const char *) (src))[3], \
359 ((__const char *) (src))[4], \
360 ((__const char *) (src))[5], \
af6f3906 361 '\0' } }); \
61eb22d3
UD
362 break; \
363 case 8: \
650425ce 364 *((__STRING2_COPY_ARR8 *) __dest) = \
af6f3906 365 ((__STRING2_COPY_ARR8) \
fab6d621
UD
366 { { ((__const char *) (src))[0], \
367 ((__const char *) (src))[1], \
368 ((__const char *) (src))[2], \
369 ((__const char *) (src))[3], \
370 ((__const char *) (src))[4], \
371 ((__const char *) (src))[5], \
372 ((__const char *) (src))[6], \
af6f3906 373 '\0' } }); \
61eb22d3
UD
374 break; \
375 } \
fab6d621 376 __dest + ((srclen) - 1); }))
61eb22d3 377# endif
9a0a462c
UD
378# endif
379#endif
380
381
382/* Copy no more than N characters of SRC to DEST. */
383#ifndef _HAVE_STRING_ARCH_strncpy
384# if defined _HAVE_STRING_ARCH_memset && defined _HAVE_STRING_ARCH_mempcpy
385# define strncpy(dest, src, n) \
650425ce
UD
386 (__extension__ ({ char *__dest = (dest); \
387 __builtin_constant_p (src) && __builtin_constant_p (n) \
388 ? (strlen (src) + 1 >= ((size_t) (n)) \
389 ? (char *) memcpy (__dest, src, n) \
390 : (memset (__mempcpy (__dest, src, strlen (src)), \
391 '\0', n - strlen (src)), \
392 __dest)) \
393 : strncpy (__dest, src, n); }))
9a0a462c
UD
394# else
395# define strncpy(dest, src, n) \
396 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
397 ? (strlen (src) + 1 >= ((size_t) (n)) \
398 ? (char *) memcpy (dest, src, n) \
399 : strncpy (dest, src, n)) \
400 : strncpy (dest, src, n)))
401# endif
402#endif
403
404
405/* Append no more than N characters from SRC onto DEST. */
406#ifndef _HAVE_STRING_ARCH_strncat
407# ifdef _HAVE_STRING_ARCH_strchr
408# define strncat(dest, src, n) \
650425ce
UD
409 (__extension__ ({ char *__dest = (dest); \
410 __builtin_constant_p (src) && __builtin_constant_p (n) \
411 ? (strlen (src) < ((size_t) (n)) \
412 ? strcat (__dest, src) \
413 : (memcpy (strchr (__dest, '\0'), src, n), __dest)) \
414 : strncat (dest, src, n); }))
9a0a462c
UD
415# else
416# define strncat(dest, src, n) \
417 (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
418 ? (strlen (src) < ((size_t) (n)) \
419 ? strcat (dest, src) \
420 : strncat (dest, src, n)) \
421 : strncat (dest, src, n)))
422# endif
423#endif
424
425
650425ce
UD
426/* Compare characters of S1 and S2. */
427#ifndef _HAVE_STRING_ARCH_strcmp
428# define strcmp(s1, s2) \
429 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
dfd2257a
UD
430 && (!__string2_1bptr_p (s1) || strlen (s1) >= 4) \
431 && (!__string2_1bptr_p (s2) || strlen (s2) >= 4) \
c756c71c 432 ? memcmp ((__const char *) (s1), (__const char *) (s2), \
fab6d621
UD
433 (strlen (s1) < strlen (s2) \
434 ? strlen (s1) : strlen (s2)) + 1) \
dfd2257a 435 : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \
da2d1bc5
UD
436 && strlen (s1) < 4 \
437 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
a5a0310d
UD
438 ? __strcmp_cc (s1, s2, strlen (s1)) \
439 : __strcmp_cg (s1, s2, strlen (s1))) \
da2d1bc5
UD
440 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \
441 && strlen (s2) < 4 \
442 ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1)\
a5a0310d
UD
443 ? __strcmp_cc (s1, s2, strlen (s2)) \
444 : __strcmp_gc (s1, s2, strlen (s2))) \
650425ce
UD
445 : strcmp (s1, s2)))))
446
a5a0310d 447# define __strcmp_cc(s1, s2, l) \
af6f3906 448 (__extension__ ({ register int __result = \
fab6d621
UD
449 (((__const unsigned char *) (__const char *) (s1))[0] \
450 - ((__const unsigned char *) (__const char *)(s2))[0]);\
a5a0310d
UD
451 if (l > 0 && __result == 0) \
452 { \
fab6d621
UD
453 __result = (((__const unsigned char *) \
454 (__const char *) (s1))[1] \
455 - ((__const unsigned char *) \
456 (__const char *) (s2))[1]); \
a5a0310d
UD
457 if (l > 1 && __result == 0) \
458 { \
af6f3906 459 __result = \
fab6d621
UD
460 (((__const unsigned char *) \
461 (__const char *) (s1))[2] \
462 - ((__const unsigned char *) \
463 (__const char *) (s2))[2]); \
a5a0310d 464 if (l > 2 && __result == 0) \
af6f3906 465 __result = \
fab6d621
UD
466 (((__const unsigned char *) \
467 (__const char *) (s1))[3] \
468 - ((__const unsigned char *) \
469 (__const char *) (s2))[3]); \
a5a0310d
UD
470 } \
471 } \
472 __result; }))
473
650425ce 474# define __strcmp_cg(s1, s2, l1) \
af6f3906 475 (__extension__ ({ __const unsigned char *__s2 = \
fab6d621 476 (__const unsigned char *) (__const char *) (s2); \
af6f3906 477 register int __result = \
fab6d621
UD
478 (((__const unsigned char *) (__const char *) (s1))[0] \
479 - __s2[0]); \
650425ce
UD
480 if (l1 > 0 && __result == 0) \
481 { \
fab6d621
UD
482 __result = (((__const unsigned char *) \
483 (__const char *) (s1))[1] - __s2[1]); \
650425ce
UD
484 if (l1 > 1 && __result == 0) \
485 { \
fab6d621
UD
486 __result = (((__const unsigned char *) \
487 (__const char *) (s1))[2] - __s2[2]);\
650425ce 488 if (l1 > 2 && __result == 0) \
fab6d621
UD
489 __result = (((__const unsigned char *) \
490 (__const char *) (s1))[3] \
af6f3906 491 - __s2[3]); \
650425ce
UD
492 } \
493 } \
494 __result; }))
495
496# define __strcmp_gc(s1, s2, l2) \
af6f3906 497 (__extension__ ({ __const unsigned char *__s1 = \
fab6d621 498 (__const unsigned char *) (__const char *) (s1); \
af6f3906 499 register int __result = \
fab6d621
UD
500 __s1[0] - ((__const unsigned char *) \
501 (__const char *) (s2))[0]; \
650425ce
UD
502 if (l2 > 0 && __result == 0) \
503 { \
af6f3906 504 __result = (__s1[1] \
fab6d621
UD
505 - ((__const unsigned char *) \
506 (__const char *) (s2))[1]); \
650425ce
UD
507 if (l2 > 1 && __result == 0) \
508 { \
af6f3906 509 __result = \
fab6d621
UD
510 (__s1[2] - ((__const unsigned char *) \
511 (__const char *) (s2))[2]); \
650425ce 512 if (l2 > 2 && __result == 0) \
af6f3906
UD
513 __result = \
514 (__s1[3] \
fab6d621
UD
515 - ((__const unsigned char *) \
516 (__const char *) (s2))[3]); \
650425ce
UD
517 } \
518 } \
519 __result; }))
520#endif
521
522
9a0a462c
UD
523/* Compare N characters of S1 and S2. */
524#ifndef _HAVE_STRING_ARCH_strncmp
525# define strncmp(s1, s2, n) \
526 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
527 ? strcmp (s1, s2) \
528 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
529 ? strcmp (s1, s2) \
530 : strncmp (s1, s2, n))))
531#endif
532
533
534/* Return the length of the initial segment of S which
535 consists entirely of characters not in REJECT. */
536#ifndef _HAVE_STRING_ARCH_strcspn
537# define strcspn(s, reject) \
dfd2257a 538 (__extension__ (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
fab6d621 539 ? (((__const char *) (reject))[0] == '\0' \
9a0a462c 540 ? strlen (s) \
fab6d621 541 : (((__const char *) (reject))[1] == '\0' \
af6f3906 542 ? __strcspn_c1 (s, ((__const char *) (reject))[0]) \
fab6d621 543 : (((__const char *) (reject))[2] == '\0' \
14c44e2e
UD
544 ? __strcspn_c2 (s, ((__const char *) (reject))[0], \
545 ((__const char *) (reject))[1]) \
fab6d621 546 : (((__const char *) (reject))[3] == '\0' \
14c44e2e
UD
547 ? __strcspn_c3 (s, \
548 ((__const char *) (reject))[0], \
549 ((__const char *) (reject))[1], \
550 ((__const char *) (reject))[2]) \
551 : strcspn (s, reject))))) \
9a0a462c
UD
552 : strcspn (s, reject)))
553
61eb22d3 554__STRING_INLINE size_t __strcspn_c1 (__const char *__s, char __reject);
9a0a462c
UD
555__STRING_INLINE size_t
556__strcspn_c1 (__const char *__s, char __reject)
557{
558 register size_t __result = 0;
559 while (__s[__result] != '\0' && __s[__result] != __reject)
560 ++__result;
561 return __result;
562}
14c44e2e
UD
563
564__STRING_INLINE size_t __strcspn_c2 (__const char *__s, char __reject1,
565 char __reject2);
566__STRING_INLINE size_t
567__strcspn_c2 (__const char *__s, char __reject1, char __reject2)
568{
569 register size_t __result = 0;
570 while (__s[__result] != '\0' && __s[__result] != __reject1
571 && __s[__result] != __reject2)
572 ++__result;
573 return __result;
574}
575
576__STRING_INLINE size_t __strcspn_c3 (__const char *__s, char __reject1,
577 char __reject2, char __reject3);
578__STRING_INLINE size_t
579__strcspn_c3 (__const char *__s, char __reject1, char __reject2,
580 char __reject3)
581{
582 register size_t __result = 0;
583 while (__s[__result] != '\0' && __s[__result] != __reject1
584 && __s[__result] != __reject2 && __s[__result] != __reject3)
585 ++__result;
586 return __result;
587}
9a0a462c
UD
588#endif
589
590
591/* Return the length of the initial segment of S which
592 consists entirely of characters in ACCEPT. */
593#ifndef _HAVE_STRING_ARCH_strspn
594# define strspn(s, accept) \
dfd2257a 595 (__extension__ (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
fab6d621 596 ? (((__const char *) (accept))[0] == '\0' \
9a0a462c 597 ? 0 \
fab6d621 598 : (((__const char *) (accept))[1] == '\0' \
af6f3906 599 ? __strspn_c1 (s, ((__const char *) (accept))[0]) \
fab6d621 600 : (((__const char *) (accept))[2] == '\0' \
14c44e2e
UD
601 ? __strspn_c2 (s, ((__const char *) (accept))[0], \
602 ((__const char *) (accept))[1]) \
fab6d621 603 : (((__const char *) (accept))[3] == '\0' \
14c44e2e
UD
604 ? __strspn_c3 (s, \
605 ((__const char *) (accept))[0], \
606 ((__const char *) (accept))[1], \
607 ((__const char *) (accept))[2]) \
608 : strspn (s, accept))))) \
9a0a462c
UD
609 : strspn (s, accept)))
610
61eb22d3 611__STRING_INLINE size_t __strspn_c1 (__const char *__s, char __accept);
9a0a462c
UD
612__STRING_INLINE size_t
613__strspn_c1 (__const char *__s, char __accept)
614{
615 register size_t __result = 0;
616 /* Please note that __accept never can be '\0'. */
617 while (__s[__result] == __accept)
618 ++__result;
619 return __result;
620}
14c44e2e
UD
621
622__STRING_INLINE size_t __strspn_c2 (__const char *__s, char __accept1,
623 char __accept2);
624__STRING_INLINE size_t
625__strspn_c2 (__const char *__s, char __accept1, char __accept2)
626{
627 register size_t __result = 0;
628 /* Please note that __accept1 and __accept2 never can be '\0'. */
629 while (__s[__result] == __accept1 || __s[__result] == __accept2)
630 ++__result;
631 return __result;
632}
633
634__STRING_INLINE size_t __strspn_c3 (__const char *__s, char __accept1,
635 char __accept2, char __accept3);
636__STRING_INLINE size_t
637__strspn_c3 (__const char *__s, char __accept1, char __accept2, char __accept3)
638{
639 register size_t __result = 0;
640 /* Please note that __accept1 to __accept3 never can be '\0'. */
641 while (__s[__result] == __accept1 || __s[__result] == __accept2
642 || __s[__result] == __accept3)
643 ++__result;
644 return __result;
645}
9a0a462c
UD
646#endif
647
648
649/* Find the first occurrence in S of any character in ACCEPT. */
650#ifndef _HAVE_STRING_ARCH_strpbrk
651# define strpbrk(s, accept) \
dfd2257a 652 (__extension__ (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
fab6d621 653 ? (((__const char *) (accept))[0] == '\0' \
9a0a462c 654 ? NULL \
fab6d621
UD
655 : (((__const char *) (accept))[1] == '\0' \
656 ? strchr (s, ((__const char *) (accept))[0]) \
657 : (((__const char *) (accept))[2] == '\0' \
14c44e2e
UD
658 ? __strpbrk_c2 (s, ((__const char *) (accept))[0], \
659 ((__const char *) (accept))[1]) \
fab6d621 660 : (((__const char *) (accept))[3] == '\0' \
14c44e2e
UD
661 ? __strpbrk_c3 (s, \
662 ((__const char *) (accept))[0], \
663 ((__const char *) (accept))[1], \
664 ((__const char *) (accept))[2]) \
665 : strpbrk (s, accept))))) \
9a0a462c 666 : strpbrk (s, accept)))
14c44e2e
UD
667
668__STRING_INLINE char *__strpbrk_c2 (__const char *__s, char __accept1,
669 char __accept2);
670__STRING_INLINE char *
671__strpbrk_c2 (__const char *__s, char __accept1, char __accept2)
672{
673 /* Please note that __accept1 and __accept2 never can be '\0'. */
674 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
675 ++__s;
676 return *__s == '\0' ? NULL : (char *) __s;
677}
678
679__STRING_INLINE char *__strpbrk_c3 (__const char *__s, char __accept1,
680 char __accept2, char __accept3);
681__STRING_INLINE char *
682__strpbrk_c3 (__const char *__s, char __accept1, char __accept2,
683 char __accept3)
684{
685 /* Please note that __accept1 to __accept3 never can be '\0'. */
686 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
687 && *__s != __accept3)
688 ++__s;
689 return *__s == '\0' ? NULL : (char *) __s;
690}
9a0a462c
UD
691#endif
692
693
694/* Find the first occurrence of NEEDLE in HAYSTACK. */
695#ifndef _HAVE_STRING_ARCH_strstr
696# define strstr(haystack, needle) \
dfd2257a 697 (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
fab6d621 698 ? (((__const char *) (needle))[0] == '\0' \
6973fc01 699 ? (char *) (haystack) \
fab6d621 700 : (((__const char *) (needle))[1] == '\0' \
af6f3906 701 ? strchr (haystack, \
fab6d621 702 ((__const char *) (needle))[0]) \
9a0a462c
UD
703 : strstr (haystack, needle))) \
704 : strstr (haystack, needle)))
705#endif
706
707
708#ifdef __USE_GNU
709# ifndef _HAVE_STRING_ARCH_strnlen
61eb22d3
UD
710__STRING_INLINE size_t strnlen (__const char *__string, size_t __maxlen);
711__STRING_INLINE size_t
9a0a462c
UD
712strnlen (__const char *__string, size_t __maxlen)
713{
714 __const char *__end = (__const char *) memchr (__string, '\0', __maxlen);
715 return __end ? __end - __string : __maxlen;
716}
717# endif
718#endif
719
720
31161268
UD
721#ifndef _HAVE_STRING_ARCH_strtok_r
722# define __strtok_r(s, sep, nextp) \
6973fc01 723 (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \
fab6d621
UD
724 ? (((__const char *) (sep))[0] != '\0' \
725 && ((__const char *) (sep))[1] == '\0' \
14c44e2e 726 ? __strtok_r_1c (s, ((__const char *) (sep))[0], nextp) \
7551a1e5
UD
727 : __strtok_r (s, sep, nextp)) \
728 : __strtok_r (s, sep, nextp)))
6973fc01
UD
729
730__STRING_INLINE char *__strtok_r_1c (char *__s, char __sep, char **__nextp);
731__STRING_INLINE char *
732__strtok_r_1c (char *__s, char __sep, char **__nextp)
733{
734 char *__result;
735 if (__s == NULL)
736 __s = *__nextp;
737 while (*__s == __sep)
738 ++__s;
739 if (*__s == '\0')
740 __result = NULL;
741 else
742 {
743 __result = __s;
744 while (*__s != '\0' && *__s != __sep)
745 ++__s;
746 if (*__s == '\0')
747 *__nextp = __s;
748 else
749 {
750 *__s = '\0';
751 *__nextp = __s + 1;
752 }
753 }
754 return __result;
755}
31161268 756# if defined __USE_POSIX || defined __USE_MISC
7551a1e5 757# define strtok_r(s, sep, nextp) __strtok_r ((s), (sep), (nextp))
6973fc01
UD
758# endif
759#endif
760
761
31161268 762#ifndef _HAVE_STRING_ARCH_strsep
61eb22d3 763
31161268 764# define __strsep(s, reject) \
dfd2257a 765 (__extension__ (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
fab6d621
UD
766 && ((__const char *) (reject))[0] != '\0' \
767 ? (((__const char *) (reject))[1] == '\0' \
af6f3906 768 ? __strsep_1c (s, \
14c44e2e 769 ((__const char *) (reject))[0]) \
fab6d621 770 : (((__const char *) (reject))[2] == '\0' \
14c44e2e
UD
771 ? __strsep_2c (s, ((__const char *) (reject))[0], \
772 ((__const char *) (reject))[1]) \
fab6d621 773 : (((__const char *) (reject))[3] == '\0' \
14c44e2e
UD
774 ? __strsep_3c (s, ((__const char *) (reject))[0], \
775 ((__const char *) (reject))[1], \
776 ((__const char *) (reject))[2]) \
777 : __strsep_g (s, reject)))) \
61eb22d3
UD
778 : __strsep_g (s, reject)))
779
780__STRING_INLINE char *__strsep_1c (char **__s, char __reject);
781__STRING_INLINE char *
782__strsep_1c (char **__s, char __reject)
783{
650425ce 784 register char *__retval = *__s;
14c44e2e
UD
785 if (__retval == NULL)
786 return *__s = NULL;
787 if (*__retval == __reject)
61eb22d3 788 *(*__s)++ = '\0';
14c44e2e
UD
789 else
790 if ((*__s = strchr (__retval, __reject)) != NULL)
791 *(*__s)++ = '\0';
792 else
793 *__s = NULL;
794 return __retval;
795}
796
797__STRING_INLINE char *__strsep_2c (char **__s, char __reject1, char __reject2);
798__STRING_INLINE char *
799__strsep_2c (char **__s, char __reject1, char __reject2)
800{
801 register char *__retval = *__s;
802 if (__retval == NULL)
803 return *__s = NULL;
804 if (*__retval == __reject1 || *__retval == __reject2)
805 *(*__s)++ = '\0';
806 else
807 {
808 register char *__cp = __retval;
809 while (*__cp != '\0' && *__cp != __reject1 && *__cp != __reject2)
810 ++__cp;
811 if (*__cp != '\0')
812 {
813 *__s = __cp;
814 *(*__s)++ = '\0';
815 }
816 else
817 *__s = NULL;
818 }
819 return __retval;
820}
821
822__STRING_INLINE char *__strsep_3c (char **__s, char __reject1, char __reject2,
823 char __reject3);
824__STRING_INLINE char *
825__strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
826{
827 register char *__retval = *__s;
828 if (__retval == NULL)
829 return *__s = NULL;
830 if (*__retval == __reject1 || *__retval == __reject2
831 || *__retval == __reject3)
832 *(*__s)++ = '\0';
833 else
834 {
835 register char *__cp = __retval;
836 while (*__cp != '\0' && *__cp != __reject1 && *__cp != __reject2
837 && *__cp != __reject3)
838 ++__cp;
839 if (*__cp != '\0')
840 {
841 *__s = __cp;
842 *(*__s)++ = '\0';
843 }
844 else
845 *__s = NULL;
846 }
650425ce 847 return __retval;
61eb22d3
UD
848}
849
850__STRING_INLINE char *__strsep_g (char **__s, __const char *__reject);
851__STRING_INLINE char *
852__strsep_g (char **__s, __const char *__reject)
853{
650425ce 854 register char *__retval = *__s;
61eb22d3
UD
855 if (__retval == NULL || *__retval == '\0')
856 return NULL;
76fbcfdd 857 if ((*__s = strpbrk (__retval, __reject)) != NULL)
61eb22d3 858 *(*__s)++ = '\0';
650425ce 859 return __retval;
61eb22d3 860}
31161268 861# ifdef __USE_BSD
7551a1e5 862# define strsep(s, reject) __strsep ((s), (reject))
31161268
UD
863# endif
864#endif
865
7ef90c15
UD
866/* We need the memory allocation functions for inline strdup().
867 Referring to stdlib.h (even minimally) is not allowed if
868 __STRICT_ANSI__. */
869#ifndef __STRICT_ANSI__
31161268 870
7ef90c15
UD
871#if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup
872# define __need_malloc_and_calloc
31161268 873# include <stdlib.h>
7ef90c15
UD
874#endif
875
876#ifndef _HAVE_STRING_ARCH_strdup
31161268
UD
877
878# define __strdup(s) \
7551a1e5 879 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
fab6d621 880 ? (((__const char *) (s))[0] == '\0' \
7551a1e5
UD
881 ? (char *) calloc (1, 1) \
882 : ({ size_t __len = strlen (s) + 1; \
883 char *__retval = (char *) malloc (__len); \
884 if (__retval != NULL) \
885 __retval = (char *) memcpy (__retval, s, __len); \
886 __retval; })) \
887 : __strdup (s)))
31161268
UD
888
889# if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
890# define strdup(s) __strdup (s)
61eb22d3
UD
891# endif
892#endif
893
7ef90c15 894#ifndef _HAVE_STRING_ARCH_strndup
7551a1e5
UD
895
896# define __strndup(s, n) \
897 (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \
fab6d621 898 ? (((__const char *) (s))[0] == '\0' \
7551a1e5
UD
899 ? (char *) calloc (1, 1) \
900 : ({ size_t __len = strlen (s) + 1; \
901 size_t __n = (n); \
902 char *__retval; \
903 if (__n < __len) \
904 __len = __n; \
905 __retval = (char *) malloc (__len); \
906 if (__retval != NULL) \
907 { \
908 __retval[__len - 1] = '\0'; \
909 __retval = (char *) memcpy (__retval, s, \
910 __len - 1); \
911 } \
912 __retval; })) \
913 : __strndup ((s), (n))))
914
915# ifdef __GNU_SOURCE
916# define strndup(s, n) __strndup ((s), (n))
917# endif
918#endif
919
7ef90c15 920#endif /* Strict ANSI */
7551a1e5 921
9a0a462c
UD
922#undef __STRING_INLINE
923
61eb22d3 924#endif /* No string inlines. */