stdlib.c 14 KB

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