1 | /* Copyright (C) 1999-2016 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_24) |
39 | /* The inline functions are not used from GLIBC 2.24 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 | size_t |
43 | __old_strcspn_c1 (const char *__s, int __reject) |
44 | { |
45 | size_t __result = 0; |
46 | while (__s[__result] != '\0' && __s[__result] != __reject) |
47 | ++__result; |
48 | return __result; |
49 | } |
50 | compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1); |
51 | |
52 | size_t |
53 | __old_strcspn_c2 (const char *__s, int __reject1, int __reject2) |
54 | { |
55 | size_t __result = 0; |
56 | while (__s[__result] != '\0' && __s[__result] != __reject1 |
57 | && __s[__result] != __reject2) |
58 | ++__result; |
59 | return __result; |
60 | } |
61 | compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1); |
62 | |
63 | size_t |
64 | __old_strcspn_c3 (const char *__s, int __reject1, int __reject2, |
65 | int __reject3) |
66 | { |
67 | size_t __result = 0; |
68 | while (__s[__result] != '\0' && __s[__result] != __reject1 |
69 | && __s[__result] != __reject2 && __s[__result] != __reject3) |
70 | ++__result; |
71 | return __result; |
72 | } |
73 | compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1); |
74 | |
75 | size_t |
76 | __old_strspn_c1 (const char *__s, int __accept) |
77 | { |
78 | size_t __result = 0; |
79 | /* Please note that __accept never can be '\0'. */ |
80 | while (__s[__result] == __accept) |
81 | ++__result; |
82 | return __result; |
83 | } |
84 | compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1); |
85 | |
86 | size_t |
87 | __old_strspn_c2 (const char *__s, int __accept1, int __accept2) |
88 | { |
89 | size_t __result = 0; |
90 | /* Please note that __accept1 and __accept2 never can be '\0'. */ |
91 | while (__s[__result] == __accept1 || __s[__result] == __accept2) |
92 | ++__result; |
93 | return __result; |
94 | } |
95 | compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1); |
96 | |
97 | size_t |
98 | __old_strspn_c3 (const char *__s, int __accept1, int __accept2, |
99 | int __accept3) |
100 | { |
101 | size_t __result = 0; |
102 | /* Please note that __accept1 to __accept3 never can be '\0'. */ |
103 | while (__s[__result] == __accept1 || __s[__result] == __accept2 |
104 | || __s[__result] == __accept3) |
105 | ++__result; |
106 | return __result; |
107 | } |
108 | compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1); |
109 | |
110 | char * |
111 | __old_strpbrk_c2 (const char *__s, int __accept1, int __accept2) |
112 | { |
113 | /* Please note that __accept1 and __accept2 never can be '\0'. */ |
114 | while (*__s != '\0' && *__s != __accept1 && *__s != __accept2) |
115 | ++__s; |
116 | return *__s == '\0' ? NULL : (char *) (size_t) __s; |
117 | } |
118 | compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1); |
119 | |
120 | char * |
121 | __old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3) |
122 | { |
123 | /* Please note that __accept1 to __accept3 never can be '\0'. */ |
124 | while (*__s != '\0' && *__s != __accept1 && *__s != __accept2 |
125 | && *__s != __accept3) |
126 | ++__s; |
127 | return *__s == '\0' ? NULL : (char *) (size_t) __s; |
128 | } |
129 | compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1); |
130 | |
131 | /* These are a few types we need for the optimizations if we cannot |
132 | use unaligned memory accesses. */ |
133 | # define __STRING2_COPY_TYPE(N) \ |
134 | typedef struct { unsigned char __arr[N]; } \ |
135 | __attribute__ ((__packed__)) __STRING2_COPY_ARR##N |
136 | __STRING2_COPY_TYPE (2); |
137 | __STRING2_COPY_TYPE (3); |
138 | __STRING2_COPY_TYPE (4); |
139 | __STRING2_COPY_TYPE (5); |
140 | __STRING2_COPY_TYPE (6); |
141 | __STRING2_COPY_TYPE (7); |
142 | __STRING2_COPY_TYPE (8); |
143 | # undef __STRING2_COPY_TYPE |
144 | |
145 | |
146 | # if _STRING_INLINE_unaligned |
147 | void * |
148 | __old_mempcpy_small (void *__dest1, |
149 | char __src0_1, char __src2_1, char __src4_1, char __src6_1, |
150 | __uint16_t __src0_2, __uint16_t __src4_2, |
151 | __uint32_t __src0_4, __uint32_t __src4_4, |
152 | size_t __srclen) |
153 | { |
154 | union { |
155 | __uint32_t __ui; |
156 | __uint16_t __usi; |
157 | unsigned char __uc; |
158 | unsigned char __c; |
159 | } *__u = __dest1; |
160 | switch ((unsigned int) __srclen) |
161 | { |
162 | case 1: |
163 | __u->__c = __src0_1; |
164 | __u = __extension__ ((void *) __u + 1); |
165 | break; |
166 | case 2: |
167 | __u->__usi = __src0_2; |
168 | __u = __extension__ ((void *) __u + 2); |
169 | break; |
170 | case 3: |
171 | __u->__usi = __src0_2; |
172 | __u = __extension__ ((void *) __u + 2); |
173 | __u->__c = __src2_1; |
174 | __u = __extension__ ((void *) __u + 1); |
175 | break; |
176 | case 4: |
177 | __u->__ui = __src0_4; |
178 | __u = __extension__ ((void *) __u + 4); |
179 | break; |
180 | case 5: |
181 | __u->__ui = __src0_4; |
182 | __u = __extension__ ((void *) __u + 4); |
183 | __u->__c = __src4_1; |
184 | __u = __extension__ ((void *) __u + 1); |
185 | break; |
186 | case 6: |
187 | __u->__ui = __src0_4; |
188 | __u = __extension__ ((void *) __u + 4); |
189 | __u->__usi = __src4_2; |
190 | __u = __extension__ ((void *) __u + 2); |
191 | break; |
192 | case 7: |
193 | __u->__ui = __src0_4; |
194 | __u = __extension__ ((void *) __u + 4); |
195 | __u->__usi = __src4_2; |
196 | __u = __extension__ ((void *) __u + 2); |
197 | __u->__c = __src6_1; |
198 | __u = __extension__ ((void *) __u + 1); |
199 | break; |
200 | case 8: |
201 | __u->__ui = __src0_4; |
202 | __u = __extension__ ((void *) __u + 4); |
203 | __u->__ui = __src4_4; |
204 | __u = __extension__ ((void *) __u + 4); |
205 | break; |
206 | } |
207 | return (void *) __u; |
208 | } |
209 | |
210 | # else |
211 | |
212 | void * |
213 | __old_mempcpy_small (void *__dest, char __src1, |
214 | __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, |
215 | __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, |
216 | __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, |
217 | __STRING2_COPY_ARR8 __src8, size_t __srclen) |
218 | { |
219 | union { |
220 | char __c; |
221 | __STRING2_COPY_ARR2 __sca2; |
222 | __STRING2_COPY_ARR3 __sca3; |
223 | __STRING2_COPY_ARR4 __sca4; |
224 | __STRING2_COPY_ARR5 __sca5; |
225 | __STRING2_COPY_ARR6 __sca6; |
226 | __STRING2_COPY_ARR7 __sca7; |
227 | __STRING2_COPY_ARR8 __sca8; |
228 | } *__u = __dest; |
229 | switch ((unsigned int) __srclen) |
230 | { |
231 | case 1: |
232 | __u->__c = __src1; |
233 | break; |
234 | case 2: |
235 | __extension__ __u->__sca2 = __src2; |
236 | break; |
237 | case 3: |
238 | __extension__ __u->__sca3 = __src3; |
239 | break; |
240 | case 4: |
241 | __extension__ __u->__sca4 = __src4; |
242 | break; |
243 | case 5: |
244 | __extension__ __u->__sca5 = __src5; |
245 | break; |
246 | case 6: |
247 | __extension__ __u->__sca6 = __src6; |
248 | break; |
249 | case 7: |
250 | __extension__ __u->__sca7 = __src7; |
251 | break; |
252 | case 8: |
253 | __extension__ __u->__sca8 = __src8; |
254 | break; |
255 | } |
256 | return __extension__ ((void *) __u + __srclen); |
257 | } |
258 | # endif |
259 | compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1); |
260 | |
261 | # if _STRING_INLINE_unaligned |
262 | char * |
263 | __old_strcpy_small (char *__dest, |
264 | __uint16_t __src0_2, __uint16_t __src4_2, |
265 | __uint32_t __src0_4, __uint32_t __src4_4, |
266 | size_t __srclen) |
267 | { |
268 | union { |
269 | __uint32_t __ui; |
270 | __uint16_t __usi; |
271 | unsigned char __uc; |
272 | } *__u = (void *) __dest; |
273 | switch ((unsigned int) __srclen) |
274 | { |
275 | case 1: |
276 | __u->__uc = '\0'; |
277 | break; |
278 | case 2: |
279 | __u->__usi = __src0_2; |
280 | break; |
281 | case 3: |
282 | __u->__usi = __src0_2; |
283 | __u = __extension__ ((void *) __u + 2); |
284 | __u->__uc = '\0'; |
285 | break; |
286 | case 4: |
287 | __u->__ui = __src0_4; |
288 | break; |
289 | case 5: |
290 | __u->__ui = __src0_4; |
291 | __u = __extension__ ((void *) __u + 4); |
292 | __u->__uc = '\0'; |
293 | break; |
294 | case 6: |
295 | __u->__ui = __src0_4; |
296 | __u = __extension__ ((void *) __u + 4); |
297 | __u->__usi = __src4_2; |
298 | break; |
299 | case 7: |
300 | __u->__ui = __src0_4; |
301 | __u = __extension__ ((void *) __u + 4); |
302 | __u->__usi = __src4_2; |
303 | __u = __extension__ ((void *) __u + 2); |
304 | __u->__uc = '\0'; |
305 | break; |
306 | case 8: |
307 | __u->__ui = __src0_4; |
308 | __u = __extension__ ((void *) __u + 4); |
309 | __u->__ui = __src4_4; |
310 | break; |
311 | } |
312 | return __dest; |
313 | } |
314 | |
315 | # else |
316 | |
317 | char * |
318 | __old_strcpy_small (char *__dest, |
319 | __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, |
320 | __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, |
321 | __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, |
322 | __STRING2_COPY_ARR8 __src8, size_t __srclen) |
323 | { |
324 | union { |
325 | char __c; |
326 | __STRING2_COPY_ARR2 __sca2; |
327 | __STRING2_COPY_ARR3 __sca3; |
328 | __STRING2_COPY_ARR4 __sca4; |
329 | __STRING2_COPY_ARR5 __sca5; |
330 | __STRING2_COPY_ARR6 __sca6; |
331 | __STRING2_COPY_ARR7 __sca7; |
332 | __STRING2_COPY_ARR8 __sca8; |
333 | } *__u = (void *) __dest; |
334 | switch ((unsigned int) __srclen) |
335 | { |
336 | case 1: |
337 | __u->__c = '\0'; |
338 | break; |
339 | case 2: |
340 | __extension__ __u->__sca2 = __src2; |
341 | break; |
342 | case 3: |
343 | __extension__ __u->__sca3 = __src3; |
344 | break; |
345 | case 4: |
346 | __extension__ __u->__sca4 = __src4; |
347 | break; |
348 | case 5: |
349 | __extension__ __u->__sca5 = __src5; |
350 | break; |
351 | case 6: |
352 | __extension__ __u->__sca6 = __src6; |
353 | break; |
354 | case 7: |
355 | __extension__ __u->__sca7 = __src7; |
356 | break; |
357 | case 8: |
358 | __extension__ __u->__sca8 = __src8; |
359 | break; |
360 | } |
361 | return __dest; |
362 | } |
363 | # endif |
364 | compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1); |
365 | |
366 | # if _STRING_INLINE_unaligned |
367 | char * |
368 | __old_stpcpy_small (char *__dest, |
369 | __uint16_t __src0_2, __uint16_t __src4_2, |
370 | __uint32_t __src0_4, __uint32_t __src4_4, |
371 | size_t __srclen) |
372 | { |
373 | union { |
374 | unsigned int __ui; |
375 | unsigned short int __usi; |
376 | unsigned char __uc; |
377 | char __c; |
378 | } *__u = (void *) __dest; |
379 | switch ((unsigned int) __srclen) |
380 | { |
381 | case 1: |
382 | __u->__uc = '\0'; |
383 | break; |
384 | case 2: |
385 | __u->__usi = __src0_2; |
386 | __u = __extension__ ((void *) __u + 1); |
387 | break; |
388 | case 3: |
389 | __u->__usi = __src0_2; |
390 | __u = __extension__ ((void *) __u + 2); |
391 | __u->__uc = '\0'; |
392 | break; |
393 | case 4: |
394 | __u->__ui = __src0_4; |
395 | __u = __extension__ ((void *) __u + 3); |
396 | break; |
397 | case 5: |
398 | __u->__ui = __src0_4; |
399 | __u = __extension__ ((void *) __u + 4); |
400 | __u->__uc = '\0'; |
401 | break; |
402 | case 6: |
403 | __u->__ui = __src0_4; |
404 | __u = __extension__ ((void *) __u + 4); |
405 | __u->__usi = __src4_2; |
406 | __u = __extension__ ((void *) __u + 1); |
407 | break; |
408 | case 7: |
409 | __u->__ui = __src0_4; |
410 | __u = __extension__ ((void *) __u + 4); |
411 | __u->__usi = __src4_2; |
412 | __u = __extension__ ((void *) __u + 2); |
413 | __u->__uc = '\0'; |
414 | break; |
415 | case 8: |
416 | __u->__ui = __src0_4; |
417 | __u = __extension__ ((void *) __u + 4); |
418 | __u->__ui = __src4_4; |
419 | __u = __extension__ ((void *) __u + 3); |
420 | break; |
421 | } |
422 | return &__u->__c; |
423 | } |
424 | |
425 | # else |
426 | |
427 | char * |
428 | __old_stpcpy_small (char *__dest, |
429 | __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3, |
430 | __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5, |
431 | __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7, |
432 | __STRING2_COPY_ARR8 __src8, size_t __srclen) |
433 | { |
434 | union { |
435 | char __c; |
436 | __STRING2_COPY_ARR2 __sca2; |
437 | __STRING2_COPY_ARR3 __sca3; |
438 | __STRING2_COPY_ARR4 __sca4; |
439 | __STRING2_COPY_ARR5 __sca5; |
440 | __STRING2_COPY_ARR6 __sca6; |
441 | __STRING2_COPY_ARR7 __sca7; |
442 | __STRING2_COPY_ARR8 __sca8; |
443 | } *__u = (void *) __dest; |
444 | switch ((unsigned int) __srclen) |
445 | { |
446 | case 1: |
447 | __u->__c = '\0'; |
448 | break; |
449 | case 2: |
450 | __extension__ __u->__sca2 = __src2; |
451 | break; |
452 | case 3: |
453 | __extension__ __u->__sca3 = __src3; |
454 | break; |
455 | case 4: |
456 | __extension__ __u->__sca4 = __src4; |
457 | break; |
458 | case 5: |
459 | __extension__ __u->__sca5 = __src5; |
460 | break; |
461 | case 6: |
462 | __extension__ __u->__sca6 = __src6; |
463 | break; |
464 | case 7: |
465 | __extension__ __u->__sca7 = __src7; |
466 | break; |
467 | case 8: |
468 | __extension__ __u->__sca8 = __src8; |
469 | break; |
470 | } |
471 | return __dest + __srclen - 1; |
472 | } |
473 | # endif |
474 | compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1); |
475 | |
476 | #endif |
477 | |