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