1 /* Copyright (C) 1999-2022 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 <https://www.gnu.org/licenses/>. */
17
18 /* This file contains compatibility definitions of functions that were
19 formerly defined as "extern inline" in string.h; it's conceivable
20 that old binaries contain references to them. */
21
22 #define __NO_STRING_INLINES
23 #include <string.h>
24
25 #include "shlib-compat.h"
26
27 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_25)
28 /* These functions were removed from string.h in glibc 2.25. */
29
30 char *
__old_strtok_r_1c(char * __s,char __sep,char ** __nextp)31 __old_strtok_r_1c (char *__s, char __sep, char **__nextp)
32 {
33 char *__result;
34 if (__s == NULL)
35 __s = *__nextp;
36 while (*__s == __sep)
37 ++__s;
38 __result = NULL;
39 if (*__s != '\0')
40 {
41 __result = __s++;
42 while (*__s != '\0')
43 if (*__s++ == __sep)
44 {
45 __s[-1] = '\0';
46 break;
47 }
48 }
49 *__nextp = __s;
50 return __result;
51 }
52 compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
53
54 char *
__old_strsep_1c(char ** __s,char __reject)55 __old_strsep_1c (char **__s, char __reject)
56 {
57 char *__retval = *__s;
58 if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
59 *(*__s)++ = '\0';
60 return __retval;
61 }
62 compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
63
64 char *
__old_strsep_2c(char ** __s,char __reject1,char __reject2)65 __old_strsep_2c (char **__s, char __reject1, char __reject2)
66 {
67 char *__retval = *__s;
68 if (__retval != NULL)
69 {
70 char *__cp = __retval;
71 while (1)
72 {
73 if (*__cp == '\0')
74 {
75 __cp = NULL;
76 break;
77 }
78 if (*__cp == __reject1 || *__cp == __reject2)
79 {
80 *__cp++ = '\0';
81 break;
82 }
83 ++__cp;
84 }
85 *__s = __cp;
86 }
87 return __retval;
88 }
89 compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
90
91 char *
__old_strsep_3c(char ** __s,char __reject1,char __reject2,char __reject3)92 __old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
93 {
94 char *__retval = *__s;
95 if (__retval != NULL)
96 {
97 char *__cp = __retval;
98 while (1)
99 {
100 if (*__cp == '\0')
101 {
102 __cp = NULL;
103 break;
104 }
105 if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
106 {
107 *__cp++ = '\0';
108 break;
109 }
110 ++__cp;
111 }
112 *__s = __cp;
113 }
114 return __retval;
115 }
116 compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
117 #endif
118
119 #if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
120 /* These functions were removed from string.h in glibc 2.24. */
121
122 size_t
__old_strcspn_c1(const char * __s,int __reject)123 __old_strcspn_c1 (const char *__s, int __reject)
124 {
125 size_t __result = 0;
126 while (__s[__result] != '\0' && __s[__result] != __reject)
127 ++__result;
128 return __result;
129 }
130 compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
131
132 size_t
__old_strcspn_c2(const char * __s,int __reject1,int __reject2)133 __old_strcspn_c2 (const char *__s, int __reject1, int __reject2)
134 {
135 size_t __result = 0;
136 while (__s[__result] != '\0' && __s[__result] != __reject1
137 && __s[__result] != __reject2)
138 ++__result;
139 return __result;
140 }
141 compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
142
143 size_t
__old_strcspn_c3(const char * __s,int __reject1,int __reject2,int __reject3)144 __old_strcspn_c3 (const char *__s, int __reject1, int __reject2,
145 int __reject3)
146 {
147 size_t __result = 0;
148 while (__s[__result] != '\0' && __s[__result] != __reject1
149 && __s[__result] != __reject2 && __s[__result] != __reject3)
150 ++__result;
151 return __result;
152 }
153 compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
154
155 size_t
__old_strspn_c1(const char * __s,int __accept)156 __old_strspn_c1 (const char *__s, int __accept)
157 {
158 size_t __result = 0;
159 /* Please note that __accept never can be '\0'. */
160 while (__s[__result] == __accept)
161 ++__result;
162 return __result;
163 }
164 compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
165
166 size_t
__old_strspn_c2(const char * __s,int __accept1,int __accept2)167 __old_strspn_c2 (const char *__s, int __accept1, int __accept2)
168 {
169 size_t __result = 0;
170 /* Please note that __accept1 and __accept2 never can be '\0'. */
171 while (__s[__result] == __accept1 || __s[__result] == __accept2)
172 ++__result;
173 return __result;
174 }
175 compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
176
177 size_t
__old_strspn_c3(const char * __s,int __accept1,int __accept2,int __accept3)178 __old_strspn_c3 (const char *__s, int __accept1, int __accept2,
179 int __accept3)
180 {
181 size_t __result = 0;
182 /* Please note that __accept1 to __accept3 never can be '\0'. */
183 while (__s[__result] == __accept1 || __s[__result] == __accept2
184 || __s[__result] == __accept3)
185 ++__result;
186 return __result;
187 }
188 compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
189
190 char *
__old_strpbrk_c2(const char * __s,int __accept1,int __accept2)191 __old_strpbrk_c2 (const char *__s, int __accept1, int __accept2)
192 {
193 /* Please note that __accept1 and __accept2 never can be '\0'. */
194 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
195 ++__s;
196 return *__s == '\0' ? NULL : (char *) (size_t) __s;
197 }
198 compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
199
200 char *
__old_strpbrk_c3(const char * __s,int __accept1,int __accept2,int __accept3)201 __old_strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
202 {
203 /* Please note that __accept1 to __accept3 never can be '\0'. */
204 while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
205 && *__s != __accept3)
206 ++__s;
207 return *__s == '\0' ? NULL : (char *) (size_t) __s;
208 }
209 compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
210
211 # if defined __mc68020__ || defined __s390__ || defined __i386__
212 # define _STRING_INLINE_unaligned 1
213 # else
214 # define _STRING_INLINE_unaligned 0
215 /* These are a few types we need for the optimizations if we cannot
216 use unaligned memory accesses. */
217 # define __STRING2_COPY_TYPE(N) \
218 typedef struct { unsigned char __arr[N]; } \
219 __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
220 __STRING2_COPY_TYPE (2);
221 __STRING2_COPY_TYPE (3);
222 __STRING2_COPY_TYPE (4);
223 __STRING2_COPY_TYPE (5);
224 __STRING2_COPY_TYPE (6);
225 __STRING2_COPY_TYPE (7);
226 __STRING2_COPY_TYPE (8);
227 # undef __STRING2_COPY_TYPE
228 # endif
229
230 # if _STRING_INLINE_unaligned
231 void *
__old_mempcpy_small(void * __dest1,char __src0_1,char __src2_1,char __src4_1,char __src6_1,__uint16_t __src0_2,__uint16_t __src4_2,__uint32_t __src0_4,__uint32_t __src4_4,size_t __srclen)232 __old_mempcpy_small (void *__dest1,
233 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
234 __uint16_t __src0_2, __uint16_t __src4_2,
235 __uint32_t __src0_4, __uint32_t __src4_4,
236 size_t __srclen)
237 {
238 union {
239 __uint32_t __ui;
240 __uint16_t __usi;
241 unsigned char __uc;
242 unsigned char __c;
243 } *__u = __dest1;
244 switch ((unsigned int) __srclen)
245 {
246 case 1:
247 __u->__c = __src0_1;
248 __u = __extension__ ((void *) __u + 1);
249 break;
250 case 2:
251 __u->__usi = __src0_2;
252 __u = __extension__ ((void *) __u + 2);
253 break;
254 case 3:
255 __u->__usi = __src0_2;
256 __u = __extension__ ((void *) __u + 2);
257 __u->__c = __src2_1;
258 __u = __extension__ ((void *) __u + 1);
259 break;
260 case 4:
261 __u->__ui = __src0_4;
262 __u = __extension__ ((void *) __u + 4);
263 break;
264 case 5:
265 __u->__ui = __src0_4;
266 __u = __extension__ ((void *) __u + 4);
267 __u->__c = __src4_1;
268 __u = __extension__ ((void *) __u + 1);
269 break;
270 case 6:
271 __u->__ui = __src0_4;
272 __u = __extension__ ((void *) __u + 4);
273 __u->__usi = __src4_2;
274 __u = __extension__ ((void *) __u + 2);
275 break;
276 case 7:
277 __u->__ui = __src0_4;
278 __u = __extension__ ((void *) __u + 4);
279 __u->__usi = __src4_2;
280 __u = __extension__ ((void *) __u + 2);
281 __u->__c = __src6_1;
282 __u = __extension__ ((void *) __u + 1);
283 break;
284 case 8:
285 __u->__ui = __src0_4;
286 __u = __extension__ ((void *) __u + 4);
287 __u->__ui = __src4_4;
288 __u = __extension__ ((void *) __u + 4);
289 break;
290 }
291 return (void *) __u;
292 }
293
294 # else
295
296 void *
__old_mempcpy_small(void * __dest,char __src1,__STRING2_COPY_ARR2 __src2,__STRING2_COPY_ARR3 __src3,__STRING2_COPY_ARR4 __src4,__STRING2_COPY_ARR5 __src5,__STRING2_COPY_ARR6 __src6,__STRING2_COPY_ARR7 __src7,__STRING2_COPY_ARR8 __src8,size_t __srclen)297 __old_mempcpy_small (void *__dest, char __src1,
298 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
299 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
300 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
301 __STRING2_COPY_ARR8 __src8, size_t __srclen)
302 {
303 union {
304 char __c;
305 __STRING2_COPY_ARR2 __sca2;
306 __STRING2_COPY_ARR3 __sca3;
307 __STRING2_COPY_ARR4 __sca4;
308 __STRING2_COPY_ARR5 __sca5;
309 __STRING2_COPY_ARR6 __sca6;
310 __STRING2_COPY_ARR7 __sca7;
311 __STRING2_COPY_ARR8 __sca8;
312 } *__u = __dest;
313 switch ((unsigned int) __srclen)
314 {
315 case 1:
316 __u->__c = __src1;
317 break;
318 case 2:
319 __extension__ __u->__sca2 = __src2;
320 break;
321 case 3:
322 __extension__ __u->__sca3 = __src3;
323 break;
324 case 4:
325 __extension__ __u->__sca4 = __src4;
326 break;
327 case 5:
328 __extension__ __u->__sca5 = __src5;
329 break;
330 case 6:
331 __extension__ __u->__sca6 = __src6;
332 break;
333 case 7:
334 __extension__ __u->__sca7 = __src7;
335 break;
336 case 8:
337 __extension__ __u->__sca8 = __src8;
338 break;
339 }
340 return __extension__ ((void *) __u + __srclen);
341 }
342 # endif
343 compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
344
345 # if _STRING_INLINE_unaligned
346 char *
__old_strcpy_small(char * __dest,__uint16_t __src0_2,__uint16_t __src4_2,__uint32_t __src0_4,__uint32_t __src4_4,size_t __srclen)347 __old_strcpy_small (char *__dest,
348 __uint16_t __src0_2, __uint16_t __src4_2,
349 __uint32_t __src0_4, __uint32_t __src4_4,
350 size_t __srclen)
351 {
352 union {
353 __uint32_t __ui;
354 __uint16_t __usi;
355 unsigned char __uc;
356 } *__u = (void *) __dest;
357 switch ((unsigned int) __srclen)
358 {
359 case 1:
360 __u->__uc = '\0';
361 break;
362 case 2:
363 __u->__usi = __src0_2;
364 break;
365 case 3:
366 __u->__usi = __src0_2;
367 __u = __extension__ ((void *) __u + 2);
368 __u->__uc = '\0';
369 break;
370 case 4:
371 __u->__ui = __src0_4;
372 break;
373 case 5:
374 __u->__ui = __src0_4;
375 __u = __extension__ ((void *) __u + 4);
376 __u->__uc = '\0';
377 break;
378 case 6:
379 __u->__ui = __src0_4;
380 __u = __extension__ ((void *) __u + 4);
381 __u->__usi = __src4_2;
382 break;
383 case 7:
384 __u->__ui = __src0_4;
385 __u = __extension__ ((void *) __u + 4);
386 __u->__usi = __src4_2;
387 __u = __extension__ ((void *) __u + 2);
388 __u->__uc = '\0';
389 break;
390 case 8:
391 __u->__ui = __src0_4;
392 __u = __extension__ ((void *) __u + 4);
393 __u->__ui = __src4_4;
394 break;
395 }
396 return __dest;
397 }
398
399 # else
400
401 char *
__old_strcpy_small(char * __dest,__STRING2_COPY_ARR2 __src2,__STRING2_COPY_ARR3 __src3,__STRING2_COPY_ARR4 __src4,__STRING2_COPY_ARR5 __src5,__STRING2_COPY_ARR6 __src6,__STRING2_COPY_ARR7 __src7,__STRING2_COPY_ARR8 __src8,size_t __srclen)402 __old_strcpy_small (char *__dest,
403 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
404 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
405 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
406 __STRING2_COPY_ARR8 __src8, size_t __srclen)
407 {
408 union {
409 char __c;
410 __STRING2_COPY_ARR2 __sca2;
411 __STRING2_COPY_ARR3 __sca3;
412 __STRING2_COPY_ARR4 __sca4;
413 __STRING2_COPY_ARR5 __sca5;
414 __STRING2_COPY_ARR6 __sca6;
415 __STRING2_COPY_ARR7 __sca7;
416 __STRING2_COPY_ARR8 __sca8;
417 } *__u = (void *) __dest;
418 switch ((unsigned int) __srclen)
419 {
420 case 1:
421 __u->__c = '\0';
422 break;
423 case 2:
424 __extension__ __u->__sca2 = __src2;
425 break;
426 case 3:
427 __extension__ __u->__sca3 = __src3;
428 break;
429 case 4:
430 __extension__ __u->__sca4 = __src4;
431 break;
432 case 5:
433 __extension__ __u->__sca5 = __src5;
434 break;
435 case 6:
436 __extension__ __u->__sca6 = __src6;
437 break;
438 case 7:
439 __extension__ __u->__sca7 = __src7;
440 break;
441 case 8:
442 __extension__ __u->__sca8 = __src8;
443 break;
444 }
445 return __dest;
446 }
447 # endif
448 compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
449
450 # if _STRING_INLINE_unaligned
451 char *
__old_stpcpy_small(char * __dest,__uint16_t __src0_2,__uint16_t __src4_2,__uint32_t __src0_4,__uint32_t __src4_4,size_t __srclen)452 __old_stpcpy_small (char *__dest,
453 __uint16_t __src0_2, __uint16_t __src4_2,
454 __uint32_t __src0_4, __uint32_t __src4_4,
455 size_t __srclen)
456 {
457 union {
458 unsigned int __ui;
459 unsigned short int __usi;
460 unsigned char __uc;
461 char __c;
462 } *__u = (void *) __dest;
463 switch ((unsigned int) __srclen)
464 {
465 case 1:
466 __u->__uc = '\0';
467 break;
468 case 2:
469 __u->__usi = __src0_2;
470 __u = __extension__ ((void *) __u + 1);
471 break;
472 case 3:
473 __u->__usi = __src0_2;
474 __u = __extension__ ((void *) __u + 2);
475 __u->__uc = '\0';
476 break;
477 case 4:
478 __u->__ui = __src0_4;
479 __u = __extension__ ((void *) __u + 3);
480 break;
481 case 5:
482 __u->__ui = __src0_4;
483 __u = __extension__ ((void *) __u + 4);
484 __u->__uc = '\0';
485 break;
486 case 6:
487 __u->__ui = __src0_4;
488 __u = __extension__ ((void *) __u + 4);
489 __u->__usi = __src4_2;
490 __u = __extension__ ((void *) __u + 1);
491 break;
492 case 7:
493 __u->__ui = __src0_4;
494 __u = __extension__ ((void *) __u + 4);
495 __u->__usi = __src4_2;
496 __u = __extension__ ((void *) __u + 2);
497 __u->__uc = '\0';
498 break;
499 case 8:
500 __u->__ui = __src0_4;
501 __u = __extension__ ((void *) __u + 4);
502 __u->__ui = __src4_4;
503 __u = __extension__ ((void *) __u + 3);
504 break;
505 }
506 return &__u->__c;
507 }
508
509 # else
510
511 char *
__old_stpcpy_small(char * __dest,__STRING2_COPY_ARR2 __src2,__STRING2_COPY_ARR3 __src3,__STRING2_COPY_ARR4 __src4,__STRING2_COPY_ARR5 __src5,__STRING2_COPY_ARR6 __src6,__STRING2_COPY_ARR7 __src7,__STRING2_COPY_ARR8 __src8,size_t __srclen)512 __old_stpcpy_small (char *__dest,
513 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
514 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
515 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
516 __STRING2_COPY_ARR8 __src8, size_t __srclen)
517 {
518 union {
519 char __c;
520 __STRING2_COPY_ARR2 __sca2;
521 __STRING2_COPY_ARR3 __sca3;
522 __STRING2_COPY_ARR4 __sca4;
523 __STRING2_COPY_ARR5 __sca5;
524 __STRING2_COPY_ARR6 __sca6;
525 __STRING2_COPY_ARR7 __sca7;
526 __STRING2_COPY_ARR8 __sca8;
527 } *__u = (void *) __dest;
528 switch ((unsigned int) __srclen)
529 {
530 case 1:
531 __u->__c = '\0';
532 break;
533 case 2:
534 __extension__ __u->__sca2 = __src2;
535 break;
536 case 3:
537 __extension__ __u->__sca3 = __src3;
538 break;
539 case 4:
540 __extension__ __u->__sca4 = __src4;
541 break;
542 case 5:
543 __extension__ __u->__sca5 = __src5;
544 break;
545 case 6:
546 __extension__ __u->__sca6 = __src6;
547 break;
548 case 7:
549 __extension__ __u->__sca7 = __src7;
550 break;
551 case 8:
552 __extension__ __u->__sca8 = __src8;
553 break;
554 }
555 return __dest + __srclen - 1;
556 }
557 # endif
558 compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
559
560 #endif
561