Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


(no commit message)
[palacios.git] / palacios / src / common / string.c
1 /*
2  * String library
3  * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4  * $Revision: 1.1.1.1 $
5  * 
6  * This is free software.  You are permitted to use,
7  * redistribute, and modify it as specified in the file "COPYING".
8  */
9
10 /*
11  * NOTE:
12  * These are slow and simple implementations of a subset of
13  * the standard C library string functions.
14  * We also have an implementation of snprintf().
15  */
16
17 #include <fmtout.h>
18 #include <string.h>
19
20 extern void *Malloc(size_t size);
21
22 void* memset(void* s, int c, size_t n)
23 {
24     unsigned char* p = (unsigned char*) s;
25
26     while (n > 0) {
27         *p++ = (unsigned char) c;
28         --n;
29     }
30
31     return s;
32 }
33
34 void* memcpy(void *dst, const void* src, size_t n)
35 {
36     unsigned char* d = (unsigned char*) dst;
37     const unsigned char* s = (const unsigned char*) src;
38
39     while (n > 0) {
40         *d++ = *s++;
41         --n;
42     }
43
44     return dst;
45 }
46
47 int memcmp(const void *s1_, const void *s2_, size_t n)
48 {
49     const signed char *s1 = s1_, *s2 = s2_;
50
51     while (n > 0) {
52         int cmp = *s1 - *s2;
53         if (cmp != 0)
54             return cmp;
55         ++s1;
56         ++s2;
57     }
58
59     return 0;
60 }
61
62 size_t strlen(const char* s)
63 {
64     size_t len = 0;
65     while (*s++ != '\0')
66         ++len;
67     return len;
68 }
69
70 /*
71  * This it a GNU extension.
72  * It is like strlen(), but it will check at most maxlen
73  * characters for the terminating nul character,
74  * returning maxlen if it doesn't find a nul.
75  * This is very useful for checking the length of untrusted
76  * strings (e.g., from user space).
77  */
78 size_t strnlen(const char *s, size_t maxlen)
79 {
80     size_t len = 0;
81     while (len < maxlen && *s++ != '\0')
82         ++len;
83     return len;
84 }
85
86 int strcmp(const char* s1, const char* s2)
87 {
88     while (1) {
89         int cmp = *s1 - *s2;
90         if (cmp != 0 || *s1 == '\0' || *s2 == '\0')
91             return cmp;
92         ++s1;
93         ++s2;
94     }
95 }
96
97 int strncmp(const char* s1, const char* s2, size_t limit)
98 {
99     size_t i = 0;
100     while (i < limit) {
101         int cmp = *s1 - *s2;
102         if (cmp != 0 || *s1 == '\0' || *s2 == '\0')
103             return cmp;
104         ++s1;
105         ++s2;
106         ++i;
107     }
108
109     /* limit reached and equal */
110     return 0;
111 }
112
113 char *strcat(char *s1, const char *s2)
114 {
115     char *t1;
116
117     t1 = s1;
118     while (*s1) s1++;
119     while(*s2) *s1++ = *s2++;
120     *s1 = '\0';
121
122     return t1;
123 }
124
125 char *strcpy(char *dest, const char *src)
126 {
127     char *ret = dest;
128
129     while (*src) {
130         *dest++ = *src++;
131     }
132     *dest = '\0';
133
134     return ret;
135 }
136
137 char *strncpy(char *dest, const char *src, size_t limit)
138 {
139     char *ret = dest;
140
141     while (*src != '\0' && limit > 0) {
142         *dest++ = *src++;
143         --limit;
144     }
145     if (limit > 0)
146         *dest = '\0';
147
148     return ret;
149 }
150
151 char *strdup(const char *s1)
152 {
153     char *ret;
154
155     ret = Malloc(strlen(s1) + 1);
156     strcpy(ret, s1);
157
158     return ret;
159 }
160
161 int atoi(const char *buf) 
162 {
163     int ret = 0;
164
165     while (*buf >= '0' && *buf <= '9') {
166        ret *= 10;
167        ret += *buf - '0';
168        buf++;
169     }
170
171     return ret;
172 }
173
174 char *strchr(const char *s, int c)
175 {
176     while (*s != '\0') {
177         if (*s == c)
178             return (char *) s;
179         ++s;
180     }
181     return 0;
182 }
183
184 char *strrchr(const char *s, int c)
185 {
186     size_t len = strlen(s);
187     const char *p = s + len;
188
189     while (p > s) {
190         --p;
191         if (*p == c)
192             return (char*) p;
193     }
194     return 0;
195 }
196
197 char *strpbrk(const char *s, const char *accept)
198 {
199     size_t setLen = strlen(accept);
200
201     while (*s != '\0') {
202         size_t i;
203         for (i = 0; i < setLen; ++i) {
204             if (*s == accept[i])
205                 return (char *) s;
206         }
207         ++s;
208     }
209
210     return 0;
211 }
212
213 struct String_Output_Sink {
214     struct Output_Sink o;
215     char *s;
216     size_t n, size;
217 };
218
219 static void String_Emit(struct Output_Sink *o_, int ch)
220 {
221     struct String_Output_Sink *o = (struct String_Output_Sink*) o_;
222
223     if (o->n < o->size)
224         *(o->s)++ = ch;
225     ++(o->n);
226 }
227
228 static void String_Finish(struct Output_Sink *o_)
229 {
230     struct String_Output_Sink *o = (struct String_Output_Sink*) o_;
231
232     if (o->n < o->size)
233         *(o->s) = '\0';
234     else
235         /*
236          * Output was truncated; write terminator at end of buffer
237          * (we will have advanced one character too far)
238          */
239         *(o->s - 1) = '\0';
240 }
241
242 int snprintf(char *s, size_t size, const char *fmt, ...)
243 {
244     struct String_Output_Sink sink;
245     int rc;
246     va_list args;
247
248     /* Prepare string output sink */
249     sink.o.Emit = &String_Emit;
250     sink.o.Finish = &String_Finish;
251     sink.s = s;
252     sink.n = 0;
253     sink.size = size;
254
255     /* Format the string */
256     va_start(args, fmt);
257     rc = Format_Output(&sink.o, fmt, args);
258     va_end(args);
259
260     return rc;
261 }