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). */
42size_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}
50compat_symbol (libc, __old_strcspn_c1, __strcspn_c1, GLIBC_2_1_1);
51
52size_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}
61compat_symbol (libc, __old_strcspn_c2, __strcspn_c2, GLIBC_2_1_1);
62
63size_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}
73compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1);
74
75size_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}
84compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1);
85
86size_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}
95compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1);
96
97size_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}
108compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
109
110char *
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}
118compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
119
120char *
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}
129compat_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
147void *
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
212void *
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
259compat_symbol (libc, __old_mempcpy_small, __mempcpy_small, GLIBC_2_1_1);
260
261# if _STRING_INLINE_unaligned
262char *
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
317char *
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
364compat_symbol (libc, __old_strcpy_small, __strcpy_small, GLIBC_2_1_1);
365
366# if _STRING_INLINE_unaligned
367char *
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
427char *
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
474compat_symbol (libc, __old_stpcpy_small, __stpcpy_small, GLIBC_2_1_1);
475
476#endif
477