2017-06-12 Wilco Dijkstra <wdijkstr@arm.com>
[glibc.git] / string / string-inlines.c
blob55c99845aa39e72d9d00aac9071b9b1f9dded18c
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> may declare some extern inline functions.
19 These functions are defined here if inlining is not possible. */
21 #undef __USE_STRING_INLINES
22 #define __USE_STRING_INLINES
23 #define _FORCE_INLINES
24 #define __STRING_INLINE /* empty */
25 #define __NO_INLINE__
27 #include <string.h>
28 #undef index
29 #undef rindex
31 #undef __NO_INLINE__
32 #include <bits/string.h>
33 #include "shlib-compat.h"
35 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
36 /* The inline functions are not used from GLIBC 2.25 and forward, however
37 they are required to provide the symbols through string-inlines.c
38 (if inlining is not possible for compatibility reasons). */
40 char *
41 __old_strtok_r_1c (char *__s, char __sep, char **__nextp)
43 char *__result;
44 if (__s == NULL)
45 __s = *__nextp;
46 while (*__s == __sep)
47 ++__s;
48 __result = NULL;
49 if (*__s != '\0')
51 __result = __s++;
52 while (*__s != '\0')
53 if (*__s++ == __sep)
55 __s[-1] = '\0';
56 break;
59 *__nextp = __s;
60 return __result;
62 compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
64 char *
65 __old_strsep_1c (char **__s, char __reject)
67 char *__retval = *__s;
68 if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
69 *(*__s)++ = '\0';
70 return __retval;
72 compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
74 char *
75 __old_strsep_2c (char **__s, char __reject1, char __reject2)
77 char *__retval = *__s;
78 if (__retval != NULL)
80 char *__cp = __retval;
81 while (1)
83 if (*__cp == '\0')
85 __cp = NULL;
86 break;
88 if (*__cp == __reject1 || *__cp == __reject2)
90 *__cp++ = '\0';
91 break;
93 ++__cp;
95 *__s = __cp;
97 return __retval;
99 compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
101 char *
102 __old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
104 char *__retval = *__s;
105 if (__retval != NULL)
107 char *__cp = __retval;
108 while (1)
110 if (*__cp == '\0')
112 __cp = NULL;
113 break;
115 if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
117 *__cp++ = '\0';
118 break;
120 ++__cp;
122 *__s = __cp;
124 return __retval;
126 compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
127 #endif
129 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
130 /* The inline functions are not used from GLIBC 2.24 and forward, however
131 they are required to provide the symbols through string-inlines.c
132 (if inlining is not possible for compatibility reasons). */
133 size_t
134 __old_strcspn_c1 (const char *__s, int __reject)
136 size_t __result = 0;
137 while (__s[__result] != '\0' && __s[__result] != __reject)
138 ++__result;
139 return __result;
141 compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
143 size_t
144 __old_strcspn_c2 (const char *__s, int __reject1, int __reject2)
146 size_t __result = 0;
147 while (__s[__result] != '\0' && __s[__result] != __reject1
148 && __s[__result] != __reject2)
149 ++__result;
150 return __result;
152 compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
154 size_t
155 __old_strcspn_c3 (const char *__s, int __reject1, int __reject2,
156 int __reject3)
158 size_t __result = 0;
159 while (__s[__result] != '\0' && __s[__result] != __reject1
160 && __s[__result] != __reject2 && __s[__result] != __reject3)
161 ++__result;
162 return __result;
164 compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
166 size_t
167 __old_strspn_c1 (const char *__s, int __accept)
169 size_t __result = 0;
170 /* Please note that __accept never can be '\0'. */
171 while (__s[__result] == __accept)
172 ++__result;
173 return __result;
175 compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
177 size_t
178 __old_strspn_c2 (const char *__s, int __accept1, int __accept2)
180 size_t __result = 0;
181 /* Please note that __accept1 and __accept2 never can be '\0'. */
182 while (__s[__result] == __accept1 || __s[__result] == __accept2)
183 ++__result;
184 return __result;
186 compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
188 size_t
189 __old_strspn_c3 (const char *__s, int __accept1, int __accept2,
190 int __accept3)
192 size_t __result = 0;
193 /* Please note that __accept1 to __accept3 never can be '\0'. */
194 while (__s[__result] == __accept1 || __s[__result] == __accept2
195 || __s[__result] == __accept3)
196 ++__result;
197 return __result;
199 compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
201 char *
202 __old_strpbrk_c2 (const char *__s, int __accept1, int __accept2)
204 /* Please note that __accept1 and __accept2 never can be '\0'. */
205 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
206 ++__s;
207 return *__s == '\0' ? NULL : (char *) (size_t) __s;
209 compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
211 char *
212 __old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
214 /* Please note that __accept1 to __accept3 never can be '\0'. */
215 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
216 && *__s != __accept3)
217 ++__s;
218 return *__s == '\0' ? NULL : (char *) (size_t) __s;
220 compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
222 /* These are a few types we need for the optimizations if we cannot
223 use unaligned memory accesses. */
224 # define __STRING2_COPY_TYPE(N) \
225 typedef struct { unsigned char __arr[N]; } \
226 __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
227 __STRING2_COPY_TYPE (2);
228 __STRING2_COPY_TYPE (3);
229 __STRING2_COPY_TYPE (4);
230 __STRING2_COPY_TYPE (5);
231 __STRING2_COPY_TYPE (6);
232 __STRING2_COPY_TYPE (7);
233 __STRING2_COPY_TYPE (8);
234 # undef __STRING2_COPY_TYPE
237 # if _STRING_INLINE_unaligned
238 void *
239 __old_mempcpy_small (void *__dest1,
240 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
241 __uint16_t __src0_2, __uint16_t __src4_2,
242 __uint32_t __src0_4, __uint32_t __src4_4,
243 size_t __srclen)
245 union {
246 __uint32_t __ui;
247 __uint16_t __usi;
248 unsigned char __uc;
249 unsigned char __c;
250 } *__u = __dest1;
251 switch ((unsigned int) __srclen)
253 case 1:
254 __u->__c = __src0_1;
255 __u = __extension__ ((void *) __u + 1);
256 break;
257 case 2:
258 __u->__usi = __src0_2;
259 __u = __extension__ ((void *) __u + 2);
260 break;
261 case 3:
262 __u->__usi = __src0_2;
263 __u = __extension__ ((void *) __u + 2);
264 __u->__c = __src2_1;
265 __u = __extension__ ((void *) __u + 1);
266 break;
267 case 4:
268 __u->__ui = __src0_4;
269 __u = __extension__ ((void *) __u + 4);
270 break;
271 case 5:
272 __u->__ui = __src0_4;
273 __u = __extension__ ((void *) __u + 4);
274 __u->__c = __src4_1;
275 __u = __extension__ ((void *) __u + 1);
276 break;
277 case 6:
278 __u->__ui = __src0_4;
279 __u = __extension__ ((void *) __u + 4);
280 __u->__usi = __src4_2;
281 __u = __extension__ ((void *) __u + 2);
282 break;
283 case 7:
284 __u->__ui = __src0_4;
285 __u = __extension__ ((void *) __u + 4);
286 __u->__usi = __src4_2;
287 __u = __extension__ ((void *) __u + 2);
288 __u->__c = __src6_1;
289 __u = __extension__ ((void *) __u + 1);
290 break;
291 case 8:
292 __u->__ui = __src0_4;
293 __u = __extension__ ((void *) __u + 4);
294 __u->__ui = __src4_4;
295 __u = __extension__ ((void *) __u + 4);
296 break;
298 return (void *) __u;
301 # else
303 void *
304 __old_mempcpy_small (void *__dest, char __src1,
305 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
306 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
307 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
308 __STRING2_COPY_ARR8 __src8, size_t __srclen)
310 union {
311 char __c;
312 __STRING2_COPY_ARR2 __sca2;
313 __STRING2_COPY_ARR3 __sca3;
314 __STRING2_COPY_ARR4 __sca4;
315 __STRING2_COPY_ARR5 __sca5;
316 __STRING2_COPY_ARR6 __sca6;
317 __STRING2_COPY_ARR7 __sca7;
318 __STRING2_COPY_ARR8 __sca8;
319 } *__u = __dest;
320 switch ((unsigned int) __srclen)
322 case 1:
323 __u->__c = __src1;
324 break;
325 case 2:
326 __extension__ __u->__sca2 = __src2;
327 break;
328 case 3:
329 __extension__ __u->__sca3 = __src3;
330 break;
331 case 4:
332 __extension__ __u->__sca4 = __src4;
333 break;
334 case 5:
335 __extension__ __u->__sca5 = __src5;
336 break;
337 case 6:
338 __extension__ __u->__sca6 = __src6;
339 break;
340 case 7:
341 __extension__ __u->__sca7 = __src7;
342 break;
343 case 8:
344 __extension__ __u->__sca8 = __src8;
345 break;
347 return __extension__ ((void *) __u + __srclen);
349 # endif
350 compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
352 # if _STRING_INLINE_unaligned
353 char *
354 __old_strcpy_small (char *__dest,
355 __uint16_t __src0_2, __uint16_t __src4_2,
356 __uint32_t __src0_4, __uint32_t __src4_4,
357 size_t __srclen)
359 union {
360 __uint32_t __ui;
361 __uint16_t __usi;
362 unsigned char __uc;
363 } *__u = (void *) __dest;
364 switch ((unsigned int) __srclen)
366 case 1:
367 __u->__uc = '\0';
368 break;
369 case 2:
370 __u->__usi = __src0_2;
371 break;
372 case 3:
373 __u->__usi = __src0_2;
374 __u = __extension__ ((void *) __u + 2);
375 __u->__uc = '\0';
376 break;
377 case 4:
378 __u->__ui = __src0_4;
379 break;
380 case 5:
381 __u->__ui = __src0_4;
382 __u = __extension__ ((void *) __u + 4);
383 __u->__uc = '\0';
384 break;
385 case 6:
386 __u->__ui = __src0_4;
387 __u = __extension__ ((void *) __u + 4);
388 __u->__usi = __src4_2;
389 break;
390 case 7:
391 __u->__ui = __src0_4;
392 __u = __extension__ ((void *) __u + 4);
393 __u->__usi = __src4_2;
394 __u = __extension__ ((void *) __u + 2);
395 __u->__uc = '\0';
396 break;
397 case 8:
398 __u->__ui = __src0_4;
399 __u = __extension__ ((void *) __u + 4);
400 __u->__ui = __src4_4;
401 break;
403 return __dest;
406 # else
408 char *
409 __old_strcpy_small (char *__dest,
410 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
411 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
412 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
413 __STRING2_COPY_ARR8 __src8, size_t __srclen)
415 union {
416 char __c;
417 __STRING2_COPY_ARR2 __sca2;
418 __STRING2_COPY_ARR3 __sca3;
419 __STRING2_COPY_ARR4 __sca4;
420 __STRING2_COPY_ARR5 __sca5;
421 __STRING2_COPY_ARR6 __sca6;
422 __STRING2_COPY_ARR7 __sca7;
423 __STRING2_COPY_ARR8 __sca8;
424 } *__u = (void *) __dest;
425 switch ((unsigned int) __srclen)
427 case 1:
428 __u->__c = '\0';
429 break;
430 case 2:
431 __extension__ __u->__sca2 = __src2;
432 break;
433 case 3:
434 __extension__ __u->__sca3 = __src3;
435 break;
436 case 4:
437 __extension__ __u->__sca4 = __src4;
438 break;
439 case 5:
440 __extension__ __u->__sca5 = __src5;
441 break;
442 case 6:
443 __extension__ __u->__sca6 = __src6;
444 break;
445 case 7:
446 __extension__ __u->__sca7 = __src7;
447 break;
448 case 8:
449 __extension__ __u->__sca8 = __src8;
450 break;
452 return __dest;
454 # endif
455 compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
457 # if _STRING_INLINE_unaligned
458 char *
459 __old_stpcpy_small (char *__dest,
460 __uint16_t __src0_2, __uint16_t __src4_2,
461 __uint32_t __src0_4, __uint32_t __src4_4,
462 size_t __srclen)
464 union {
465 unsigned int __ui;
466 unsigned short int __usi;
467 unsigned char __uc;
468 char __c;
469 } *__u = (void *) __dest;
470 switch ((unsigned int) __srclen)
472 case 1:
473 __u->__uc = '\0';
474 break;
475 case 2:
476 __u->__usi = __src0_2;
477 __u = __extension__ ((void *) __u + 1);
478 break;
479 case 3:
480 __u->__usi = __src0_2;
481 __u = __extension__ ((void *) __u + 2);
482 __u->__uc = '\0';
483 break;
484 case 4:
485 __u->__ui = __src0_4;
486 __u = __extension__ ((void *) __u + 3);
487 break;
488 case 5:
489 __u->__ui = __src0_4;
490 __u = __extension__ ((void *) __u + 4);
491 __u->__uc = '\0';
492 break;
493 case 6:
494 __u->__ui = __src0_4;
495 __u = __extension__ ((void *) __u + 4);
496 __u->__usi = __src4_2;
497 __u = __extension__ ((void *) __u + 1);
498 break;
499 case 7:
500 __u->__ui = __src0_4;
501 __u = __extension__ ((void *) __u + 4);
502 __u->__usi = __src4_2;
503 __u = __extension__ ((void *) __u + 2);
504 __u->__uc = '\0';
505 break;
506 case 8:
507 __u->__ui = __src0_4;
508 __u = __extension__ ((void *) __u + 4);
509 __u->__ui = __src4_4;
510 __u = __extension__ ((void *) __u + 3);
511 break;
513 return &__u->__c;
516 # else
518 char *
519 __old_stpcpy_small (char *__dest,
520 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
521 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
522 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
523 __STRING2_COPY_ARR8 __src8, size_t __srclen)
525 union {
526 char __c;
527 __STRING2_COPY_ARR2 __sca2;
528 __STRING2_COPY_ARR3 __sca3;
529 __STRING2_COPY_ARR4 __sca4;
530 __STRING2_COPY_ARR5 __sca5;
531 __STRING2_COPY_ARR6 __sca6;
532 __STRING2_COPY_ARR7 __sca7;
533 __STRING2_COPY_ARR8 __sca8;
534 } *__u = (void *) __dest;
535 switch ((unsigned int) __srclen)
537 case 1:
538 __u->__c = '\0';
539 break;
540 case 2:
541 __extension__ __u->__sca2 = __src2;
542 break;
543 case 3:
544 __extension__ __u->__sca3 = __src3;
545 break;
546 case 4:
547 __extension__ __u->__sca4 = __src4;
548 break;
549 case 5:
550 __extension__ __u->__sca5 = __src5;
551 break;
552 case 6:
553 __extension__ __u->__sca6 = __src6;
554 break;
555 case 7:
556 __extension__ __u->__sca7 = __src7;
557 break;
558 case 8:
559 __extension__ __u->__sca8 = __src8;
560 break;
562 return __dest + __srclen - 1;
564 # endif
565 compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
567 #endif