Fix typo in NEWS
[glibc.git] / string / string-inlines.c
blobfa4a1594b2a1558f77a9c0de7263c94b6abee763
1 /* Copyright (C) 1999-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
18 /* <bits/string.h> and <bits/string2.h> declare some extern inline
19 functions. These functions are declared additionally here if
20 inlining is not possible. */
22 #undef __USE_STRING_INLINES
23 #define __USE_STRING_INLINES
24 #define _FORCE_INLINES
25 #define __STRING_INLINE /* empty */
26 #define __NO_INLINE__
28 #include <string.h>
29 #undef index
30 #undef rindex
32 #undef __NO_INLINE__
33 #include <bits/string.h>
34 #include <bits/string2.h>
36 #include "shlib-compat.h"
38 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
39 /* The inline functions are not used from GLIBC 2.25 and forward, however
40 they are required to provide the symbols through string-inlines.c
41 (if inlining is not possible for compatibility reasons). */
43 char *
44 __old_strtok_r_1c (char *__s, char __sep, char **__nextp)
46 char *__result;
47 if (__s == NULL)
48 __s = *__nextp;
49 while (*__s == __sep)
50 ++__s;
51 __result = NULL;
52 if (*__s != '\0')
54 __result = __s++;
55 while (*__s != '\0')
56 if (*__s++ == __sep)
58 __s[-1] = '\0';
59 break;
62 *__nextp = __s;
63 return __result;
65 compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
67 char *
68 __old_strsep_1c (char **__s, char __reject)
70 char *__retval = *__s;
71 if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
72 *(*__s)++ = '\0';
73 return __retval;
75 compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
77 char *
78 __old_strsep_2c (char **__s, char __reject1, char __reject2)
80 char *__retval = *__s;
81 if (__retval != NULL)
83 char *__cp = __retval;
84 while (1)
86 if (*__cp == '\0')
88 __cp = NULL;
89 break;
91 if (*__cp == __reject1 || *__cp == __reject2)
93 *__cp++ = '\0';
94 break;
96 ++__cp;
98 *__s = __cp;
100 return __retval;
102 compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
104 char *
105 __old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
107 char *__retval = *__s;
108 if (__retval != NULL)
110 char *__cp = __retval;
111 while (1)
113 if (*__cp == '\0')
115 __cp = NULL;
116 break;
118 if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
120 *__cp++ = '\0';
121 break;
123 ++__cp;
125 *__s = __cp;
127 return __retval;
129 compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
130 #endif
132 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
133 /* The inline functions are not used from GLIBC 2.24 and forward, however
134 they are required to provide the symbols through string-inlines.c
135 (if inlining is not possible for compatibility reasons). */
136 size_t
137 __old_strcspn_c1 (const char *__s, int __reject)
139 size_t __result = 0;
140 while (__s[__result] != '\0' && __s[__result] != __reject)
141 ++__result;
142 return __result;
144 compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
146 size_t
147 __old_strcspn_c2 (const char *__s, int __reject1, int __reject2)
149 size_t __result = 0;
150 while (__s[__result] != '\0' && __s[__result] != __reject1
151 && __s[__result] != __reject2)
152 ++__result;
153 return __result;
155 compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
157 size_t
158 __old_strcspn_c3 (const char *__s, int __reject1, int __reject2,
159 int __reject3)
161 size_t __result = 0;
162 while (__s[__result] != '\0' && __s[__result] != __reject1
163 && __s[__result] != __reject2 && __s[__result] != __reject3)
164 ++__result;
165 return __result;
167 compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
169 size_t
170 __old_strspn_c1 (const char *__s, int __accept)
172 size_t __result = 0;
173 /* Please note that __accept never can be '\0'. */
174 while (__s[__result] == __accept)
175 ++__result;
176 return __result;
178 compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
180 size_t
181 __old_strspn_c2 (const char *__s, int __accept1, int __accept2)
183 size_t __result = 0;
184 /* Please note that __accept1 and __accept2 never can be '\0'. */
185 while (__s[__result] == __accept1 || __s[__result] == __accept2)
186 ++__result;
187 return __result;
189 compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
191 size_t
192 __old_strspn_c3 (const char *__s, int __accept1, int __accept2,
193 int __accept3)
195 size_t __result = 0;
196 /* Please note that __accept1 to __accept3 never can be '\0'. */
197 while (__s[__result] == __accept1 || __s[__result] == __accept2
198 || __s[__result] == __accept3)
199 ++__result;
200 return __result;
202 compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
204 char *
205 __old_strpbrk_c2 (const char *__s, int __accept1, int __accept2)
207 /* Please note that __accept1 and __accept2 never can be '\0'. */
208 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
209 ++__s;
210 return *__s == '\0' ? NULL : (char *) (size_t) __s;
212 compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
214 char *
215 __old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
217 /* Please note that __accept1 to __accept3 never can be '\0'. */
218 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
219 && *__s != __accept3)
220 ++__s;
221 return *__s == '\0' ? NULL : (char *) (size_t) __s;
223 compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
225 /* These are a few types we need for the optimizations if we cannot
226 use unaligned memory accesses. */
227 # define __STRING2_COPY_TYPE(N) \
228 typedef struct { unsigned char __arr[N]; } \
229 __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
230 __STRING2_COPY_TYPE (2);
231 __STRING2_COPY_TYPE (3);
232 __STRING2_COPY_TYPE (4);
233 __STRING2_COPY_TYPE (5);
234 __STRING2_COPY_TYPE (6);
235 __STRING2_COPY_TYPE (7);
236 __STRING2_COPY_TYPE (8);
237 # undef __STRING2_COPY_TYPE
240 # if _STRING_INLINE_unaligned
241 void *
242 __old_mempcpy_small (void *__dest1,
243 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
244 __uint16_t __src0_2, __uint16_t __src4_2,
245 __uint32_t __src0_4, __uint32_t __src4_4,
246 size_t __srclen)
248 union {
249 __uint32_t __ui;
250 __uint16_t __usi;
251 unsigned char __uc;
252 unsigned char __c;
253 } *__u = __dest1;
254 switch ((unsigned int) __srclen)
256 case 1:
257 __u->__c = __src0_1;
258 __u = __extension__ ((void *) __u + 1);
259 break;
260 case 2:
261 __u->__usi = __src0_2;
262 __u = __extension__ ((void *) __u + 2);
263 break;
264 case 3:
265 __u->__usi = __src0_2;
266 __u = __extension__ ((void *) __u + 2);
267 __u->__c = __src2_1;
268 __u = __extension__ ((void *) __u + 1);
269 break;
270 case 4:
271 __u->__ui = __src0_4;
272 __u = __extension__ ((void *) __u + 4);
273 break;
274 case 5:
275 __u->__ui = __src0_4;
276 __u = __extension__ ((void *) __u + 4);
277 __u->__c = __src4_1;
278 __u = __extension__ ((void *) __u + 1);
279 break;
280 case 6:
281 __u->__ui = __src0_4;
282 __u = __extension__ ((void *) __u + 4);
283 __u->__usi = __src4_2;
284 __u = __extension__ ((void *) __u + 2);
285 break;
286 case 7:
287 __u->__ui = __src0_4;
288 __u = __extension__ ((void *) __u + 4);
289 __u->__usi = __src4_2;
290 __u = __extension__ ((void *) __u + 2);
291 __u->__c = __src6_1;
292 __u = __extension__ ((void *) __u + 1);
293 break;
294 case 8:
295 __u->__ui = __src0_4;
296 __u = __extension__ ((void *) __u + 4);
297 __u->__ui = __src4_4;
298 __u = __extension__ ((void *) __u + 4);
299 break;
301 return (void *) __u;
304 # else
306 void *
307 __old_mempcpy_small (void *__dest, char __src1,
308 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
309 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
310 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
311 __STRING2_COPY_ARR8 __src8, size_t __srclen)
313 union {
314 char __c;
315 __STRING2_COPY_ARR2 __sca2;
316 __STRING2_COPY_ARR3 __sca3;
317 __STRING2_COPY_ARR4 __sca4;
318 __STRING2_COPY_ARR5 __sca5;
319 __STRING2_COPY_ARR6 __sca6;
320 __STRING2_COPY_ARR7 __sca7;
321 __STRING2_COPY_ARR8 __sca8;
322 } *__u = __dest;
323 switch ((unsigned int) __srclen)
325 case 1:
326 __u->__c = __src1;
327 break;
328 case 2:
329 __extension__ __u->__sca2 = __src2;
330 break;
331 case 3:
332 __extension__ __u->__sca3 = __src3;
333 break;
334 case 4:
335 __extension__ __u->__sca4 = __src4;
336 break;
337 case 5:
338 __extension__ __u->__sca5 = __src5;
339 break;
340 case 6:
341 __extension__ __u->__sca6 = __src6;
342 break;
343 case 7:
344 __extension__ __u->__sca7 = __src7;
345 break;
346 case 8:
347 __extension__ __u->__sca8 = __src8;
348 break;
350 return __extension__ ((void *) __u + __srclen);
352 # endif
353 compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
355 # if _STRING_INLINE_unaligned
356 char *
357 __old_strcpy_small (char *__dest,
358 __uint16_t __src0_2, __uint16_t __src4_2,
359 __uint32_t __src0_4, __uint32_t __src4_4,
360 size_t __srclen)
362 union {
363 __uint32_t __ui;
364 __uint16_t __usi;
365 unsigned char __uc;
366 } *__u = (void *) __dest;
367 switch ((unsigned int) __srclen)
369 case 1:
370 __u->__uc = '\0';
371 break;
372 case 2:
373 __u->__usi = __src0_2;
374 break;
375 case 3:
376 __u->__usi = __src0_2;
377 __u = __extension__ ((void *) __u + 2);
378 __u->__uc = '\0';
379 break;
380 case 4:
381 __u->__ui = __src0_4;
382 break;
383 case 5:
384 __u->__ui = __src0_4;
385 __u = __extension__ ((void *) __u + 4);
386 __u->__uc = '\0';
387 break;
388 case 6:
389 __u->__ui = __src0_4;
390 __u = __extension__ ((void *) __u + 4);
391 __u->__usi = __src4_2;
392 break;
393 case 7:
394 __u->__ui = __src0_4;
395 __u = __extension__ ((void *) __u + 4);
396 __u->__usi = __src4_2;
397 __u = __extension__ ((void *) __u + 2);
398 __u->__uc = '\0';
399 break;
400 case 8:
401 __u->__ui = __src0_4;
402 __u = __extension__ ((void *) __u + 4);
403 __u->__ui = __src4_4;
404 break;
406 return __dest;
409 # else
411 char *
412 __old_strcpy_small (char *__dest,
413 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
414 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
415 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
416 __STRING2_COPY_ARR8 __src8, size_t __srclen)
418 union {
419 char __c;
420 __STRING2_COPY_ARR2 __sca2;
421 __STRING2_COPY_ARR3 __sca3;
422 __STRING2_COPY_ARR4 __sca4;
423 __STRING2_COPY_ARR5 __sca5;
424 __STRING2_COPY_ARR6 __sca6;
425 __STRING2_COPY_ARR7 __sca7;
426 __STRING2_COPY_ARR8 __sca8;
427 } *__u = (void *) __dest;
428 switch ((unsigned int) __srclen)
430 case 1:
431 __u->__c = '\0';
432 break;
433 case 2:
434 __extension__ __u->__sca2 = __src2;
435 break;
436 case 3:
437 __extension__ __u->__sca3 = __src3;
438 break;
439 case 4:
440 __extension__ __u->__sca4 = __src4;
441 break;
442 case 5:
443 __extension__ __u->__sca5 = __src5;
444 break;
445 case 6:
446 __extension__ __u->__sca6 = __src6;
447 break;
448 case 7:
449 __extension__ __u->__sca7 = __src7;
450 break;
451 case 8:
452 __extension__ __u->__sca8 = __src8;
453 break;
455 return __dest;
457 # endif
458 compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
460 # if _STRING_INLINE_unaligned
461 char *
462 __old_stpcpy_small (char *__dest,
463 __uint16_t __src0_2, __uint16_t __src4_2,
464 __uint32_t __src0_4, __uint32_t __src4_4,
465 size_t __srclen)
467 union {
468 unsigned int __ui;
469 unsigned short int __usi;
470 unsigned char __uc;
471 char __c;
472 } *__u = (void *) __dest;
473 switch ((unsigned int) __srclen)
475 case 1:
476 __u->__uc = '\0';
477 break;
478 case 2:
479 __u->__usi = __src0_2;
480 __u = __extension__ ((void *) __u + 1);
481 break;
482 case 3:
483 __u->__usi = __src0_2;
484 __u = __extension__ ((void *) __u + 2);
485 __u->__uc = '\0';
486 break;
487 case 4:
488 __u->__ui = __src0_4;
489 __u = __extension__ ((void *) __u + 3);
490 break;
491 case 5:
492 __u->__ui = __src0_4;
493 __u = __extension__ ((void *) __u + 4);
494 __u->__uc = '\0';
495 break;
496 case 6:
497 __u->__ui = __src0_4;
498 __u = __extension__ ((void *) __u + 4);
499 __u->__usi = __src4_2;
500 __u = __extension__ ((void *) __u + 1);
501 break;
502 case 7:
503 __u->__ui = __src0_4;
504 __u = __extension__ ((void *) __u + 4);
505 __u->__usi = __src4_2;
506 __u = __extension__ ((void *) __u + 2);
507 __u->__uc = '\0';
508 break;
509 case 8:
510 __u->__ui = __src0_4;
511 __u = __extension__ ((void *) __u + 4);
512 __u->__ui = __src4_4;
513 __u = __extension__ ((void *) __u + 3);
514 break;
516 return &__u->__c;
519 # else
521 char *
522 __old_stpcpy_small (char *__dest,
523 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
524 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
525 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
526 __STRING2_COPY_ARR8 __src8, size_t __srclen)
528 union {
529 char __c;
530 __STRING2_COPY_ARR2 __sca2;
531 __STRING2_COPY_ARR3 __sca3;
532 __STRING2_COPY_ARR4 __sca4;
533 __STRING2_COPY_ARR5 __sca5;
534 __STRING2_COPY_ARR6 __sca6;
535 __STRING2_COPY_ARR7 __sca7;
536 __STRING2_COPY_ARR8 __sca8;
537 } *__u = (void *) __dest;
538 switch ((unsigned int) __srclen)
540 case 1:
541 __u->__c = '\0';
542 break;
543 case 2:
544 __extension__ __u->__sca2 = __src2;
545 break;
546 case 3:
547 __extension__ __u->__sca3 = __src3;
548 break;
549 case 4:
550 __extension__ __u->__sca4 = __src4;
551 break;
552 case 5:
553 __extension__ __u->__sca5 = __src5;
554 break;
555 case 6:
556 __extension__ __u->__sca6 = __src6;
557 break;
558 case 7:
559 __extension__ __u->__sca7 = __src7;
560 break;
561 case 8:
562 __extension__ __u->__sca8 = __src8;
563 break;
565 return __dest + __srclen - 1;
567 # endif
568 compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
570 #endif