diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/lib/ap/gen |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/lib/ap/gen')
53 files changed, 1908 insertions, 0 deletions
diff --git a/sys/src/ape/lib/ap/gen/_assert.c b/sys/src/ape/lib/ap/gen/_assert.c new file mode 100755 index 000000000..e39e147a4 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/_assert.c @@ -0,0 +1,18 @@ +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> + +void +_assert(char *f, unsigned line) +{ + char buf[20], *p, *s = &buf[20]; + write(2, "assertion failed: file ", 23); + for(p = f; *p; p++) continue; + write(2, f, p-f); + write(2, ":", 7); + *--s = '\n'; + do *--s = line%10 + '0'; while (line /= 10); + write(2, s, &buf[20] - s); + abort(); + +} diff --git a/sys/src/ape/lib/ap/gen/abort.c b/sys/src/ape/lib/ap/gen/abort.c new file mode 100755 index 000000000..67b878541 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/abort.c @@ -0,0 +1,9 @@ +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> + +void +abort(void) +{ + kill(getpid(), SIGABRT); +} diff --git a/sys/src/ape/lib/ap/gen/abs.c b/sys/src/ape/lib/ap/gen/abs.c new file mode 100755 index 000000000..7d670ffb3 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/abs.c @@ -0,0 +1,17 @@ +#include <stdlib.h> + +int +abs(int a) +{ + if(a < 0) + return -a; + return a; +} + +long +labs(long a) +{ + if(a < 0) + return -a; + return a; +} diff --git a/sys/src/ape/lib/ap/gen/atof.c b/sys/src/ape/lib/ap/gen/atof.c new file mode 100755 index 000000000..63b8bfea4 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/atof.c @@ -0,0 +1,7 @@ +#include <stdlib.h> + +double +atof(const char *s) +{ + return(strtod(s, (char **)0)); +} diff --git a/sys/src/ape/lib/ap/gen/atoi.c b/sys/src/ape/lib/ap/gen/atoi.c new file mode 100755 index 000000000..8b9bddd41 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/atoi.c @@ -0,0 +1,7 @@ +#include <stdlib.h> + +int +atoi(const char *s) +{ + return(strtol(s, (char **)0, 10)); +} diff --git a/sys/src/ape/lib/ap/gen/atol.c b/sys/src/ape/lib/ap/gen/atol.c new file mode 100755 index 000000000..41e6040fe --- /dev/null +++ b/sys/src/ape/lib/ap/gen/atol.c @@ -0,0 +1,7 @@ +#include <stdlib.h> + +long +atol(const char *s) +{ + return(strtol(s, (char **)0, 10)); +} diff --git a/sys/src/ape/lib/ap/gen/atoll.c b/sys/src/ape/lib/ap/gen/atoll.c new file mode 100755 index 000000000..55f28000a --- /dev/null +++ b/sys/src/ape/lib/ap/gen/atoll.c @@ -0,0 +1,7 @@ +#include <stdlib.h> + +long long +atoll(const char *s) +{ + return(strtoll(s, (char **)0, 10)); +} diff --git a/sys/src/ape/lib/ap/gen/bsearch.c b/sys/src/ape/lib/ap/gen/bsearch.c new file mode 100755 index 000000000..ae0342f99 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/bsearch.c @@ -0,0 +1,24 @@ +#include <stdlib.h> +#include <stdio.h> +void* +bsearch(const void* key, const void* base, size_t nmemb, size_t size, + int (*compar)(const void*, const void*)) +{ + long i, bot, top, new; + void *p; + + bot = 0; + top = bot + nmemb - 1; + while(bot <= top){ + new = (top + bot)/2; + p = (char *)base+new*size; + i = (*compar)(key, p); + if(i == 0) + return p; + if(i > 0) + bot = new + 1; + else + top = new - 1; + } + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/calloc.c b/sys/src/ape/lib/ap/gen/calloc.c new file mode 100755 index 000000000..e52210d84 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/calloc.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#include <string.h> + +void * +calloc(size_t nmemb, size_t size) +{ + void *mp; + + nmemb = nmemb*size; + if(mp = malloc(nmemb)) + memset(mp, 0, nmemb); + return(mp); +} diff --git a/sys/src/ape/lib/ap/gen/clock.c b/sys/src/ape/lib/ap/gen/clock.c new file mode 100755 index 000000000..d7d5d4b67 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/clock.c @@ -0,0 +1,12 @@ +#include <time.h> +#include <sys/times.h> + +clock_t +clock(void) +{ + struct tms t; + + if(times(&t) == (clock_t)-1) + return (clock_t)-1; + return t.tms_utime+t.tms_stime; +} diff --git a/sys/src/ape/lib/ap/gen/ctype.c b/sys/src/ape/lib/ap/gen/ctype.c new file mode 100755 index 000000000..3829a171a --- /dev/null +++ b/sys/src/ape/lib/ap/gen/ctype.c @@ -0,0 +1,56 @@ +#include <ctype.h> + +unsigned char _ctype[] = +{ +/* 0 1 2 3 */ +/* 4 5 6 7 */ + +/* 0*/ _IScntrl, _IScntrl, _IScntrl, _IScntrl, + _IScntrl, _IScntrl, _IScntrl, _IScntrl, +/* 10*/ _IScntrl, _ISspace|_IScntrl, _ISspace|_IScntrl, _ISspace|_IScntrl, + _ISspace|_IScntrl, _ISspace|_IScntrl, _IScntrl, _IScntrl, +/* 20*/ _IScntrl, _IScntrl, _IScntrl, _IScntrl, + _IScntrl, _IScntrl, _IScntrl, _IScntrl, +/* 30*/ _IScntrl, _IScntrl, _IScntrl, _IScntrl, + _IScntrl, _IScntrl, _IScntrl, _IScntrl, +/* 40*/ _ISspace|_ISblank, _ISpunct, _ISpunct, _ISpunct, + _ISpunct, _ISpunct, _ISpunct, _ISpunct, +/* 50*/ _ISpunct, _ISpunct, _ISpunct, _ISpunct, + _ISpunct, _ISpunct, _ISpunct, _ISpunct, +/* 60*/ _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, + _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, +/* 70*/ _ISdigit|_ISxdigit, _ISdigit|_ISxdigit, _ISpunct, _ISpunct, + _ISpunct, _ISpunct, _ISpunct, _ISpunct, +/*100*/ _ISpunct, _ISupper|_ISxdigit, _ISupper|_ISxdigit, _ISupper|_ISxdigit, + _ISupper|_ISxdigit, _ISupper|_ISxdigit, _ISupper|_ISxdigit, _ISupper, +/*110*/ _ISupper, _ISupper, _ISupper, _ISupper, + _ISupper, _ISupper, _ISupper, _ISupper, +/*120*/ _ISupper, _ISupper, _ISupper, _ISupper, + _ISupper, _ISupper, _ISupper, _ISupper, +/*130*/ _ISupper, _ISupper, _ISupper, _ISpunct, + _ISpunct, _ISpunct, _ISpunct, _ISpunct, +/*140*/ _ISpunct, _ISlower|_ISxdigit, _ISlower|_ISxdigit, _ISlower|_ISxdigit, + _ISlower|_ISxdigit, _ISlower|_ISxdigit, _ISlower|_ISxdigit, _ISlower, +/*150*/ _ISlower, _ISlower, _ISlower, _ISlower, + _ISlower, _ISlower, _ISlower, _ISlower, +/*160*/ _ISlower, _ISlower, _ISlower, _ISlower, + _ISlower, _ISlower, _ISlower, _ISlower, +/*170*/ _ISlower, _ISlower, _ISlower, _ISpunct, + _ISpunct, _ISpunct, _ISpunct, _IScntrl, +/*200*/ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; diff --git a/sys/src/ape/lib/ap/gen/difftime.c b/sys/src/ape/lib/ap/gen/difftime.c new file mode 100755 index 000000000..97ac3cee9 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/difftime.c @@ -0,0 +1,9 @@ +#include <time.h> + +/* Difference in seconds between two calendar times */ + +double +difftime(time_t t1, time_t t0) +{ + return (double)t1-(double)t0; +} diff --git a/sys/src/ape/lib/ap/gen/div.c b/sys/src/ape/lib/ap/gen/div.c new file mode 100755 index 000000000..10d92d97b --- /dev/null +++ b/sys/src/ape/lib/ap/gen/div.c @@ -0,0 +1,9 @@ +#include <stdlib.h> + +div_t div(int numer, int denom) +{ + div_t ans; + ans.quot=numer/denom; /* assumes division truncates */ + ans.rem=numer-ans.quot*denom; + return ans; +} diff --git a/sys/src/ape/lib/ap/gen/getenv.c b/sys/src/ape/lib/ap/gen/getenv.c new file mode 100755 index 000000000..e911d3298 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/getenv.c @@ -0,0 +1,18 @@ +#include <stdlib.h> + +extern char **environ; + +char * +getenv(const char *name) +{ + char **p = environ; + char *v, *s1, *s2; + + while (*p != NULL){ + for(s1 = (char *)name, s2 = *p++; *s1 == *s2; s1++, s2++) + continue; + if(*s1 == '\0' && *s2 == '=') + return s2+1; + } + return NULL ; +} diff --git a/sys/src/ape/lib/ap/gen/isalnum.c b/sys/src/ape/lib/ap/gen/isalnum.c new file mode 100755 index 000000000..e1ab47cde --- /dev/null +++ b/sys/src/ape/lib/ap/gen/isalnum.c @@ -0,0 +1,24 @@ +#include <ctype.h> + +#undef isalnum +#undef isalpha +#undef iscntrl +#undef isdigit +#undef isgraph +#undef islower +#undef isprint +#undef ispunct +#undef isspace +#undef isupper +#undef isxdigit +int isalnum(int c){ return (_ctype+1)[c]&(_ISupper|_ISlower|_ISdigit); } +int isalpha(int c){ return (_ctype+1)[c]&(_ISupper|_ISlower); } +int iscntrl(int c){ return (_ctype+1)[c]&_IScntrl; } +int isdigit(int c){ return (_ctype+1)[c]&_ISdigit; } +int isgraph(int c){ return (_ctype+1)[c]&(_ISpunct|_ISupper|_ISlower|_ISdigit); } +int islower(int c){ return (_ctype+1)[c]&_ISlower; } +int isprint(int c){ return (_ctype+1)[c]&(_ISpunct|_ISupper|_ISlower|_ISdigit|_ISblank); } +int ispunct(int c){ return (_ctype+1)[c]&_ISpunct; } +int isspace(int c){ return (_ctype+1)[c]&_ISspace; } +int isupper(int c){ return (_ctype+1)[c]&_ISupper; } +int isxdigit(int c){ return (_ctype+1)[c]&_ISxdigit; } diff --git a/sys/src/ape/lib/ap/gen/itoa.c b/sys/src/ape/lib/ap/gen/itoa.c new file mode 100755 index 000000000..9e686556b --- /dev/null +++ b/sys/src/ape/lib/ap/gen/itoa.c @@ -0,0 +1,7 @@ +#include <stdlib.h> + +int +itoa(const char *s) +{ + return(strtol(s, (char **)0, 10)); +} diff --git a/sys/src/ape/lib/ap/gen/itol.c b/sys/src/ape/lib/ap/gen/itol.c new file mode 100755 index 000000000..a618acc8a --- /dev/null +++ b/sys/src/ape/lib/ap/gen/itol.c @@ -0,0 +1,7 @@ +#include <stdlib.h> + +long +itol(const char *s) +{ + return(strtol(s, (char **)0, 10)); +} diff --git a/sys/src/ape/lib/ap/gen/ldiv.c b/sys/src/ape/lib/ap/gen/ldiv.c new file mode 100755 index 000000000..01313e6ac --- /dev/null +++ b/sys/src/ape/lib/ap/gen/ldiv.c @@ -0,0 +1,9 @@ +#include <stdlib.h> + +ldiv_t ldiv(long int numer, long int denom) +{ + ldiv_t ans; + ans.quot=numer/denom; + ans.rem=numer-ans.quot*denom; + return ans; +} diff --git a/sys/src/ape/lib/ap/gen/mbwc.c b/sys/src/ape/lib/ap/gen/mbwc.c new file mode 100755 index 000000000..66a982193 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/mbwc.c @@ -0,0 +1,165 @@ +#include <stdlib.h> + +/* + * Use the FSS-UTF transformation proposed by posix. + * We define 7 byte types: + * T0 0xxxxxxx 7 free bits + * Tx 10xxxxxx 6 free bits + * T1 110xxxxx 5 free bits + * T2 1110xxxx 4 free bits + * + * Encoding is as follows. + * From hex Thru hex Sequence Bits + * 00000000 0000007F T0 7 + * 00000080 000007FF T1 Tx 11 + * 00000800 0000FFFF T2 Tx Tx 16 + */ + +int +mblen(const char *s, size_t n) +{ + + return mbtowc(0, s, n); +} + +int +mbtowc(wchar_t *pwc, const char *s, size_t n) +{ + int c, c1, c2; + long l; + + if(!s) + return 0; + + if(n < 1) + goto bad; + c = s[0] & 0xff; + if((c & 0x80) == 0x00) { + if(pwc) + *pwc = c; + if(c == 0) + return 0; + return 1; + } + + if(n < 2) + goto bad; + c1 = (s[1] ^ 0x80) & 0xff; + if((c1 & 0xC0) != 0x00) + goto bad; + if((c & 0xE0) == 0xC0) { + l = ((c << 6) | c1) & 0x7FF; + if(l < 0x080) + goto bad; + if(pwc) + *pwc = l; + return 2; + } + + if(n < 3) + goto bad; + c2 = (s[2] ^ 0x80) & 0xff; + if((c2 & 0xC0) != 0x00) + goto bad; + if((c & 0xF0) == 0xE0) { + l = ((((c << 6) | c1) << 6) | c2) & 0xFFFF; + if(l < 0x0800) + goto bad; + if(pwc) + *pwc = l; + return 3; + } + + /* + * bad decoding + */ +bad: + return -1; + +} + +int +wctomb(char *s, wchar_t wchar) +{ + long c; + + if(!s) + return 0; + + c = wchar & 0xFFFF; + if(c < 0x80) { + s[0] = c; + return 1; + } + + if(c < 0x800) { + s[0] = 0xC0 | (c >> 6); + s[1] = 0x80 | (c & 0x3F); + return 2; + } + + s[0] = 0xE0 | (c >> 12); + s[1] = 0x80 | ((c >> 6) & 0x3F); + s[2] = 0x80 | (c & 0x3F); + return 3; +} + +size_t +mbstowcs(wchar_t *pwcs, const char *s, size_t n) +{ + int i, d, c; + + for(i=0; i < n; i++) { + c = *s & 0xff; + if(c < 0x80) { + *pwcs = c; + if(c == 0) + break; + s++; + } else { + d = mbtowc(pwcs, s, 3); + if(d <= 0) + return (size_t)((d<0) ? -1 : i); + s += d; + } + pwcs++; + } + return i; +} + +size_t +wcstombs(char *s, const wchar_t *pwcs, size_t n) +{ + int i, d; + long c; + char *p, *pe; + char buf[3]; + + p = s; + pe = p+n-3; + while(p < pe) { + c = *pwcs++; + if(c < 0x80) + *p++ = c; + else + p += wctomb(p, c); + if(c == 0) + return p-s; + } + while(p < pe+3) { + c = *pwcs++; + d = wctomb(buf, c); + if(p+d <= pe+3) { + *p++ = buf[0]; + if(d > 1) { + *p++ = buf[2]; + if(d > 2) + *p++ = buf[3]; + } + } + if(c == 0) + break; + } + return p-s; +} + diff --git a/sys/src/ape/lib/ap/gen/memccpy.c b/sys/src/ape/lib/ap/gen/memccpy.c new file mode 100755 index 000000000..2f7b610d2 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/memccpy.c @@ -0,0 +1,17 @@ +#include <string.h> + +void* +memccpy(void *a1, void *a2, int c, size_t n) +{ + unsigned char *s1, *s2; + + s1 = a1; + s2 = a2; + c &= 0xFF; + while(n > 0) { + if((*s1++ = *s2++) == c) + return s1; + n--; + } + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/memchr.c b/sys/src/ape/lib/ap/gen/memchr.c new file mode 100755 index 000000000..e63aefe8e --- /dev/null +++ b/sys/src/ape/lib/ap/gen/memchr.c @@ -0,0 +1,16 @@ +#include <string.h> + +void* +memchr(const void *ap, int c, size_t n) +{ + unsigned char *sp; + + sp = ap; + c &= 0xFF; + while(n > 0) { + if(*sp++ == c) + return sp-1; + n--; + } + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/memcmp.c b/sys/src/ape/lib/ap/gen/memcmp.c new file mode 100755 index 000000000..c07fbd0e9 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/memcmp.c @@ -0,0 +1,22 @@ +#include <string.h> + +int +memcmp(const void *a1, const void *a2, size_t n) +{ + char *s1, *s2; + unsigned c1, c2; + + s1 = a1; + s2 = a2; + while(n > 0) { + c1 = *s1++; + c2 = *s2++; + if(c1 != c2) { + if(c1 > c2) + return 1; + return -1; + } + n--; + } + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/memmove.c b/sys/src/ape/lib/ap/gen/memmove.c new file mode 100755 index 000000000..7eec93f68 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/memmove.c @@ -0,0 +1,35 @@ +#include <string.h> + +void* +memmove(void *a1, const void *a2, size_t n) +{ + char *s1, *s2; + extern void abort(void); + + if((long)n < 0) + abort(); + if(a1 > a2) + goto back; + s1 = a1; + s2 = a2; + while(n > 0) { + *s1++ = *s2++; + n--; + } + return a1; + +back: + s1 = (char*)a1 + n; + s2 = (char*)a2 + n; + while(n > 0) { + *--s1 = *--s2; + n--; + } + return a1; +} + +void* +memcpy(void *a1, const void *a2, size_t n) +{ + return memmove(a1, a2, n); +} diff --git a/sys/src/ape/lib/ap/gen/memset.c b/sys/src/ape/lib/ap/gen/memset.c new file mode 100755 index 000000000..902874412 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/memset.c @@ -0,0 +1,14 @@ +#include <string.h> + +void* +memset(void *ap, int c, size_t n) +{ + char *p; + + p = ap; + while(n > 0) { + *p++ = c; + n--; + } + return ap; +} diff --git a/sys/src/ape/lib/ap/gen/mkfile b/sys/src/ape/lib/ap/gen/mkfile new file mode 100755 index 000000000..e9653bba1 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/mkfile @@ -0,0 +1,63 @@ +APE=/sys/src/ape +<$APE/config +LIB=/$objtype/lib/ape/libap.a + +ALLOFILES=\ + _assert.$O\ + abort.$O\ + abs.$O\ + atof.$O\ + atoi.$O\ + atol.$O\ + atoll.$O\ + bsearch.$O\ + calloc.$O\ + clock.$O\ + ctype.$O\ + difftime.$O\ + div.$O\ + getenv.$O\ + isalnum.$O\ + itoa.$O\ + itol.$O\ + ldiv.$O\ + mbwc.$O\ + memccpy.$O\ + memchr.$O\ + memcmp.$O\ + memmove.$O\ + memset.$O\ + mktime.$O\ + qsort.$O\ + raise.$O\ + rand.$O\ + strcat.$O\ + strchr.$O\ + strcmp.$O\ + strcoll.$O\ + strcpy.$O\ + strcspn.$O\ + strftime.$O\ + strlen.$O\ + strncat.$O\ + strncmp.$O\ + strncpy.$O\ + strpbrk.$O\ + strrchr.$O\ + strspn.$O\ + strstr.$O\ + strtod.$O\ + strtok.$O\ + strtol.$O\ + strtoll.$O\ + strtoul.$O\ + strtoull.$O\ + strxfrm.$O\ + toupper.$O\ + +# cull things in the per-machine directories from this list +OFILES= `{rc ./reduce $O $objtype $ALLOFILES} + +</sys/src/cmd/mksyslib + +CFLAGS=-c -D_POSIX_SOURCE diff --git a/sys/src/ape/lib/ap/gen/mktime.c b/sys/src/ape/lib/ap/gen/mktime.c new file mode 100755 index 000000000..2c8fa79fa --- /dev/null +++ b/sys/src/ape/lib/ap/gen/mktime.c @@ -0,0 +1,122 @@ +#include <time.h> + +/* + * BUG: Doesn't do leap years in full glory, + * or calendar changes. In 2038 the sign bit + * will be needed in time_t, but we say it + * can't be represented. + */ +static int +dysize(int y) +{ + y += 1900; /* arg is a tm_year, number of years since 1900 */ + if((y%4) == 0 && ((y%100) !=0 || (y%400) == 0)) + return 366; + return 365; +} + +static int +dmsize(int m, int y) +{ + static char sizes[12] = + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if(m == 1) + return (dysize(y)==366)? 29 : 28; + else + return sizes[m]; +} + +/* Reduce *v to [0, mult), adding 1 to *next for every mult + * subtracted from *v, and return 1 if reduction worked (no overflow) + */ +static int +reduce(int *v, int *next, int mult) +{ + int oldnext; + + while(*v < 0){ + *v += mult; + oldnext = *next; + --*next; + if(!(*next < oldnext)) + return 0; + } + while(*v >= mult){ + *v -= mult; + oldnext = *next; + ++*next; + if(!(*next > oldnext)) + return 0; + } + return 1; +} + +static int +jan1(int yr) +{ + int y, d; + + y = yr+1900; + d = (4+y+(y+3)/4-(y-1701)/100+(y-1601)/400+3)%7; + return d; +} + +time_t +mktime(struct tm *t) +{ + time_t a; + int i, d; + struct tm *ptm; + + if(!(reduce(&t->tm_sec, &t->tm_min, 60) && + reduce(&t->tm_min, &t->tm_hour, 60) && + reduce(&t->tm_hour, &t->tm_mday, 24) && + reduce(&t->tm_mon, &t->tm_year, 12))) + return -1; + while(t->tm_mday < 1){ + if(--t->tm_mon == -1){ + t->tm_mon = 11; + t->tm_year--; + } + t->tm_mday += dmsize(t->tm_mon, t->tm_year); + } + while(t->tm_mday > dmsize(t->tm_mon, t->tm_year)){ + t->tm_mday -= dmsize(t->tm_mon, t->tm_year); + if(++t->tm_mon == 12){ + t->tm_mon = 0; + t->tm_year++; + } + } + a = t->tm_sec + 60*t->tm_min + 3600*t->tm_hour; + t->tm_yday = t->tm_mday-1; + for(i=0; i<t->tm_mon; i++) + t->tm_yday += dmsize(i, t->tm_year); + a += t->tm_yday*86400L; + if(t->tm_year < 70){ + for(i=t->tm_year; i<70; i++) + if((a -= dysize(i)*86400L) < 0) + return -1; + }else if(t->tm_year > 70){ + for(i=70; i<t->tm_year; i++) + if((a += dysize(i)*86400L) < 0) + return -1; + } + /* + * Now a is number of seconds past Jan 1 1970. + * Convert to GMT. + */ + ptm = gmtime(&a); + d = ptm->tm_hour; + ptm = localtime(&a); + d -= ptm->tm_hour; + if(d < 0) + d += 24; + if(t->tm_isdst == 0 && ptm->tm_isdst) + d--; + if(t->tm_isdst > 0 && !ptm->tm_isdst) + d++; + a += d*3600; + t->tm_wday = (jan1(t->tm_year)+t->tm_yday)%7; + return a; +} diff --git a/sys/src/ape/lib/ap/gen/qsort.c b/sys/src/ape/lib/ap/gen/qsort.c new file mode 100755 index 000000000..e3fb9d12f --- /dev/null +++ b/sys/src/ape/lib/ap/gen/qsort.c @@ -0,0 +1,90 @@ +/* qsort -- qsort interface implemented by faster quicksort */ +#include <stdlib.h> + +#define SWAPINIT(a, es) swaptype = \ + (a - (char*) 0) % sizeof(long) || es % sizeof(long) ? 2 : \ + es == sizeof(long) ? 0 : 1; +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / (int) sizeof(TYPE); \ + register TYPE *pi = (TYPE *) (parmi); \ + register TYPE *pj = (TYPE *) (parmj); \ + do { \ + register TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} +static void swapfunc(char *a, char *b, int n, int swaptype) +{ if (swaptype <= 1) swapcode(long, a, b, n) + else swapcode(char, a, b, n) +} +#define swap(a, b) { \ + if (swaptype == 0) { \ + long t = * (long *) (a); \ + * (long *) (a) = * (long *) (b); \ + * (long *) (b) = t; \ + } else \ + swapfunc(a, b, es, swaptype); \ +} +#define vecswap(a, b, n) { if (n > 0) swapfunc(a, b, n*es, swaptype); } + +static char *med3func(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) +{ return cmp(a, b) < 0 ? + (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ) ) + : (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ) ); +} +#define med3(a, b, c) med3func(a, b, c, cmp) + +void qsort(void *va, size_t n, size_t es, int (*cmp)(const void *, const void *)) +{ + char *a, *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int r, swaptype, na, nb, nc, nd, d; + + a = va; + SWAPINIT(a, es); + if (n < 7) { /* Insertion sort on small arrays */ + for (pm = a + es; pm < a + n*es; pm += es) + for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es) + swap(pl, pl-es); + return; + } + pm = a + (n/2) * es; + if (n > 7) { + pl = a; + pn = a + (n-1) * es; + if (n > 40) { /* On big arrays, pseudomedian of 9 */ + d = (n/8) * es; + pl = med3(pl, pl+d, pl+2*d); + pm = med3(pm-d, pm, pm+d); + pn = med3(pn-2*d, pn-d, pn); + } + pm = med3(pl, pm, pn); /* On medium arrays, median of 3 */ + } + swap(a, pm); /* On tiny arrays, partition around middle */ + pa = pb = a + es; + pc = pd = pn = a + (n-1)*es; + for (;;) { + while (pb <= pc && (r = cmp(pb, a)) <= 0) { + if (r == 0) { swap(pa, pb); pa += es; } + pb += es; + } + while (pb <= pc && (r = cmp(pc, a)) >= 0) { + if (r == 0) { swap(pc, pd); pd -= es; } + pc -= es; + } + if (pb > pc) break; + swap(pb, pc); + pb += es; + pc -= es; + } + na = (pa - a) / es; + nb = (pb - pa) / es; + nc = (pd - pc) / es; + nd = (pn - pd) / es; + if (na < nb) { vecswap(a, a + nb*es, na); } + else { vecswap(a, a + na*es, nb); } + if (nc < nd) { vecswap(pb, pb + nd*es, nc); } + else { vecswap(pb, pb + nc*es, nd); } + if (nb > 1) qsort(a, nb, es, cmp); + if (nc > 1) qsort(a + (n-nc) * es, nc, es, cmp); +} diff --git a/sys/src/ape/lib/ap/gen/raise.c b/sys/src/ape/lib/ap/gen/raise.c new file mode 100755 index 000000000..f93b20d3a --- /dev/null +++ b/sys/src/ape/lib/ap/gen/raise.c @@ -0,0 +1,11 @@ +/* not a posix function, but implemented with posix kill, getpid */ + +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> + +int +raise(int sig) +{ + return kill(getpid(), sig); +} diff --git a/sys/src/ape/lib/ap/gen/rand.c b/sys/src/ape/lib/ap/gen/rand.c new file mode 100755 index 000000000..c73ad826c --- /dev/null +++ b/sys/src/ape/lib/ap/gen/rand.c @@ -0,0 +1,75 @@ +#include <stdlib.h> + +/* + * algorithm by + * D. P. Mitchell & J. A. Reeds + */ +#define LEN 607 +#define TAP 273 +#define MASK 0x7fffffffL +#define A 48271 +#define M 2147483647 +#define Q 44488 +#define R 3399 + +typedef unsigned long ulong; + +static ulong rng_vec[LEN]; +static ulong* rng_tap = rng_vec; +static ulong* rng_feed = 0; + +void +srand(unsigned int seed) +{ + long lo, hi, x; + int i; + + rng_tap = rng_vec; + rng_feed = rng_vec+LEN-TAP; + seed = seed%M; + if(seed < 0) + seed += M; + if(seed == 0) + seed = 89482311; + x = seed; + /* + * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1) + */ + for(i = -20; i < LEN; i++) { + hi = x / Q; + lo = x % Q; + x = A*lo - R*hi; + if(x < 0) + x += M; + if(i >= 0) + rng_vec[i] = x; + } +} + +static long +lrand(void) +{ + ulong x; + + rng_tap--; + if(rng_tap < rng_vec) { + if(rng_feed == 0) { + srand(1); + rng_tap--; + } + rng_tap += LEN; + } + rng_feed--; + if(rng_feed < rng_vec) + rng_feed += LEN; + x = (*rng_feed + *rng_tap) & MASK; + *rng_feed = x; + return x; +} + +int +rand(void) +{ + + return lrand() & 0x7fff; +} diff --git a/sys/src/ape/lib/ap/gen/reduce b/sys/src/ape/lib/ap/gen/reduce new file mode 100755 index 000000000..584f8b9ab --- /dev/null +++ b/sys/src/ape/lib/ap/gen/reduce @@ -0,0 +1,16 @@ +O=$1 +shift +objtype=$1 +shift + +ls -p ../$objtype/*.[cs] >[2]/dev/null | sed 's/..$//;s/^/^/' > /tmp/reduce.$pid +# +# if empty directory, just return the input files +# +if (! ~ $status '|') { + echo $* + rm /tmp/reduce.$pid + exit 0 +} +echo $* | tr ' ' \012 | grep -v -f /tmp/reduce.$pid | tr \012 ' ' +rm /tmp/reduce.$pid diff --git a/sys/src/ape/lib/ap/gen/strcat.c b/sys/src/ape/lib/ap/gen/strcat.c new file mode 100755 index 000000000..6aa75d109 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strcat.c @@ -0,0 +1,9 @@ +#include <string.h> + +char* +strcat(char *s1, const char *s2) +{ + + strcpy(strchr(s1, 0), s2); + return s1; +} diff --git a/sys/src/ape/lib/ap/gen/strchr.c b/sys/src/ape/lib/ap/gen/strchr.c new file mode 100755 index 000000000..b6d935f57 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strchr.c @@ -0,0 +1,18 @@ +#include <string.h> + +char* +strchr(const char *s, int c) +{ + char c1; + + if(c == 0) { + while(*s++) + ; + return s-1; + } + + while(c1 = *s++) + if(c1 == c) + return s-1; + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/strcmp.c b/sys/src/ape/lib/ap/gen/strcmp.c new file mode 100755 index 000000000..a9b4827e7 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strcmp.c @@ -0,0 +1,19 @@ +#include <string.h> + +int +strcmp(const char *s1, const char *s2) +{ + unsigned c1, c2; + + for(;;) { + c1 = *s1++; + c2 = *s2++; + if(c1 != c2) { + if(c1 > c2) + return 1; + return -1; + } + if(c1 == 0) + return 0; + } +} diff --git a/sys/src/ape/lib/ap/gen/strcoll.c b/sys/src/ape/lib/ap/gen/strcoll.c new file mode 100755 index 000000000..fda140945 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strcoll.c @@ -0,0 +1,8 @@ +#include <string.h> + +int +strcoll(const char *s1, const char *s2) +{ + /* BUG: supposed to pay attention to LC_COLLATE of current locale */ + return strcmp(s1, s2); +} diff --git a/sys/src/ape/lib/ap/gen/strcpy.c b/sys/src/ape/lib/ap/gen/strcpy.c new file mode 100755 index 000000000..6a294eee5 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strcpy.c @@ -0,0 +1,30 @@ +#include <string.h> +#define N 10000 + +static void* +memccpy(void *a1, void *a2, int c, unsigned long n) +{ + char *s1, *s2; + + s1 = a1; + s2 = a2; + while(n > 0) { + if((*s1++ = *s2++) == c) + return s1; + n--; + } + return 0; +} + +char* +strcpy(char *s1, const char *s2) +{ + char *os1; + + os1 = s1; + while(!memccpy(s1, s2, 0, N)) { + s1 += N; + s2 += N; + } + return os1; +} diff --git a/sys/src/ape/lib/ap/gen/strcspn.c b/sys/src/ape/lib/ap/gen/strcspn.c new file mode 100755 index 000000000..f7628e8ae --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strcspn.c @@ -0,0 +1,20 @@ +#include <string.h> + +#define N 256 + +size_t +strcspn(const char *s, const char *b) +{ + char map[N], *os; + + memset(map, 0, N); + for(;;) { + map[*(unsigned char*)b] = 1; + if(*b++ == 0) + break; + } + os = s; + while(map[*(unsigned char*)s++] == 0) + ; + return s - os - 1; +} diff --git a/sys/src/ape/lib/ap/gen/strftime.c b/sys/src/ape/lib/ap/gen/strftime.c new file mode 100755 index 000000000..f86606089 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strftime.c @@ -0,0 +1,202 @@ +#include <time.h> +#include <string.h> + +static char *awday[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; +static char *wday[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday"}; +static char *amon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static char *mon[12] = {"January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"}; +static char *ampm[2] = {"AM", "PM"}; +static char *tz[2] = {"EST", "EDT"}; + +static int jan1(int); +static char *strval(char *, char *, char **, int, int); +static char *dval(char *, char *, int, int); + +size_t +strftime(char *s, size_t maxsize, const char *format, const struct tm *t) +{ + char *sp, *se, *fp; + int i; + + sp = s; + se = s+maxsize; + for(fp=(char *)format; *fp && sp<se; fp++){ + if(*fp != '%') + *sp++ = *fp; + else switch(*++fp){ + case 'a': + sp = strval(sp, se, awday, t->tm_wday, 7); + break; + case 'A': + sp = strval(sp, se, wday, t->tm_wday, 7); + break; + case 'b': + sp = strval(sp, se, amon, t->tm_mon, 12); + break; + case 'B': + sp = strval(sp, se, mon, t->tm_mon, 12); + break; + case 'c': + sp += strftime(sp, se-sp, "%a %b %d %H:%M:%S %Y", t); + break; + case 'd': + sp = dval(sp, se, t->tm_mday, 2); + break; + case 'H': + sp = dval(sp, se, t->tm_hour, 2); + break; + case 'I': + i = t->tm_hour; + if(i == 0) + i = 12; + else if(i > 12) + i -= 12; + sp = dval(sp, se, i, 2); + break; + case 'j': + sp = dval(sp, se, t->tm_yday+1, 3); + break; + case 'm': + sp = dval(sp, se, t->tm_mon+1, 2); + break; + case 'M': + sp = dval(sp, se, t->tm_min, 2); + break; + case 'p': + i = (t->tm_hour < 12)? 0 : 1; + sp = strval(sp, se, ampm, i, 2); + break; + case 'S': + sp = dval(sp, se, t->tm_sec, 2); + break; + case 'U': + i = 7-jan1(t->tm_year); + if(i == 7) + i = 0; + /* Now i is yday number of first sunday in year */ + if(t->tm_yday < i) + i = 0; + else + i = (t->tm_yday-i)/7 + 1; + sp = dval(sp, se, i, 2); + break; + case 'w': + sp = dval(sp, se, t->tm_wday, 1); + break; + case 'W': + i = 8-jan1(t->tm_year); + if(i >= 7) + i -= 7; + /* Now i is yday number of first monday in year */ + if(t->tm_yday < i) + i = 0; + else + i = (t->tm_yday-i)/7 + 1; + sp = dval(sp, se, i, 2); + break; + case 'x': + sp += strftime(sp, se-sp, "%a %b %d, %Y", t); + break; + case 'X': + sp += strftime(sp, se-sp, "%H:%M:%S", t); + break; + case 'y': + sp = dval(sp, se, t->tm_year%100, 2); + break; + case 'Y': + sp = dval(sp, se, t->tm_year+1900, 4); + break; + case 'Z': + /* hack for now: assume eastern time zone */ + i = t->tm_isdst? 1 : 0; + sp = strval(sp, se, tz, i, 2); + break; + case 0: + fp--; /* stop loop after next fp incr */ + break; + default: + *sp++ = *fp; + } + } + if(*fp) + sp = s; /* format string didn't end: no room for conversion */ + if(sp<se) + *sp = 0; + return sp-s; +} + +static char * +strval(char *start, char *end, char **array, int index, int alen) +{ + int n; + + if(index<0 || index>=alen){ + *start = '?'; + return start+1; + } + n = strlen(array[index]); + if(n > end-start) + n = end-start; + memcpy(start, array[index], n); + return start+n; +} + +static char * +dval(char *start, char *end, int val, int width) +{ + char *p; + + if(val<0 || end-start<width){ + *start = '?'; + return start+1; + } + p = start+width-1; + while(p>=start){ + *p-- = val%10 + '0'; + val /= 10; + } + if(val>0) + *start = '*'; + return start+width; +} + +/* + * return day of the week + * of jan 1 of given year + */ +static int +jan1(int yr) +{ + int y, d; + +/* + * normal gregorian calendar + * one extra day per four years + */ + + y = yr+1900; + d = 4+y+(y+3)/4; + +/* + * julian calendar + * regular gregorian + * less three days per 400 + */ + + if(y > 1800) { + d -= (y-1701)/100; + d += (y-1601)/400; + } + +/* + * great calendar changeover instant + */ + + if(y > 1752) + d += 3; + + return(d%7); +} diff --git a/sys/src/ape/lib/ap/gen/strlen.c b/sys/src/ape/lib/ap/gen/strlen.c new file mode 100755 index 000000000..e339cb16b --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strlen.c @@ -0,0 +1,8 @@ +#include <string.h> + +size_t +strlen(const char *s) +{ + + return strchr(s, 0) - s; +} diff --git a/sys/src/ape/lib/ap/gen/strncat.c b/sys/src/ape/lib/ap/gen/strncat.c new file mode 100755 index 000000000..8891724b4 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strncat.c @@ -0,0 +1,20 @@ +#include <string.h> + +char* +strncat(char *s1, const char *s2, size_t n) +{ + char *os1; + long nn; + + os1 = s1; + nn = n; + while(*s1++) + ; + s1--; + while(*s1++ = *s2++) + if(--nn < 0) { + s1[-1] = 0; + break; + } + return os1; +} diff --git a/sys/src/ape/lib/ap/gen/strncmp.c b/sys/src/ape/lib/ap/gen/strncmp.c new file mode 100755 index 000000000..e76b09b9d --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strncmp.c @@ -0,0 +1,23 @@ +#include <string.h> + +int +strncmp(const char *s1, const char *s2, size_t n) +{ + unsigned c1, c2; + long nn; + + nn = n; + while(nn > 0) { + c1 = *s1++; + c2 = *s2++; + nn--; + if(c1 != c2) { + if(c1 > c2) + return 1; + return -1; + } + if(c1 == 0) + break; + } + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/strncpy.c b/sys/src/ape/lib/ap/gen/strncpy.c new file mode 100755 index 000000000..28a5a522c --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strncpy.c @@ -0,0 +1,17 @@ +#include <string.h> + +char* +strncpy(char *s1, const char *s2, size_t n) +{ + int i; + char *os1; + + os1 = s1; + for(i = 0; i < n; i++) + if((*s1++ = *s2++) == 0) { + while(++i < n) + *s1++ = 0; + return os1; + } + return os1; +} diff --git a/sys/src/ape/lib/ap/gen/strpbrk.c b/sys/src/ape/lib/ap/gen/strpbrk.c new file mode 100755 index 000000000..407f1c266 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strpbrk.c @@ -0,0 +1,20 @@ +#include <string.h> +#define N 256 + +char* +strpbrk(const char *s, const char *b) +{ + char map[N]; + + memset(map, 0, N); + for(;;) { + map[*b] = 1; + if(*b++ == 0) + break; + } + while(map[*s++] == 0) + ; + if(*--s) + return s; + return 0; +} diff --git a/sys/src/ape/lib/ap/gen/strrchr.c b/sys/src/ape/lib/ap/gen/strrchr.c new file mode 100755 index 000000000..038b06ad2 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strrchr.c @@ -0,0 +1,14 @@ +#include <string.h> + +char* +strrchr(const char *s, int c) +{ + char *r; + + if(c == 0) + return strchr(s, 0); + r = 0; + while(s = strchr(s, c)) + r = s++; + return r; +} diff --git a/sys/src/ape/lib/ap/gen/strspn.c b/sys/src/ape/lib/ap/gen/strspn.c new file mode 100755 index 000000000..57ebfd1b5 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strspn.c @@ -0,0 +1,17 @@ +#include <string.h> + +#define N 256 + +size_t +strspn(const char *s, const char *b) +{ + char map[N], *os; + + memset(map, 0, N); + while(*b) + map[*(unsigned char *)b++] = 1; + os = s; + while(map[*(unsigned char *)s++]) + ; + return s - os - 1; +} diff --git a/sys/src/ape/lib/ap/gen/strstr.c b/sys/src/ape/lib/ap/gen/strstr.c new file mode 100755 index 000000000..4e6828571 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strstr.c @@ -0,0 +1,27 @@ +#include <string.h> + +/* Return pointer to first occurrence of s2 in s1, NULL if none */ + +char +*strstr(const char *s1, const char *s2) +{ + char *p, *pa, *pb; + int c0, c; + + c0 = *s2; + if(c0 == 0) + return s1; + s2++; + for(p=strchr(s1, c0); p; p=strchr(p+1, c0)) { + pa = p; + for(pb=s2;; pb++) { + c = *pb; + if(c == 0) + return p; + if(c != *++pa) + break; + } + } + return 0; +} + diff --git a/sys/src/ape/lib/ap/gen/strtod.c b/sys/src/ape/lib/ap/gen/strtod.c new file mode 100755 index 000000000..ca4939100 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strtod.c @@ -0,0 +1,91 @@ +#include <math.h> +#include <errno.h> + +/* + * bug: should detect overflow, set errno = ERANGE, and return +/- HUGE_VAL + */ +double +strtod(const char *cp, char **endptr) +{ + double num, dem; + extern double pow10(int); + int neg, eneg, dig, predig, exp, c; + const char *p; + + p = cp; + num = 0; + neg = 0; + dig = 0; + predig = 0; + exp = 0; + eneg = 0; + + c = *p++; + while(c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' || c == '\r') + c = *p++; + if(c == '-' || c == '+'){ + if(c == '-') + neg = 1; + c = *p++; + } + while(c >= '0' && c <= '9'){ + num = num*10 + c-'0'; + predig++; + c = *p++; + } + if(c == '.') + c = *p++; + while(c >= '0' && c <= '9'){ + num = num*10 + c-'0'; + dig++; + c = *p++; + } + if(dig+predig == 0){ + if(endptr) + *endptr = (char *)cp; + return 0.0; + } + if(c == 'e' || c == 'E'){ + c = *p++; + if(c == '-' || c == '+'){ + if(c == '-'){ + dig = -dig; + eneg = 1; + } + c = *p++; + } + while(c >= '0' && c <= '9'){ + exp = exp*10 + c-'0'; + c = *p++; + } + } + exp -= dig; + if(exp < 0){ + exp = -exp; + eneg = !eneg; + } + dem = pow10(exp); + if(dem==HUGE_VAL) + num = eneg? 0.0 : HUGE_VAL; + else if(dem==0) + num = eneg? HUGE_VAL : 0.0; + else if(eneg) + num /= dem; + else + num *= dem; + if(neg) + num = -num; + if(endptr){ + *endptr = (char *)--p; + /* + * Fix cases like 2.3e+ + */ + while(p > cp){ + c = *--p; + if(c!='-' && c!='+' && c!='e' && c!='E') + break; + (*endptr)--; + } + } + return num; +} diff --git a/sys/src/ape/lib/ap/gen/strtok.c b/sys/src/ape/lib/ap/gen/strtok.c new file mode 100755 index 000000000..24155782a --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strtok.c @@ -0,0 +1,36 @@ +#include <string.h> + +#define N 256 + +char* +strtok_r(char *s, const char *b, char **last) +{ + char map[N], *os; + + memset(map, 0, N); + while(*b) + map[*(unsigned char*)b++] = 1; + if(s == 0) + s = *last; + while(map[*(unsigned char*)s++]) + ; + if(*--s == 0) + return 0; + os = s; + while(map[*(unsigned char*)s] == 0) + if(*s++ == 0) { + *last = s-1; + return os; + } + *s++ = 0; + *last = s; + return os; +} + +char* +strtok(char *s, const char *b) +{ + static char *under_rock; + + return strtok_r(s, b, &under_rock); +} diff --git a/sys/src/ape/lib/ap/gen/strtol.c b/sys/src/ape/lib/ap/gen/strtol.c new file mode 100755 index 000000000..1c5d99632 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strtol.c @@ -0,0 +1,94 @@ +#include <stdlib.h> +#include <limits.h> +#include <errno.h> + +long +strtol(const char *nptr, char **endptr, int base) +{ + const char *p; + long n, nn; + int c, ovfl, v, neg, ndig; + + p = nptr; + neg = 0; + n = 0; + ndig = 0; + ovfl = 0; + + /* + * White space + */ + for(;;p++){ + switch(*p){ + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + case '\v': + continue; + } + break; + } + + /* + * Sign + */ + if(*p=='-' || *p=='+') + if(*p++ == '-') + neg = 1; + + /* + * Base + */ + if(base==0){ + if(*p != '0') + base = 10; + else{ + base = 8; + if(p[1]=='x' || p[1]=='X'){ + p += 2; + base = 16; + } + } + }else if(base==16 && *p=='0'){ + if(p[1]=='x' || p[1]=='X') + p += 2; + }else if(base<0 || 36<base) + goto Return; + + /* + * Non-empty sequence of digits + */ + for(;; p++,ndig++){ + c = *p; + v = base; + if('0'<=c && c<='9') + v = c - '0'; + else if('a'<=c && c<='z') + v = c - 'a' + 10; + else if('A'<=c && c<='Z') + v = c - 'A' + 10; + if(v >= base) + break; + nn = n*base + v; + if(nn < n) + ovfl = 1; + n = nn; + } + + Return: + if(ndig == 0) + p = nptr; + if(endptr) + *endptr = (char *)p; + if(ovfl){ + errno = ERANGE; + if(neg) + return LONG_MIN; + return LONG_MAX; + } + if(neg) + return -n; + return n; +} diff --git a/sys/src/ape/lib/ap/gen/strtoll.c b/sys/src/ape/lib/ap/gen/strtoll.c new file mode 100755 index 000000000..e633d2d08 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strtoll.c @@ -0,0 +1,103 @@ +#include <stdlib.h> +#include <limits.h> +#include <errno.h> + +#define VLONG_MAX ~(1LL<<63) +#define VLONG_MIN (1LL<<63) + +long long +strtoll(char *nptr, char **endptr, int base) +{ + char *p; + long long n, nn, m; + int c, ovfl, v, neg, ndig; + + p = nptr; + neg = 0; + n = 0; + ndig = 0; + ovfl = 0; + + /* + * White space + */ + for(;; p++) { + switch(*p) { + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + case '\v': + continue; + } + break; + } + + /* + * Sign + */ + if(*p=='-' || *p=='+') + if(*p++ == '-') + neg = 1; + + /* + * Base + */ + if(base==0){ + base = 10; + if(*p == '0') { + base = 8; + if(p[1]=='x' || p[1]=='X') { + p += 2; + base = 16; + } + } + } else + if(base==16 && *p=='0') { + if(p[1]=='x' || p[1]=='X') + p += 2; + } else + if(base<0 || 36<base) + goto Return; + + /* + * Non-empty sequence of digits + */ + m = VLONG_MAX/base; + for(;; p++,ndig++) { + c = *p; + v = base; + if('0'<=c && c<='9') + v = c - '0'; + else + if('a'<=c && c<='z') + v = c - 'a' + 10; + else + if('A'<=c && c<='Z') + v = c - 'A' + 10; + if(v >= base) + break; + if(n > m) + ovfl = 1; + nn = n*base + v; + if(nn < n) + ovfl = 1; + n = nn; + } + +Return: + if(ndig == 0) + p = nptr; + if(endptr) + *endptr = p; + if(ovfl){ + errno = ERANGE; + if(neg) + return VLONG_MIN; + return VLONG_MAX; + } + if(neg) + return -n; + return n; +} diff --git a/sys/src/ape/lib/ap/gen/strtoul.c b/sys/src/ape/lib/ap/gen/strtoul.c new file mode 100755 index 000000000..bb7dce7ae --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strtoul.c @@ -0,0 +1,92 @@ +#include <stdlib.h> +#include <errno.h> +#include <limits.h> + +unsigned long +strtoul(const char *nptr, char **endptr, int base) +{ + const char *p; + unsigned long n, nn; + int c, ovfl, neg, v, ndig; + + p = (char*)nptr; + neg = 0; + n = 0; + ndig = 0; + ovfl = 0; + + /* + * White space + */ + for(;;p++){ + switch(*p){ + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + case '\v': + continue; + } + break; + } + + /* + * Sign + */ + if(*p=='-' || *p=='+') + if(*p++ == '-') + neg = 1; + + /* + * Base + */ + if(base==0){ + if(*p != '0') + base = 10; + else{ + base = 8; + if(p[1]=='x' || p[1]=='X'){ + p += 2; + base = 16; + } + } + }else if(base==16 && *p=='0'){ + if(p[1]=='x' || p[1]=='X') + p += 2; + }else if(base<0 || 36<base) + goto Return; + + /* + * Non-empty sequence of digits + */ + for(;; p++,ndig++){ + c = *p; + v = base; + if('0'<=c && c<='9') + v = c - '0'; + else if('a'<=c && c<='z') + v = c - 'a' + 10; + else if('A'<=c && c<='Z') + v = c - 'A' + 10; + if(v >= base) + break; + nn = n*base + v; + if(nn < n) + ovfl = 1; + n = nn; + } + + Return: + if(ndig == 0) + p = nptr; + if(endptr) + *endptr = (char *)p; + if(ovfl){ + errno = ERANGE; + return ULONG_MAX; + } + if(neg) + return -n; + return n; +} diff --git a/sys/src/ape/lib/ap/gen/strtoull.c b/sys/src/ape/lib/ap/gen/strtoull.c new file mode 100755 index 000000000..76aa392a4 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strtoull.c @@ -0,0 +1,100 @@ +#include <stdlib.h> +#include <errno.h> +#include <limits.h> + +#define UVLONG_MAX (1LL<<63) + +unsigned long long +strtoull(char *nptr, char **endptr, int base) +{ + char *p; + unsigned long long n, nn, m; + int c, ovfl, v, neg, ndig; + + p = nptr; + neg = 0; + n = 0; + ndig = 0; + ovfl = 0; + + /* + * White space + */ + for(;; p++) { + switch(*p) { + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + case '\v': + continue; + } + break; + } + + /* + * Sign + */ + if(*p == '-' || *p == '+') + if(*p++ == '-') + neg = 1; + + /* + * Base + */ + if(base == 0) { + base = 10; + if(*p == '0') { + base = 8; + if(p[1] == 'x' || p[1] == 'X'){ + p += 2; + base = 16; + } + } + } else + if(base == 16 && *p == '0') { + if(p[1] == 'x' || p[1] == 'X') + p += 2; + } else + if(base < 0 || 36 < base) + goto Return; + + /* + * Non-empty sequence of digits + */ + m = UVLONG_MAX/base; + for(;; p++,ndig++) { + c = *p; + v = base; + if('0' <= c && c <= '9') + v = c - '0'; + else + if('a' <= c && c <= 'z') + v = c - 'a' + 10; + else + if('A' <= c && c <= 'Z') + v = c - 'A' + 10; + if(v >= base) + break; + if(n > m) + ovfl = 1; + nn = n*base + v; + if(nn < n) + ovfl = 1; + n = nn; + } + +Return: + if(ndig == 0) + p = nptr; + if(endptr) + *endptr = p; + if(ovfl){ + errno = ERANGE; + return UVLONG_MAX; + } + if(neg) + return -n; + return n; +} diff --git a/sys/src/ape/lib/ap/gen/strxfrm.c b/sys/src/ape/lib/ap/gen/strxfrm.c new file mode 100755 index 000000000..ecb095064 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/strxfrm.c @@ -0,0 +1,17 @@ +#include <string.h> + +size_t +strxfrm(char *s1, const char *s2, size_t n) +{ + /* + * BUG: supposed to transform s2 to a canonical form + * so that strcmp can be used instead of strcoll, but + * our strcoll just uses strcmp. + */ + + size_t xn = strlen(s2); + if(n > xn) + n = xn; + memcpy(s1, s2, n); + return xn; +} diff --git a/sys/src/ape/lib/ap/gen/toupper.c b/sys/src/ape/lib/ap/gen/toupper.c new file mode 100755 index 000000000..eb1e8efd5 --- /dev/null +++ b/sys/src/ape/lib/ap/gen/toupper.c @@ -0,0 +1,17 @@ +#include <ctype.h> + +toupper(int c) +{ + + if(c < 'a' || c > 'z') + return c; + return (c-'a'+'A'); +} + +tolower(int c) +{ + + if(c < 'A' || c > 'Z') + return c; + return (c-'A'+'a'); +} |