stdlib.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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. #define _ISOC99_SOURCE /* for ULLONG primarily... */
  27. #define _GNU_SOURCE
  28. #include <limits.h>
  29. #include <stdint.h>
  30. #include <inttypes.h>
  31. #include <ctype.h>
  32. #include <errno.h>
  33. #include <assert.h>
  34. #include <unistd.h>
  35. /* Work around gcc's refusal to create aliases. */
  36. #define atoi __ignore_atoi
  37. #define abs __ignore_abs
  38. #include <stdlib.h>
  39. #undef atoi
  40. #undef abs
  41. extern unsigned long
  42. _stdlib_strto_l(register const char * __restrict str,
  43. char ** __restrict endptr, int base, int sflag);
  44. #if defined(ULLONG_MAX)
  45. extern unsigned long long
  46. _stdlib_strto_ll(register const char * __restrict str,
  47. char ** __restrict endptr, int base, int sflag);
  48. #endif
  49. /**********************************************************************/
  50. #ifdef L_atof
  51. double atof(const char *nptr)
  52. {
  53. return strtod(nptr, (char **) NULL);
  54. }
  55. #endif
  56. /**********************************************************************/
  57. #ifdef L_abs
  58. #if UINT_MAX < ULONG_MAX
  59. int abs(int j)
  60. {
  61. return (j >= 0) ? j : -j;
  62. }
  63. #endif /* UINT_MAX < ULONG_MAX */
  64. #endif
  65. /**********************************************************************/
  66. #ifdef L_labs
  67. #if UINT_MAX == ULONG_MAX
  68. strong_alias(labs,abs)
  69. #endif
  70. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  71. long long int llabs (long long int j)
  72. {
  73. return (j >= 0) ? j : -j;
  74. }
  75. #endif
  76. #if ULONG_MAX == UINTMAX_MAX
  77. strong_alias(labs,imaxabs)
  78. #endif
  79. long int labs(long int j)
  80. {
  81. return (j >= 0) ? j : -j;
  82. }
  83. #endif
  84. /**********************************************************************/
  85. #ifdef L_llabs
  86. #if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)
  87. #if (ULLONG_MAX == UINTMAX_MAX)
  88. strong_alias(llabs,imaxabs)
  89. #endif
  90. long long int llabs(long long int j)
  91. {
  92. return (j >= 0) ? j : -j;
  93. }
  94. #endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */
  95. #endif
  96. /**********************************************************************/
  97. #ifdef L_atoi
  98. #if UINT_MAX < ULONG_MAX
  99. int atoi(const char *nptr)
  100. {
  101. return (int) strtol(nptr, (char **) NULL, 10);
  102. }
  103. #endif /* UINT_MAX < ULONG_MAX */
  104. #endif
  105. /**********************************************************************/
  106. #ifdef L_atol
  107. #if UINT_MAX == ULONG_MAX
  108. strong_alias(atol,atoi)
  109. #endif
  110. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  111. long long int atoll (const char *nptr)
  112. {
  113. return strtol(nptr, (char **) NULL, 10);
  114. }
  115. #endif
  116. long atol(const char *nptr)
  117. {
  118. return strtol(nptr, (char **) NULL, 10);
  119. }
  120. #endif
  121. /**********************************************************************/
  122. #ifdef L_atoll
  123. #if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)
  124. long long atoll(const char *nptr)
  125. {
  126. return strtoll(nptr, (char **) NULL, 10);
  127. }
  128. #endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */
  129. #endif
  130. /**********************************************************************/
  131. #ifdef L_strtol
  132. #if ULONG_MAX == UINTMAX_MAX
  133. strong_alias(strtol,strtoimax)
  134. #endif
  135. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  136. long long int strtoll (__const char *__restrict str, char **__restrict endptr, int base)
  137. {
  138. return _stdlib_strto_l(str, endptr, base, 1);
  139. }
  140. #endif
  141. long strtol(const char * __restrict str, char ** __restrict endptr, int base)
  142. {
  143. return _stdlib_strto_l(str, endptr, base, 1);
  144. }
  145. #endif
  146. /**********************************************************************/
  147. #ifdef L_strtoll
  148. #if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)
  149. #if (ULLONG_MAX == UINTMAX_MAX)
  150. strong_alias(strtoll,strtoimax)
  151. #endif
  152. long long strtoll(const char * __restrict str,
  153. char ** __restrict endptr, int base)
  154. {
  155. return (long long) _stdlib_strto_ll(str, endptr, base, 1);
  156. }
  157. #endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */
  158. #endif
  159. /**********************************************************************/
  160. #ifdef L_strtoul
  161. #if ULONG_MAX == UINTMAX_MAX
  162. strong_alias(strtoul,strtoumax)
  163. #endif
  164. #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
  165. unsigned long long int strtoull (__const char *__restrict str,
  166. char **__restrict endptr, int base)
  167. {
  168. return _stdlib_strto_l(str, endptr, base, 0);
  169. }
  170. #endif
  171. unsigned long strtoul(const char * __restrict str,
  172. char ** __restrict endptr, int base)
  173. {
  174. return _stdlib_strto_l(str, endptr, base, 0);
  175. }
  176. #endif
  177. /**********************************************************************/
  178. #ifdef L_strtoull
  179. #if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)
  180. #if (ULLONG_MAX == UINTMAX_MAX)
  181. strong_alias(strtoull,strtoumax)
  182. #endif
  183. unsigned long long strtoull(const char * __restrict str,
  184. char ** __restrict endptr, int base)
  185. {
  186. return _stdlib_strto_ll(str, endptr, base, 0);
  187. }
  188. #endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */
  189. #endif
  190. /**********************************************************************/
  191. /* Support routines follow */
  192. /**********************************************************************/
  193. /* Set if we want errno set appropriately. */
  194. /* NOTE: Implies _STRTO_ENDPTR below */
  195. #define _STRTO_ERRNO 1
  196. /* Set if we want support for the endptr arg. */
  197. /* Implied by _STRTO_ERRNO. */
  198. #define _STRTO_ENDPTR 1
  199. #if _STRTO_ERRNO
  200. #undef _STRTO_ENDPTR
  201. #define _STRTO_ENDPTR 1
  202. #define SET_ERRNO(X) __set_errno(X)
  203. #else
  204. #define SET_ERRNO(X) ((void)(X)) /* keep side effects */
  205. #endif
  206. /**********************************************************************/
  207. #ifdef L__stdlib_strto_l
  208. /* This is the main work fuction which handles both strtol (sflag = 1) and
  209. * strtoul (sflag = 0). */
  210. unsigned long _stdlib_strto_l(register const char * __restrict str,
  211. char ** __restrict endptr, int base, int sflag)
  212. {
  213. unsigned long number, cutoff;
  214. #if _STRTO_ENDPTR
  215. const char *fail_char;
  216. #define SET_FAIL(X) fail_char = (X)
  217. #else
  218. #define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
  219. #endif
  220. unsigned char negative, digit, cutoff_digit;
  221. assert((sflag == 0) || (sflag == 1));
  222. SET_FAIL(str);
  223. while (isspace(*str)) { /* Skip leading whitespace. */
  224. ++str;
  225. }
  226. /* Handle optional sign. */
  227. negative = 0;
  228. switch(*str) {
  229. case '-': negative = 1; /* Fall through to increment str. */
  230. case '+': ++str;
  231. }
  232. if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */
  233. base += 10; /* Default is 10 (26). */
  234. if (*str == '0') {
  235. SET_FAIL(++str);
  236. base -= 2; /* Now base is 8 or 16 (24). */
  237. if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
  238. ++str;
  239. base += base; /* Base is 16 (16 or 48). */
  240. }
  241. }
  242. if (base > 16) { /* Adjust in case base wasn't dynamic. */
  243. base = 16;
  244. }
  245. }
  246. number = 0;
  247. if (((unsigned)(base - 2)) < 35) { /* Legal base. */
  248. cutoff_digit = ULONG_MAX % base;
  249. cutoff = ULONG_MAX / base;
  250. do {
  251. digit = (((unsigned char)(*str - '0')) <= 9)
  252. ? (*str - '0')
  253. : ((*str >= 'A')
  254. ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
  255. : 40);
  256. if (digit >= base) {
  257. break;
  258. }
  259. SET_FAIL(++str);
  260. if ((number > cutoff)
  261. || ((number == cutoff) && (digit > cutoff_digit))) {
  262. number = ULONG_MAX;
  263. negative &= sflag;
  264. SET_ERRNO(ERANGE);
  265. } else {
  266. number = number * base + digit;
  267. }
  268. } while (1);
  269. }
  270. #if _STRTO_ENDPTR
  271. if (endptr) {
  272. *endptr = (char *) fail_char;
  273. }
  274. #endif
  275. {
  276. unsigned long tmp = ((negative)
  277. ? ((unsigned long)(-(1+LONG_MIN)))+1
  278. : LONG_MAX);
  279. if (sflag && (number > tmp)) {
  280. number = tmp;
  281. SET_ERRNO(ERANGE);
  282. }
  283. }
  284. return negative ? (unsigned long)(-((long)number)) : number;
  285. }
  286. #endif
  287. /**********************************************************************/
  288. #ifdef L__stdlib_strto_ll
  289. #if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)
  290. /* This is the main work fuction which handles both strtoll (sflag = 1) and
  291. * strtoull (sflag = 0). */
  292. unsigned long long _stdlib_strto_ll(register const char * __restrict str,
  293. char ** __restrict endptr, int base,
  294. int sflag)
  295. {
  296. unsigned long long number;
  297. #if _STRTO_ENDPTR
  298. const char *fail_char;
  299. #define SET_FAIL(X) fail_char = (X)
  300. #else
  301. #define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
  302. #endif
  303. unsigned int n1;
  304. unsigned char negative, digit;
  305. assert((sflag == 0) || (sflag == 1));
  306. SET_FAIL(str);
  307. while (isspace(*str)) { /* Skip leading whitespace. */
  308. ++str;
  309. }
  310. /* Handle optional sign. */
  311. negative = 0;
  312. switch(*str) {
  313. case '-': negative = 1; /* Fall through to increment str. */
  314. case '+': ++str;
  315. }
  316. if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */
  317. base += 10; /* Default is 10 (26). */
  318. if (*str == '0') {
  319. SET_FAIL(++str);
  320. base -= 2; /* Now base is 8 or 16 (24). */
  321. if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
  322. ++str;
  323. base += base; /* Base is 16 (16 or 48). */
  324. }
  325. }
  326. if (base > 16) { /* Adjust in case base wasn't dynamic. */
  327. base = 16;
  328. }
  329. }
  330. number = 0;
  331. if (((unsigned)(base - 2)) < 35) { /* Legal base. */
  332. do {
  333. digit = (((unsigned char)(*str - '0')) <= 9)
  334. ? (*str - '0')
  335. : ((*str >= 'A')
  336. ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
  337. : 40);
  338. if (digit >= base) {
  339. break;
  340. }
  341. SET_FAIL(++str);
  342. #if 1
  343. /* Optional, but speeds things up in the usual case. */
  344. if (number <= (ULLONG_MAX >> 6)) {
  345. number = number * base + digit;
  346. } else
  347. #endif
  348. {
  349. n1 = ((unsigned char) number) * base + digit;
  350. number = (number >> CHAR_BIT) * base;
  351. if (number + (n1 >> CHAR_BIT) <= (ULLONG_MAX >> CHAR_BIT)) {
  352. number = (number << CHAR_BIT) + n1;
  353. } else { /* Overflow. */
  354. number = ULLONG_MAX;
  355. negative &= sflag;
  356. SET_ERRNO(ERANGE);
  357. }
  358. }
  359. } while (1);
  360. }
  361. #if _STRTO_ENDPTR
  362. if (endptr) {
  363. *endptr = (char *) fail_char;
  364. }
  365. #endif
  366. {
  367. unsigned long long tmp = ((negative)
  368. ? ((unsigned long long)(-(1+LLONG_MIN)))+1
  369. : LLONG_MAX);
  370. if (sflag && (number > tmp)) {
  371. number = tmp;
  372. SET_ERRNO(ERANGE);
  373. }
  374. }
  375. return negative ? (unsigned long long)(-((long long)number)) : number;
  376. }
  377. #endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */
  378. #endif
  379. /**********************************************************************/
  380. /* Made _Exit() an alias for _exit(), as per C99. */
  381. /* #ifdef L__Exit */
  382. /* void _Exit(int status) */
  383. /* { */
  384. /* _exit(status); */
  385. /* } */
  386. /* #endif */
  387. /**********************************************************************/
  388. #ifdef L_bsearch
  389. void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
  390. size_t size, int (*compar)(const void *, const void *))
  391. {
  392. register char *p;
  393. size_t low;
  394. size_t mid;
  395. int r;
  396. if (size > 0) { /* TODO: change this to an assert?? */
  397. low = 0;
  398. while (low < high) {
  399. mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */
  400. p = ((char *)base) + mid * size; /* Could overflow here... */
  401. r = (*compar)(key, p); /* but that's an application problem! */
  402. if (r > 0) {
  403. low = mid + 1;
  404. } else if (r < 0) {
  405. high = mid;
  406. } else {
  407. return p;
  408. }
  409. }
  410. }
  411. return NULL;
  412. }
  413. #endif
  414. /**********************************************************************/
  415. #ifdef L_qsort
  416. /* This code is derived from a public domain shell sort routine by
  417. * Ray Gardner and found in Bob Stout's snippets collection. The
  418. * original code is included below in an #if 0/#endif block.
  419. *
  420. * I modified it to avoid the possibility of overflow in the wgap
  421. * calculation, as well as to reduce the generated code size with
  422. * bcc and gcc. */
  423. void qsort (void *base,
  424. size_t nel,
  425. size_t width,
  426. int (*comp)(const void *, const void *))
  427. {
  428. size_t wgap, i, j, k;
  429. char tmp;
  430. if ((nel > 1) && (width > 0)) {
  431. assert( nel <= ((size_t)(-1)) / width ); /* check for overflow */
  432. wgap = 0;
  433. do {
  434. wgap = 3 * wgap + 1;
  435. } while (wgap < (nel-1)/3);
  436. /* From the above, we know that either wgap == 1 < nel or */
  437. /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
  438. wgap *= width; /* So this can not overflow if wnel doesn't. */
  439. nel *= width; /* Convert nel to 'wnel' */
  440. do {
  441. i = wgap;
  442. do {
  443. j = i;
  444. do {
  445. register char *a;
  446. register char *b;
  447. j -= wgap;
  448. a = j + ((char *)base);
  449. b = a + wgap;
  450. if ( (*comp)(a, b) <= 0 ) {
  451. break;
  452. }
  453. k = width;
  454. do {
  455. tmp = *a;
  456. *a++ = *b;
  457. *b++ = tmp;
  458. } while ( --k );
  459. } while (j >= wgap);
  460. i += width;
  461. } while (i < nel);
  462. wgap = (wgap - width)/3;
  463. } while (wgap);
  464. }
  465. }
  466. /* ---------- original snippets version below ---------- */
  467. #if 0
  468. /*
  469. ** ssort() -- Fast, small, qsort()-compatible Shell sort
  470. **
  471. ** by Ray Gardner, public domain 5/90
  472. */
  473. #include <stddef.h>
  474. void ssort (void *base,
  475. size_t nel,
  476. size_t width,
  477. int (*comp)(const void *, const void *))
  478. {
  479. size_t wnel, gap, wgap, i, j, k;
  480. char *a, *b, tmp;
  481. wnel = width * nel;
  482. for (gap = 0; ++gap < nel;)
  483. gap *= 3;
  484. while ( gap /= 3 )
  485. {
  486. wgap = width * gap;
  487. for (i = wgap; i < wnel; i += width)
  488. {
  489. for (j = i - wgap; ;j -= wgap)
  490. {
  491. a = j + (char *)base;
  492. b = a + wgap;
  493. if ( (*comp)(a, b) <= 0 )
  494. break;
  495. k = width;
  496. do
  497. {
  498. tmp = *a;
  499. *a++ = *b;
  500. *b++ = tmp;
  501. } while ( --k );
  502. if (j < wgap)
  503. break;
  504. }
  505. }
  506. }
  507. }
  508. #endif
  509. #endif
  510. /**********************************************************************/