<string.h>: Make strchrnul, strcasestr, memmem available by default
[platform/upstream/glibc.git] / string / string-inlines.c
1 /* Copyright (C) 1999-2023 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 *
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 *
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 *
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 *
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
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
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
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
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
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
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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