initial check-in, version 0.5.0

This commit is contained in:
Rich Felker
2011-02-12 00:22:29 -05:00
commit 0b44a0315b
1021 changed files with 45711 additions and 0 deletions

7
src/string/bcmp.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
#include <strings.h>
int bcmp(const void *s1, const void *s2, size_t n)
{
return memcmp(s1, s2, n);
}

7
src/string/bcopy.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
#include <strings.h>
void bcopy(const void *s1, void *s2, size_t n)
{
memmove(s2, s1, n);
}

7
src/string/bzero.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
#include <strings.h>
void bzero(void *s, size_t n)
{
memset(s, 0, n);
}

7
src/string/index.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
#include <strings.h>
char *index(const char *s, int c)
{
return strchr(s, c);
}

24
src/string/memchr.c Normal file
View File

@ -0,0 +1,24 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#define SS (sizeof(size_t))
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
void *memchr(const void *src, int c, size_t n)
{
const unsigned char *s = src;
c = (unsigned char)c;
for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
if (n && *s != c) {
const size_t *w;
size_t k = ONES * c;
for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
for (s = (const void *)w; n && *s != c; s++, n--);
}
return n ? (void *)s : 0;
}

8
src/string/memcmp.c Normal file
View File

@ -0,0 +1,8 @@
#include <string.h>
int memcmp(const void *vl, const void *vr, size_t n)
{
const unsigned char *l=vl, *r=vr;
for (; n && *l == *r; n--, l++, r++);
return n ? *l-*r : 0;
}

29
src/string/memcpy.c Normal file
View File

@ -0,0 +1,29 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#define SS (sizeof(size_t))
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
void *memcpy(void *dest, const void *src, size_t n)
{
unsigned char *d = dest;
const unsigned char *s = src;
if (((uintptr_t)d & ALIGN) != ((uintptr_t)s & ALIGN))
goto misaligned;
for (; ((uintptr_t)d & ALIGN) && n; n--) *d++ = *s++;
if (n) {
size_t *wd = (void *)d;
const size_t *ws = (const void *)s;
for (; n>=SS; n-=SS) *wd++ = *ws++;
d = (void *)wd;
s = (const void *)ws;
misaligned:
for (; n; n--) *d++ = *s++;
}
return dest;
}

14
src/string/memmove.c Normal file
View File

@ -0,0 +1,14 @@
#include <string.h>
void *memmove(void *dest, const void *src, size_t n)
{
char *d = dest;
const char *s = src;
if (d==s) return d;
if ((size_t)(d-s) < n) {
while (n--) d[n] = s[n];
return dest;
}
/* Assumes memcpy is overlap-safe when dest < src */
return memcpy(d, s, n);
}

7
src/string/mempcpy.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
void *mempcpy(void *dest, void *src, size_t n)
{
memcpy(dest, src, n);
return (char *)dest + n;
}

21
src/string/memset.c Normal file
View File

@ -0,0 +1,21 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#define SS (sizeof(size_t))
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
void *memset(void *dest, int c, size_t n)
{
unsigned char *s = dest;
c = (unsigned char)c;
for (; ((uintptr_t)s & ALIGN) && n; n--) *s++ = c;
if (n) {
size_t *w, k = ONES * c;
for (w = (void *)s; n>=SS; n-=SS, w++) *w = k;
for (s = (void *)w; n; n--, s++) *s = c;
}
return dest;
}

7
src/string/rindex.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
#include <strings.h>
char *rindex(const char *s, int c)
{
return strrchr(s, c);
}

29
src/string/stpcpy.c Normal file
View File

@ -0,0 +1,29 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include "libc.h"
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
char *__stpcpy(char *d, const char *s)
{
size_t *wd;
const size_t *ws;
if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
for (; (*d=*s) && ((uintptr_t)s & ALIGN); s++, d++);
if (!*s) return d;
wd=(void *)d; ws=(const void *)s;
for (; !HASZERO(*ws); *wd++ = *ws++);
d=(void *)wd; s=(const void *)ws;
}
for (; (*d=*s); s++, d++);
return d;
}
weak_alias(__stpcpy, stpcpy);

