*** empty log message ***
[oota-llvm.git] / runtime / GCCLibraries / libc / string.c
1 //===-- string.c - String functions for the LLVM libc Library -----*- C -*-===//
2 // 
3 // A lot of this code is ripped gratuitously from glibc and libiberty.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include <stdlib.h>
8 void *malloc(size_t);
9 void free(void *);
10
11 size_t strlen(const char *Str) {
12   size_t Count = 0;
13   while (*Str) { ++Count; ++Str; }
14   return Count;
15 }
16
17 char *strdup(const char *str) {
18   long Len = strlen(str);
19   char *Result = (char*)malloc((Len+1)*sizeof(char));
20   memcpy(Result, str, Len+1);
21   return Result;
22 }
23
24 char *strcpy(char *s1, const char *s2) {
25   while ((*s1++ = *s2++));
26   return s1;
27 }
28
29 char *strcat(char *s1, const char *s2) {
30   strcpy(s1+strlen(s1), s2);
31   return s1;
32 }
33
34
35 /* Compare S1 and S2, returning less than, equal to or
36    greater than zero if S1 is lexicographically less than,
37    equal to or greater than S2.  */
38 int strcmp (const char *p1, const char *p2) {
39   register const unsigned char *s1 = (const unsigned char *) p1;
40   register const unsigned char *s2 = (const unsigned char *) p2;
41   unsigned char c1, c2;
42
43   do
44     {
45       c1 = (unsigned char) *s1++;
46       c2 = (unsigned char) *s2++;
47       if (c1 == '\0')
48         return c1 - c2;
49     }
50   while (c1 == c2);
51
52   return c1 - c2;
53 }
54
55 // http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/generic/?cvsroot=glibc
56
57 typedef unsigned int op_t;
58 #define OPSIZ 4
59
60 void *memset (void *dstpp, int c, size_t len) {
61   long long int dstp = (long long int) dstpp;
62
63   if (len >= 8)
64     {
65       size_t xlen;
66       op_t cccc;
67
68       cccc = (unsigned char) c;
69       cccc |= cccc << 8;
70       cccc |= cccc << 16;
71       if (OPSIZ > 4)
72         /* Do the shift in two steps to avoid warning if long has 32 bits.  */
73         cccc |= (cccc << 16) << 16;
74
75       /* There are at least some bytes to set.
76          No need to test for LEN == 0 in this alignment loop.  */
77       while (dstp % OPSIZ != 0)
78         {
79           ((unsigned char *) dstp)[0] = c;
80           dstp += 1;
81           len -= 1;
82         }
83
84       /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */
85       xlen = len / (OPSIZ * 8);
86       while (xlen > 0)
87         {
88           ((op_t *) dstp)[0] = cccc;
89           ((op_t *) dstp)[1] = cccc;
90           ((op_t *) dstp)[2] = cccc;
91           ((op_t *) dstp)[3] = cccc;
92           ((op_t *) dstp)[4] = cccc;
93           ((op_t *) dstp)[5] = cccc;
94           ((op_t *) dstp)[6] = cccc;
95           ((op_t *) dstp)[7] = cccc;
96           dstp += 8 * OPSIZ;
97           xlen -= 1;
98         }
99       len %= OPSIZ * 8;
100
101       /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */
102       xlen = len / OPSIZ;
103       while (xlen > 0)
104         {
105           ((op_t *) dstp)[0] = cccc;
106           dstp += OPSIZ;
107           xlen -= 1;
108         }
109       len %= OPSIZ;
110     }
111
112   /* Write the last few bytes.  */
113   while (len > 0)
114     {
115       ((unsigned char *) dstp)[0] = c;
116       dstp += 1;
117       len -= 1;
118     }
119
120   return dstpp;
121 }
122
123 void *memcpy(void *dstpp, const void *srcpp, size_t len) {
124   char *dstp = (char*)dstpp;
125   char *srcp = (char*) srcpp;
126   unsigned i;
127
128   for (i = 0; i < len; ++i)
129     dstp[i] = srcp[i];
130
131   return dstpp;
132 }