c2e63b6ebccbb3c845f1ef963a2d13f6d4419885
[kopensolaris-gnu/glibc.git] / string / bits / string2.h
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.
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
21 #ifndef _STRING_H
22 # error "Never use <bits/string2.h> directly; include <string.h> instead."
23 #endif
24
25 #ifndef __NO_STRING_INLINES
26
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.
34
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.
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
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) \
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
81
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)
85
86
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
94
95
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)))
104
105 # if _STRING_ARCH_unaligned
106 #  define __strcpy_small(dest, src, srclen) \
107   (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);         \
108                     switch (srclen)                                           \
109                       {                                                       \
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;                                                \
150                       }                                                       \
151                     (char *) __dest; }))
152 # else
153 #  define __strcpy_small(dest, src, srclen) \
154   (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);         \
155                     switch (srclen)                                           \
156                       {                                                       \
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;                                                \
200                     }                                                         \
201                   (char *) __dest; }))
202 # endif
203 #endif
204
205
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)
218
219 #  if _STRING_ARCH_unaligned
220 #   define __stpcpy_small(dest, src, srclen) \
221   (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);         \
222                     switch (srclen)                                           \
223                       {                                                       \
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;                                                \
271                       }                                                       \
272                     (char *) __dest; }))
273 #  else
274 #   define __stpcpy_small(dest, src, srclen) \
275   (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);         \
276                     switch (srclen)                                           \
277                       {                                                       \
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;                                                \
321                     }                                                         \
322                   (char *) (__dest + ((srclen) - 1)); }))
323 #  endif
324 # endif
325 #endif
326
327
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
349
350
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
370
371
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)))))
391
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)                               \
396                       {                                                       \
397                         __result = ((unsigned char) (s1)[1]                   \
398                                     - (unsigned char) (s2)[1]);               \
399                         if (l > 1 && __result == 0)                           \
400                           {                                                   \
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]);         \
406                           }                                                   \
407                       }                                                       \
408                     __result; }))
409
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)                              \
414                       {                                                       \
415                         __result = (unsigned char) (s1)[1] - __s2[1];         \
416                         if (l1 > 1 && __result == 0)                          \
417                           {                                                   \
418                             __result = (unsigned char) (s1)[2] - __s2[2];     \
419                             if (l1 > 2 && __result == 0)                      \
420                               __result = (unsigned char) (s1)[3] - __s2[3];   \
421                           }                                                   \
422                       }                                                       \
423                     __result; }))
424
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)                              \
429                       {                                                       \
430                         __result = __s1[1] - (unsigned char) (s2)[1];         \
431                         if (l2 > 1 && __result == 0)                          \
432                           {                                                   \
433                             __result = __s1[2] - (unsigned char) (s2)[2];     \
434                             if (l2 > 2 && __result == 0)                      \
435                               __result = __s1[3] - (unsigned char) (s2)[3];   \
436                           }                                                   \
437                       }                                                       \
438                     __result; }))
439 #endif
440
441
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
451
452
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)))
464
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)
468 {
469   register size_t __result = 0;
470   while (__s[__result] != '\0' && __s[__result] != __reject)
471     ++__result;
472   return __result;
473 }
474 #endif
475
476
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)))
488
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)
492 {
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;
498 }
499 #endif
500
501
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
513
514
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
526
527
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)
533 {
534   __const char *__end = (__const char *) memchr (__string, '\0', __maxlen);
535   return __end ? __end - __string : __maxlen;
536 }
537 # endif
538 #endif
539
540
541 #ifdef __USE_BSD
542 # ifndef _HAVE_STRING_ARCH_strsep
543
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)))
550
551 __STRING_INLINE char *__strsep_1c (char **__s, char __reject);
552 __STRING_INLINE char *
553 __strsep_1c (char **__s, char __reject)
554 {
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;
563 }
564
565 __STRING_INLINE char *__strsep_g (char **__s, __const char *__reject);
566 __STRING_INLINE char *
567 __strsep_g (char **__s, __const char *__reject)
568 {
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;
575 }
576 # endif
577 #endif
578
579
580 #undef __STRING_INLINE
581
582 #endif /* No string inlines.  */