32
src/string/stpncpy.c Normal file
View File

@ -0,0 +1,32 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include "libc.h"
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
char *__stpncpy(char *d, const char *s, size_t n)
{
size_t *wd;
const size_t *ws;
if (((uintptr_t)s & ALIGN) != ((uintptr_t)d & ALIGN)) {
for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
if (!n || !*s) goto tail;
wd=(void *)d; ws=(const void *)s;
for (; n>=sizeof(size_t) && !HASZERO(*ws);
n-=sizeof(size_t), ws++, *wd++) *wd = *ws;
d=(void *)wd; s=(const void *)ws;
}
for (; n && (*d=*s); n--, s++, d++);
tail:
memset(d, 0, n);
return d;
}
weak_alias(__stpncpy, stpncpy);

9
src/string/strcasecmp.c Normal file
View File

@ -0,0 +1,9 @@
#include <strings.h>
#include <ctype.h>
int strcasecmp(const char *_l, const char *_r)
{
const unsigned char *l=_l, *r=_r;
for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++);
return tolower(*l) - tolower(*r);
}

7
src/string/strcasestr.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
char *strcasestr(const char *h, const char *n)
{
//FIXME!
return strstr(h, n);
}

7
src/string/strcat.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
char *strcat(char *dest, const char *src)
{
strcpy(dest + strlen(dest), src);
return dest;
}

23
src/string/strchr.c Normal file
View File

