aboutsummaryrefslogtreecommitdiff
path: root/runtime/GCCLibraries/libc/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/GCCLibraries/libc/string.c')
-rw-r--r--runtime/GCCLibraries/libc/string.c172
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;
+}