stdlib.c 26 KB

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