@ -0,0 +1,23 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
char *strchr(const char *s, int c)
{
c = (char)c;
if (!c) return (char *)s + strlen(s);
for (; ((uintptr_t)s & ALIGN) && *s && *s != c; s++);
if (*s && *s != c) {
const size_t *w;
size_t k = ONES * c;
for (w = (const void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
for (s = (const void *)w; *s && *s != c; s++);
}
return *s ? (char *)s : 0;
}

7
src/string/strchrnul.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
char *strchrnul(const char *s, int c)
{
char *p = strchr(s, c);
return p ? p : (char *)s + strlen(s);
}

7
src/string/strcmp.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
int strcmp(const char *l, const char *r)
{
for (; *l==*r && *l && *r; l++, r++);
return *(unsigned char *)l - *(unsigned char *)r;
}

16
src/string/strcpy.c Normal file
View File

@ -0,0 +1,16 @@
#include <string.h>
char *__stpcpy(char *, const char *);
char *strcpy(char *dest, const char *src)
{
#if 1
__stpcpy(dest, src);
return dest;
#else
const unsigned char *s = src;
unsigned char *d = dest;
while ((*d++ = *s++));
return dest;
#endif
}

20
src/string/strcspn.c Normal file
View File

@ -0,0 +1,20 @@
#include <string.h>
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
size_t strcspn(const char *_s, const char *_c)
{
const unsigned char *s = _s;
const unsigned char *c = _c;
const unsigned char *a = s;
size_t byteset[32/sizeof(size_t)];
if (!c[0]) return strlen(s);
if (!c[1]) return (s=strchr(s, *c)) ? s-a : strlen(a);
memset(byteset, 0, sizeof byteset);
for (; *c && BITOP(byteset, *c, |=); c++);
for (; *s && !BITOP(byteset, *s, &); s++);
return s-a;
}

13
src/string/strdup.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdlib.h>
#include <string.h>
#include "libc.h"
char *__strdup(const char *s)
{
size_t l = strlen(s);
char *d = malloc(l+1);
if (!d) return NULL;
return memcpy(d, s, l+1);
}
weak_alias(__strdup, strdup);

11
src/string/strerror_r.c Normal file
View File

@ -0,0 +1,11 @@
#include <string.h>
#include <errno.h>
int strerror_r(int err, char *buf, size_t buflen)
{
char *msg = strerror(err);
if (strlen(msg) >= buflen)
return ERANGE;
strcpy(buf, msg);
return 0;
}

8
src/string/strlcat.c Normal file
View File

@ -0,0 +1,8 @@
#include <string.h>
size_t strlcat(char *d, const char *s, size_t n)
{
size_t l = strnlen(d, n);
if (l == n) return l + strlen(s);
return l + strlcpy(d+l, s, n-l);
}

32
src/string/strlcpy.c Normal file
View File

@ -0,0 +1,32 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include "libc.h"
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
size_t strlcpy(char *d, const char *s, size_t n)
{
char *d0 = d;
size_t *wd;
const size_t *ws;
if (!n--) goto finish;
if (((uintptr_t)s & ALIGN) != ((uintptr_t)d & ALIGN)) {
for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
if (n && *s) {
wd=(void *)d; ws=(const void *)s;
for (; n>=sizeof(size_t) && !HASZERO(*ws);
n-=sizeof(size_t), ws++, *wd++) *wd = *ws;
d=(void *)wd; s=(const void *)ws;
}
}
for (; n && (*d=*s); n--, s++, d++);
*d = 0;
finish:
return d-d0 + strlen(s);
}

21
src/string/strlen.c Normal file
View File

@ -0,0 +1,21 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#define ALIGN (sizeof(size_t)-1)
#define ONES ((size_t)-1/UCHAR_MAX)
#define HIGHS (ONES * (UCHAR_MAX/2+1))
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
size_t strlen(const char *s)
{
const char *a = s;
const size_t *w;
for (; ((uintptr_t)s & ALIGN) && *s; s++);
if (*s) {
for (w = (const void *)s; !HASZERO(*w); w++);
for (s = (const void *)w; *s; s++);
}
return s-a;
}

10
src/string/strncasecmp.c Normal file
View File

@ -0,0 +1,10 @@
#include <strings.h>
#include <ctype.h>
int strncasecmp(const char *_l, const char *_r, size_t n)
{
const unsigned char *l=_l, *r=_r;
if (!n--) return 0;
for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--);
return tolower(*l) - tolower(*r);
}

10
src/string/strncat.c Normal file
View File

@ -0,0 +1,10 @@
#include <string.h>
char *strncat(char *d, const char *s, size_t n)
{
char *a = d;
d += strlen(d);
while (n && (*d++ = *s++)) n--;
*d++ = 0;
return a;
}

9
src/string/strncmp.c Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
int strncmp(const char *_l, const char *_r, size_t n)
{
const unsigned char *l=_l, *r=_r;
if (!n--) return 0;
for (; *l && *r && n && *l == *r ; l++, r++, n--);
return *l - *r;
}

9
src/string/strncpy.c Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
char *__stpncpy(char *, const char *, size_t);
char *strncpy(char *d, const char *s, size_t n)
{
__stpncpy(d, s, n);
return d;
}

12
src/string/strndup.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdlib.h>
#include <string.h>
char *strndup(const char *s, size_t n)
{
size_t l = strnlen(s, n);
char *d = malloc(l+1);
if (!d) return NULL;
memcpy(d, s, l);
d[l] = 0;
return d;
}

7
src/string/strnlen.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
size_t strnlen(const char *s, size_t n)
{
const char *p = memchr(s, 0, n);
return p ? p-s : n;
}

7
src/string/strpbrk.c Normal file
View File

@ -0,0 +1,7 @@
#include <string.h>
char *strpbrk(const char *s, const char *b)
{
s += strcspn(s, b);
return *s ? (char *)s : 0;
}

9
src/string/strrchr.c Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
char *strrchr(const char *s, int c)
{
const char *p;
c = (char)c;
for (p=s+strlen(s); p>=s && *p!=c; p--);
return p>=s ? (char *)p : 0;
}

12
src/string/strsep.c Normal file
View File

@ -0,0 +1,12 @@
#include <string.h>
char *strsep(char **str, const char *sep)
{
char *s = *str, *end;
if (!s) return NULL;
end = s + strcspn(s, sep);
if (*end) *end++ = 0;
else end = 0;
*str = end;
return s;
}

98
src/string/strsignal.c Normal file
View File

@ -0,0 +1,98 @@
#include <signal.h>
#if (SIGHUP == 1) && (SIGINT == 2) && (SIGQUIT == 3) && (SIGILL == 4) \
&& (SIGTRAP == 5) && (SIGABRT == 6) && (SIGBUS == 7) && (SIGFPE == 8) \
&& (SIGKILL == 9) && (SIGUSR1 == 10) && (SIGSEGV == 11) && (SIGUSR2 == 12) \
&& (SIGPIPE == 13) && (SIGALRM == 14) && (SIGTERM == 15) && (SIGSTKFLT == 16) \
&& (SIGCHLD == 17) && (SIGCONT == 18) && (SIGSTOP == 19) && (SIGTSTP == 20) \
&& (SIGTTIN == 21) && (SIGTTOU == 22) && (SIGURG == 23) && (SIGXCPU == 24) \
&& (SIGXFSZ == 25) && (SIGVTALRM == 26) && (SIGPROF == 27) && (SIGWINCH == 28) \
&& (SIGPOLL == 29) && (SIGPWR == 30) && (SIGSYS == 31)
#define sigmap(x) x
#else
static const char map[] = {
[SIGHUP] = 1,
[SIGINT] = 2,
[SIGQUIT] = 3,
[SIGILL] = 4,
[SIGTRAP] = 5,
[SIGABRT] = 6,
[SIGBUS] = 7,
[SIGFPE] = 8,
[SIGKILL] = 9,
[SIGUSR1] = 10,
[SIGSEGV] = 11,
[SIGUSR2] = 12,
[SIGPIPE] = 13,
[SIGALRM] = 14,
[SIGTERM] = 15,
[SIGSTKFLT] = 16,
[SIGCHLD] = 17,
[SIGCONT] = 18,
[SIGSTOP] = 19,
[SIGTSTP] = 20,
[SIGTTIN] = 21,
[SIGTTOU] = 22,
[SIGURG] = 23,
[SIGXCPU] = 24,
[SIGXFSZ] = 25,
[SIGVTALRM] = 26,
[SIGPROF] = 27,
[SIGWINCH] = 28,
[SIGPOLL] = 29,
[SIGPWR] = 30,
[SIGSYS] = 31
};
#define sigmap(x) ((unsigned)(x) > sizeof map ? 0 : map[(unsigned)(x)])
#endif
static const char strings[] =
"Unknown signal\0"
"Hangup\0"
"Interrupt\0"
"Quit\0"
"Illegal instruction\0"
"Trace/breakpoint trap\0"
"Aborted\0"
"Bus error\0"
"Floating point exception\0"
"Killed\0"
"User defined signal 1\0"
"Segmentation fault\0"
"User defined signal 2\0"
"Broken pipe\0"
"Alarm clock\0"
"Terminated\0"
"Stack fault\0"
"Child exited\0"
"Continued\0"
"Stopped (signal)\0"
"Stopped\0"
"Stopped (tty input)\0"
"Stopped (tty output)\0"
"Urgent I/O condition\0"
"CPU time limit exceeded\0"
"File size limit exceeded\0"
"Virtual timer expired\0"
"Profiling timer expired\0"
"Window changed\0"
"I/O possible\0"
"Power failure\0"
"Bad system call";
char *strsignal(int signum)
{
char *s = (char *)strings;
signum = sigmap(signum);
if ((unsigned)signum - 1 > 31) signum = 0;
for (; signum--; s++) for (; *s; s++);
return s;
}

22
src/string/strspn.c Normal file
View File

@ -0,0 +1,22 @@
#include <string.h>
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
size_t strspn(const char *_s, const char *_c)
{
const unsigned char *s = _s;
const unsigned char *c = _c;
const unsigned char *a = s;
size_t byteset[32/sizeof(size_t)] = { 0 };
if (!c[0]) return 0;
if (!c[1]) {
for (; *s == *c; s++);
return s-a;
}
for (; *c && BITOP(byteset, *c, |=); c++);
for (; *s && BITOP(byteset, *s, &); s++);
return s-a;
}

166
src/string/strstr.c Normal file
View File

@ -0,0 +1,166 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
static char *twobyte_strstr(const unsigned char *h, const unsigned char *n)
{
uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
for (h++; *h && hw != nw; hw = hw<<8 | *++h);
return *h ? (char *)h-1 : 0;
}
static char *threebyte_strstr(const unsigned char *h, const unsigned char *n)
{
uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
return *h ? (char *)h-2 : 0;
}
static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)
{
uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
for (h+=3; *h && hw != nw; hw = hw<<8 | *++h);
return *h ? (char *)h-3 : 0;
}
#if 0
static char *naive_strstr(const char *h, const char *n)
{
size_t i;
for (i=0; n[i] && h[i]; i++)
for ( ; n[i] != h[i]; h++, i=0);
return n[i] ? 0 : (char *)h;
}
#endif
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
{
const unsigned char *z;
size_t l, ip, jp, k, p, ms, p0, mem, mem0;
size_t byteset[32 / sizeof(size_t)] = { 0 };
size_t shift[256];
/* Computing length of needle and fill shift table */
for (l=0; n[l] && h[l]; l++)
BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
if (n[l]) return 0; /* hit the end of h */
/* Compute maximal suffix */
ip = -1; jp = 0; k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else k++;
} else if (n[ip+k] > n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
ms = ip;
p0 = p;
/* And with the opposite comparison */
ip = -1; jp = 0; k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else k++;
} else if (n[ip+k] < n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
if (ip+1 > ms+1) ms = ip;
else p = p0;
/* Periodic needle? */
if (memcmp(n, n+p, ms+1)) {
mem0 = 0;
p = MAX(ms, l-ms-1) + 1;
} else mem0 = l-p;
mem = 0;
/* Initialize incremental end-of-haystack pointer */
z = h;
/* Search loop */
for (;;) {
/* Update incremental end-of-haystack pointer */
if (z-h < l) {
/* Fast estimate for MIN(l,63) */
size_t grow = l | 63;
const char *z2 = memchr(z, 0, grow);
if (z2) {
z = z2;
if (z-h < l) return 0;
} else z += grow;
}
/* Check last byte first; advance by shift on mismatch */
if (BITOP(byteset, h[l-1], &)) {
k = l-shift[h[l-1]];
//printf("adv by %zu (on %c) at [%s] (%zu;l=%zu)\n", k, h[l-1], h, shift[h[l-1]], l);
if (k) {
if (mem0 && mem && k < p) k = l-p;
h += k;
mem = 0;
continue;
}
} else {
h += l;
mem = 0;
continue;
}
/* Compare right half */
for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
if (n[k]) {
h += k-ms;
mem = 0;
continue;
}
/* Compare left half */
for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
if (k == mem) return (char *)h;
h += p;
mem = mem0;
}
}
char *strstr(const char *h, const char *n)
{
/* Return immediately on empty needle */
if (!n[0]) return (char *)h;
/* Use faster algorithms for short needles */
h = strchr(h, *n);
if (!h || !n[1]) return (char *)h;
if (!h[1]) return 0;
if (!n[2]) return twobyte_strstr(h, n);
if (!h[2]) return 0;
if (!n[3]) return threebyte_strstr(h, n);
if (!h[3]) return 0;
if (!n[4]) return fourbyte_strstr(h, n);
return twoway_strstr(h, n);
}

