]>
Commit | Line | Data |
---|---|---|
9a0a462c | 1 | /* Machine-independant string function optimizations. |
482eec0d | 2 | Copyright (C) 1997, 1998, 1999 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 | ||
9bbd7837 UD |
42 | #ifndef __STRING_INLINE |
43 | # ifdef __cplusplus | |
44 | # define __STRING_INLINE inline | |
45 | # else | |
46 | # define __STRING_INLINE extern __inline | |
47 | # endif | |
9a0a462c UD |
48 | #endif |
49 | ||
61eb22d3 UD |
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> | |
54 | ||
55 | # if __BYTE_ORDER == __LITTLE_ENDIAN | |
56 | # define __STRING2_SMALL_GET16(src, idx) \ | |
fab6d621 UD |
57 | (((__const unsigned char *) (__const char *) (src))[idx + 1] << 8 \ |
58 | | ((__const unsigned char *) (__const char *) (src))[idx]) | |
61eb22d3 | 59 | # define __STRING2_SMALL_GET32(src, idx) \ |
fab6d621 UD |
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]) | |
61eb22d3 UD |
64 | # else |
65 | # define __STRING2_SMALL_GET16(src, idx) \ | |
fab6d621 UD |
66 | (((__const unsigned char *) (__const char *) (src))[idx] << 8 \ |
67 | | ((__const unsigned char *) (__const char *) (src))[idx + 1]) | |
61eb22d3 | 68 | # define __STRING2_SMALL_GET32(src, idx) \ |
fab6d621 UD |
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]) | |
61eb22d3 UD |
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) \ | |
fab6d621 | 78 | typedef struct { unsigned char __arr[N]; } \ |
61eb22d3 UD |
79 | __STRING2_COPY_ARR##N __attribute__ ((packed)) |
80 | __STRING2_COPY_TYPE (2); | |
81 | __STRING2_COPY_TYPE (3); | |
82 | __STRING2_COPY_TYPE (4); | |
83 | __STRING2_COPY_TYPE (5); | |
84 | __STRING2_COPY_TYPE (6); | |
85 | __STRING2_COPY_TYPE (7); | |
86 | __STRING2_COPY_TYPE (8); | |
87 | # undef __STRING2_COPY_TYPE | |
88 | #endif | |
89 | ||
7ef90c15 UD |
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) \ | |
36ab45e1 | 94 | ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1) |
61eb22d3 UD |
95 | |
96 | /* Set N bytes of S to C. */ | |
97 | #ifndef _HAVE_STRING_ARCH_memset | |
23f5f62d UD |
98 | # if _STRING_ARCH_unaligned |
99 | # define memset(s, c, n) \ | |
99434729 | 100 | (__extension__ (__builtin_constant_p (n) && (n) <= 16 \ |
c1d226e7 UD |
101 | ? ((n) == 1 \ |
102 | ? __memset_1 (s, c) \ | |
6c8f9de3 | 103 | : __memset_gc (s, c, n)) \ |
99434729 UD |
104 | : (__builtin_constant_p (c) && (c) == '\0' \ |
105 | ? ({ void *__s = (s); __bzero (__s, n); __s; }) \ | |
106 | : memset (s, c, n)))) | |
107 | ||
23f5f62d | 108 | # define __memset_1(s, c) ({ void *__s = (s); \ |
6c8f9de3 | 109 | *((__uint8_t *) __s) = (__uint8_t) c; __s; }) |
c1d226e7 | 110 | |
23f5f62d | 111 | # define __memset_gc(s, c, n) \ |
99434729 | 112 | ({ void *__s = (s); \ |
722c33bb UD |
113 | union { \ |
114 | unsigned int __ui; \ | |
115 | unsigned short int __usi; \ | |
116 | unsigned char __uc; \ | |
117 | } *__u = __s; \ | |
6c8f9de3 | 118 | __uint8_t __c = (__uint8_t) (c); \ |
722c33bb | 119 | \ |
99434729 UD |
120 | /* This `switch' statement will be removed at compile-time. */ \ |
121 | switch (n) \ | |
122 | { \ | |
123 | case 15: \ | |
722c33bb | 124 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 125 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 126 | case 11: \ |
722c33bb | 127 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 128 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 129 | case 7: \ |
722c33bb | 130 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 131 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 132 | case 3: \ |
722c33bb | 133 | __u->__usi = (unsigned short int) __c * 0x0101; \ |
87843f15 | 134 | __u = __extension__ ((void *) __u + 2); \ |
722c33bb | 135 | __u->__uc = (unsigned char) __c; \ |
99434729 UD |
136 | break; \ |
137 | \ | |
138 | case 14: \ | |
722c33bb | 139 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 140 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 141 | case 10: \ |
722c33bb | 142 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 143 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 144 | case 6: \ |
722c33bb | 145 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 146 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 147 | case 2: \ |
722c33bb | 148 | __u->__usi = (unsigned short int) __c * 0x0101; \ |
99434729 UD |
149 | break; \ |
150 | \ | |
151 | case 13: \ | |
722c33bb | 152 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 153 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 154 | case 9: \ |
722c33bb | 155 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 156 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 157 | case 5: \ |
722c33bb | 158 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 159 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 160 | case 1: \ |
722c33bb | 161 | __u->__uc = (unsigned char) __c; \ |
99434729 UD |
162 | break; \ |
163 | \ | |
164 | case 16: \ | |
722c33bb | 165 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 166 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 167 | case 12: \ |
722c33bb | 168 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 169 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 170 | case 8: \ |
722c33bb | 171 | __u->__ui = __c * 0x01010101; \ |
87843f15 | 172 | __u = __extension__ ((void *) __u + 4); \ |
99434729 | 173 | case 4: \ |
722c33bb | 174 | __u->__ui = __c * 0x01010101; \ |
99434729 UD |
175 | case 0: \ |
176 | break; \ | |
177 | } \ | |
178 | \ | |
179 | __s; }) | |
23f5f62d UD |
180 | # else |
181 | # define memset(s, c, n) \ | |
182 | (__extension__ (__builtin_constant_p (c) && (c) == '\0' \ | |
183 | ? ({ void *__s = (s); __bzero (__s, n); __s; }) \ | |
184 | : memset (s, c, n))) | |
185 | # endif | |
186 | ||
4360eafd UD |
187 | /* GCC optimizes memset(s, 0, n) but not bzero(s, n). |
188 | The optimization is broken before EGCS 1.1. */ | |
722c33bb | 189 | # if __GNUC_PREREQ (2, 91) |
a97d1494 | 190 | # define __bzero(s, n) __builtin_memset (s, '\0', n) |
23f5f62d | 191 | # endif |
c1d226e7 | 192 | |
61eb22d3 | 193 | #endif |
9a0a462c UD |
194 | |
195 | ||
e7c5513d UD |
196 | /* Copy N bytes from SRC to DEST, returning pointer to byte following the |
197 | last copied. */ | |
198 | #ifdef __USE_GNU | |
199 | # ifndef _HAVE_STRING_ARCH_mempcpy | |
200 | # define __mempcpy(dest, src, n) \ | |
201 | (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \ | |
202 | && __string2_1bptr_p (src) && n <= 8 \ | |
36ab45e1 | 203 | ? __mempcpy_small (dest, __mempcpy_args (src), n) \ |
e7c5513d UD |
204 | : __mempcpy (dest, src, n))) |
205 | /* In glibc we use this function frequently but for namespace reasons | |
206 | we have to use the name `__mempcpy'. */ | |
207 | # define mempcpy(dest, src, n) __mempcpy (dest, src, n) | |
208 | ||
209 | # if _STRING_ARCH_unaligned | |
36ab45e1 UD |
210 | # define __mempcpy_args(src) \ |
211 | ((char *) (src))[0], ((char *) (src))[2], ((char *) (src))[4], \ | |
212 | ((char *) (src))[6], \ | |
213 | __extension__ __STRING2_SMALL_GET16 (src, 0), \ | |
214 | __extension__ __STRING2_SMALL_GET16 (src, 4), \ | |
215 | __extension__ __STRING2_SMALL_GET32 (src, 0), \ | |
216 | __extension__ __STRING2_SMALL_GET32 (src, 4) | |
fcab9698 UD |
217 | __STRING_INLINE void *__mempcpy_small (void *, char, char, char, char, |
218 | __uint16_t, __uint16_t, __uint32_t, | |
219 | __uint32_t, size_t); | |
36ab45e1 UD |
220 | __STRING_INLINE void * |
221 | __mempcpy_small (void *__dest1, | |
222 | char __src0_1, char __src2_1, char __src4_1, char __src6_1, | |
223 | __uint16_t __src0_2, __uint16_t __src4_2, | |
224 | __uint32_t __src0_4, __uint32_t __src4_4, | |
225 | size_t __srclen) | |
226 | { | |
722c33bb UD |
227 | union { |
228 | __uint32_t __ui; | |
229 | __uint16_t __usi; | |
230 | unsigned char __uc; | |
231 | unsigned char __c; | |
232 | } *__u = __dest1; | |
36ab45e1 UD |
233 | switch (__srclen) |
234 | { | |
235 | case 1: | |
722c33bb | 236 | __u->__c = __src0_1; |
87843f15 | 237 | __u = __extension__ ((void *) __u + 1); |
36ab45e1 UD |
238 | break; |
239 | case 2: | |
722c33bb | 240 | __u->__usi = __src0_2; |
87843f15 | 241 | __u = __extension__ ((void *) __u + 2); |
36ab45e1 UD |
242 | break; |
243 | case 3: | |
722c33bb | 244 | __u->__usi = __src0_2; |
87843f15 | 245 | __u = __extension__ ((void *) __u + 2); |
722c33bb | 246 | __u->__c = __src2_1; |
87843f15 | 247 | __u = __extension__ ((void *) __u + 1); |
36ab45e1 UD |
248 | break; |
249 | case 4: | |
722c33bb | 250 | __u->__ui = __src0_4; |
87843f15 | 251 | __u = __extension__ ((void *) __u + 4); |
36ab45e1 UD |
252 | break; |
253 | case 5: | |
722c33bb | 254 | __u->__ui = __src0_4; |
87843f15 | 255 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 256 | __u->__c = __src4_1; |
87843f15 | 257 | __u = __extension__ ((void *) __u + 1); |
36ab45e1 UD |
258 | break; |
259 | case 6: | |
722c33bb | 260 | __u->__ui = __src0_4; |
87843f15 | 261 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 262 | __u->__usi = __src4_2; |
87843f15 | 263 | __u = __extension__ ((void *) __u + 2); |
36ab45e1 UD |
264 | break; |
265 | case 7: | |
722c33bb | 266 | __u->__ui = __src0_4; |
87843f15 | 267 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 268 | __u->__usi = __src4_2; |
87843f15 | 269 | __u = __extension__ ((void *) __u + 2); |
722c33bb | 270 | __u->__c = __src6_1; |
87843f15 | 271 | __u = __extension__ ((void *) __u + 1); |
36ab45e1 UD |
272 | break; |
273 | case 8: | |
722c33bb | 274 | __u->__ui = __src0_4; |
87843f15 | 275 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 276 | __u->__ui = __src4_4; |
87843f15 | 277 | __u = __extension__ ((void *) __u + 4); |
36ab45e1 UD |
278 | break; |
279 | } | |
722c33bb | 280 | return (void *) __u; |
36ab45e1 | 281 | } |
e7c5513d | 282 | # else |
36ab45e1 | 283 | # define __mempcpy_args(src) \ |
431f91ba | 284 | ((__const char *) (src))[0], \ |
36ab45e1 UD |
285 | __extension__ ((__STRING2_COPY_ARR2) \ |
286 | { { ((__const char *) (src))[0], ((__const char *) (src))[1] } }), \ | |
287 | __extension__ ((__STRING2_COPY_ARR3) \ | |
288 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
289 | ((__const char *) (src))[2] } }), \ | |
290 | __extension__ ((__STRING2_COPY_ARR4) \ | |
291 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
292 | ((__const char *) (src))[2], ((__const char *) (src))[3] } }), \ | |
293 | __extension__ ((__STRING2_COPY_ARR5) \ | |
294 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
295 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
296 | ((__const char *) (src))[4] } }), \ | |
297 | __extension__ ((__STRING2_COPY_ARR6) \ | |
298 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
299 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
300 | ((__const char *) (src))[4], ((__const char *) (src))[5] } }), \ | |
301 | __extension__ ((__STRING2_COPY_ARR7) \ | |
302 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
303 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
304 | ((__const char *) (src))[4], ((__const char *) (src))[5], \ | |
305 | ((__const char *) (src))[6] } }), \ | |
306 | __extension__ ((__STRING2_COPY_ARR8) \ | |
307 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
308 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
309 | ((__const char *) (src))[4], ((__const char *) (src))[5], \ | |
310 | ((__const char *) (src))[6], ((__const char *) (src))[7] } }) | |
fcab9698 UD |
311 | __STRING_INLINE void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2, |
312 | __STRING2_COPY_ARR3, | |
313 | __STRING2_COPY_ARR4, | |
314 | __STRING2_COPY_ARR5, | |
315 | __STRING2_COPY_ARR6, | |
316 | __STRING2_COPY_ARR7, | |
317 | __STRING2_COPY_ARR8, size_t); | |
36ab45e1 | 318 | __STRING_INLINE void * |
722c33bb | 319 | __mempcpy_small (void *__dest, char __src1, |
36ab45e1 UD |
320 | __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, |
321 | __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, | |
322 | __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, | |
323 | __STRING2_COPY_ARR8 __src8, size_t __srclen) | |
324 | { | |
722c33bb UD |
325 | union { |
326 | char __c; | |
327 | __STRING2_COPY_ARR2 __sca2; | |
328 | __STRING2_COPY_ARR3 __sca3; | |
329 | __STRING2_COPY_ARR4 __sca4; | |
330 | __STRING2_COPY_ARR5 __sca5; | |
331 | __STRING2_COPY_ARR6 __sca6; | |
332 | __STRING2_COPY_ARR7 __sca7; | |
333 | __STRING2_COPY_ARR8 __sca8; | |
334 | } *__u = __dest; | |
36ab45e1 UD |
335 | switch (__srclen) |
336 | { | |
337 | case 1: | |
722c33bb | 338 | __u->__c = __src1; |
36ab45e1 UD |
339 | break; |
340 | case 2: | |
722c33bb | 341 | __extension__ __u->__sca2 = __src2; |
36ab45e1 UD |
342 | break; |
343 | case 3: | |
722c33bb | 344 | __extension__ __u->__sca3 = __src3; |
36ab45e1 UD |
345 | break; |
346 | case 4: | |
722c33bb | 347 | __extension__ __u->__sca4 = __src4; |
36ab45e1 UD |
348 | break; |
349 | case 5: | |
722c33bb | 350 | __extension__ __u->__sca5 = __src5; |
36ab45e1 UD |
351 | break; |
352 | case 6: | |
722c33bb | 353 | __extension__ __u->__sca6 = __src6; |
36ab45e1 UD |
354 | break; |
355 | case 7: | |
722c33bb | 356 | __extension__ __u->__sca7 = __src7; |
36ab45e1 UD |
357 | break; |
358 | case 8: | |
722c33bb | 359 | __extension__ __u->__sca8 = __src8; |
36ab45e1 UD |
360 | break; |
361 | } | |
722c33bb | 362 | return __extension__ ((void *) __u + __srclen); |
36ab45e1 | 363 | } |
e7c5513d UD |
364 | # endif |
365 | # endif | |
366 | #endif | |
367 | ||
368 | ||
482eec0d UD |
369 | /* Return pointer to C in S. */ |
370 | #ifndef _HAVE_STRING_ARCH_strchr | |
c1422e5b | 371 | extern void *__rawmemchr (const void *__s, int __c); |
482eec0d UD |
372 | # define strchr(s, c) \ |
373 | (__extension__ (__builtin_constant_p (c) && (c) == '\0' \ | |
374 | ? (char *) __rawmemchr (s, c) \ | |
375 | : strchr (s, c))) | |
376 | #endif | |
377 | ||
378 | ||
9a0a462c UD |
379 | /* Copy SRC to DEST. */ |
380 | #ifndef _HAVE_STRING_ARCH_strcpy | |
381 | # define strcpy(dest, src) \ | |
382 | (__extension__ (__builtin_constant_p (src) \ | |
dfd2257a | 383 | ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \ |
36ab45e1 UD |
384 | ? __strcpy_small (dest, __strcpy_args (src), \ |
385 | strlen (src) + 1) \ | |
9a0a462c UD |
386 | : (char *) memcpy (dest, src, strlen (src) + 1)) \ |
387 | : strcpy (dest, src))) | |
388 | ||
61eb22d3 | 389 | # if _STRING_ARCH_unaligned |
36ab45e1 UD |
390 | # define __strcpy_args(src) \ |
391 | __extension__ __STRING2_SMALL_GET16 (src, 0), \ | |
392 | __extension__ __STRING2_SMALL_GET16 (src, 4), \ | |
393 | __extension__ __STRING2_SMALL_GET32 (src, 0), \ | |
394 | __extension__ __STRING2_SMALL_GET32 (src, 4) | |
fcab9698 UD |
395 | __STRING_INLINE char *__strcpy_small (char *, __uint16_t, __uint16_t, |
396 | __uint32_t, __uint32_t, size_t); | |
36ab45e1 UD |
397 | __STRING_INLINE char * |
398 | __strcpy_small (char *__dest, | |
399 | __uint16_t __src0_2, __uint16_t __src4_2, | |
400 | __uint32_t __src0_4, __uint32_t __src4_4, | |
401 | size_t __srclen) | |
402 | { | |
722c33bb UD |
403 | union { |
404 | __uint32_t __ui; | |
405 | __uint16_t __usi; | |
406 | unsigned char __uc; | |
407 | } *__u = (void *) __dest; | |
36ab45e1 UD |
408 | switch (__srclen) |
409 | { | |
410 | case 1: | |
722c33bb | 411 | __u->__uc = '\0'; |
36ab45e1 UD |
412 | break; |
413 | case 2: | |
722c33bb | 414 | __u->__usi = __src0_2; |
36ab45e1 UD |
415 | break; |
416 | case 3: | |
722c33bb | 417 | __u->__usi = __src0_2; |
87843f15 | 418 | __u = __extension__ ((void *) __u + 2); |
722c33bb | 419 | __u->__uc = '\0'; |
36ab45e1 UD |
420 | break; |
421 | case 4: | |
722c33bb | 422 | __u->__ui = __src0_4; |
36ab45e1 UD |
423 | break; |
424 | case 5: | |
722c33bb | 425 | __u->__ui = __src0_4; |
87843f15 | 426 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 427 | __u->__uc = '\0'; |
36ab45e1 UD |
428 | break; |
429 | case 6: | |
722c33bb | 430 | __u->__ui = __src0_4; |
87843f15 | 431 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 432 | __u->__usi = __src4_2; |
36ab45e1 UD |
433 | break; |
434 | case 7: | |
722c33bb | 435 | __u->__ui = __src0_4; |
87843f15 | 436 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 437 | __u->__usi = __src4_2; |
87843f15 | 438 | __u = __extension__ ((void *) __u + 2); |
722c33bb | 439 | __u->__uc = '\0'; |
36ab45e1 UD |
440 | break; |
441 | case 8: | |
722c33bb | 442 | __u->__ui = __src0_4; |
87843f15 | 443 | __u = __extension__ ((void *) __u + 4); |
83f6a990 | 444 | __u->__ui = __src4_4; |
36ab45e1 UD |
445 | break; |
446 | } | |
447 | return __dest; | |
448 | } | |
61eb22d3 | 449 | # else |
36ab45e1 UD |
450 | # define __strcpy_args(src) \ |
451 | __extension__ ((__STRING2_COPY_ARR2) \ | |
452 | { { ((__const char *) (src))[0], '\0' } }), \ | |
453 | __extension__ ((__STRING2_COPY_ARR3) \ | |
454 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
455 | '\0' } }), \ | |
456 | __extension__ ((__STRING2_COPY_ARR4) \ | |
457 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
458 | ((__const char *) (src))[2], '\0' } }), \ | |
459 | __extension__ ((__STRING2_COPY_ARR5) \ | |
460 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
461 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
462 | '\0' } }), \ | |
463 | __extension__ ((__STRING2_COPY_ARR6) \ | |
464 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
465 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
466 | ((__const char *) (src))[4], '\0' } }), \ | |
467 | __extension__ ((__STRING2_COPY_ARR7) \ | |
468 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
469 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
470 | ((__const char *) (src))[4], ((__const char *) (src))[5], \ | |
471 | '\0' } }), \ | |
472 | __extension__ ((__STRING2_COPY_ARR8) \ | |
473 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
474 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
475 | ((__const char *) (src))[4], ((__const char *) (src))[5], \ | |
476 | ((__const char *) (src))[6], '\0' } }) | |
fcab9698 UD |
477 | __STRING_INLINE char *__strcpy_small (char *, __STRING2_COPY_ARR2, |
478 | __STRING2_COPY_ARR3, | |
479 | __STRING2_COPY_ARR4, | |
480 | __STRING2_COPY_ARR5, | |
481 | __STRING2_COPY_ARR6, | |
482 | __STRING2_COPY_ARR7, | |
483 | __STRING2_COPY_ARR8, size_t); | |
36ab45e1 UD |
484 | __STRING_INLINE char * |
485 | __strcpy_small (char *__dest, | |
486 | __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, | |
487 | __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, | |
488 | __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, | |
489 | __STRING2_COPY_ARR8 __src8, size_t __srclen) | |
490 | { | |
722c33bb UD |
491 | union { |
492 | char __c; | |
493 | __STRING2_COPY_ARR2 __sca2; | |
494 | __STRING2_COPY_ARR3 __sca3; | |
495 | __STRING2_COPY_ARR4 __sca4; | |
496 | __STRING2_COPY_ARR5 __sca5; | |
497 | __STRING2_COPY_ARR6 __sca6; | |
498 | __STRING2_COPY_ARR7 __sca7; | |
499 | __STRING2_COPY_ARR8 __sca8; | |
b18ac18e | 500 | } *__u = (void *) __dest; |
36ab45e1 UD |
501 | switch (__srclen) |
502 | { | |
503 | case 1: | |
722c33bb | 504 | __u->__c = '\0'; |
36ab45e1 UD |
505 | break; |
506 | case 2: | |
722c33bb | 507 | __extension__ __u->__sca2 = __src2; |
36ab45e1 UD |
508 | break; |
509 | case 3: | |
722c33bb | 510 | __extension__ __u->__sca3 = __src3; |
36ab45e1 UD |
511 | break; |
512 | case 4: | |
722c33bb | 513 | __extension__ __u->__sca4 = __src4; |
36ab45e1 UD |
514 | break; |
515 | case 5: | |
722c33bb | 516 | __extension__ __u->__sca5 = __src5; |
36ab45e1 UD |
517 | break; |
518 | case 6: | |
722c33bb | 519 | __extension__ __u->__sca6 = __src6; |
36ab45e1 UD |
520 | break; |
521 | case 7: | |
722c33bb | 522 | __extension__ __u->__sca7 = __src7; |
36ab45e1 UD |
523 | break; |
524 | case 8: | |
722c33bb | 525 | __extension__ __u->__sca8 = __src8; |
36ab45e1 UD |
526 | break; |
527 | } | |
528 | return __dest; | |
529 | } | |
61eb22d3 | 530 | # endif |
9a0a462c UD |
531 | #endif |
532 | ||
533 | ||
534 | /* Copy SRC to DEST, returning pointer to final NUL byte. */ | |
535 | #ifdef __USE_GNU | |
536 | # ifndef _HAVE_STRING_ARCH_stpcpy | |
537 | # define __stpcpy(dest, src) \ | |
538 | (__extension__ (__builtin_constant_p (src) \ | |
dfd2257a | 539 | ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 \ |
36ab45e1 UD |
540 | ? __stpcpy_small (dest, __stpcpy_args (src), \ |
541 | strlen (src) + 1) \ | |
9a0a462c UD |
542 | : ((char *) __mempcpy (dest, src, strlen (src) + 1) - 1))\ |
543 | : __stpcpy (dest, src))) | |
544 | /* In glibc we use this function frequently but for namespace reasons | |
545 | we have to use the name `__stpcpy'. */ | |
546 | # define stpcpy(dest, src) __stpcpy (dest, src) | |
547 | ||
61eb22d3 | 548 | # if _STRING_ARCH_unaligned |
36ab45e1 UD |
549 | # define __stpcpy_args(src) \ |
550 | __extension__ __STRING2_SMALL_GET16 (src, 0), \ | |
551 | __extension__ __STRING2_SMALL_GET16 (src, 4), \ | |
552 | __extension__ __STRING2_SMALL_GET32 (src, 0), \ | |
553 | __extension__ __STRING2_SMALL_GET32 (src, 4) | |
fcab9698 UD |
554 | __STRING_INLINE char *__stpcpy_small (char *, __uint16_t, __uint16_t, |
555 | __uint32_t, __uint32_t, size_t); | |
36ab45e1 UD |
556 | __STRING_INLINE char * |
557 | __stpcpy_small (char *__dest, | |
558 | __uint16_t __src0_2, __uint16_t __src4_2, | |
559 | __uint32_t __src0_4, __uint32_t __src4_4, | |
560 | size_t __srclen) | |
561 | { | |
722c33bb UD |
562 | union { |
563 | unsigned int __ui; | |
564 | unsigned short int __usi; | |
565 | unsigned char __uc; | |
566 | } *__u = (void *) __dest; | |
36ab45e1 UD |
567 | switch (__srclen) |
568 | { | |
569 | case 1: | |
722c33bb | 570 | __u->__uc = '\0'; |
36ab45e1 UD |
571 | break; |
572 | case 2: | |
722c33bb | 573 | __u->__usi = __src0_2; |
87843f15 | 574 | __u = __extension__ ((void *) __u + 1); |
36ab45e1 UD |
575 | break; |
576 | case 3: | |
722c33bb | 577 | __u->__usi = __src0_2; |
87843f15 | 578 | __u = __extension__ ((void *) __u + 2); |
722c33bb | 579 | __u->__uc = '\0'; |
36ab45e1 UD |
580 | break; |
581 | case 4: | |
722c33bb | 582 | __u->__ui = __src0_4; |
87843f15 | 583 | __u = __extension__ ((void *) __u + 3); |
36ab45e1 UD |
584 | break; |
585 | case 5: | |
722c33bb | 586 | __u->__ui = __src0_4; |
87843f15 | 587 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 588 | __u->__uc = '\0'; |
36ab45e1 UD |
589 | break; |
590 | case 6: | |
722c33bb | 591 | __u->__ui = __src0_4; |
87843f15 | 592 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 593 | __u->__usi = __src4_2; |
87843f15 | 594 | __u = __extension__ ((void *) __u + 1); |
36ab45e1 UD |
595 | break; |
596 | case 7: | |
722c33bb | 597 | __u->__ui = __src0_4; |
87843f15 | 598 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 599 | __u->__usi = __src4_2; |
87843f15 | 600 | __u = __extension__ ((void *) __u + 2); |
722c33bb | 601 | __u->__uc = '\0'; |
36ab45e1 UD |
602 | break; |
603 | case 8: | |
722c33bb | 604 | __u->__ui = __src0_4; |
87843f15 | 605 | __u = __extension__ ((void *) __u + 4); |
722c33bb | 606 | __u->__ui = __src4_4; |
87843f15 | 607 | __u = __extension__ ((void *) __u + 3); |
36ab45e1 UD |
608 | break; |
609 | } | |
722c33bb | 610 | return &__u->__uc; |
36ab45e1 | 611 | } |
61eb22d3 | 612 | # else |
36ab45e1 UD |
613 | # define __stpcpy_args(src) \ |
614 | __extension__ ((__STRING2_COPY_ARR2) \ | |
615 | { { ((__const char *) (src))[0], '\0' } }), \ | |
616 | __extension__ ((__STRING2_COPY_ARR3) \ | |
617 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
618 | '\0' } }), \ | |
619 | __extension__ ((__STRING2_COPY_ARR4) \ | |
620 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
621 | ((__const char *) (src))[2], '\0' } }), \ | |
622 | __extension__ ((__STRING2_COPY_ARR5) \ | |
623 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
624 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
625 | '\0' } }), \ | |
626 | __extension__ ((__STRING2_COPY_ARR6) \ | |
627 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
628 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
629 | ((__const char *) (src))[4], '\0' } }), \ | |
630 | __extension__ ((__STRING2_COPY_ARR7) \ | |
631 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
632 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
633 | ((__const char *) (src))[4], ((__const char *) (src))[5], \ | |
634 | '\0' } }), \ | |
635 | __extension__ ((__STRING2_COPY_ARR8) \ | |
636 | { { ((__const char *) (src))[0], ((__const char *) (src))[1], \ | |
637 | ((__const char *) (src))[2], ((__const char *) (src))[3], \ | |
638 | ((__const char *) (src))[4], ((__const char *) (src))[5], \ | |
639 | ((__const char *) (src))[6], '\0' } }) | |
fcab9698 UD |
640 | __STRING_INLINE char *__stpcpy_small (char *, __STRING2_COPY_ARR2, |
641 | __STRING2_COPY_ARR3, | |
642 | __STRING2_COPY_ARR4, | |
643 | __STRING2_COPY_ARR5, | |
644 | __STRING2_COPY_ARR6, | |
645 | __STRING2_COPY_ARR7, | |
646 | __STRING2_COPY_ARR8, size_t); | |
36ab45e1 UD |
647 | __STRING_INLINE char * |
648 | __stpcpy_small (char *__dest, | |
649 | __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, | |
650 | __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, | |
651 | __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, | |
652 | __STRING2_COPY_ARR8 __src8, size_t __srclen) | |
653 | { | |
722c33bb UD |
654 | union { |
655 | char __c; | |
656 | __STRING2_COPY_ARR2 __sca2; | |
657 | __STRING2_COPY_ARR3 __sca3; | |
658 | __STRING2_COPY_ARR4 __sca4; | |
659 | __STRING2_COPY_ARR5 __sca5; | |
660 | __STRING2_COPY_ARR6 __sca6; | |
661 | __STRING2_COPY_ARR7 __sca7; | |
662 | __STRING2_COPY_ARR8 __sca8; | |
b18ac18e | 663 | } *__u = (void *) __dest; |
36ab45e1 UD |
664 | switch (__srclen) |
665 | { | |
666 | case 1: | |
b18ac18e | 667 | __u->__c = '\0'; |
36ab45e1 UD |
668 | break; |
669 | case 2: | |
722c33bb | 670 | __extension__ __u->__sca2 = __src2; |
36ab45e1 UD |
671 | break; |
672 | case 3: | |
722c33bb | 673 | __extension__ __u->__sca3 = __src3; |
36ab45e1 UD |
674 | break; |
675 | case 4: | |
722c33bb | 676 | __extension__ __u->__sca4 = __src4; |
36ab45e1 UD |
677 | break; |
678 | case 5: | |
722c33bb | 679 | __extension__ __u->__sca5 = __src5; |
36ab45e1 UD |
680 | break; |
681 | case 6: | |
722c33bb | 682 | __extension__ __u->__sca6 = __src6; |
36ab45e1 UD |
683 | break; |
684 | case 7: | |
722c33bb | 685 | __extension__ __u->__sca7 = __src7; |
36ab45e1 UD |
686 | break; |
687 | case 8: | |
722c33bb | 688 | __extension__ __u->__sca8 = __src8; |
36ab45e1 UD |
689 | break; |
690 | } | |
691 | return __dest + __srclen - 1; | |
692 | } | |
61eb22d3 | 693 | # endif |
9a0a462c UD |
694 | # endif |
695 | #endif | |
696 | ||
697 | ||
698 | /* Copy no more than N characters of SRC to DEST. */ | |
699 | #ifndef _HAVE_STRING_ARCH_strncpy | |
700 | # if defined _HAVE_STRING_ARCH_memset && defined _HAVE_STRING_ARCH_mempcpy | |
701 | # define strncpy(dest, src, n) \ | |
650425ce UD |
702 | (__extension__ ({ char *__dest = (dest); \ |
703 | __builtin_constant_p (src) && __builtin_constant_p (n) \ | |
704 | ? (strlen (src) + 1 >= ((size_t) (n)) \ | |
705 | ? (char *) memcpy (__dest, src, n) \ | |
706 | : (memset (__mempcpy (__dest, src, strlen (src)), \ | |
707 | '\0', n - strlen (src)), \ | |
708 | __dest)) \ | |
709 | : strncpy (__dest, src, n); })) | |
9a0a462c UD |
710 | # else |
711 | # define strncpy(dest, src, n) \ | |
712 | (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \ | |
713 | ? (strlen (src) + 1 >= ((size_t) (n)) \ | |
714 | ? (char *) memcpy (dest, src, n) \ | |
715 | : strncpy (dest, src, n)) \ | |
716 | : strncpy (dest, src, n))) | |
717 | # endif | |
718 | #endif | |
719 | ||
720 | ||
721 | /* Append no more than N characters from SRC onto DEST. */ | |
722 | #ifndef _HAVE_STRING_ARCH_strncat | |
723 | # ifdef _HAVE_STRING_ARCH_strchr | |
724 | # define strncat(dest, src, n) \ | |
650425ce UD |
725 | (__extension__ ({ char *__dest = (dest); \ |
726 | __builtin_constant_p (src) && __builtin_constant_p (n) \ | |
727 | ? (strlen (src) < ((size_t) (n)) \ | |
728 | ? strcat (__dest, src) \ | |
729 | : (memcpy (strchr (__dest, '\0'), src, n), __dest)) \ | |
730 | : strncat (dest, src, n); })) | |
9a0a462c UD |
731 | # else |
732 | # define strncat(dest, src, n) \ | |
733 | (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \ | |
734 | ? (strlen (src) < ((size_t) (n)) \ | |
735 | ? strcat (dest, src) \ | |
736 | : strncat (dest, src, n)) \ | |
737 | : strncat (dest, src, n))) | |
738 | # endif | |
739 | #endif | |
740 | ||
741 | ||
650425ce UD |
742 | /* Compare characters of S1 and S2. */ |
743 | #ifndef _HAVE_STRING_ARCH_strcmp | |
744 | # define strcmp(s1, s2) \ | |
36ab45e1 UD |
745 | __extension__ \ |
746 | ({ size_t __s1_len, __s2_len; \ | |
fcab9698 | 747 | (__builtin_constant_p (s1) && __builtin_constant_p (s2) \ |
36ab45e1 UD |
748 | && (__s1_len = strlen (s1), __s2_len = strlen (s2), \ |
749 | (!__string2_1bptr_p (s1) || __s1_len >= 4) \ | |
750 | && (!__string2_1bptr_p (s2) || __s2_len >= 4)) \ | |
751 | ? memcmp ((__const char *) (s1), (__const char *) (s2), \ | |
752 | (__s1_len < __s2_len ? __s1_len : __s2_len) + 1) \ | |
fcab9698 | 753 | : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \ |
36ab45e1 | 754 | && (__s1_len = strlen (s1), __s1_len < 4) \ |
fcab9698 | 755 | ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \ |
36ab45e1 UD |
756 | ? __strcmp_cc (s1, s2, __s1_len) \ |
757 | : __strcmp_cg (s1, s2, __s1_len)) \ | |
fcab9698 | 758 | : (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \ |
36ab45e1 | 759 | && (__s2_len = strlen (s2), __s2_len < 4) \ |
fcab9698 | 760 | ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \ |
36ab45e1 UD |
761 | ? __strcmp_cc (s1, s2, __s2_len) \ |
762 | : __strcmp_gc (s1, s2, __s2_len)) \ | |
763 | : strcmp (s1, s2)))); }) | |
650425ce | 764 | |
a5a0310d | 765 | # define __strcmp_cc(s1, s2, l) \ |
af6f3906 | 766 | (__extension__ ({ register int __result = \ |
fab6d621 UD |
767 | (((__const unsigned char *) (__const char *) (s1))[0] \ |
768 | - ((__const unsigned char *) (__const char *)(s2))[0]);\ | |
a5a0310d UD |
769 | if (l > 0 && __result == 0) \ |
770 | { \ | |
fab6d621 UD |
771 | __result = (((__const unsigned char *) \ |
772 | (__const char *) (s1))[1] \ | |
773 | - ((__const unsigned char *) \ | |
774 | (__const char *) (s2))[1]); \ | |
a5a0310d UD |
775 | if (l > 1 && __result == 0) \ |
776 | { \ | |
af6f3906 | 777 | __result = \ |
fab6d621 UD |
778 | (((__const unsigned char *) \ |
779 | (__const char *) (s1))[2] \ | |
780 | - ((__const unsigned char *) \ | |
781 | (__const char *) (s2))[2]); \ | |
a5a0310d | 782 | if (l > 2 && __result == 0) \ |
af6f3906 | 783 | __result = \ |
fab6d621 UD |
784 | (((__const unsigned char *) \ |
785 | (__const char *) (s1))[3] \ | |
786 | - ((__const unsigned char *) \ | |
787 | (__const char *) (s2))[3]); \ | |
a5a0310d UD |
788 | } \ |
789 | } \ | |
790 | __result; })) | |
791 | ||
650425ce | 792 | # define __strcmp_cg(s1, s2, l1) \ |
af6f3906 | 793 | (__extension__ ({ __const unsigned char *__s2 = \ |
fab6d621 | 794 | (__const unsigned char *) (__const char *) (s2); \ |
af6f3906 | 795 | register int __result = \ |
fab6d621 UD |
796 | (((__const unsigned char *) (__const char *) (s1))[0] \ |
797 | - __s2[0]); \ | |
650425ce UD |
798 | if (l1 > 0 && __result == 0) \ |
799 | { \ | |
fab6d621 UD |
800 | __result = (((__const unsigned char *) \ |
801 | (__const char *) (s1))[1] - __s2[1]); \ | |
650425ce UD |
802 | if (l1 > 1 && __result == 0) \ |
803 | { \ | |
fab6d621 UD |
804 | __result = (((__const unsigned char *) \ |
805 | (__const char *) (s1))[2] - __s2[2]);\ | |
650425ce | 806 | if (l1 > 2 && __result == 0) \ |
fab6d621 UD |
807 | __result = (((__const unsigned char *) \ |
808 | (__const char *) (s1))[3] \ | |
af6f3906 | 809 | - __s2[3]); \ |
650425ce UD |
810 | } \ |
811 | } \ | |
812 | __result; })) | |
813 | ||
814 | # define __strcmp_gc(s1, s2, l2) \ | |
af6f3906 | 815 | (__extension__ ({ __const unsigned char *__s1 = \ |
fab6d621 | 816 | (__const unsigned char *) (__const char *) (s1); \ |
af6f3906 | 817 | register int __result = \ |
fab6d621 UD |
818 | __s1[0] - ((__const unsigned char *) \ |
819 | (__const char *) (s2))[0]; \ | |
650425ce UD |
820 | if (l2 > 0 && __result == 0) \ |
821 | { \ | |
af6f3906 | 822 | __result = (__s1[1] \ |
fab6d621 UD |
823 | - ((__const unsigned char *) \ |
824 | (__const char *) (s2))[1]); \ | |
650425ce UD |
825 | if (l2 > 1 && __result == 0) \ |
826 | { \ | |
af6f3906 | 827 | __result = \ |
fab6d621 UD |
828 | (__s1[2] - ((__const unsigned char *) \ |
829 | (__const char *) (s2))[2]); \ | |
650425ce | 830 | if (l2 > 2 && __result == 0) \ |
af6f3906 UD |
831 | __result = \ |
832 | (__s1[3] \ | |
fab6d621 UD |
833 | - ((__const unsigned char *) \ |
834 | (__const char *) (s2))[3]); \ | |
650425ce UD |
835 | } \ |
836 | } \ | |
837 | __result; })) | |
838 | #endif | |
839 | ||
840 | ||
9a0a462c UD |
841 | /* Compare N characters of S1 and S2. */ |
842 | #ifndef _HAVE_STRING_ARCH_strncmp | |
d30da2a8 UD |
843 | # define strncmp(s1, s2, n) \ |
844 | (__extension__ (__builtin_constant_p (n) \ | |
845 | && ((__builtin_constant_p (s1) \ | |
846 | && strlen (s1) < ((size_t) (n))) \ | |
847 | || (__builtin_constant_p (s2) \ | |
848 | && strlen (s2) < ((size_t) (n)))) \ | |
849 | ? strcmp (s1, s2) : strncmp (s1, s2, n))) | |
9a0a462c UD |
850 | #endif |
851 | ||
852 | ||
853 | /* Return the length of the initial segment of S which | |
854 | consists entirely of characters not in REJECT. */ | |
855 | #ifndef _HAVE_STRING_ARCH_strcspn | |
856 | # define strcspn(s, reject) \ | |
36ab45e1 UD |
857 | __extension__ \ |
858 | ({ char __r0, __r1, __r2; \ | |
859 | (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \ | |
860 | ? ((__r0 = ((__const char *) (reject))[0], __r0 == '\0') \ | |
861 | ? strlen (s) \ | |
862 | : ((__r1 = ((__const char *) (reject))[1], __r1 == '\0') \ | |
863 | ? __strcspn_c1 (s, __r0) \ | |
864 | : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \ | |
865 | ? __strcspn_c2 (s, __r0, __r1) \ | |
866 | : (((__const char *) (reject))[3] == '\0' \ | |
867 | ? __strcspn_c3 (s, __r0, __r1, __r2) \ | |
868 | : strcspn (s, reject))))) \ | |
869 | : strcspn (s, reject)); }) | |
9a0a462c | 870 | |
61eb22d3 | 871 | __STRING_INLINE size_t __strcspn_c1 (__const char *__s, char __reject); |
9a0a462c UD |
872 | __STRING_INLINE size_t |
873 | __strcspn_c1 (__const char *__s, char __reject) | |
874 | { | |
875 | register size_t __result = 0; | |
876 | while (__s[__result] != '\0' && __s[__result] != __reject) | |
877 | ++__result; | |
878 | return __result; | |
879 | } | |
14c44e2e UD |
880 | |
881 | __STRING_INLINE size_t __strcspn_c2 (__const char *__s, char __reject1, | |
882 | char __reject2); | |
883 | __STRING_INLINE size_t | |
884 | __strcspn_c2 (__const char *__s, char __reject1, char __reject2) | |
885 | { | |
886 | register size_t __result = 0; | |
887 | while (__s[__result] != '\0' && __s[__result] != __reject1 | |
888 | && __s[__result] != __reject2) | |
889 | ++__result; | |
890 | return __result; | |
891 | } | |
892 | ||
893 | __STRING_INLINE size_t __strcspn_c3 (__const char *__s, char __reject1, | |
894 | char __reject2, char __reject3); | |
895 | __STRING_INLINE size_t | |
896 | __strcspn_c3 (__const char *__s, char __reject1, char __reject2, | |
897 | char __reject3) | |
898 | { | |
899 | register size_t __result = 0; | |
900 | while (__s[__result] != '\0' && __s[__result] != __reject1 | |
901 | && __s[__result] != __reject2 && __s[__result] != __reject3) | |
902 | ++__result; | |
903 | return __result; | |
904 | } | |
9a0a462c UD |
905 | #endif |
906 | ||
907 | ||
908 | /* Return the length of the initial segment of S which | |
909 | consists entirely of characters in ACCEPT. */ | |
910 | #ifndef _HAVE_STRING_ARCH_strspn | |
911 | # define strspn(s, accept) \ | |
36ab45e1 UD |
912 | __extension__ \ |
913 | ({ char __a0, __a1, __a2; \ | |
914 | (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \ | |
915 | ? ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \ | |
916 | ? 0 \ | |
917 | : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \ | |
918 | ? __strspn_c1 (s, __a0) \ | |
919 | : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \ | |
920 | ? __strspn_c2 (s, __a0, __a1) \ | |
921 | : (((__const char *) (accept))[3] == '\0' \ | |
922 | ? __strspn_c3 (s, __a0, __a1, __a2) \ | |
923 | : strspn (s, accept))))) \ | |
924 | : strspn (s, accept)); }) | |
9a0a462c | 925 | |
61eb22d3 | 926 | __STRING_INLINE size_t __strspn_c1 (__const char *__s, char __accept); |
9a0a462c UD |
927 | __STRING_INLINE size_t |
928 | __strspn_c1 (__const char *__s, char __accept) | |
929 | { | |
930 | register size_t __result = 0; | |
931 | /* Please note that __accept never can be '\0'. */ | |
932 | while (__s[__result] == __accept) | |
933 | ++__result; | |
934 | return __result; | |
935 | } | |
14c44e2e UD |
936 | |
937 | __STRING_INLINE size_t __strspn_c2 (__const char *__s, char __accept1, | |
938 | char __accept2); | |
939 | __STRING_INLINE size_t | |
940 | __strspn_c2 (__const char *__s, char __accept1, char __accept2) | |
941 | { | |
942 | register size_t __result = 0; | |
943 | /* Please note that __accept1 and __accept2 never can be '\0'. */ | |
944 | while (__s[__result] == __accept1 || __s[__result] == __accept2) | |
945 | ++__result; | |
946 | return __result; | |
947 | } | |
948 | ||
949 | __STRING_INLINE size_t __strspn_c3 (__const char *__s, char __accept1, | |
950 | char __accept2, char __accept3); | |
951 | __STRING_INLINE size_t | |
952 | __strspn_c3 (__const char *__s, char __accept1, char __accept2, char __accept3) | |
953 | { | |
954 | register size_t __result = 0; | |
955 | /* Please note that __accept1 to __accept3 never can be '\0'. */ | |
956 | while (__s[__result] == __accept1 || __s[__result] == __accept2 | |
957 | || __s[__result] == __accept3) | |
958 | ++__result; | |
959 | return __result; | |
960 | } | |
9a0a462c UD |
961 | #endif |
962 | ||
963 | ||
964 | /* Find the first occurrence in S of any character in ACCEPT. */ | |
965 | #ifndef _HAVE_STRING_ARCH_strpbrk | |
966 | # define strpbrk(s, accept) \ | |
36ab45e1 UD |
967 | __extension__ \ |
968 | ({ char __a0, __a1, __a2; \ | |
969 | (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \ | |
970 | ? ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \ | |
971 | ? NULL \ | |
972 | : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \ | |
973 | ? strchr (s, __a0) \ | |
974 | : ((__a2 = ((__const char *) (accept))[2], __a2 == '\0') \ | |
975 | ? __strpbrk_c2 (s, __a0, __a1) \ | |
976 | : (((__const char *) (accept))[3] == '\0' \ | |
977 | ? __strpbrk_c3 (s, __a0, __a1, __a2) \ | |
978 | : strpbrk (s, accept))))) \ | |
979 | : strpbrk (s, accept)); }) | |
14c44e2e UD |
980 | |
981 | __STRING_INLINE char *__strpbrk_c2 (__const char *__s, char __accept1, | |
982 | char __accept2); | |
983 | __STRING_INLINE char * | |
984 | __strpbrk_c2 (__const char *__s, char __accept1, char __accept2) | |
985 | { | |
986 | /* Please note that __accept1 and __accept2 never can be '\0'. */ | |
987 | while (*__s != '\0' && *__s != __accept1 && *__s != __accept2) | |
988 | ++__s; | |
d2537a47 | 989 | return *__s == '\0' ? NULL : (char *) (size_t) __s; |
14c44e2e UD |
990 | } |
991 | ||
992 | __STRING_INLINE char *__strpbrk_c3 (__const char *__s, char __accept1, | |
993 | char __accept2, char __accept3); | |
994 | __STRING_INLINE char * | |
995 | __strpbrk_c3 (__const char *__s, char __accept1, char __accept2, | |
996 | char __accept3) | |
997 | { | |
998 | /* Please note that __accept1 to __accept3 never can be '\0'. */ | |
999 | while (*__s != '\0' && *__s != __accept1 && *__s != __accept2 | |
1000 | && *__s != __accept3) | |
1001 | ++__s; | |
d2537a47 | 1002 | return *__s == '\0' ? NULL : (char *) (size_t) __s; |
14c44e2e | 1003 | } |
9a0a462c UD |
1004 | #endif |
1005 | ||
1006 | ||
1007 | /* Find the first occurrence of NEEDLE in HAYSTACK. */ | |
1008 | #ifndef _HAVE_STRING_ARCH_strstr | |
1009 | # define strstr(haystack, needle) \ | |
dfd2257a | 1010 | (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \ |
fab6d621 | 1011 | ? (((__const char *) (needle))[0] == '\0' \ |
d2537a47 | 1012 | ? (char *) (size_t) (haystack) \ |
fab6d621 | 1013 | : (((__const char *) (needle))[1] == '\0' \ |
af6f3906 | 1014 | ? strchr (haystack, \ |
fab6d621 | 1015 | ((__const char *) (needle))[0]) \ |
9a0a462c UD |
1016 | : strstr (haystack, needle))) \ |
1017 | : strstr (haystack, needle))) | |
1018 | #endif | |
1019 | ||
1020 | ||
9bbd7837 | 1021 | #if defined __USE_GNU && !defined _FORCE_INLINES |
9a0a462c | 1022 | # ifndef _HAVE_STRING_ARCH_strnlen |
61eb22d3 | 1023 | __STRING_INLINE size_t |
9a0a462c UD |
1024 | strnlen (__const char *__string, size_t __maxlen) |
1025 | { | |
1026 | __const char *__end = (__const char *) memchr (__string, '\0', __maxlen); | |
1027 | return __end ? __end - __string : __maxlen; | |
1028 | } | |
1029 | # endif | |
1030 | #endif | |
1031 | ||
1032 | ||
31161268 UD |
1033 | #ifndef _HAVE_STRING_ARCH_strtok_r |
1034 | # define __strtok_r(s, sep, nextp) \ | |
6973fc01 | 1035 | (__extension__ (__builtin_constant_p (sep) && __string2_1bptr_p (sep) \ |
fab6d621 UD |
1036 | ? (((__const char *) (sep))[0] != '\0' \ |
1037 | && ((__const char *) (sep))[1] == '\0' \ | |
14c44e2e | 1038 | ? __strtok_r_1c (s, ((__const char *) (sep))[0], nextp) \ |
7551a1e5 UD |
1039 | : __strtok_r (s, sep, nextp)) \ |
1040 | : __strtok_r (s, sep, nextp))) | |
6973fc01 UD |
1041 | |
1042 | __STRING_INLINE char *__strtok_r_1c (char *__s, char __sep, char **__nextp); | |
1043 | __STRING_INLINE char * | |
1044 | __strtok_r_1c (char *__s, char __sep, char **__nextp) | |
1045 | { | |
1046 | char *__result; | |
1047 | if (__s == NULL) | |
1048 | __s = *__nextp; | |
1049 | while (*__s == __sep) | |
1050 | ++__s; | |
1051 | if (*__s == '\0') | |
1052 | __result = NULL; | |
1053 | else | |
1054 | { | |
1055 | __result = __s; | |
1056 | while (*__s != '\0' && *__s != __sep) | |
1057 | ++__s; | |
1058 | if (*__s == '\0') | |
1059 | *__nextp = __s; | |
1060 | else | |
1061 | { | |
1062 | *__s = '\0'; | |
1063 | *__nextp = __s + 1; | |
1064 | } | |
1065 | } | |
1066 | return __result; | |
1067 | } | |
31161268 | 1068 | # if defined __USE_POSIX || defined __USE_MISC |
7551a1e5 | 1069 | # define strtok_r(s, sep, nextp) __strtok_r ((s), (sep), (nextp)) |
6973fc01 UD |
1070 | # endif |
1071 | #endif | |
1072 | ||
1073 | ||
31161268 | 1074 | #ifndef _HAVE_STRING_ARCH_strsep |
61eb22d3 | 1075 | |
31161268 | 1076 | # define __strsep(s, reject) \ |
36ab45e1 UD |
1077 | __extension__ \ |
1078 | ({ char __r0, __r1, __r2; \ | |
1079 | (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \ | |
1080 | && (__r0 = ((__const char *) (reject))[0], __r0 != '\0') \ | |
1081 | ? ((__r1 = ((__const char *) (reject))[1], __r1 == '\0') \ | |
1082 | ? __strsep_1c (s, __r0) \ | |
1083 | : ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \ | |
1084 | ? __strsep_2c (s, __r0, __r1) \ | |
1085 | : (((__const char *) (reject))[3] == '\0' \ | |
1086 | ? __strsep_3c (s, __r0, __r1, __r2) \ | |
1087 | : __strsep_g (s, reject)))) \ | |
1088 | : __strsep_g (s, reject)); }) | |
61eb22d3 UD |
1089 | |
1090 | __STRING_INLINE char *__strsep_1c (char **__s, char __reject); | |
1091 | __STRING_INLINE char * | |
1092 | __strsep_1c (char **__s, char __reject) | |
1093 | { | |
650425ce | 1094 | register char *__retval = *__s; |
14c44e2e UD |
1095 | if (__retval == NULL) |
1096 | return *__s = NULL; | |
1097 | if (*__retval == __reject) | |
61eb22d3 | 1098 | *(*__s)++ = '\0'; |
14c44e2e UD |
1099 | else |
1100 | if ((*__s = strchr (__retval, __reject)) != NULL) | |
1101 | *(*__s)++ = '\0'; | |
1102 | else | |
1103 | *__s = NULL; | |
1104 | return __retval; | |
1105 | } | |
1106 | ||
1107 | __STRING_INLINE char *__strsep_2c (char **__s, char __reject1, char __reject2); | |
1108 | __STRING_INLINE char * | |
1109 | __strsep_2c (char **__s, char __reject1, char __reject2) | |
1110 | { | |
1111 | register char *__retval = *__s; | |
1112 | if (__retval == NULL) | |
1113 | return *__s = NULL; | |
1114 | if (*__retval == __reject1 || *__retval == __reject2) | |
1115 | *(*__s)++ = '\0'; | |
1116 | else | |
1117 | { | |
1118 | register char *__cp = __retval; | |
1119 | while (*__cp != '\0' && *__cp != __reject1 && *__cp != __reject2) | |
1120 | ++__cp; | |
1121 | if (*__cp != '\0') | |
1122 | { | |
1123 | *__s = __cp; | |
1124 | *(*__s)++ = '\0'; | |
1125 | } | |
1126 | else | |
1127 | *__s = NULL; | |
1128 | } | |
1129 | return __retval; | |
1130 | } | |
1131 | ||
1132 | __STRING_INLINE char *__strsep_3c (char **__s, char __reject1, char __reject2, | |
1133 | char __reject3); | |
1134 | __STRING_INLINE char * | |
1135 | __strsep_3c (char **__s, char __reject1, char __reject2, char __reject3) | |
1136 | { | |
1137 | register char *__retval = *__s; | |
1138 | if (__retval == NULL) | |
1139 | return *__s = NULL; | |
1140 | if (*__retval == __reject1 || *__retval == __reject2 | |
1141 | || *__retval == __reject3) | |
1142 | *(*__s)++ = '\0'; | |
1143 | else | |
1144 | { | |
1145 | register char *__cp = __retval; | |
1146 | while (*__cp != '\0' && *__cp != __reject1 && *__cp != __reject2 | |
1147 | && *__cp != __reject3) | |
1148 | ++__cp; | |
1149 | if (*__cp != '\0') | |
1150 | { | |
1151 | *__s = __cp; | |
1152 | *(*__s)++ = '\0'; | |
1153 | } | |
1154 | else | |
1155 | *__s = NULL; | |
1156 | } | |
650425ce | 1157 | return __retval; |
61eb22d3 UD |
1158 | } |
1159 | ||
1160 | __STRING_INLINE char *__strsep_g (char **__s, __const char *__reject); | |
1161 | __STRING_INLINE char * | |
1162 | __strsep_g (char **__s, __const char *__reject) | |
1163 | { | |
650425ce | 1164 | register char *__retval = *__s; |
61eb22d3 UD |
1165 | if (__retval == NULL || *__retval == '\0') |
1166 | return NULL; | |
76fbcfdd | 1167 | if ((*__s = strpbrk (__retval, __reject)) != NULL) |
61eb22d3 | 1168 | *(*__s)++ = '\0'; |
650425ce | 1169 | return __retval; |
61eb22d3 | 1170 | } |
31161268 | 1171 | # ifdef __USE_BSD |
7551a1e5 | 1172 | # define strsep(s, reject) __strsep ((s), (reject)) |
31161268 UD |
1173 | # endif |
1174 | #endif | |
1175 | ||
7ef90c15 | 1176 | /* We need the memory allocation functions for inline strdup(). |
d2537a47 | 1177 | Referring to stdlib.h (even minimally) is not allowed |
4a582094 | 1178 | in any of the tight standards compliant modes. */ |
6e2cc2c1 | 1179 | #ifdef __USE_MISC |
31161268 | 1180 | |
4a582094 UD |
1181 | # if !defined _HAVE_STRING_ARCH_strdup || !defined _HAVE_STRING_ARCH_strndup |
1182 | # define __need_malloc_and_calloc | |
1183 | # include <stdlib.h> | |
1184 | # endif | |
7ef90c15 | 1185 | |
4a582094 | 1186 | # ifndef _HAVE_STRING_ARCH_strdup |
31161268 | 1187 | |
4a582094 | 1188 | # define __strdup(s) \ |
7551a1e5 | 1189 | (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \ |
fab6d621 | 1190 | ? (((__const char *) (s))[0] == '\0' \ |
7551a1e5 UD |
1191 | ? (char *) calloc (1, 1) \ |
1192 | : ({ size_t __len = strlen (s) + 1; \ | |
1193 | char *__retval = (char *) malloc (__len); \ | |
1194 | if (__retval != NULL) \ | |
1195 | __retval = (char *) memcpy (__retval, s, __len); \ | |
1196 | __retval; })) \ | |
1197 | : __strdup (s))) | |
31161268 | 1198 | |
4a582094 UD |
1199 | # if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED |
1200 | # define strdup(s) __strdup (s) | |
1201 | # endif | |
61eb22d3 | 1202 | # endif |
61eb22d3 | 1203 | |
4a582094 | 1204 | # ifndef _HAVE_STRING_ARCH_strndup |
7551a1e5 | 1205 | |
4a582094 | 1206 | # define __strndup(s, n) \ |
7551a1e5 | 1207 | (__extension__ (__builtin_constant_p (s) && __string2_1bptr_p (s) \ |
fab6d621 | 1208 | ? (((__const char *) (s))[0] == '\0' \ |
7551a1e5 UD |
1209 | ? (char *) calloc (1, 1) \ |
1210 | : ({ size_t __len = strlen (s) + 1; \ | |
1211 | size_t __n = (n); \ | |
1212 | char *__retval; \ | |
1213 | if (__n < __len) \ | |
1214 | __len = __n; \ | |
1215 | __retval = (char *) malloc (__len); \ | |
1216 | if (__retval != NULL) \ | |
1217 | { \ | |
1218 | __retval[__len - 1] = '\0'; \ | |
1219 | __retval = (char *) memcpy (__retval, s, \ | |
1220 | __len - 1); \ | |
1221 | } \ | |
1222 | __retval; })) \ | |
1223 | : __strndup ((s), (n)))) | |
1224 | ||
4a582094 UD |
1225 | # ifdef __GNU_SOURCE |
1226 | # define strndup(s, n) __strndup ((s), (n)) | |
1227 | # endif | |
7551a1e5 | 1228 | # endif |
7551a1e5 | 1229 | |
4a582094 | 1230 | #endif /* Use misc. or use GNU. */ |
7551a1e5 | 1231 | |
9bbd7837 UD |
1232 | #ifndef _FORCE_INLINES |
1233 | # undef __STRING_INLINE | |
1234 | #endif | |
9a0a462c | 1235 | |
61eb22d3 | 1236 | #endif /* No string inlines. */ |