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