13
src/string/strtok.c Normal file
View File

@ -0,0 +1,13 @@
#include <string.h>
char *strtok(char *s, const char *sep)
{
static char *p;
if (!s && !(s = p)) return NULL;
s += strspn(s, sep);
if (!*s) return p = 0;
p = s + strcspn(s, sep);
if (*p) *p++ = 0;
else p = 0;
return s;
}

12
src/string/strtok_r.c Normal file
View File

@ -0,0 +1,12 @@
#include <string.h>
char *strtok_r(char *s, const char *sep, char **p)
{
if (!s && !(s = *p)) return NULL;
s += strspn(s, sep);
if (!*s) return *p = 0;
*p = s + strcspn(s, sep);
if (**p) *(*p)++ = 0;
else *p = 0;
return s;
}

13
src/string/swab.c Normal file
View File

@ -0,0 +1,13 @@
#include <unistd.h>
void swab(const void *_src, void *_dest, ssize_t n)
{
const char *src = _src;
char *dest = _dest;
for (; n>0; n-=2) {
dest[0] = src[1];
dest[1] = src[0];
dest += 2;
src += 2;
}
}

7
src/string/wcscat.c Normal file
View File

@ -0,0 +1,7 @@
#include <wchar.h>
wchar_t *wcscat(wchar_t *dest, const wchar_t *src)
{
wcscpy(dest + wcslen(dest), src);
return dest;
}

