Fix build issue on x86.
[glibc.git] / string / string-inlines.c
blob9f145366b64e6ed716aa2418f45d9bf4ec55d4b9
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
30 #undef __stpcpy
32 #undef __NO_INLINE__
33 #include <bits/string.h>
34 #include "shlib-compat.h"
36 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
37 /* The inline functions are not used from GLIBC 2.25 and forward, however
38 they are required to provide the symbols through string-inlines.c
39 (if inlining is not possible for compatibility reasons). */
41 char *
42 __old_strtok_r_1c (char *__s, char __sep, char **__nextp)
44 char *__result;
45 if (__s == NULL)
46 __s = *__nextp;
47 while (*__s == __sep)
48 ++__s;
49 __result = NULL;
50 if (*__s != '\0')
52 __result = __s++;
53 while (*__s != '\0')
54 if (*__s++ == __sep)
56 __s[-1] = '\0';
57 break;
60 *__nextp = __s;
61 return __result;
63 compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
65 char *
66 __old_strsep_1c (char **__s, char __reject)
68 char *__retval = *__s;
69 if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
70 *(*__s)++ = '\0';
71 return __retval;
73 compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
75 char *
76 __old_strsep_2c (char **__s, char __reject1, char __reject2)
78 char *__retval = *__s;
79 if (__retval != NULL)
81 char *__cp = __retval;
82 while (1)
84 if (*__cp == '\0')
86 __cp = NULL;
87 break;
89 if (*__cp == __reject1 || *__cp == __reject2)
91 *__cp++ = '\0';
92 break;
94 ++__cp;
96 *__s = __cp;
98 return __retval;
100 compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
102 char *
103 __old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
105 char *__retval = *__s;
106 if (__retval != NULL)
108 char *__cp = __retval;
109 while (1)
111 if (*__cp == '\0')
113 __cp = NULL;
114 break;
116 if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
118 *__cp++ = '\0';
119 break;
121 ++__cp;
123 *__s = __cp;
125 return __retval;
127 compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
128 #endif
130 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
131 /* The inline functions are not used from GLIBC 2.24 and forward, however
132 they are required to provide the symbols through string-inlines.c
133 (if inlining is not possible for compatibility reasons). */
134 size_t
135 __old_strcspn_c1 (const char *__s, int __reject)
137 size_t __result = 0;
138 while (__s[__result] != '\0' && __s[__result] != __reject)
139 ++__result;
140 return __result;
142 compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
144 size_t
145 __old_strcspn_c2 (const char *__s, int __reject1, int __reject2)
147 size_t __result = 0;
148 while (__s[__result] != '\0' && __s[__result] != __reject1
149 && __s[__result] != __reject2)
150 ++__result;
151 return __result;
153 compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
155 size_t
156 __old_strcspn_c3 (const char *__s, int __reject1, int __reject2,
157 int __reject3)
159 size_t __result = 0;
160 while (__s[__result] != '\0' && __s[__result] != __reject1
161 && __s[__result] != __reject2 && __s[__result] != __reject3)
162 ++__result;
163 return __result;
165 compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
167 size_t
168 __old_strspn_c1 (const char *__s, int __accept)
170 size_t __result = 0;
171 /* Please note that __accept never can be '\0'. */
172 while (__s[__result] == __accept)
173 ++__result;
174 return __result;
176 compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
178 size_t
179 __old_strspn_c2 (const char *__s, int __accept1, int __accept2)
181 size_t __result = 0;
182 /* Please note that __accept1 and __accept2 never can be '\0'. */
183 while (__s[__result] == __accept1 || __s[__result] == __accept2)
184 ++__result;
185 return __result;
187 compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
189 size_t
190 __old_strspn_c3 (const char *__s, int __accept1, int __accept2,
191 int __accept3)
193 size_t __result = 0;
194 /* Please note that __accept1 to __accept3 never can be '\0'. */
195 while (__s[__result] == __accept1 || __s[__result] == __accept2
196 || __s[__result] == __accept3)
197 ++__result;
198 return __result;
200 compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
202 char *
203 __old_strpbrk_c2 (const char *__s, int __accept1, int __accept2)
205 /* Please note that __accept1 and __accept2 never can be '\0'. */
206 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
207 ++__s;
208 return *__s == '\0' ? NULL : (char *) (size_t) __s;
210 compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
212 char *
213 __old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
215 /* Please note that __accept1 to __accept3 never can be '\0'. */
216 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
217 && *__s != __accept3)
218 ++__s;
219 return *__s == '\0' ? NULL : (char *) (size_t) __s;
221 compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
223 /* These are a few types we need for the optimizations if we cannot
224 use unaligned memory accesses. */
225 # define __STRING2_COPY_TYPE(N) \
226 typedef struct { unsigned char __arr[N]; } \
227 __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
228 __STRING2_COPY_TYPE (2);
229 __STRING2_COPY_TYPE (3);
230 __STRING2_COPY_TYPE (4);
231 __STRING2_COPY_TYPE (5);
232 __STRING2_COPY_TYPE (6);
233 __STRING2_COPY_TYPE (7);
234 __STRING2_COPY_TYPE (8);
235 # undef __STRING2_COPY_TYPE
238 # if _STRING_INLINE_unaligned
239 void *
240 __old_mempcpy_small (void *__dest1,
241 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
242 __uint16_t __src0_2, __uint16_t __src4_2,
243 __uint32_t __src0_4, __uint32_t __src4_4,
244 size_t __srclen)
246 union {
247 __uint32_t __ui;
248 __uint16_t __usi;
249 unsigned char __uc;
250 unsigned char __c;
251 } *__u = __dest1;
252 switch ((unsigned int) __srclen)
254 case 1:
255 __u->__c = __src0_1;
256 __u = __extension__ ((void *) __u + 1);
257 break;
258 case 2:
259 __u->__usi = __src0_2;
260 __u = __extension__ ((void *) __u + 2);
261 break;
262 case 3:
263 __u->__usi = __src0_2;
264 __u = __extension__ ((void *) __u + 2);
265 __u->__c = __src2_1;
266 __u = __extension__ ((void *) __u + 1);
267 break;
268 case 4:
269 __u->__ui = __src0_4;
270 __u = __extension__ ((void *) __u + 4);
271 break;
272 case 5:
273 __u->__ui = __src0_4;
274 __u = __extension__ ((void *) __u + 4);
275 __u->__c = __src4_1;
276 __u = __extension__ ((void *) __u + 1);
277 break;
278 case 6:
279 __u->__ui = __src0_4;
280 __u = __extension__ ((void *) __u + 4);
281 __u->__usi = __src4_2;
282 __u = __extension__ ((void *) __u + 2);
283 break;
284 case 7:
285 __u->__ui = __src0_4;
286 __u = __extension__ ((void *) __u + 4);
287 __u->__usi = __src4_2;
288 __u = __extension__ ((void *) __u + 2);
289 __u->__c = __src6_1;
290 __u = __extension__ ((void *) __u + 1);
291 break;
292 case 8:
293 __u->__ui = __src0_4;
294 __u = __extension__ ((void *) __u + 4);
295 __u->__ui = __src4_4;
296 __u = __extension__ ((void *) __u + 4);
297 break;
299 return (void *) __u;
302 # else
304 void *
305 __old_mempcpy_small (void *__dest, char __src1,
306 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
307 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
308 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
309 __STRING2_COPY_ARR8 __src8, size_t __srclen)
311 union {
312 char __c;
313 __STRING2_COPY_ARR2 __sca2;
314 __STRING2_COPY_ARR3 __sca3;
315 __STRING2_COPY_ARR4 __sca4;
316 __STRING2_COPY_ARR5 __sca5;
317 __STRING2_COPY_ARR6 __sca6;
318 __STRING2_COPY_ARR7 __sca7;
319 __STRING2_COPY_ARR8 __sca8;
320 } *__u = __dest;
321 switch ((unsigned int) __srclen)
323 case 1:
324 __u->__c = __src1;
325 break;
326 case 2:
327 __extension__ __u->__sca2 = __src2;
328 break;
329 case 3:
330 __extension__ __u->__sca3 = __src3;
331 break;
332 case 4:
333 __extension__ __u->__sca4 = __src4;
334 break;
335 case 5:
336 __extension__ __u->__sca5 = __src5;
337 break;
338 case 6:
339 __extension__ __u->__sca6 = __src6;
340 break;
341 case 7:
342 __extension__ __u->__sca7 = __src7;
343 break;
344 case 8:
345 __extension__ __u->__sca8 = __src8;
346 break;
348 return __extension__ ((void *) __u + __srclen);
350 # endif
351 compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
353 # if _STRING_INLINE_unaligned
354 char *
355 __old_strcpy_small (char *__dest,
356 __uint16_t __src0_2, __uint16_t __src4_2,
357 __uint32_t __src0_4, __uint32_t __src4_4,
358 size_t __srclen)
360 union {
361 __uint32_t __ui;
362 __uint16_t __usi;
363 unsigned char __uc;
364 } *__u = (void *) __dest;
365 switch ((unsigned int) __srclen)
367 case 1:
368 __u->__uc = '\0';
369 break;
370 case 2:
371 __u->__usi = __src0_2;
372 break;
373 case 3:
374 __u->__usi = __src0_2;
375 __u = __extension__ ((void *) __u + 2);
376 __u->__uc = '\0';
377 break;
378 case 4:
379 __u->__ui = __src0_4;
380 break;
381 case 5:
382 __u->__ui = __src0_4;
383 __u = __extension__ ((void *) __u + 4);
384 __u->__uc = '\0';
385 break;
386 case 6:
387 __u->__ui = __src0_4;
388 __u = __extension__ ((void *) __u + 4);
389 __u->__usi = __src4_2;
390 break;
391 case 7:
392 __u->__ui = __src0_4;
393 __u = __extension__ ((void *) __u + 4);
394 __u->__usi = __src4_2;
395 __u = __extension__ ((void *) __u + 2);
396 __u->__uc = '\0';
397 break;
398 case 8:
399 __u->__ui = __src0_4;
400 __u = __extension__ ((void *) __u + 4);
401 __u->__ui = __src4_4;
402 break;
404 return __dest;
407 # else
409 char *
410 __old_strcpy_small (char *__dest,
411 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
412 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
413 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
414 __STRING2_COPY_ARR8 __src8, size_t __srclen)
416 union {
417 char __c;
418 __STRING2_COPY_ARR2 __sca2;
419 __STRING2_COPY_ARR3 __sca3;
420 __STRING2_COPY_ARR4 __sca4;
421 __STRING2_COPY_ARR5 __sca5;
422 __STRING2_COPY_ARR6 __sca6;
423 __STRING2_COPY_ARR7 __sca7;
424 __STRING2_COPY_ARR8 __sca8;
425 } *__u = (void *) __dest;
426 switch ((unsigned int) __srclen)
428 case 1:
429 __u->__c = '\0';
430 break;
431 case 2:
432 __extension__ __u->__sca2 = __src2;
433 break;
434 case 3:
435 __extension__ __u->__sca3 = __src3;
436 break;
437 case 4:
438 __extension__ __u->__sca4 = __src4;
439 break;
440 case 5:
441 __extension__ __u->__sca5 = __src5;
442 break;
443 case 6:
444 __extension__ __u->__sca6 = __src6;
445 break;
446 case 7:
447 __extension__ __u->__sca7 = __src7;
448 break;
449 case 8:
450 __extension__ __u->__sca8 = __src8;
451 break;
453 return __dest;
455 # endif
456 compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
458 # if _STRING_INLINE_unaligned
459 char *
460 __old_stpcpy_small (char *__dest,
461 __uint16_t __src0_2, __uint16_t __src4_2,
462 __uint32_t __src0_4, __uint32_t __src4_4,
463 size_t __srclen)
465 union {
466 unsigned int __ui;
467 unsigned short int __usi;
468 unsigned char __uc;
469 char __c;
470 } *__u = (void *) __dest;
471 switch ((unsigned int) __srclen)
473 case 1:
474 __u->__uc = '\0';
475 break;
476 case 2:
477 __u->__usi = __src0_2;
478 __u = __extension__ ((void *) __u + 1);
479 break;
480 case 3:
481 __u->__usi = __src0_2;
482 __u = __extension__ ((void *) __u + 2);
483 __u->__uc = '\0';
484 break;
485 case 4:
486 __u->__ui = __src0_4;
487 __u = __extension__ ((void *) __u + 3);
488 break;
489 case 5:
490 __u->__ui = __src0_4;
491 __u = __extension__ ((void *) __u + 4);
492 __u->__uc = '\0';
493 break;
494 case 6:
495 __u->__ui = __src0_4;
496 __u = __extension__ ((void *) __u + 4);
497 __u->__usi = __src4_2;
498 __u = __extension__ ((void *) __u + 1);
499 break;
500 case 7:
501 __u->__ui = __src0_4;
502 __u = __extension__ ((void *) __u + 4);
503 __u->__usi = __src4_2;
504 __u = __extension__ ((void *) __u + 2);
505 __u->__uc = '\0';
506 break;
507 case 8:
508 __u->__ui = __src0_4;
509 __u = __extension__ ((void *) __u + 4);
510 __u->__ui = __src4_4;
511 __u = __extension__ ((void *) __u + 3);
512 break;
514 return &__u->__c;
517 # else
519 char *
520 __old_stpcpy_small (char *__dest,
521 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
522 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
523 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
524 __STRING2_COPY_ARR8 __src8, size_t __srclen)
526 union {
527 char __c;
528 __STRING2_COPY_ARR2 __sca2;
529 __STRING2_COPY_ARR3 __sca3;
530 __STRING2_COPY_ARR4 __sca4;
531 __STRING2_COPY_ARR5 __sca5;
532 __STRING2_COPY_ARR6 __sca6;
533 __STRING2_COPY_ARR7 __sca7;
534 __STRING2_COPY_ARR8 __sca8;
535 } *__u = (void *) __dest;
536 switch ((unsigned int) __srclen)
538 case 1:
539 __u->__c = '\0';
540 break;
541 case 2:
542 __extension__ __u->__sca2 = __src2;
543 break;
544 case 3:
545 __extension__ __u->__sca3 = __src3;
546 break;
547 case 4:
548 __extension__ __u->__sca4 = __src4;
549 break;
550 case 5:
551 __extension__ __u->__sca5 = __src5;
552 break;
553 case 6:
554 __extension__ __u->__sca6 = __src6;
555 break;
556 case 7:
557 __extension__ __u->__sca7 = __src7;
558 break;
559 case 8:
560 __extension__ __u->__sca8 = __src8;
561 break;
563 return __dest + __srclen - 1;
565 # endif
566 compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
568 #endif