stdlib.c 25 KB

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