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