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