string-inlines.c 14 KB

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