- add localsettings.texi which contains Stanford-local macros and variables
[pintos.git] / src / lib / string.c
blobd223c89f48493793c52dc45dbcf288328776fd6f
1 #include <string.h>
2 #include <debug.h>
4 /* Copies SIZE bytes from SRC to DST, which must not overlap.
5 Returns DST. */
6 void *
7 memcpy (void *dst_, const void *src_, size_t size)
9 unsigned char *dst = dst_;
10 const unsigned char *src = src_;
12 ASSERT (dst != NULL || size == 0);
13 ASSERT (src != NULL || size == 0);
15 while (size-- > 0)
16 *dst++ = *src++;
18 return dst_;
21 /* Copies SIZE bytes from SRC to DST, which are allowed to
22 overlap. Returns DST. */
23 void *
24 memmove (void *dst_, const void *src_, size_t size)
26 unsigned char *dst = dst_;
27 const unsigned char *src = src_;
29 ASSERT (dst != NULL || size == 0);
30 ASSERT (src != NULL || size == 0);
32 if (dst < src)
34 while (size-- > 0)
35 *dst++ = *src++;
37 else
39 dst += size;
40 src += size;
41 while (size-- > 0)
42 *--dst = *--src;
45 return dst;
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. */
52 int
53 memcmp (const void *a_, const void *b_, size_t size)
55 const unsigned char *a = a_;
56 const unsigned char *b = b_;
58 ASSERT (a != NULL || size == 0);
59 ASSERT (b != NULL || size == 0);
61 for (; size-- > 0; a++, b++)
62 if (*a != *b)
63 return *a > *b ? +1 : -1;
64 return 0;
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. */
72 int
73 strcmp (const char *a_, const char *b_)
75 const unsigned char *a = (const unsigned char *) a_;
76 const unsigned char *b = (const unsigned char *) b_;
78 ASSERT (a != NULL);
79 ASSERT (b != NULL);
81 while (*a != '\0' && *a == *b)
83 a++;
84 b++;
87 return *a < *b ? -1 : *a > *b;
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. */
93 void *
94 memchr (const void *block_, int ch_, size_t size)
96 const unsigned char *block = block_;
97 unsigned char ch = ch_;
99 ASSERT (block != NULL || size == 0);
101 for (; size-- > 0; block++)
102 if (*block == ch)
103 return (void *) block;
105 return NULL;
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. */
112 char *
113 strchr (const char *string, int c_)
115 char c = c_;
117 ASSERT (string != NULL);
119 for (;;)
120 if (*string == c)
121 return (char *) string;
122 else if (*string == '\0')
123 return NULL;
124 else
125 string++;
128 /* Returns the length of the initial substring of STRING that
129 consists of characters that are not in STOP. */
130 size_t
131 strcspn (const char *string, const char *stop)
133 size_t length;
135 for (length = 0; string[length] != '\0'; length++)
136 if (strchr (stop, string[length]) != NULL)
137 break;
138 return length;
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. */
144 char *
145 strpbrk (const char *string, const char *stop)
147 for (; *string != '\0'; string++)
148 if (strchr (stop, *string) != NULL)
149 return (char *) string;
150 return NULL;
153 /* Returns a pointer to the last occurrence of C in STRING.
154 Returns a null pointer if C does not occur in STRING. */
155 char *
156 strrchr (const char *string, int c_)
158 char c = c_;
159 const char *p = NULL;
161 for (; *string != '\0'; string++)
162 if (*string == c)
163 p = string;
164 return (char *) p;
167 /* Returns the length of the initial substring of STRING that
168 consists of characters in SKIP. */
169 size_t
170 strspn (const char *string, const char *skip)
172 size_t length;
174 for (length = 0; string[length] != '\0'; length++)
175 if (strchr (skip, string[length]) == NULL)
176 break;
177 return length;
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. */
183 char *
184 strstr (const char *haystack, const char *needle)
186 size_t haystack_len = strlen (haystack);
187 size_t needle_len = strlen (needle);
189 if (haystack_len >= needle_len)
191 size_t i;
193 for (i = 0; i <= haystack_len - needle_len; i++)
194 if (!memcmp (haystack + i, needle, needle_len))
195 return (char *) haystack + i;
198 return NULL;
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.
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.
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'.
219 Example usage:
221 char s[] = " String to tokenize. ";
222 char *token, *save_ptr;
224 for (token = strtok_r (s, " ", &save_ptr); token != NULL;
225 token = strtok_r (NULL, " ", &save_ptr))
226 printf ("'%s'\n", token);
228 outputs:
230 'String'
231 'to'
232 'tokenize.'
234 char *
235 strtok_r (char *s, const char *delimiters, char **save_ptr)
237 char *token;
239 ASSERT (delimiters != NULL);
240 ASSERT (save_ptr != NULL);
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);
248 /* Skip any DELIMITERS at our current position. */
249 while (strchr (delimiters, *s) != NULL)
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')
256 *save_ptr = s;
257 return NULL;
260 s++;
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')
269 *s = '\0';
270 *save_ptr = s + 1;
272 else
273 *save_ptr = s;
274 return token;
277 /* Sets the SIZE bytes in DST to VALUE. */
278 void *
279 memset (void *dst_, int value, size_t size)
281 unsigned char *dst = dst_;
283 ASSERT (dst != NULL || size == 0);
285 while (size-- > 0)
286 *dst++ = value;
288 return dst_;
291 /* Returns the length of STRING. */
292 size_t
293 strlen (const char *string)
295 const char *p;
297 ASSERT (string != NULL);
299 for (p = string; *p != '\0'; p++)
300 continue;
301 return p - string;
304 /* If STRING is less than MAXLEN characters in length, returns
305 its actual length. Otherwise, returns MAXLEN. */
306 size_t
307 strnlen (const char *string, size_t maxlen)
309 size_t length;
311 for (length = 0; string[length] != '\0' && length < maxlen; length++)
312 continue;
313 return length;
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.
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(). */
325 size_t
326 strlcpy (char *dst, const char *src, size_t size)
328 size_t src_len;
330 ASSERT (dst != NULL);
331 ASSERT (src != NULL);
333 src_len = strlen (src);
334 if (size > 0)
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';
342 return src_len;
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.
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(). */
355 size_t
356 strlcat (char *dst, const char *src, size_t size)
358 size_t src_len, dst_len;
360 ASSERT (dst != NULL);
361 ASSERT (src != NULL);
363 src_len = strlen (src);
364 dst_len = strlen (dst);
365 if (size > 0 && dst_len < size)
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';
373 return src_len + dst_len;