8
src/string/wcschr.c Normal file
View File

@ -0,0 +1,8 @@
#include <wchar.h>
wchar_t *wcschr(const wchar_t *s, wchar_t c)
{
if (!c) return (wchar_t *)s + wcslen(s);
for (; *s && *s != c; s++);
return *s ? (wchar_t *)s : 0;
}

7
src/string/wcscmp.c Normal file
View File

@ -0,0 +1,7 @@
#include <wchar.h>
int wcscmp(const wchar_t *l, const wchar_t *r)
{
for (; *l==*r && *l && *r; l++, r++);
return *l - *r;
}

8
src/string/wcscpy.c Normal file
View File

@ -0,0 +1,8 @@
#include <wchar.h>
wchar_t *wcscpy(wchar_t *d, const wchar_t *s)
{
wchar_t *a = d;
while ((*d++ = *s++));
return a;
}

10
src/string/wcscspn.c Normal file
View File

@ -0,0 +1,10 @@
#include <wchar.h>
size_t wcscspn(const wchar_t *s, const wchar_t *c)
{
const wchar_t *a;
if (!c[0]) return wcslen(s);
if (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);
for (a=s; *s && !wcschr(c, *s); s++);
return s-a;
}

8
src/string/wcslen.c Normal file
View File

@ -0,0 +1,8 @@
#include <wchar.h>
size_t wcslen(const wchar_t *s)
{
const wchar_t *a;
for (a=s; *s; s++);
return s-a;
}

