PKUOS - Pintos
Pintos source browser for PKU Operating System course
string.c
Go to the documentation of this file.
1#include <string.h>
2#include <debug.h>
3
4/** Copies SIZE bytes from SRC to DST, which must not overlap.
5 Returns DST. */
6void *
7memcpy (void *dst_, const void *src_, size_t size)
8{
9 unsigned char *dst = dst_;
10 const unsigned char *src = src_;
11
12 ASSERT (dst != NULL || size == 0);
13 ASSERT (src != NULL || size == 0);
14
15 while (size-- > 0)
16 *dst++ = *src++;
17
18 return dst_;
19}
20
21/** Copies SIZE bytes from SRC to DST, which are allowed to
22 overlap. Returns DST. */
23void *
24memmove (void *dst_, const void *src_, size_t size)
25{
26 unsigned char *dst = dst_;
27 const unsigned char *src = src_;
28
29 ASSERT (dst != NULL || size == 0);
30 ASSERT (src != NULL || size == 0);
31
32 if (dst < src)
33 {
34 while (size-- > 0)
35 *dst++ = *src++;
36 }
37 else
38 {
39 dst += size;
40 src += size;
41 while (size-- > 0)
42 *--dst = *--src;
43 }
44
45 return dst;
46}
47
48/** Find the first differing byte in the two blocks of SIZE bytes
49 at A and B. Returns a positive value if the byte in A is
50 greater, a negative value if the byte in B is greater, or zero
51 if blocks A and B are equal. */
52int
53memcmp (const void *a_, const void *b_, size_t size)
54{
55 const unsigned char *a = a_;
56 const unsigned char *b = b_;
57
58 ASSERT (a != NULL || size == 0);
59 ASSERT (b != NULL || size == 0);
60
61 for (; size-- > 0; a++, b++)
62 if (*a != *b)
63 return *a > *b ? +1 : -1;
64 return 0;
65}
66
67/** Finds the first differing characters in strings A and B.
68 Returns a positive value if the character in A (as an unsigned
69 char) is greater, a negative value if the character in B (as
70 an unsigned char) is greater, or zero if strings A and B are
71 equal. */
72int
73strcmp (const char *a_, const char *b_)
74{
75 const unsigned char *a = (const unsigned char *) a_;
76 const unsigned char *b = (const unsigned char *) b_;
77
78 ASSERT (a != NULL);
79 ASSERT (b != NULL);
80
81 while (*a != '\0' && *a == *b)
82 {
83 a++;
84 b++;
85 }
86
87 return *a < *b ? -1 : *a > *b;
88}
89
90/** Returns a pointer to the first occurrence of CH in the first
91 SIZE bytes starting at BLOCK. Returns a null pointer if CH
92 does not occur in BLOCK. */
93void *
94memchr (const void *block_, int ch_, size_t size)
95{
96 const unsigned char *block = block_;
97 unsigned char ch = ch_;
98
99 ASSERT (block != NULL || size == 0);
100
101 for (; size-- > 0; block++)
102 if (*block == ch)
103 return (void *) block;
104
105 return NULL;
106}
107
108/** Finds and returns the first occurrence of C in STRING, or a
109 null pointer if C does not appear in STRING. If C == '\0'
110 then returns a pointer to the null terminator at the end of
111 STRING. */
112char *
113strchr (const char *string, int c_)
114{
115 char c = c_;
116
117 ASSERT (string != NULL);
118
119 for (;;)
120 if (*string == c)
121 return (char *) string;
122 else if (*string == '\0')
123 return NULL;
124 else
125 string++;
126}
127
128/** Returns the length of the initial substring of STRING that
129 consists of characters that are not in STOP. */
130size_t
131strcspn (const char *string, const char *stop)
132{
133 size_t length;
134
135 for (length = 0; string[length] != '\0'; length++)
136 if (strchr (stop, string[length]) != NULL)
137 break;
138 return length;
139}
140
141/** Returns a pointer to the first character in STRING that is
142 also in STOP. If no character in STRING is in STOP, returns a
143 null pointer. */
144char *
145strpbrk (const char *string, const char *stop)
146{
147 for (; *string != '\0'; string++)
148 if (strchr (stop, *string) != NULL)
149 return (char *) string;
150 return NULL;
151}
152
153/** Returns a pointer to the last occurrence of C in STRING.
154 Returns a null pointer if C does not occur in STRING. */
155char *
156strrchr (const char *string, int c_)
157{
158 char c = c_;
159 const char *p = NULL;
160
161 for (; *string != '\0'; string++)
162 if (*string == c)
163 p = string;
164 return (char *) p;
165}
166
167/** Returns the length of the initial substring of STRING that
168 consists of characters in SKIP. */
169size_t
170strspn (const char *string, const char *skip)
171{
172 size_t length;
173
174 for (length = 0; string[length] != '\0'; length++)
175 if (strchr (skip, string[length]) == NULL)
176 break;
177 return length;
178}
179
180/** Returns a pointer to the first occurrence of NEEDLE within
181 HAYSTACK. Returns a null pointer if NEEDLE does not exist
182 within HAYSTACK. */
183char *
184strstr (const char *haystack, const char *needle)
185{
186 size_t haystack_len = strlen (haystack);
187 size_t needle_len = strlen (needle);
188
189 if (haystack_len >= needle_len)
190 {
191 size_t i;
192
193 for (i = 0; i <= haystack_len - needle_len; i++)
194 if (!memcmp (haystack + i, needle, needle_len))
195 return (char *) haystack + i;
196 }
197
198 return NULL;
199}
200
201/** Breaks a string into tokens separated by DELIMITERS. The
202 first time this function is called, S should be the string to
203 tokenize, and in subsequent calls it must be a null pointer.
204 SAVE_PTR is the address of a `char *' variable used to keep
205 track of the tokenizer's position. The return value each time
206 is the next token in the string, or a null pointer if no
207 tokens remain.
208
209 This function treats multiple adjacent delimiters as a single
210 delimiter. The returned tokens will never be length 0.
211 DELIMITERS may change from one call to the next within a
212 single string.
213
214 strtok_r() modifies the string S, changing delimiters to null
215 bytes. Thus, S must be a modifiable string. String literals,
216 in particular, are *not* modifiable in C, even though for
217 backward compatibility they are not `const'.
218
219 Example usage:
220
221 char s[] = " String to tokenize. ";
222 char *token, *save_ptr;
223
224 for (token = strtok_r (s, " ", &save_ptr); token != NULL;
225 token = strtok_r (NULL, " ", &save_ptr))
226 printf ("'%s'\n", token);
227
228 outputs:
229
230 'String'
231 'to'
232 'tokenize.'
233*/
234char *
235strtok_r (char *s, const char *delimiters, char **save_ptr)
236{
237 char *token;
238
239 ASSERT (delimiters != NULL);
240 ASSERT (save_ptr != NULL);
241
242 /* If S is nonnull, start from it.
243 If S is null, start from saved position. */
244 if (s == NULL)
245 s = *save_ptr;
246 ASSERT (s != NULL);
247
248 /* Skip any DELIMITERS at our current position. */
249 while (strchr (delimiters, *s) != NULL)
250 {
251 /* strchr() will always return nonnull if we're searching
252 for a null byte, because every string contains a null
253 byte (at the end). */
254 if (*s == '\0')
255 {
256 *save_ptr = s;
257 return NULL;
258 }
259
260 s++;
261 }
262
263 /* Skip any non-DELIMITERS up to the end of the string. */
264 token = s;
265 while (strchr (delimiters, *s) == NULL)
266 s++;
267 if (*s != '\0')
268 {
269 *s = '\0';
270 *save_ptr = s + 1;
271 }
272 else
273 *save_ptr = s;
274 return token;
275}
276
277/** Sets the SIZE bytes in DST to VALUE. */
278void *
279memset (void *dst_, int value, size_t size)
280{
281 unsigned char *dst = dst_;
282
283 ASSERT (dst != NULL || size == 0);
284
285 while (size-- > 0)
286 *dst++ = value;
287
288 return dst_;
289}
290
291/** Returns the length of STRING. */
292size_t
293strlen (const char *string)
294{
295 const char *p;
296
297 ASSERT (string != NULL);
298
299 for (p = string; *p != '\0'; p++)
300 continue;
301 return p - string;
302}
303
304/** If STRING is less than MAXLEN characters in length, returns
305 its actual length. Otherwise, returns MAXLEN. */
306size_t
307strnlen (const char *string, size_t maxlen)
308{
309 size_t length;
310
311 for (length = 0; string[length] != '\0' && length < maxlen; length++)
312 continue;
313 return length;
314}
315
316/** Copies string SRC to DST. If SRC is longer than SIZE - 1
317 characters, only SIZE - 1 characters are copied. A null
318 terminator is always written to DST, unless SIZE is 0.
319 Returns the length of SRC, not including the null terminator.
320
321 strlcpy() is not in the standard C library, but it is an
322 increasingly popular extension. See
323 http://www.courtesan.com/todd/papers/strlcpy.html for
324 information on strlcpy(). */
325size_t
326strlcpy (char *dst, const char *src, size_t size)
327{
328 size_t src_len;
329
330 ASSERT (dst != NULL);
331 ASSERT (src != NULL);
332
333 src_len = strlen (src);
334 if (size > 0)
335 {
336 size_t dst_len = size - 1;
337 if (src_len < dst_len)
338 dst_len = src_len;
339 memcpy (dst, src, dst_len);
340 dst[dst_len] = '\0';
341 }
342 return src_len;
343}
344
345/** Concatenates string SRC to DST. The concatenated string is
346 limited to SIZE - 1 characters. A null terminator is always
347 written to DST, unless SIZE is 0. Returns the length that the
348 concatenated string would have assuming that there was
349 sufficient space, not including a null terminator.
350
351 strlcat() is not in the standard C library, but it is an
352 increasingly popular extension. See
353 http://www.courtesan.com/todd/papers/strlcpy.html for
354 information on strlcpy(). */
355size_t
356strlcat (char *dst, const char *src, size_t size)
357{
358 size_t src_len, dst_len;
359
360 ASSERT (dst != NULL);
361 ASSERT (src != NULL);
362
363 src_len = strlen (src);
364 dst_len = strlen (dst);
365 if (size > 0 && dst_len < size)
366 {
367 size_t copy_cnt = size - dst_len - 1;
368 if (src_len < copy_cnt)
369 copy_cnt = src_len;
370 memcpy (dst + dst_len, src, copy_cnt);
371 dst[dst_len + copy_cnt] = '\0';
372 }
373 return src_len + dst_len;
374}
375
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
static uint8_t s[256]
RC4-based pseudo-random number generator (PRNG).
Definition: random.c:17
#define NULL
Definition: stddef.h:4
size_t strnlen(const char *string, size_t maxlen)
If STRING is less than MAXLEN characters in length, returns its actual length.
Definition: string.c:307
size_t strlcat(char *dst, const char *src, size_t size)
Concatenates string SRC to DST.
Definition: string.c:356
char * strchr(const char *string, int c_)
Finds and returns the first occurrence of C in STRING, or a null pointer if C does not appear in STRI...
Definition: string.c:113
int memcmp(const void *a_, const void *b_, size_t size)
Find the first differing byte in the two blocks of SIZE bytes at A and B.
Definition: string.c:53
size_t strspn(const char *string, const char *skip)
Returns the length of the initial substring of STRING that consists of characters in SKIP.
Definition: string.c:170
size_t strlen(const char *string)
Returns the length of STRING.
Definition: string.c:293
void * memset(void *dst_, int value, size_t size)
Sets the SIZE bytes in DST to VALUE.
Definition: string.c:279
size_t strlcpy(char *dst, const char *src, size_t size)
Copies string SRC to DST.
Definition: string.c:326
size_t strcspn(const char *string, const char *stop)
Returns the length of the initial substring of STRING that consists of characters that are not in STO...
Definition: string.c:131
void * memmove(void *dst_, const void *src_, size_t size)
Copies SIZE bytes from SRC to DST, which are allowed to overlap.
Definition: string.c:24
void * memcpy(void *dst_, const void *src_, size_t size)
Copies SIZE bytes from SRC to DST, which must not overlap.
Definition: string.c:7
char * strtok_r(char *s, const char *delimiters, char **save_ptr)
Breaks a string into tokens separated by DELIMITERS.
Definition: string.c:235
char * strrchr(const char *string, int c_)
Returns a pointer to the last occurrence of C in STRING.
Definition: string.c:156
char * strpbrk(const char *string, const char *stop)
Returns a pointer to the first character in STRING that is also in STOP.
Definition: string.c:145
char * strstr(const char *haystack, const char *needle)
Returns a pointer to the first occurrence of NEEDLE within HAYSTACK.
Definition: string.c:184
void * memchr(const void *block_, int ch_, size_t size)
Returns a pointer to the first occurrence of CH in the first SIZE bytes starting at BLOCK.
Definition: string.c:94
int strcmp(const char *a_, const char *b_)
Finds the first differing characters in strings A and B.
Definition: string.c:73
A block device.
Definition: block.c:10
A linked list element.
Definition: list.c:23