1 | /* Copyright (C) 1999-2017 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. |
3 | |
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. |
8 | |
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. |
13 | |
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/>. */ |
17 | |
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. */ |
21 | |
22 | #undef __USE_STRING_INLINES |
23 | #define __USE_STRING_INLINES |
24 | #define _FORCE_INLINES |
25 | #define __STRING_INLINE /* empty */ |
26 | #define __NO_INLINE__ |
27 | |
28 | #include <string.h> |
29 | #undef index |
30 | #undef rindex |
31 | |
32 | #undef __NO_INLINE__ |
33 | #include <bits/string.h> |
34 | #include <bits/string2.h> |
35 | |
36 | #include "shlib-compat.h" |
37 | |
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). */ |
42 | |
43 | char * |
44 | __old_strtok_r_1c (char *__s, char __sep, char **__nextp) |
45 | { |
46 | char *__result; |
47 | if (__s == NULL) |
48 | __s = *__nextp; |
49 | while (*__s == __sep) |
50 | ++__s; |
51 | __result = NULL; |
52 | if (*__s != '\0') |
53 | { |
54 | __result = __s++; |
55 | while (*__s != '\0') |
56 | if (*__s++ == __sep) |
57 | { |
58 | __s[-1] = '\0'; |
59 | break; |
60 | } |
61 | } |
62 | *__nextp = __s; |
63 | return __result; |
64 | } |
65 | compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1); |
66 | |
67 | char * |
68 | __old_strsep_1c (char **__s, char __reject) |
69 | { |
70 | char *__retval = *__s; |
71 | if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL) |
72 | *(*__s)++ = '\0'; |
73 | return __retval; |
74 | } |
75 | compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1); |
76 | |
77 | char * |
78 | __old_strsep_2c (char **__s, char __reject1, char __reject2) |
79 | { |
80 | char *__retval = *__s; |
81 | if (__retval != NULL) |
82 | { |
83 | char *__cp = __retval; |
84 | while (1) |
85 | { |
86 | if (*__cp == '\0') |
87 | { |
88 | __cp = NULL; |
89 | break; |
90 | } |
91 | if (*__cp == __reject1 || *__cp == __reject2) |
92 | { |
93 | *__cp++ = '\0'; |
94 | break; |
95 | } |
96 | ++__cp; |
97 | } |
98 | *__s = __cp; |
99 | } |
100 | return __retval; |
101 | } |
102 | compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1); |
103 | |
104 | char * |
105 | __old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3) |
106 | { |
107 | char *__retval = *__s; |
108 | if (__retval != NULL) |
109 | { |
110 | char *__cp = __retval; |
111 | while (1) |
112 | { |
113 | if (*__cp == '\0') |
114 | { |
115 | __cp = NULL; |
116 | break; |
117 | } |
118 | if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3) |
119 | { |
120 | *__cp++ = '\0'; |
121 | break; |
122 | } |
123 | ++__cp; |
124 | } |
125 | *__s = __cp; |
126 | } |
127 | return __retval; |
128 | } |
129 | compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1); |
130 | #endif |
131 | |
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) |
138 | { |
139 | size_t __result = 0; |
140 | while (__s[__result] != '\0' && __s[__result] != __reject) |
141 | ++__result; |
142 | return __result; |
143 | } |
144 | compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1); |
145 | |
146 | size_t |
147 | __old_strcspn_c2 (const char *__s, int __reject1, int __reject2) |
148 | { |
149 | size_t __result = 0; |
150 | while (__s[__result] != '\0' && __s[__result] != __reject1 |
151 | && __s[__result] != __reject2) |
152 | ++__result; |
153 | return __result; |
154 | } |
155 | compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1); |
156 | |
157 | size_t |
158 | __old_strcspn_c3 (const char *__s, int __reject1, int __reject2, |
159 | int __reject3) |
160 | { |
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; |
166 | } |
167 | compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1); |
168 | |
169 | size_t |
170 | __old_strspn_c1 (const char *__s, int __accept) |
171 | { |
172 | size_t __result = 0; |
173 | /* Please note that __accept never can be '\0'. */ |
174 | while (__s[__result] == __accept) |
175 | ++__result; |
176 | return __result; |
177 | } |
178 | compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1); |
179 | |
180 | size_t |
181 | __old_strspn_c2 (const char *__s, int __accept1, int __accept2) |
182 | { |
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; |
188 | } |
189 | compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1); |
190 | |
191 | size_t |
192 | __old_strspn_c3 (const char *__s, int __accept1, int __accept2, |
193 | int __accept3) |
194 | { |
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; |
201 | } |
202 | compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1); |
203 | |
204 | char * |
205 | __old_strpbrk_c2 (const char *__s, int __accept1, int __accept2) |
206 | { |
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; |
211 | } |
212 | compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1); |
213 | |
214 | char * |
215 | __old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3) |
216 | { |
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; |
222 | } |
223 | compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1); |
224 | |
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 |
238 | |
239 | |
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) |
247 | { |
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) |
255 | { |
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; |
300 | } |
301 | return (void *) __u; |
302 | } |
303 | |
304 | # else |
305 | |
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) |
312 | { |
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) |
324 | { |
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; |
349 | } |
350 | return __extension__ ((void *) __u + __srclen); |
351 | } |
352 | # endif |
353 | compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1); |
354 | |
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) |
361 | { |
362 | union { |
363 | __uint32_t __ui; |
364 | __uint16_t __usi; |
365 | unsigned char __uc; |
366 | } *__u = (void *) __dest; |
367 | switch ((unsigned int) __srclen) |
368 | { |
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; |
405 | } |
406 | return __dest; |
407 | } |
408 | |
409 | # else |
410 | |
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) |
417 | { |
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) |
429 | { |
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; |
454 | } |
455 | return __dest; |
456 | } |
457 | # endif |
458 | compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1); |
459 | |
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) |
466 | { |
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) |
474 | { |
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; |
515 | } |
516 | return &__u->__c; |
517 | } |
518 | |
519 | # else |
520 | |
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) |
527 | { |
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) |
539 | { |
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; |
564 | } |
565 | return __dest + __srclen - 1; |
566 | } |
567 | # endif |
568 | compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1); |
569 | |
570 | #endif |
571 | |