/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/Makefile |
---|
0,0 → 1,5 |
THIS_SRCS = abort.c abs.c atexit.c atof.c atoi.c atol.c atold.c bsearch.c \ |
calloc.c div.c exit.c getenv.c labs.c ldiv.c malloc.c qsort.c \ |
rand.c strtod.c strtol.c strtold.c strtoul.c system.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/abort.c |
---|
0,0 → 1,13 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <unistd.h> |
#include <io.h> |
#include <assert.h> |
static char msg[] = "Abort!\n"; |
void abort() |
{ |
__libclog_printf(msg); |
exit(-1); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/abs.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
int |
abs(int j) |
{ |
return j<0 ? -j : j; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/atexit.c |
---|
0,0 → 1,18 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <libc/atexit.h> |
int |
atexit(void (*a)(void)) |
{ |
struct __atexit *ap; |
if (a == 0) |
return -1; |
ap = (struct __atexit *)malloc(sizeof(struct __atexit)); |
if (!ap) |
return -1; |
ap->__next = __atexit_ptr; |
ap->__function = a; |
__atexit_ptr = ap; |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/atof.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
double |
atof(const char *ascii) |
{ |
return strtod(ascii, 0); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/atoi.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
int |
atoi(const char *str) |
{ |
return (int)strtol(str, 0, 10); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/atol.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
long |
atol(const char *str) |
{ |
return strtol(str, 0, 10); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/atold.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
long double |
_atold(const char *ascii) |
{ |
return _strtold(ascii, 0); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/bsearch.c |
---|
0,0 → 1,26 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <libc/unconst.h> |
void * |
bsearch(const void *key, const void *base0, size_t nelem, |
size_t size, int (*cmp)(const void *ck, const void *ce)) |
{ |
char *base = unconst(base0, char *); |
int lim, cmpval; |
void *p; |
for (lim = nelem; lim != 0; lim >>= 1) |
{ |
p = base + (lim >> 1) * size; |
cmpval = (*cmp)(key, p); |
if (cmpval == 0) |
return p; |
if (cmpval > 0) |
{ /* key > p: move right */ |
base = (char *)p + size; |
lim--; |
} /* else move left */ |
} |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/calloc.c |
---|
0,0 → 1,12 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <string.h> |
void * |
calloc(size_t size, size_t nelem) |
{ |
void *rv = malloc(size*nelem); |
if (rv) |
memset(rv, 0, size*nelem); |
return rv; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/div.c |
---|
0,0 → 1,24 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
div_t |
div(int num, int denom) |
{ |
div_t r; |
if (num > 0 && denom < 0) { |
num = -num; |
denom = -denom; |
} |
r.quot = num / denom; |
r.rem = num % denom; |
if (num < 0 && denom > 0) |
{ |
if (r.rem > 0) |
{ |
r.quot++; |
r.rem -= denom; |
} |
} |
return r; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/exit.c |
---|
0,0 → 1,37 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <dos.h> |
#include <io.h> |
#include <libc/atexit.h> |
struct __atexit *__atexit_ptr = 0; |
extern void (*__stdio_cleanup_hook)(void); |
/* typedef void (*FUNC)(void); |
extern FUNC djgpp_first_dtor[] __asm__("djgpp_first_dtor"); |
extern FUNC djgpp_last_dtor[] __asm__("djgpp_last_dtor"); */ |
int keypress_at_exit=0; |
void exit(int status) |
{ |
int i; |
struct __atexit *a = __atexit_ptr; |
// dosemu_atexit(); // <- this function is already in atexit list |
// (see crt1.c). - diamond |
/* if(keypress_at_exit) while(!__menuet__getkey()); */ |
while (a) |
{ |
(a->__function)(); |
a = a->__next; |
} |
/* if (__stdio_cleanup_hook) |
__stdio_cleanup_hook(); |
for (i=0; i<djgpp_last_dtor-djgpp_first_dtor; i++) |
djgpp_first_dtor[i]();*/ |
_exit(status); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/getenv.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <string.h> |
extern char * __libc_getenv(const char *name); // from crt0/env.c |
char * getenv(const char *name) |
{ |
return __libc_getenv(name); |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/labs.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
long |
labs(long j) |
{ |
return j<0 ? -j : j; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/ldiv.c |
---|
0,0 → 1,25 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
ldiv_t |
ldiv(long num, long denom) |
{ |
ldiv_t r; |
if (num > 0 && denom < 0) |
{ |
num = -num; |
denom = -denom; |
} |
r.quot = num / denom; |
r.rem = num % denom; |
if (num < 0 && denom > 0) |
{ |
if (r.rem > 0) |
{ |
r.quot++; |
r.rem -= denom; |
} |
} |
return r; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/malloc.c |
---|
0,0 → 1,358 |
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <menuet/sem.h> |
typedef struct BLOCK { |
size_t size; |
struct BLOCK *next; |
int bucket; |
} BLOCK; |
#define BEFORE(bp) ((BLOCK *)((char *)bp - *(int *)((char *)bp - 4) - 8)) |
#define BEFSZ(bp) (*(size_t *)((char *)bp - 4)) |
#define ENDSZ(bp) (*(size_t *)((char *)bp + bp->size + 4)) |
#define AFTER(bp) ((BLOCK *)((char *)bp + bp->size + 8)) |
#define DATA(bp) ((char *)&(bp->next)) |
#define NUMSMALL 0 |
#define ALIGN 8 |
#define SMALL (NUMSMALL*ALIGN) |
DECLARE_STATIC_SEM(malloc_mutex) |
static BLOCK *slop = 0; |
static BLOCK *freelist[30]; |
#if NUMSMALL |
static BLOCK *smallblocks[NUMSMALL]; |
#endif |
static inline void malloc_lock(void) |
{ |
sem_lock(&malloc_mutex); |
} |
static inline void malloc_unlock(void) |
{ |
sem_unlock(&malloc_mutex); |
} |
#define MIN_SAVE_EXTRA 64 |
#define BIG_BLOCK 4096 |
#define DEBUG 0 |
#if DEBUG |
static void |
check(BLOCK *b) |
{ |
printf("check %08x %d %08x %d\n", b, b->size, &(ENDSZ(b)), ENDSZ(b)); |
} |
#define CHECK(p) do { check(p); assert(p->size == ENDSZ(p)); consistency(); } while (0) |
#define CHECK1(p) do { check(p); assert(p->size == ENDSZ(p)); } while (0) |
static void |
consistency() |
{ |
#if 0 |
int b; |
BLOCK *bl; |
if (slop) |
CHECK1(slop); |
for (b=0; b<32; b++) |
for (bl=freelist[b]; bl; bl=bl->next) |
CHECK1(bl); |
#endif |
} |
#else |
#define CHECK(p) |
#endif |
static inline int |
size2bucket(size_t size) |
{ |
int rv=0; |
size>>=2; |
while (size) |
{ |
rv++; |
size>>=1; |
} |
return rv; |
} |
static inline int |
b2bucket(BLOCK *b) |
{ |
if (b->bucket == -1) |
b->bucket = size2bucket(b->size); |
return b->bucket; |
} |
static inline BLOCK * |
split_block(BLOCK *b, size_t size) |
{ |
BLOCK *rv = (BLOCK *)((char *)b + size+8); |
#if DEBUG |
printf(" split %u/%08x to %u/%08x, %u/%08x\n", |
b->size, b, size, b, b->size - size - 8, rv); |
#endif |
rv->size = b->size - size - 8; |
rv->bucket = -1; |
b->size = size; |
ENDSZ(b) = b->size; |
ENDSZ(rv) = rv->size; |
CHECK(b); |
CHECK(rv); |
return rv; |
} |
#define RET(rv) CHECK(rv); ENDSZ(rv) |= 1; rv->size |= 1; return DATA(rv) |
void * malloc(size_t size) |
{ |
int b, chunk_size; |
BLOCK *rv, **prev; |
static BLOCK *expected_sbrk = 0; |
if (size<ALIGN) size = ALIGN; |
size = (size+(ALIGN-1))&~(ALIGN-1); |
#if DEBUG |
printf("malloc(%u)\n", size); |
#endif |
#if NUMSMALL |
if (size < SMALL) |
{ |
rv = smallblocks[size/ALIGN]; |
if (rv) |
{ |
smallblocks[size/ALIGN] = rv->next; |
return DATA(rv); |
} |
} |
#endif |
if (slop && slop->size >= size) |
{ |
rv = slop; |
#if DEBUG |
printf(" using slop %u/%08x\n", slop->size, slop); |
#endif |
if (slop->size >= size+MIN_SAVE_EXTRA) |
{ |
slop = split_block(slop, size); |
#if DEBUG |
printf(" remaining slop %u/%08x\n", slop->size, slop); |
#endif |
} |
else |
slop = 0; |
RET(rv); |
} |
b = size2bucket(size); |
prev = &(freelist[b]); |
for (rv=freelist[b]; rv; prev=&(rv->next), rv=rv->next) |
{ |
if (rv->size >= size && rv->size < size+size/4) |
{ |
*prev = rv->next; |
RET(rv); |
} |
} |
while (b < 30) |
{ |
prev = &(freelist[b]); |
#if DEBUG |
printf(" checking bucket %d\n", b); |
#endif |
for (rv=freelist[b]; rv; prev=&(rv->next), rv=rv->next) |
if (rv->size >= size) |
{ |
#if DEBUG |
printf(" found size %d/%08x\n", rv->size, rv); |
#endif |
*prev = rv->next; |
if (rv->size >= size+MIN_SAVE_EXTRA) |
{ |
#if DEBUG |
printf(" enough to save\n"); |
#endif |
if (slop) |
{ |
b = b2bucket(slop); |
#if DEBUG |
printf(" putting old slop %u/%08x on free list %d\n", |
slop->size, slop, b); |
#endif |
slop->next = freelist[b]; |
freelist[b] = slop; |
} |
slop = split_block(rv, size); |
#if DEBUG |
printf(" slop size %u/%08x\n", slop->size, slop); |
#endif |
} |
RET(rv); |
} |
b++; |
} |
chunk_size = size+16; /* two ends plus two placeholders */ |
rv = (BLOCK *)sbrk(chunk_size); |
if (rv == (BLOCK *)(-1)) |
return 0; |
#if DEBUG |
printf("sbrk(%d) -> %08x, expected %08x\n", chunk_size, rv, expected_sbrk); |
#endif |
if (rv == expected_sbrk) |
{ |
expected_sbrk = (BLOCK *)((char *)rv + chunk_size); |
/* absorb old end-block-marker */ |
#if DEBUG |
printf(" got expected sbrk\n"); |
#endif |
rv = (BLOCK *)((char *)rv - 4); |
} |
else |
{ |
expected_sbrk = (BLOCK *)((char *)rv + chunk_size); |
#if DEBUG |
printf(" disconnected sbrk\n"); |
#endif |
/* build start-block-marker */ |
rv->size = 1; |
rv = (BLOCK *)((char *)rv + 4); |
chunk_size -= 8; |
} |
rv->size = chunk_size - 8; |
ENDSZ(rv) = rv->size; |
AFTER(rv)->size = 1; |
CHECK(rv); |
RET(rv); |
} |
static inline BLOCK * |
merge(BLOCK *a, BLOCK *b, BLOCK *c) |
{ |
int bu; |
BLOCK *bp, **bpp; |
#if DEBUG |
printf(" merge %u/%08x + %u/%08x = %u\n", |
a->size, a, b->size, b, a->size+b->size+8); |
#endif |
CHECK(a); |
CHECK(b); |
CHECK(c); |
if (c == slop) |
{ |
#if DEBUG |
printf(" snipping slop %u/%08x\n", slop->size, slop); |
#endif |
slop = 0; |
} |
bu = b2bucket(c); |
#if DEBUG |
printf("bucket for %u/%08x is %d\n", c->size, c, bu); |
#endif |
bpp = freelist+bu; |
for (bp=freelist[bu]; bp; bpp=&(bp->next), bp=bp->next) |
{ |
#if DEBUG |
printf(" %08x", bp); |
#endif |
if (bp == c) |
{ |
#if DEBUG |
printf("\n snipping %u/%08x from freelist[%d]\n", bp->size, bp, bu); |
#endif |
*bpp = bp->next; |
break; |
} |
} |
CHECK(c); |
a->size += b->size + 8; |
a->bucket = -1; |
ENDSZ(a) = a->size; |
CHECK(a); |
return a; |
} |
void |
free(void *ptr) |
{ |
int b; |
BLOCK *block; |
if (ptr == 0) |
return; |
block = (BLOCK *)((char *)ptr-4); |
#if NUMSMALL |
if (block->size < SMALL) |
{ |
block->next = smallblocks[block->size/ALIGN]; |
smallblocks[block->size/ALIGN] = block; |
return; |
} |
#endif |
block->size &= ~1; |
ENDSZ(block) &= ~1; |
block->bucket = -1; |
#if DEBUG |
printf("free(%u/%08x)\n", block->size, block); |
#endif |
CHECK(block); |
if (! (AFTER(block)->size & 1)) |
{ |
CHECK(AFTER(block)); |
} |
if (! (BEFSZ(block) & 1)) |
{ |
CHECK(BEFORE(block)); |
block = merge(BEFORE(block), block, BEFORE(block)); |
} |
CHECK(block); |
if (! (AFTER(block)->size & 1)) |
{ |
CHECK(AFTER(block)); |
block = merge(block, AFTER(block), AFTER(block)); |
} |
CHECK(block); |
b = b2bucket(block); |
block->next = freelist[b]; |
freelist[b] = block; |
CHECK(block); |
} |
void * realloc(void *ptr, size_t size) |
{ |
BLOCK *b; |
char *newptr; |
size_t copysize; |
if (ptr == 0) return malloc(size); |
b = (BLOCK *)((char *)ptr-4); |
copysize = b->size & ~1; |
if (size <= copysize) |
{ |
return ptr; |
copysize = size; |
} |
newptr = (char *)malloc(size); |
if (!newptr) return NULL; |
memcpy(newptr, ptr, copysize); |
free(ptr); |
return newptr; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/qsort.c |
---|
0,0 → 1,238 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
/*- |
* Copyright (c) 1980, 1983 The Regents of the University of California. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms are permitted |
* provided that: (1) source distributions retain this entire copyright |
* notice and comment, and (2) distributions including binaries display |
* the following acknowledgement: ``This product includes software |
* developed by the University of California, Berkeley and its contributors'' |
* in the documentation or other materials provided with the distribution |
* and in all advertising materials mentioning features or use of this |
* software. Neither the name of the University nor the names of its |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
*/ |
/* |
* qsort.c: |
* Our own version of the system qsort routine which is faster by an average |
* of 25%, with lows and highs of 10% and 50%. |
* The THRESHold below is the insertion sort threshold, and has been adjusted |
* for records of size 48 bytes. |
* The MTHREShold is where we stop finding a better median. |
*/ |
#define THRESH 4 /* threshold for insertion */ |
#define MTHRESH 6 /* threshold for median */ |
static int (*qcmp)(const void *, const void *); /* the comparison routine */ |
static int qsz; /* size of each record */ |
static int thresh; /* THRESHold in chars */ |
static int mthresh; /* MTHRESHold in chars */ |
/* |
* qst: |
* Do a quicksort |
* First, find the median element, and put that one in the first place as the |
* discriminator. (This "median" is just the median of the first, last and |
* middle elements). (Using this median instead of the first element is a big |
* win). Then, the usual partitioning/swapping, followed by moving the |
* discriminator into the right place. Then, figure out the sizes of the two |
* partions, do the smaller one recursively and the larger one via a repeat of |
* this code. Stopping when there are less than THRESH elements in a partition |
* and cleaning up with an insertion sort (in our caller) is a huge win. |
* All data swaps are done in-line, which is space-losing but time-saving. |
* (And there are only three places where this is done). |
*/ |
static void |
qst(char *base, char *max) |
{ |
char c, *i, *j, *jj; |
int ii; |
char *mid, *tmp; |
int lo, hi; |
/* |
* At the top here, lo is the number of characters of elements in the |
* current partition. (Which should be max - base). |
* Find the median of the first, last, and middle element and make |
* that the middle element. Set j to largest of first and middle. |
* If max is larger than that guy, then it's that guy, else compare |
* max with loser of first and take larger. Things are set up to |
* prefer the middle, then the first in case of ties. |
*/ |
lo = max - base; /* number of elements as chars */ |
do { |
mid = i = base + qsz * ((lo / qsz) >> 1); |
if (lo >= mthresh) |
{ |
j = (qcmp((jj = base), i) > 0 ? jj : i); |
if (qcmp(j, (tmp = max - qsz)) > 0) |
{ |
/* switch to first loser */ |
j = (j == jj ? i : jj); |
if (qcmp(j, tmp) < 0) |
j = tmp; |
} |
if (j != i) |
{ |
ii = qsz; |
do { |
c = *i; |
*i++ = *j; |
*j++ = c; |
} while (--ii); |
} |
} |
/* |
* Semi-standard quicksort partitioning/swapping |
*/ |
for (i = base, j = max - qsz; ; ) |
{ |
while (i < mid && qcmp(i, mid) <= 0) |
i += qsz; |
while (j > mid) |
{ |
if (qcmp(mid, j) <= 0) |
{ |
j -= qsz; |
continue; |
} |
tmp = i + qsz; /* value of i after swap */ |
if (i == mid) |
{ |
/* j <-> mid, new mid is j */ |
mid = jj = j; |
} |
else |
{ |
/* i <-> j */ |
jj = j; |
j -= qsz; |
} |
goto swap; |
} |
if (i == mid) |
{ |
break; |
} |
else |
{ |
/* i <-> mid, new mid is i */ |
jj = mid; |
tmp = mid = i; /* value of i after swap */ |
j -= qsz; |
} |
swap: |
ii = qsz; |
do { |
c = *i; |
*i++ = *jj; |
*jj++ = c; |
} while (--ii); |
i = tmp; |
} |
/* |
* Look at sizes of the two partitions, do the smaller |
* one first by recursion, then do the larger one by |
* making sure lo is its size, base and max are update |
* correctly, and branching back. But only repeat |
* (recursively or by branching) if the partition is |
* of at least size THRESH. |
*/ |
i = (j = mid) + qsz; |
if ((lo = j - base) <= (hi = max - i)) |
{ |
if (lo >= thresh) |
qst(base, j); |
base = i; |
lo = hi; |
} |
else |
{ |
if (hi >= thresh) |
qst(i, max); |
max = j; |
} |
} while (lo >= thresh); |
} |
/* |
* qsort: |
* First, set up some global parameters for qst to share. Then, quicksort |
* with qst(), and then a cleanup insertion sort ourselves. Sound simple? |
* It's not... |
*/ |
void |
qsort(void *base0, size_t n, size_t size, int (*compar)(const void *, const void *)) |
{ |
char *base = (char *)base0; |
char c, *i, *j, *lo, *hi; |
char *min, *max; |
if (n <= 1) |
return; |
qsz = size; |
qcmp = compar; |
thresh = qsz * THRESH; |
mthresh = qsz * MTHRESH; |
max = base + n * qsz; |
if (n >= THRESH) |
{ |
qst(base, max); |
hi = base + thresh; |
} |
else |
{ |
hi = max; |
} |
/* |
* First put smallest element, which must be in the first THRESH, in |
* the first position as a sentinel. This is done just by searching |
* the first THRESH elements (or the first n if n < THRESH), finding |
* the min, and swapping it into the first position. |
*/ |
for (j = lo = base; (lo += qsz) < hi; ) |
if (qcmp(j, lo) > 0) |
j = lo; |
if (j != base) |
{ |
/* swap j into place */ |
for (i = base, hi = base + qsz; i < hi; ) |
{ |
c = *j; |
*j++ = *i; |
*i++ = c; |
} |
} |
/* |
* With our sentinel in place, we now run the following hyper-fast |
* insertion sort. For each remaining element, min, from [1] to [n-1], |
* set hi to the index of the element AFTER which this one goes. |
* Then, do the standard insertion sort shift on a character at a time |
* basis for each element in the frob. |
*/ |
for (min = base; (hi = min += qsz) < max; ) |
{ |
while (qcmp(hi -= qsz, min) > 0) |
/* void */; |
if ((hi += qsz) != min) { |
for (lo = min + qsz; --lo >= min; ) |
{ |
c = *lo; |
for (i = j = lo; (j -= qsz) >= hi; i = j) |
*i = *j; |
*i = c; |
} |
} |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/rand.c |
---|
0,0 → 1,18 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
static unsigned long long next = 0; |
int |
rand(void) |
{ |
next = next * 1103515245L + 12345; |
next = (next<<15) ^ (next >> 27); |
return (int)((next >> 4) & RAND_MAX); |
} |
void |
srand(unsigned seed) |
{ |
next = seed; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/strtod.c |
---|
0,0 → 1,96 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <math.h> |
#include <stdlib.h> |
#include <libc/unconst.h> |
double |
strtod(const char *s, char **sret) |
{ |
long double r; /* result */ |
int e; /* exponent */ |
long double d; /* scale */ |
int sign; /* +- 1.0 */ |
int esign; |
int i; |
int flags=0; |
r = 0.0; |
sign = 1.0; |
e = 0; |
esign = 1; |
while ((*s == ' ') || (*s == '\t')) |
s++; |
if (*s == '+') |
s++; |
else if (*s == '-') |
{ |
sign = -1; |
s++; |
} |
while ((*s >= '0') && (*s <= '9')) |
{ |
flags |= 1; |
r *= 10.0; |
r += *s - '0'; |
s++; |
} |
if (*s == '.') |
{ |
d = 0.1L; |
s++; |
while ((*s >= '0') && (*s <= '9')) |
{ |
flags |= 2; |
r += d * (*s - '0'); |
s++; |
d *= 0.1L; |
} |
} |
if (flags == 0) |
{ |
if (sret) |
*sret = unconst(s, char *); |
return 0; |
} |
if ((*s == 'e') || (*s == 'E')) |
{ |
s++; |
if (*s == '+') |
s++; |
else if (*s == '-') |
{ |
s++; |
esign = -1; |
} |
if ((*s < '0') || (*s > '9')) |
{ |
if (sret) |
*sret = unconst(s, char *); |
return r; |
} |
while ((*s >= '0') && (*s <= '9')) |
{ |
e *= 10; |
e += *s - '0'; |
s++; |
} |
} |
if (esign < 0) |
for (i = 1; i <= e; i++) |
r *= 0.1L; |
else |
for (i = 1; i <= e; i++) |
r *= 10.0; |
if (sret) |
*sret = unconst(s, char *); |
return r * sign; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/strtol.c |
---|
0,0 → 1,91 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <limits.h> |
#include <ctype.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <libc/unconst.h> |
long |
strtol(const char *nptr, char **endptr, int base) |
{ |
const char *s = nptr; |
unsigned long acc; |
int c; |
unsigned long cutoff; |
int neg = 0, any, cutlim; |
/* |
* Skip white space and pick up leading +/- sign if any. |
* If base is 0, allow 0x for hex and 0 for octal, else |
* assume decimal; if base is already 16, allow 0x. |
*/ |
do { |
c = *s++; |
} while (isspace(c)); |
if (c == '-') |
{ |
neg = 1; |
c = *s++; |
} |
else if (c == '+') |
c = *s++; |
if ((base == 0 || base == 16) && |
c == '0' && (*s == 'x' || *s == 'X')) |
{ |
c = s[1]; |
s += 2; |
base = 16; |
} |
if (base == 0) |
base = c == '0' ? 8 : 10; |
/* |
* Compute the cutoff value between legal numbers and illegal |
* numbers. That is the largest legal value, divided by the |
* base. An input number that is greater than this value, if |
* followed by a legal input character, is too big. One that |
* is equal to this value may be valid or not; the limit |
* between valid and invalid numbers is then based on the last |
* digit. For instance, if the range for longs is |
* [-2147483648..2147483647] and the input base is 10, |
* cutoff will be set to 214748364 and cutlim to either |
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated |
* a value > 214748364, or equal but the next digit is > 7 (or 8), |
* the number is too big, and we will return a range error. |
* |
* Set any if any `digits' consumed; make it negative to indicate |
* overflow. |
*/ |
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; |
cutlim = cutoff % (unsigned long)base; |
cutoff /= (unsigned long)base; |
for (acc = 0, any = 0;; c = *s++) |
{ |
if (isdigit(c)) |
c -= '0'; |
else if (isalpha(c)) |
c -= isupper(c) ? 'A' - 10 : 'a' - 10; |
else |
break; |
if (c >= base) |
break; |
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) |
any = -1; |
else |
{ |
any = 1; |
acc *= base; |
acc += c; |
} |
} |
if (any < 0) |
{ |
acc = neg ? LONG_MIN : LONG_MAX; |
errno = ERANGE; |
} |
else if (neg) |
acc = -acc; |
if (endptr != 0) |
*endptr = any ? unconst(s, char *) - 1 : unconst(nptr, char *); |
return acc; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/strtold.c |
---|
0,0 → 1,120 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <ctype.h> |
#include <libc/unconst.h> |
static long double powten[] = |
{ |
1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L, |
1e512L, 1e1024L, 1e2048L, 1e4096L |
}; |
long double |
_strtold(const char *s, char **sret) |
{ |
long double r; /* result */ |
int e, ne; /* exponent */ |
int sign; /* +- 1.0 */ |
int esign; |
int flags=0; |
int l2powm1; |
r = 0.0L; |
sign = 1; |
e = ne = 0; |
esign = 1; |
while(*s && isspace(*s)) |
s++; |
if (*s == '+') |
s++; |
else if (*s == '-') |
{ |
sign = -1; |
s++; |
} |
while ((*s >= '0') && (*s <= '9')) |
{ |
flags |= 1; |
r *= 10.0L; |
r += *s - '0'; |
s++; |
} |
if (*s == '.') |
{ |
s++; |
while ((*s >= '0') && (*s <= '9')) |
{ |
flags |= 2; |
r *= 10.0L; |
r += *s - '0'; |
s++; |
ne++; |
} |
} |
if (flags == 0) |
{ |
if (sret) |
*sret = unconst(s, char *); |
return 0.0L; |
} |
if ((*s == 'e') || (*s == 'E')) |
{ |
s++; |
if (*s == '+') |
s++; |
else if (*s == '-') |
{ |
s++; |
esign = -1; |
} |
while ((*s >= '0') && (*s <= '9')) |
{ |
e *= 10; |
e += *s - '0'; |
s++; |
} |
} |
if (esign < 0) |
{ |
esign = -esign; |
e = -e; |
} |
e = e - ne; |
if (e < -4096) |
{ |
/* possibly subnormal number, 10^e would overflow */ |
r *= 1.0e-2048L; |
e += 2048; |
} |
if (e < 0) |
{ |
e = -e; |
esign = -esign; |
} |
if (e >= 8192) |
e = 8191; |
if (e) |
{ |
long double d = 1.0L; |
l2powm1 = 0; |
while (e) |
{ |
if (e & 1) |
d *= powten[l2powm1]; |
e >>= 1; |
l2powm1++; |
} |
if (esign > 0) |
r *= d; |
else |
r /= d; |
} |
if (sret) |
*sret = unconst(s, char *); |
return r * sign; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/strtoul.c |
---|
0,0 → 1,75 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <limits.h> |
#include <ctype.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <libc/unconst.h> |
/* |
* Convert a string to an unsigned long integer. |
* |
* Ignores `locale' stuff. Assumes that the upper and lower case |
* alphabets and digits are each contiguous. |
*/ |
unsigned long |
strtoul(const char *nptr, char **endptr, int base) |
{ |
const char *s = nptr; |
unsigned long acc; |
int c; |
unsigned long cutoff; |
int neg = 0, any, cutlim; |
/* |
* See strtol for comments as to the logic used. |
*/ |
do { |
c = *s++; |
} while (isspace(c)); |
if (c == '-') |
{ |
neg = 1; |
c = *s++; |
} |
else if (c == '+') |
c = *s++; |
if ((base == 0 || base == 16) && |
c == '0' && (*s == 'x' || *s == 'X')) |
{ |
c = s[1]; |
s += 2; |
base = 16; |
} |
if (base == 0) |
base = c == '0' ? 8 : 10; |
cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; |
cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; |
for (acc = 0, any = 0;; c = *s++) |
{ |
if (isdigit(c)) |
c -= '0'; |
else if (isalpha(c)) |
c -= isupper(c) ? 'A' - 10 : 'a' - 10; |
else |
break; |
if (c >= base) |
break; |
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) |
any = -1; |
else { |
any = 1; |
acc *= base; |
acc += c; |
} |
} |
if (any < 0) |
{ |
acc = ULONG_MAX; |
errno = ERANGE; |
} |
else if (neg) |
acc = -acc; |
if (endptr != 0) |
*endptr = any ? unconst(s, char *) - 1 : unconst(nptr, char *); |
return acc; |
} |
/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/system.c |
---|
0,0 → 1,18 |
#include <libc/stubs.h> |
#include <fcntl.h> |
#include <sys/stat.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <ctype.h> |
#include <errno.h> |
#include <process.h> |
#include <libc/dosexec.h> |
#include <libc/unconst.h> |
#include <assert.h> |
int system (const char *cmdline) |
{ |
unimpl(); |
} |