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
43char *
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}
65compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
66
67char *
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}
75compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
76
77char *
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}
102compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
103
104char *
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}
129compat_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). */
136size_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}
144compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
145
146size_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}
155compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
156
157size_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}
167compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
168
169size_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}
178compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
179
180size_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}
189compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
190
191size_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}
202compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
203
204char *
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}
212compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
213
214char *
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}
223compat_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
241void *
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
306void *
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
353compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
354
355# if _STRING_INLINE_unaligned
356char *
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
411char *
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
458compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
459
460# if _STRING_INLINE_unaligned
461char *
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
521char *
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
568compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
569
570#endif
571