diff options
Diffstat (limited to 'runtime/GCCLibraries/libc/string.c')
-rw-r--r-- | runtime/GCCLibraries/libc/string.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/runtime/GCCLibraries/libc/string.c b/runtime/GCCLibraries/libc/string.c new file mode 100644 index 0000000000..bd43b34100 --- /dev/null +++ b/runtime/GCCLibraries/libc/string.c @@ -0,0 +1,172 @@ +//===-- string.c - String functions for the LLVM libc Library -----*- C -*-===// +// +// A lot of this code is ripped gratuitously from glibc and libiberty. +// +//===----------------------------------------------------------------------===// + +#include <stdlib.h> +#include <string.h> + +#ifdef strlen +#undef strlen +#endif +size_t strlen(const char *Str) { + size_t Count = 0; + while (*Str) { ++Count; ++Str; } + return Count; +} + +#ifdef strdup +#undef strdup +#endif +char *strdup(const char *str) { + size_t Len = strlen(str); + char *Result = (char*)malloc((Len+1)*sizeof(char)); + memcpy(Result, str, Len+1); + return Result; +} + +#ifdef strndup +#undef strndup +#endif +char *strndup(const char *str, size_t n) { + size_t Len = strlen(str); + if (Len > n) Len = n; + char *Result = (char*)malloc((Len+1)*sizeof(char)); + memcpy(Result, str, Len); + Result[Len] = 0; + return Result; +} + +#ifdef strcpy +#undef strcpy +#endif +char *strcpy(char *s1, const char *s2) { + char *dest = s1; + while ((*s1++ = *s2++)); + return dest; +} + +#ifdef strncpy +#undef strncpy +#endif +char *strncpy(char *s1, const char *s2, size_t n) { + char *dest = s1; + while (n-- && (*s1++ = *s2++)); + return dest; +} + +#ifdef strcat +#undef strcat +#endif +char *strcat(char *s1, const char *s2) { + strcpy(s1+strlen(s1), s2); + return s1; +} + + +#ifdef strcmp +#undef strcmp +#endif +/* Compare S1 and S2, returning less than, equal to or + greater than zero if S1 is lexicographically less than, + equal to or greater than S2. */ +int strcmp (const char *p1, const char *p2) { + register const unsigned char *s1 = (const unsigned char *) p1; + register const unsigned char *s2 = (const unsigned char *) p2; + unsigned char c1, c2; + + do + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0') + return c1 - c2; + } + while (c1 == c2); + + return c1 - c2; +} + +// http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/generic/?cvsroot=glibc +#if 0 +typedef unsigned int op_t; +#define OPSIZ 4 + +void *memset (void *dstpp, int c, size_t len) { + long long int dstp = (long long int) dstpp; + + if (len >= 8) + { + size_t xlen; + op_t cccc; + + cccc = (unsigned char) c; + cccc |= cccc << 8; + cccc |= cccc << 16; + if (OPSIZ > 4) + /* Do the shift in two steps to avoid warning if long has 32 bits. */ + cccc |= (cccc << 16) << 16; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ + xlen = len / (OPSIZ * 8); + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + ((op_t *) dstp)[1] = cccc; + ((op_t *) dstp)[2] = cccc; + ((op_t *) dstp)[3] = cccc; + ((op_t *) dstp)[4] = cccc; + ((op_t *) dstp)[5] = cccc; + ((op_t *) dstp)[6] = cccc; + ((op_t *) dstp)[7] = cccc; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ + xlen = len / OPSIZ; + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len > 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + return dstpp; +} +#endif + +#ifdef memcpy +#undef memcpy +#endif +void *memcpy(void *dstpp, const void *srcpp, size_t len) { + char *dstp = (char*)dstpp; + char *srcp = (char*) srcpp; + unsigned i; + + for (i = 0; i < len; ++i) + dstp[i] = srcp[i]; + + return dstpp; +} |