10
src/string/wcsncat.c Normal file
View File

@ -0,0 +1,10 @@
#include <wchar.h>
wchar_t *wcsncat(wchar_t *d, const wchar_t *s, size_t n)
{
wchar_t *a = d;
d += wcslen(d);
while (n && (*d++ = *s++)) n--;
*d++ = 0;
return a;
}

7
src/string/wcsncmp.c Normal file
View File

@ -0,0 +1,7 @@
#include <wchar.h>
int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
{
for (; n && *l==*r && *l && *r; l++, r++);
return n ? *l - *r : 0;
}

9
src/string/wcsncpy.c Normal file
View File

@ -0,0 +1,9 @@
#include <wchar.h>
wchar_t *wcsncpy(wchar_t *d, const wchar_t *s, size_t n)
{
wchar_t *a = d;
while (n && (*d++ = *s++)) n--;
wmemset(d, 0, n);
return a;
}

7
src/string/wcspbrk.c Normal file
View File

@ -0,0 +1,7 @@
#include <wchar.h>
wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)
{
s += wcscspn(s, b);
return *s ? (wchar_t *)s : NULL;
}

8
src/string/wcsrchr.c Normal file
View File

@ -0,0 +1,8 @@
#include <wchar.h>
wchar_t *wcsrchr(const wchar_t *s, wint_t c)
{
const wchar_t *p;
for (p=s+wcslen(s); p>=s && *p!=c; p--);
return p>=s ? (wchar_t *)p : 0;
}

8
src/string/wcsspn.c Normal file
View File

@ -0,0 +1,8 @@
#include <wchar.h>
size_t wcsspn(const wchar_t *s, const wchar_t *c)
{
const wchar_t *a;
for (a=s; *s && wcschr(c, *s); s++);
return s-a;
}

