stdlib.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. /* Copyright (C) 2002 Manuel Novoa III
  2. * From my (incomplete) stdlib library for linux and (soon) elks.
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This 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. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the Free
  16. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
  19. *
  20. * This code is currently under development. Also, I plan to port
  21. * it to elks which is a 16-bit environment with a fairly limited
  22. * compiler. Therefore, please refrain from modifying this code
  23. * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel
  24. *
  25. * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
  26. /* Oct 29, 2002
  27. * Fix a couple of 'restrict' bugs in mbstowcs and wcstombs.
  28. *
  29. * Nov 21, 2002
  30. * Add wscto{inttype} functions.
  31. */
  32. #define _ISOC99_SOURCE /* for ULLONG primarily... */
  33. #define _GNU_SOURCE
  34. #include <limits.h>
  35. #include <stdint.h>
  36. #include <inttypes.h>
  37. #include <ctype.h>
  38. #include <errno.h>
  39. #include <assert.h>
  40. #include <unistd.h>
  41. /* Work around gcc's refusal to create aliases.
  42. * TODO: Add in a define to disable the aliases? */
  43. #if UINT_MAX == ULONG_MAX
  44. #define atoi __ignore_atoi
  45. #define abs __ignore_abs
  46. #endif
  47. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  48. #define llabs __ignore_llabs
  49. #define atoll __ignore_atoll
  50. #define strtoll __ignore_strtoll
  51. #define strtoull __ignore_strtoull
  52. #define wcstoll __ignore_wcstoll
  53. #define wcstoull __ignore_wcstoull
  54. #endif
  55. #include <stdlib.h>
  56. #ifdef __UCLIBC_HAS_WCHAR__
  57. #include <locale.h>
  58. #include <wchar.h>
  59. #include <wctype.h>
  60. /* TODO: clean up the following... */
  61. #if WCHAR_MAX > 0xffffUL
  62. #define UTF_8_MAX_LEN 6
  63. #else
  64. #define UTF_8_MAX_LEN 3
  65. #endif
  66. #ifdef __UCLIBC_HAS_LOCALE__
  67. #define ENCODING (__global_locale.encoding)
  68. #ifndef __CTYPE_HAS_UTF_8_LOCALES
  69. #warning __CTYPE_HAS_UTF_8_LOCALES not set!
  70. #endif
  71. #else
  72. #ifdef __UCLIBC_MJN3_ONLY__
  73. #warning devel checks
  74. #endif
  75. #define ENCODING (__ctype_encoding_7_bit)
  76. #ifdef __CTYPE_HAS_8_BIT_LOCALES
  77. #error __CTYPE_HAS_8_BIT_LOCALES is defined!
  78. #endif
  79. #ifdef __CTYPE_HAS_UTF_8_LOCALES
  80. #error __CTYPE_HAS_UTF_8_LOCALES is defined!
  81. #endif
  82. #endif
  83. #endif
  84. #if UINT_MAX == ULONG_MAX
  85. #undef atoi
  86. #undef abs
  87. #endif
  88. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  89. #undef llabs
  90. #undef atoll
  91. #undef strtoll
  92. #undef strtoull
  93. #undef wcstoll
  94. #undef wcstoull
  95. #endif /* __UCLIBC_HAS_WCHAR__ */
  96. /**********************************************************************/
  97. extern unsigned long
  98. _stdlib_strto_l(register const char * __restrict str,
  99. char ** __restrict endptr, int base, int sflag);
  100. #if defined(ULLONG_MAX)
  101. extern unsigned long long
  102. _stdlib_strto_ll(register const char * __restrict str,
  103. char ** __restrict endptr, int base, int sflag);
  104. #endif
  105. #ifdef __UCLIBC_HAS_WCHAR__
  106. extern unsigned long
  107. _stdlib_wcsto_l(register const wchar_t * __restrict str,
  108. wchar_t ** __restrict endptr, int base, int sflag);
  109. #if defined(ULLONG_MAX)
  110. extern unsigned long long
  111. _stdlib_wcsto_ll(register const wchar_t * __restrict str,
  112. wchar_t ** __restrict endptr, int base, int sflag);
  113. #endif
  114. #endif /* __UCLIBC_HAS_WCHAR__ */
  115. /**********************************************************************/
  116. #ifdef L_atof
  117. double atof(const char *nptr)
  118. {
  119. return strtod(nptr, (char **) NULL);
  120. }
  121. #endif
  122. /**********************************************************************/
  123. #ifdef L_abs
  124. #if INT_MAX < LONG_MAX
  125. int abs(int j)
  126. {
  127. return (j >= 0) ? j : -j;
  128. }
  129. #endif /* INT_MAX < LONG_MAX */
  130. #endif
  131. /**********************************************************************/
  132. #ifdef L_labs
  133. #if UINT_MAX == ULONG_MAX
  134. strong_alias(labs,abs)
  135. #endif
  136. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  137. strong_alias(labs,llabs)
  138. #endif
  139. #if ULONG_MAX == UINTMAX_MAX
  140. strong_alias(labs,imaxabs)
  141. #endif
  142. long int labs(long int j)
  143. {
  144. return (j >= 0) ? j : -j;
  145. }
  146. #endif
  147. /**********************************************************************/
  148. #ifdef L_llabs
  149. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  150. #if (ULLONG_MAX == UINTMAX_MAX)
  151. strong_alias(llabs,imaxabs)
  152. #endif
  153. long long int llabs(long long int j)
  154. {
  155. return (j >= 0) ? j : -j;
  156. }
  157. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  158. #endif
  159. /**********************************************************************/
  160. #ifdef L_atoi
  161. #if INT_MAX < LONG_MAX
  162. int atoi(const char *nptr)
  163. {
  164. return (int) strtol(nptr, (char **) NULL, 10);
  165. }
  166. #endif /* INT_MAX < LONG_MAX */
  167. #endif
  168. /**********************************************************************/
  169. #ifdef L_atol
  170. #if UINT_MAX == ULONG_MAX
  171. strong_alias(atol,atoi)
  172. #endif
  173. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  174. strong_alias(atol,atoll)
  175. #endif
  176. long atol(const char *nptr)
  177. {
  178. return strtol(nptr, (char **) NULL, 10);
  179. }
  180. #endif
  181. /**********************************************************************/
  182. #ifdef L_atoll
  183. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  184. long long atoll(const char *nptr)
  185. {
  186. return strtoll(nptr, (char **) NULL, 10);
  187. }
  188. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  189. #endif
  190. /**********************************************************************/
  191. #ifdef L_strtol
  192. #if ULONG_MAX == UINTMAX_MAX
  193. strong_alias(strtol,strtoimax)
  194. #endif
  195. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  196. strong_alias(strtol,strtoll)
  197. #endif
  198. long strtol(const char * __restrict str, char ** __restrict endptr, int base)
  199. {
  200. return _stdlib_strto_l(str, endptr, base, 1);
  201. }
  202. #endif
  203. /**********************************************************************/
  204. #ifdef L_strtoll
  205. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  206. #if (ULLONG_MAX == UINTMAX_MAX)
  207. strong_alias(strtoll,strtoimax)
  208. #endif
  209. strong_alias(strtoll,strtoq)
  210. long long strtoll(const char * __restrict str,
  211. char ** __restrict endptr, int base)
  212. {
  213. return (long long) _stdlib_strto_ll(str, endptr, base, 1);
  214. }
  215. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  216. #endif
  217. /**********************************************************************/
  218. #ifdef L_strtoul
  219. #if ULONG_MAX == UINTMAX_MAX
  220. strong_alias(strtoul,strtoumax)
  221. #endif
  222. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  223. strong_alias(strtoul,strtoull)
  224. #endif
  225. unsigned long strtoul(const char * __restrict str,
  226. char ** __restrict endptr, int base)
  227. {
  228. return _stdlib_strto_l(str, endptr, base, 0);
  229. }
  230. #endif
  231. /**********************************************************************/
  232. #ifdef L_strtoull
  233. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  234. #if (ULLONG_MAX == UINTMAX_MAX)
  235. strong_alias(strtoull,strtoumax)
  236. #endif
  237. strong_alias(strtoull,strtouq)
  238. unsigned long long strtoull(const char * __restrict str,
  239. char ** __restrict endptr, int base)
  240. {
  241. return _stdlib_strto_ll(str, endptr, base, 0);
  242. }
  243. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  244. #endif
  245. /**********************************************************************/
  246. /* Support routines follow */
  247. /**********************************************************************/
  248. /* Set if we want errno set appropriately. */
  249. /* NOTE: Implies _STRTO_ENDPTR below */
  250. #define _STRTO_ERRNO 1
  251. /* Set if we want support for the endptr arg. */
  252. /* Implied by _STRTO_ERRNO. */
  253. #define _STRTO_ENDPTR 1
  254. #if _STRTO_ERRNO
  255. #undef _STRTO_ENDPTR
  256. #define _STRTO_ENDPTR 1
  257. #define SET_ERRNO(X) __set_errno(X)
  258. #else
  259. #define SET_ERRNO(X) ((void)(X)) /* keep side effects */
  260. #endif
  261. /**********************************************************************/
  262. #ifdef L__stdlib_wcsto_l
  263. #define L__stdlib_strto_l
  264. #endif
  265. #ifdef L__stdlib_strto_l
  266. #ifdef L__stdlib_wcsto_l
  267. #define _stdlib_strto_l _stdlib_wcsto_l
  268. #define Wchar wchar_t
  269. #define ISSPACE iswspace
  270. #else
  271. #define Wchar char
  272. #define ISSPACE isspace
  273. #endif
  274. /* This is the main work fuction which handles both strtol (sflag = 1) and
  275. * strtoul (sflag = 0). */
  276. unsigned long _stdlib_strto_l(register const Wchar * __restrict str,
  277. Wchar ** __restrict endptr, int base, int sflag)
  278. {
  279. unsigned long number, cutoff;
  280. #if _STRTO_ENDPTR
  281. const Wchar *fail_char;
  282. #define SET_FAIL(X) fail_char = (X)
  283. #else
  284. #define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
  285. #endif
  286. unsigned char negative, digit, cutoff_digit;
  287. assert(((unsigned int)sflag) <= 1);
  288. SET_FAIL(str);
  289. while (ISSPACE(*str)) { /* Skip leading whitespace. */
  290. ++str;
  291. }
  292. /* Handle optional sign. */
  293. negative = 0;
  294. switch(*str) {
  295. case '-': negative = 1; /* Fall through to increment str. */
  296. case '+': ++str;
  297. }
  298. if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */
  299. base += 10; /* Default is 10 (26). */
  300. if (*str == '0') {
  301. SET_FAIL(++str);
  302. base -= 2; /* Now base is 8 or 16 (24). */
  303. if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
  304. ++str;
  305. base += base; /* Base is 16 (16 or 48). */
  306. }
  307. }
  308. if (base > 16) { /* Adjust in case base wasn't dynamic. */
  309. base = 16;
  310. }
  311. }
  312. number = 0;
  313. if (((unsigned)(base - 2)) < 35) { /* Legal base. */
  314. cutoff_digit = ULONG_MAX % base;
  315. cutoff = ULONG_MAX / base;
  316. do {
  317. digit = (((unsigned char)(*str - '0')) <= 9)
  318. ? (*str - '0')
  319. : ((*str >= 'A')
  320. ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
  321. : 40);
  322. if (digit >= base) {
  323. break;
  324. }
  325. SET_FAIL(++str);
  326. if ((number > cutoff)
  327. || ((number == cutoff) && (digit > cutoff_digit))) {
  328. number = ULONG_MAX;
  329. negative &= sflag;
  330. SET_ERRNO(ERANGE);
  331. } else {
  332. number = number * base + digit;
  333. }
  334. } while (1);
  335. }
  336. #if _STRTO_ENDPTR
  337. if (endptr) {
  338. *endptr = (Wchar *) fail_char;
  339. }
  340. #endif
  341. {
  342. unsigned long tmp = ((negative)
  343. ? ((unsigned long)(-(1+LONG_MIN)))+1
  344. : LONG_MAX);
  345. if (sflag && (number > tmp)) {
  346. number = tmp;
  347. SET_ERRNO(ERANGE);
  348. }
  349. }
  350. return negative ? (unsigned long)(-((long)number)) : number;
  351. }
  352. #endif
  353. /**********************************************************************/
  354. #ifdef L__stdlib_wcsto_ll
  355. #define L__stdlib_strto_ll
  356. #endif
  357. #ifdef L__stdlib_strto_ll
  358. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  359. #ifdef L__stdlib_wcsto_ll
  360. #define _stdlib_strto_ll _stdlib_wcsto_ll
  361. #define Wchar wchar_t
  362. #define ISSPACE iswspace
  363. #else
  364. #define Wchar char
  365. #define ISSPACE isspace
  366. #endif
  367. /* This is the main work fuction which handles both strtoll (sflag = 1) and
  368. * strtoull (sflag = 0). */
  369. unsigned long long _stdlib_strto_ll(register const Wchar * __restrict str,
  370. Wchar ** __restrict endptr, int base,
  371. int sflag)
  372. {
  373. unsigned long long number;
  374. #if _STRTO_ENDPTR
  375. const Wchar *fail_char;
  376. #define SET_FAIL(X) fail_char = (X)
  377. #else
  378. #define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
  379. #endif
  380. unsigned int n1;
  381. unsigned char negative, digit;
  382. assert(((unsigned int)sflag) <= 1);
  383. SET_FAIL(str);
  384. while (ISSPACE(*str)) { /* Skip leading whitespace. */
  385. ++str;
  386. }
  387. /* Handle optional sign. */
  388. negative = 0;
  389. switch(*str) {
  390. case '-': negative = 1; /* Fall through to increment str. */
  391. case '+': ++str;
  392. }
  393. if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */
  394. base += 10; /* Default is 10 (26). */
  395. if (*str == '0') {
  396. SET_FAIL(++str);
  397. base -= 2; /* Now base is 8 or 16 (24). */
  398. if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
  399. ++str;
  400. base += base; /* Base is 16 (16 or 48). */
  401. }
  402. }
  403. if (base > 16) { /* Adjust in case base wasn't dynamic. */
  404. base = 16;
  405. }
  406. }
  407. number = 0;
  408. if (((unsigned)(base - 2)) < 35) { /* Legal base. */
  409. do {
  410. digit = (((unsigned char)(*str - '0')) <= 9)
  411. ? (*str - '0')
  412. : ((*str >= 'A')
  413. ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
  414. : 40);
  415. if (digit >= base) {
  416. break;
  417. }
  418. SET_FAIL(++str);
  419. #if 1
  420. /* Optional, but speeds things up in the usual case. */
  421. if (number <= (ULLONG_MAX >> 6)) {
  422. number = number * base + digit;
  423. } else
  424. #endif
  425. {
  426. n1 = ((unsigned char) number) * base + digit;
  427. number = (number >> CHAR_BIT) * base;
  428. if (number + (n1 >> CHAR_BIT) <= (ULLONG_MAX >> CHAR_BIT)) {
  429. number = (number << CHAR_BIT) + n1;
  430. } else { /* Overflow. */
  431. number = ULLONG_MAX;
  432. negative &= sflag;
  433. SET_ERRNO(ERANGE);
  434. }
  435. }
  436. } while (1);
  437. }
  438. #if _STRTO_ENDPTR
  439. if (endptr) {
  440. *endptr = (Wchar *) fail_char;
  441. }
  442. #endif
  443. {
  444. unsigned long long tmp = ((negative)
  445. ? ((unsigned long long)(-(1+LLONG_MIN)))+1
  446. : LLONG_MAX);
  447. if (sflag && (number > tmp)) {
  448. number = tmp;
  449. SET_ERRNO(ERANGE);
  450. }
  451. }
  452. return negative ? (unsigned long long)(-((long long)number)) : number;
  453. }
  454. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  455. #endif
  456. /**********************************************************************/
  457. /* Made _Exit() an alias for _exit(), as per C99. */
  458. /* #ifdef L__Exit */
  459. /* void _Exit(int status) */
  460. /* { */
  461. /* _exit(status); */
  462. /* } */
  463. /* #endif */
  464. /**********************************************************************/
  465. #ifdef L_bsearch
  466. void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
  467. size_t size, int (*compar)(const void *, const void *))
  468. {
  469. register char *p;
  470. size_t low;
  471. size_t mid;
  472. int r;
  473. if (size > 0) { /* TODO: change this to an assert?? */
  474. low = 0;
  475. while (low < high) {
  476. mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */
  477. p = ((char *)base) + mid * size; /* Could overflow here... */
  478. r = (*compar)(key, p); /* but that's an application problem! */
  479. if (r > 0) {
  480. low = mid + 1;
  481. } else if (r < 0) {
  482. high = mid;
  483. } else {
  484. return p;
  485. }
  486. }
  487. }
  488. return NULL;
  489. }
  490. #endif
  491. /**********************************************************************/
  492. #ifdef L_qsort
  493. /* This code is derived from a public domain shell sort routine by
  494. * Ray Gardner and found in Bob Stout's snippets collection. The
  495. * original code is included below in an #if 0/#endif block.
  496. *
  497. * I modified it to avoid the possibility of overflow in the wgap
  498. * calculation, as well as to reduce the generated code size with
  499. * bcc and gcc. */
  500. void qsort (void *base,
  501. size_t nel,
  502. size_t width,
  503. int (*comp)(const void *, const void *))
  504. {
  505. size_t wgap, i, j, k;
  506. char tmp;
  507. if ((nel > 1) && (width > 0)) {
  508. assert( nel <= ((size_t)(-1)) / width ); /* check for overflow */
  509. wgap = 0;
  510. do {
  511. wgap = 3 * wgap + 1;
  512. } while (wgap < (nel-1)/3);
  513. /* From the above, we know that either wgap == 1 < nel or */
  514. /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
  515. wgap *= width; /* So this can not overflow if wnel doesn't. */
  516. nel *= width; /* Convert nel to 'wnel' */
  517. do {
  518. i = wgap;
  519. do {
  520. j = i;
  521. do {
  522. register char *a;
  523. register char *b;
  524. j -= wgap;
  525. a = j + ((char *)base);
  526. b = a + wgap;
  527. if ( (*comp)(a, b) <= 0 ) {
  528. break;
  529. }
  530. k = width;
  531. do {
  532. tmp = *a;
  533. *a++ = *b;
  534. *b++ = tmp;
  535. } while ( --k );
  536. } while (j >= wgap);
  537. i += width;
  538. } while (i < nel);
  539. wgap = (wgap - width)/3;
  540. } while (wgap);
  541. }
  542. }
  543. /* ---------- original snippets version below ---------- */
  544. #if 0
  545. /*
  546. ** ssort() -- Fast, small, qsort()-compatible Shell sort
  547. **
  548. ** by Ray Gardner, public domain 5/90
  549. */
  550. #include <stddef.h>
  551. void ssort (void *base,
  552. size_t nel,
  553. size_t width,
  554. int (*comp)(const void *, const void *))
  555. {
  556. size_t wnel, gap, wgap, i, j, k;
  557. char *a, *b, tmp;
  558. wnel = width * nel;
  559. for (gap = 0; ++gap < nel;)
  560. gap *= 3;
  561. while ( gap /= 3 )
  562. {
  563. wgap = width * gap;
  564. for (i = wgap; i < wnel; i += width)
  565. {
  566. for (j = i - wgap; ;j -= wgap)
  567. {
  568. a = j + (char *)base;
  569. b = a + wgap;
  570. if ( (*comp)(a, b) <= 0 )
  571. break;
  572. k = width;
  573. do
  574. {
  575. tmp = *a;
  576. *a++ = *b;
  577. *b++ = tmp;
  578. } while ( --k );
  579. if (j < wgap)
  580. break;
  581. }
  582. }
  583. }
  584. }
  585. #endif
  586. #endif
  587. /**********************************************************************/
  588. #ifdef L__stdlib_mb_cur_max
  589. size_t _stdlib_mb_cur_max(void)
  590. {
  591. #ifdef __CTYPE_HAS_UTF_8_LOCALES
  592. return __global_locale.mb_cur_max;
  593. #else
  594. #ifdef __CTYPE_HAS_8_BIT_LOCALES
  595. #ifdef __UCLIBC_MJN3_ONLY__
  596. #warning need to change this when/if transliteration is implemented
  597. #endif
  598. #endif
  599. return 1;
  600. #endif
  601. }
  602. #endif
  603. /**********************************************************************/
  604. #ifdef L_mblen
  605. int mblen(register const char *s, size_t n)
  606. {
  607. static mbstate_t state;
  608. size_t r;
  609. if (!s) {
  610. state.mask = 0;
  611. #ifdef __CTYPE_HAS_UTF_8_LOCALES
  612. return ENCODING == __ctype_encoding_utf8;
  613. #else
  614. return 0;
  615. #endif
  616. }
  617. if ((r = mbrlen(s, n, &state)) == (size_t) -2) {
  618. /* TODO: Should we set an error state? */
  619. state.wc = 0xffffU; /* Make sure we're in an error state. */
  620. return (size_t) -1; /* TODO: Change error code above? */
  621. }
  622. return r;
  623. }
  624. #endif
  625. /**********************************************************************/
  626. #ifdef L_mbtowc
  627. int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n)
  628. {
  629. static mbstate_t state;
  630. size_t r;
  631. if (!s) {
  632. state.mask = 0;
  633. #ifdef __CTYPE_HAS_UTF_8_LOCALES
  634. return ENCODING == __ctype_encoding_utf8;
  635. #else
  636. return 0;
  637. #endif
  638. }
  639. if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) {
  640. /* TODO: Should we set an error state? */
  641. state.wc = 0xffffU; /* Make sure we're in an error state. */
  642. return (size_t) -1; /* TODO: Change error code above? */
  643. }
  644. return r;
  645. }
  646. #endif
  647. /**********************************************************************/
  648. #ifdef L_wctomb
  649. /* Note: We completely ignore state in all currently supported conversions. */
  650. int wctomb(register char *__restrict s, wchar_t swc)
  651. {
  652. return (!s)
  653. ?
  654. #ifdef __CTYPE_HAS_UTF_8_LOCALES
  655. (ENCODING == __ctype_encoding_utf8)
  656. #else
  657. 0 /* Encoding is stateless. */
  658. #endif
  659. : ((ssize_t) wcrtomb(s, swc, NULL));
  660. }
  661. #endif
  662. /**********************************************************************/
  663. #ifdef L_mbstowcs
  664. size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
  665. {
  666. mbstate_t state;
  667. const char *e = s; /* Needed because of restrict. */
  668. state.mask = 0; /* Always start in initial shift state. */
  669. return mbsrtowcs(pwcs, &e, n, &state);
  670. }
  671. #endif
  672. /**********************************************************************/
  673. #ifdef L_wcstombs
  674. /* Note: We completely ignore state in all currently supported conversions. */
  675. size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
  676. {
  677. const wchar_t *e = pwcs; /* Needed because of restrict. */
  678. return wcsrtombs(s, &e, n, NULL);
  679. }
  680. #endif
  681. /**********************************************************************/
  682. #ifdef L_wcstol
  683. #if ULONG_MAX == UINTMAX_MAX
  684. strong_alias(wcstol,wcstoimax)
  685. #endif
  686. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  687. strong_alias(wcstol,wcstoll)
  688. #endif
  689. long wcstol(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base)
  690. {
  691. return _stdlib_wcsto_l(str, endptr, base, 1);
  692. }
  693. #endif
  694. /**********************************************************************/
  695. #ifdef L_wcstoll
  696. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  697. #if (ULLONG_MAX == UINTMAX_MAX)
  698. strong_alias(wcstoll,wcstoimax)
  699. #endif
  700. strong_alias(wcstoll,wcstoq)
  701. long long wcstoll(const wchar_t * __restrict str,
  702. wchar_t ** __restrict endptr, int base)
  703. {
  704. return (long long) _stdlib_wcsto_ll(str, endptr, base, 1);
  705. }
  706. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  707. #endif
  708. /**********************************************************************/
  709. #ifdef L_wcstoul
  710. #if ULONG_MAX == UINTMAX_MAX
  711. strong_alias(wcstoul,wcstoumax)
  712. #endif
  713. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  714. strong_alias(wcstoul,wcstoull)
  715. #endif
  716. unsigned long wcstoul(const wchar_t * __restrict str,
  717. wchar_t ** __restrict endptr, int base)
  718. {
  719. return _stdlib_wcsto_l(str, endptr, base, 0);
  720. }
  721. #endif
  722. /**********************************************************************/
  723. #ifdef L_wcstoull
  724. #if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
  725. #if (ULLONG_MAX == UINTMAX_MAX)
  726. strong_alias(wcstoull,wcstoumax)
  727. #endif
  728. strong_alias(wcstoull,wcstouq)
  729. unsigned long long wcstoull(const wchar_t * __restrict str,
  730. wchar_t ** __restrict endptr, int base)
  731. {
  732. return _stdlib_wcsto_ll(str, endptr, base, 0);
  733. }
  734. #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
  735. #endif
  736. /**********************************************************************/