117
src/string/wcsstr.c Normal file
View File

@ -0,0 +1,117 @@
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
static wchar_t *naive_wcsstr(const wchar_t *h, const wchar_t *n)
{
size_t i;
for (i=0; n[i] && h[i]; i++)
for ( ; n[i] != h[i]; h++, i=0);
return n[i] ? 0 : (wchar_t *)h;
}
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
{
const wchar_t *z;
size_t l, ip, jp, k, p, ms, p0, mem, mem0;
/* Computing length of needle */
for (l=0; n[l] && h[l]; l++);
if (n[l]) return 0; /* hit the end of h */
/* Compute maximal suffix */
ip = -1; jp = 0; k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else k++;
} else if (n[ip+k] > n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
ms = ip;
p0 = p;
/* And with the opposite comparison */
ip = -1; jp = 0; k = p = 1;
while (jp+k<l) {
if (n[ip+k] == n[jp+k]) {
if (k == p) {
jp += p;
k = 1;
} else k++;
} else if (n[ip+k] < n[jp+k]) {
jp += k;
k = 1;
p = jp - ip;
} else {
ip = jp++;
k = p = 1;
}
}
if (ip+1 > ms+1) ms = ip;
else p = p0;
/* Periodic needle? */
if (wmemcmp(n, n+p, ms+1)) {
mem0 = 0;
p = MAX(ms, l-ms-1) + 1;
} else mem0 = l-p;
mem = 0;
/* Initialize incremental end-of-haystack pointer */
z = h;
/* Search loop */
for (;;) {
/* Update incremental end-of-haystack pointer */
if (z-h < l) {
/* Fast estimate for MIN(l,63) */
size_t grow = l | 63;
const wchar_t *z2 = wmemchr(z, 0, grow);
if (z2) {
z = z2;
if (z-h < l) return 0;
} else z += grow;
}
/* Compare right half */
for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
if (n[k]) {
h += k-ms;
mem = 0;
continue;
}
/* Compare left half */
for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
if (k == mem) return (wchar_t *)h;
h += p;
mem = mem0;
}
}
wchar_t *wcsstr(const wchar_t *h, const wchar_t *n)
{
/* Return immediately on empty needle or haystack */
if (!n[0]) return (wchar_t *)h;
if (!h[0]) return 0;
/* Use faster algorithms for short needles */
h = wcschr(h, *n);
if (!h || !n[1]) return (wchar_t *)h;
if (!h[1]) return 0;
if (!n[2] || !n[3] || !n[4]) return naive_wcsstr(h, n);
return twoway_wcsstr(h, n);
}

6
src/string/wcswcs.c Normal file
View File

@ -0,0 +1,6 @@
#include <wchar.h>
wchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)
{
return wcsstr(haystack, needle);
}

8
src/string/wmemchr.c Normal file
View File

@ -0,0 +1,8 @@
#include <string.h>
#include <wchar.h>
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
{
for (; n && *s != c; s++);
return n ? (wchar_t *)s : 0;
}

8
src/string/wmemcmp.c Normal file
View File

@ -0,0 +1,8 @@
#include <string.h>
#include <wchar.h>
int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)
{
for (; n && *l==*r; n--, l++, r++);
return n ? *l-*r : 0;
}

9
src/string/wmemcpy.c Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
#include <wchar.h>
wchar_t *wmemcpy(wchar_t *d, const wchar_t *s, size_t n)
{
wchar_t *a = d;
while (n--) *d++ = *s++;
return a;
}

11
src/string/wmemmove.c Normal file
View File

@ -0,0 +1,11 @@
#include <string.h>
#include <wchar.h>
wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
{
if ((size_t)(d-s) < n) {
while (n--) d[n] = s[n];
return d;
}
return wmemcpy(d, s, n);
}

9
src/string/wmemset.c Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
#include <wchar.h>
wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)
{
wchar_t *ret = d;
while (n--) *d++ = c;
return ret;
}