1 | /*␊ |
2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
7 | * Reserved. This file contains Original Code and/or Modifications of␊ |
8 | * Original Code as defined in and that are subject to the Apple Public␊ |
9 | * Source License Version 2.0 (the "License"). You may not use this file␊ |
10 | * except in compliance with the License. Please obtain a copy of the␊ |
11 | * License at http://www.apple.com/publicsource and read it before using␊ |
12 | * this file.␊ |
13 | * ␊ |
14 | * The Original Code and all software distributed under the License are␊ |
15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the␊ |
19 | * License for the specific language governing rights and limitations␊ |
20 | * under the License.␊ |
21 | * ␊ |
22 | * @APPLE_LICENSE_HEADER_END@␊ |
23 | */␊ |
24 | /* string operations */␊ |
25 | ␊ |
26 | #include "libsa.h"␊ |
27 | ␊ |
28 | static int _mach_strlen(const char *str);␊ |
29 | static char *STRDUP(const char *string);␊ |
30 | ␊ |
31 | /*␊ |
32 | * Abstract:␊ |
33 | * strcmp (s1, s2) compares the strings "s1" and "s2".␊ |
34 | * It returns 0 if the strings are identical. It returns␊ |
35 | * > 0 if the first character that differs in the two strings␊ |
36 | * is larger in s1 than in s2 or if s1 is longer than s2 and␊ |
37 | * the contents are identical up to the length of s2.␊ |
38 | * It returns < 0 if the first differing character is smaller␊ |
39 | * in s1 than in s2 or if s1 is shorter than s2 and the␊ |
40 | * contents are identical upto the length of s1.␊ |
41 | * Deprecation Warning:␊ |
42 | *␉strcmp() is being deprecated. Please use strncmp() instead.␊ |
43 | */␊ |
44 | ␊ |
45 | int␊ |
46 | strcmp(␊ |
47 | ␉ const char *s1,␊ |
48 | ␉ const char *s2)␊ |
49 | {␊ |
50 | ␉unsigned int a, b;␊ |
51 | ␉␊ |
52 | ␉do {␊ |
53 | ␉␉a = *s1++;␊ |
54 | ␉␉b = *s2++;␊ |
55 | ␉␉if (a != b)␊ |
56 | ␉␉␉return a-b; /* includes case when␊ |
57 | ␉␉␉␉␉␉␉ 'a' is zero and 'b' is not zero␊ |
58 | ␉␉␉␉␉␉␉ or vice versa */␊ |
59 | ␉} while (a != '\0');␊ |
60 | ␉␊ |
61 | ␉return 0; /* both are zero */␊ |
62 | }␊ |
63 | ␊ |
64 | /*␊ |
65 | * Abstract:␊ |
66 | * strncmp (s1, s2, n) compares the strings "s1" and "s2"␊ |
67 | * in exactly the same way as strcmp does. Except the␊ |
68 | * comparison runs for at most "n" characters.␊ |
69 | */␊ |
70 | ␊ |
71 | int␊ |
72 | strncmp(␊ |
73 | const char *s1,␊ |
74 | const char *s2,␊ |
75 | size_t n)␊ |
76 | {␊ |
77 | ␉unsigned int a, b;␊ |
78 | ␉␊ |
79 | ␉while (n != 0) {␊ |
80 | ␉␉a = *s1++;␊ |
81 | ␉␉b = *s2++;␊ |
82 | ␉␉if (a != b)␊ |
83 | ␉␉␉return a-b; /* includes case when␊ |
84 | ␉␉␉␉␉␉␉ 'a' is zero and 'b' is not zero␊ |
85 | ␉␉␉␉␉␉␉ or vice versa */␊ |
86 | ␉␉if (a == '\0')␊ |
87 | ␉␉␉return 0; /* both are zero */␊ |
88 | ␉␉n--;␊ |
89 | ␉}␊ |
90 | ␉␊ |
91 | ␉return 0;␊ |
92 | }␊ |
93 | ␊ |
94 | /*␊ |
95 | * Abstract:␊ |
96 | * strcpy copies the contents of the string "from" including␊ |
97 | * the null terminator to the string "to". A pointer to "to"␊ |
98 | * is returned.␊ |
99 | * Deprecation Warning: ␊ |
100 | *␉strcpy() is being deprecated. Please use strlcpy() instead.␊ |
101 | */␊ |
102 | char *␊ |
103 | strcpy(␊ |
104 | ␉ char *to,␊ |
105 | ␉ const char *from)␊ |
106 | {␊ |
107 | ␉char *ret = to;␊ |
108 | ␉␊ |
109 | ␉while ((*to++ = *from++) != '\0')␊ |
110 | ␉␉continue;␊ |
111 | ␉␊ |
112 | ␉return ret;␊ |
113 | }␊ |
114 | ␊ |
115 | /*␊ |
116 | * Abstract:␊ |
117 | * strncpy copies "count" characters from the "from" string to␊ |
118 | * the "to" string. If "from" contains less than "count" characters␊ |
119 | * "to" will be padded with null characters until exactly "count"␊ |
120 | * characters have been written. The return value is a pointer␊ |
121 | * to the "to" string.␊ |
122 | */␊ |
123 | ␊ |
124 | char *␊ |
125 | strncpy(␊ |
126 | ␉␉char *s1, ␊ |
127 | ␉␉const char *s2,␊ |
128 | ␉␉size_t n)␊ |
129 | {␊ |
130 | ␉char *os1 = s1;␊ |
131 | ␉unsigned long i;␊ |
132 | ␉␊ |
133 | ␉for (i = 0; i < n;)␊ |
134 | ␉␉if ((*s1++ = *s2++) == '\0')␊ |
135 | ␉␉␉for (i++; i < n; i++)␊ |
136 | ␉␉␉␉*s1++ = '\0';␊ |
137 | ␉␉else␊ |
138 | ␉␉␉i++;␊ |
139 | ␉return (os1);␊ |
140 | }␊ |
141 | ␊ |
142 | /*␊ |
143 | * Copy src to string dst of size siz. At most siz-1 characters␊ |
144 | * will be copied. Always NUL terminates (unless siz == 0).␊ |
145 | * Returns strlen(src); if retval >= siz, truncation occurred.␊ |
146 | */␊ |
147 | size_t␊ |
148 | strlcpy(char *dst, const char *src, size_t siz)␊ |
149 | {␊ |
150 | ␉char *d = dst;␊ |
151 | ␉const char *s = src;␊ |
152 | ␉size_t n = siz;␊ |
153 | ␉␊ |
154 | ␉/* Copy as many bytes as will fit */␊ |
155 | ␉if (n != 0 && --n != 0) {␊ |
156 | ␉␉do {␊ |
157 | ␉␉␉if ((*d++ = *s++) == 0)␊ |
158 | ␉␉␉␉break;␊ |
159 | ␉␉} while (--n != 0);␊ |
160 | ␉}␊ |
161 | ␉␊ |
162 | ␉/* Not enough room in dst, add NUL and traverse rest of src */␊ |
163 | ␉if (n == 0) {␊ |
164 | ␉␉if (siz != 0)␊ |
165 | ␉␉␉*d = '\0';␉␉/* NUL-terminate dst */␊ |
166 | ␉␉while (*s++)␊ |
167 | ␉␉␉;␊ |
168 | ␉}␊ |
169 | ␉␊ |
170 | ␉return(s - src - 1);␉/* count does not include NUL */␊ |
171 | }␊ |
172 | ␊ |
173 | /*␊ |
174 | * History:␊ |
175 | * 2002-01-24 ␉gvdl␉Initial implementation of strstr␊ |
176 | */␊ |
177 | ␊ |
178 | const char *␊ |
179 | strstr(const char *in, const char *str)␊ |
180 | {␊ |
181 | char c;␊ |
182 | size_t len;␊ |
183 | ␉␊ |
184 | c = *str++;␊ |
185 | if (!c)␊ |
186 | return (const char *) in;␉// Trivial empty string case␊ |
187 | ␉␊ |
188 | len = strlen(str);␊ |
189 | do {␊ |
190 | char sc;␊ |
191 | ␉␉␊ |
192 | do {␊ |
193 | sc = *in++;␊ |
194 | if (!sc)␊ |
195 | return (char *) 0;␊ |
196 | } while (sc != c);␊ |
197 | } while (strncmp(in, str, len) != 0);␊ |
198 | ␉␊ |
199 | return (const char *) (in - 1);␊ |
200 | }␊ |
201 | ␊ |
202 | void *␊ |
203 | memmove(void *dst, const void *src, size_t ulen)␊ |
204 | {␊ |
205 | bcopy(src, dst, ulen); ␊ |
206 | return dst;␊ |
207 | }␊ |
208 | ␊ |
209 | int␊ |
210 | ptol(const char *str)␊ |
211 | {␊ |
212 | ␉register int c = *str;␊ |
213 | ␉␊ |
214 | ␉if (c <= '7' && c >= '0')␊ |
215 | ␉␉c -= '0';␊ |
216 | ␉else if (c <= 'h' && c >= 'a')␊ |
217 | ␉␉c -= 'a';␊ |
218 | ␉else c = 0;␊ |
219 | ␉return c;␊ |
220 | }␊ |
221 | ␊ |
222 | /*␊ |
223 | * atoi:␊ |
224 | *␊ |
225 | * This function converts an ascii string into an integer.␊ |
226 | *␊ |
227 | * input : string␊ |
228 | * output : a number␊ |
229 | */␊ |
230 | ␊ |
231 | int␊ |
232 | atoi(const char *cp)␊ |
233 | {␊ |
234 | ␉int number;␊ |
235 | ␉␊ |
236 | ␉for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++)␊ |
237 | ␉␉number = (number * 10) + (*cp - '0');␊ |
238 | ␉␊ |
239 | ␉return( number );␊ |
240 | }␊ |
241 | ␊ |
242 | /*␊ |
243 | * convert an integer to an ASCII string.␊ |
244 | * inputs:␊ |
245 | *␉num␉integer to be converted␊ |
246 | *␉str␉string pointer.␊ |
247 | *␊ |
248 | * outputs:␊ |
249 | *␉pointer to string start.␊ |
250 | */␊ |
251 | ␊ |
252 | char *␊ |
253 | itoa(␊ |
254 | ␉ int␉num,␊ |
255 | ␉ char␉*str)␊ |
256 | {␊ |
257 | ␉char digits[11];␊ |
258 | ␉char *dp;␊ |
259 | ␉char *cp = str;␊ |
260 | ␉␊ |
261 | ␉if (num == 0) {␊ |
262 | ␉␉*cp++ = '0';␊ |
263 | ␉}␊ |
264 | ␉else {␊ |
265 | ␉␉dp = digits;␊ |
266 | ␉␉while (num) {␊ |
267 | ␉␉␉*dp++ = '0' + num % 10;␊ |
268 | ␉␉␉num /= 10;␊ |
269 | ␉␉}␊ |
270 | ␉␉while (dp != digits) {␊ |
271 | ␉␉␉*cp++ = *--dp;␊ |
272 | ␉␉}␊ |
273 | ␉}␊ |
274 | ␉*cp++ = '\0';␊ |
275 | ␉␊ |
276 | ␉return str;␊ |
277 | }␊ |
278 | /*␊ |
279 | * Appends src to string dst of size siz (unlike strncat, siz is the␊ |
280 | * full size of dst, not space left). At most siz-1 characters␊ |
281 | * will be copied. Always NUL terminates (unless siz <= strlen(dst)).␊ |
282 | * Returns strlen(src) + MIN(siz, strlen(initial dst)).␊ |
283 | * If retval >= siz, truncation occurred.␊ |
284 | */␊ |
285 | size_t␊ |
286 | strlcat(char *dst, const char *src, size_t siz)␊ |
287 | {␊ |
288 | ␉char *d = dst;␊ |
289 | ␉const char *s = src;␊ |
290 | ␉size_t n = siz;␊ |
291 | ␉size_t dlen;␊ |
292 | ␉␊ |
293 | ␉/* Find the end of dst and adjust bytes left but don't go past end */␊ |
294 | ␉while (n-- != 0 && *d != '\0')␊ |
295 | ␉␉d++;␊ |
296 | ␉dlen = d - dst;␊ |
297 | ␉n = siz - dlen;␊ |
298 | ␉␊ |
299 | ␉if (n == 0)␊ |
300 | ␉␉return(dlen + strlen(s));␊ |
301 | ␉while (*s != '\0') {␊ |
302 | ␉␉if (n != 1) {␊ |
303 | ␉␉␉*d++ = *s;␊ |
304 | ␉␉␉n--;␊ |
305 | ␉␉}␊ |
306 | ␉␉s++;␊ |
307 | ␉}␊ |
308 | ␉*d = '\0';␊ |
309 | ␉␊ |
310 | ␉return(dlen + (s - src)); /* count does not include NUL */␊ |
311 | }␊ |
312 | ␊ |
313 | /*␊ |
314 | *␊ |
315 | */␊ |
316 | ␊ |
317 | char *␊ |
318 | strncat(char *s1, const char *s2, unsigned long n)␊ |
319 | {␊ |
320 | ␉char *os1;␊ |
321 | ␉int i = n;␊ |
322 | ␉␊ |
323 | ␉os1 = s1;␊ |
324 | ␉while (*s1++)␊ |
325 | ␉␉;␊ |
326 | ␉--s1;␊ |
327 | ␉while ((*s1++ = *s2++))␊ |
328 | ␉␉if (--i < 0) {␊ |
329 | ␉␉␉*--s1 = '\0';␊ |
330 | ␉␉␉break;␊ |
331 | ␉␉}␊ |
332 | ␉return(os1);␊ |
333 | }␊ |
334 | ␊ |
335 | static int␊ |
336 | _mach_strlen(const char *str)␊ |
337 | {␊ |
338 | ␉const char *p;␊ |
339 | ␉for (p = str; p; p++) {␊ |
340 | ␉␉if (*p == '\0') {␊ |
341 | ␉␉␉return (p - str);␊ |
342 | ␉␉}␊ |
343 | ␉}␊ |
344 | ␉/* NOTREACHED */␊ |
345 | ␉return 0;␊ |
346 | }␊ |
347 | ␊ |
348 | size_t strlen(const char * str)␊ |
349 | {␉␊ |
350 | ␉return (size_t)_mach_strlen(str);␊ |
351 | }␊ |
352 | ␊ |
353 | /*␊ |
354 | * Does the same thing as strlen, except only looks up␊ |
355 | * to max chars inside the buffer. ␊ |
356 | * Taken from archive/kern-stuff/sbf_machine.c in ␊ |
357 | * seatbelt. ␊ |
358 | * inputs:␊ |
359 | * ␉s␉string whose length is to be measured␊ |
360 | *␉max␉maximum length of string to search for null␊ |
361 | * outputs:␊ |
362 | *␉length of s or max; whichever is smaller␊ |
363 | */␊ |
364 | size_t ␊ |
365 | strnlen(const char *s, size_t max) {␊ |
366 | ␉const char *es = s + max, *p = s;␊ |
367 | ␉while(*p && p != es) ␊ |
368 | ␉␉p++;␊ |
369 | ␉␊ |
370 | ␉return p - s;␊ |
371 | }␊ |
372 | ␊ |
373 | /* ␊ |
374 | * Deprecation Warning:␊ |
375 | *␉strcat() is being deprecated. Please use strlcat() instead.␊ |
376 | */␊ |
377 | char *␊ |
378 | strcat(␊ |
379 | ␉ char *dest,␊ |
380 | ␉ const char *src)␊ |
381 | {␊ |
382 | ␉char *old = dest;␊ |
383 | ␉␊ |
384 | ␉while (*dest)␊ |
385 | ␉␉++dest;␊ |
386 | ␉while ((*dest++ = *src++))␊ |
387 | ␉␉;␊ |
388 | ␉return (old);␊ |
389 | }␊ |
390 | ␊ |
391 | /*␊ |
392 | * STRDUP␊ |
393 | *␊ |
394 | * Description: The STRDUP function allocates sufficient memory for a copy␊ |
395 | * of the string "string", does the copy, and returns a pointer␊ |
396 | * it. The pointer may subsequently be used as an argument to␊ |
397 | * the macro FREE().␊ |
398 | *␊ |
399 | * Parameters: string␉␉String to be duplicated␊ |
400 | *␊ |
401 | * Returns: char * A pointer to the newly allocated string with␊ |
402 | * duplicated contents in it.␊ |
403 | *␊ |
404 | * NULL␉␉If MALLOC() fails.␊ |
405 | * ␊ |
406 | */␊ |
407 | ␊ |
408 | static char *␊ |
409 | STRDUP(const char *string)␊ |
410 | {␊ |
411 | ␉size_t len;␊ |
412 | ␉char *copy; ␊ |
413 | ␉␊ |
414 | ␉len = strlen(string) + 1;␊ |
415 | ␉␊ |
416 | copy = calloc(len, sizeof(char));␊ |
417 | ␉␊ |
418 | ␉if (copy == NULL)␊ |
419 | ␉␉return (NULL);␊ |
420 | ␉bcopy(string, copy, len);␊ |
421 | ␉return (copy); ␊ |
422 | }␊ |
423 | ␊ |
424 | char *strdup(const char *string)␊ |
425 | {␊ |
426 | ␉if (string) {␊ |
427 | ␉␉return STRDUP(string);␊ |
428 | ␉}␊ |
429 | ␉return (NULL);␊ |
430 | }␊ |
431 | ␊ |
432 | #if STRNCASECMP␊ |
433 | ␊ |
434 | //␊ |
435 | // Lame implementation just for use by strcasecmp/strncasecmp␊ |
436 | //␊ |
437 | static int␊ |
438 | tolower(unsigned char ch)␊ |
439 | {␊ |
440 | if (ch >= 'A' && ch <= 'Z')␊ |
441 | ␉␉ch = 'a' + (ch - 'A');␊ |
442 | ␉␊ |
443 | return ch;␊ |
444 | }␊ |
445 | ␊ |
446 | int␊ |
447 | strcasecmp(const char *s1, const char *s2)␊ |
448 | {␊ |
449 | const unsigned char *us1 = (const u_char *)s1,␊ |
450 | ␉*us2 = (const u_char *)s2;␊ |
451 | ␉␊ |
452 | while (tolower(*us1) == tolower(*us2++))␊ |
453 | ␉␉if (*us1++ == '\0')␊ |
454 | ␉␉␉return (0);␊ |
455 | return (tolower(*us1) - tolower(*--us2));␊ |
456 | }␊ |
457 | ␊ |
458 | int␊ |
459 | strncasecmp(const char *s1, const char *s2, size_t n)␊ |
460 | {␊ |
461 | if (n != 0) {␊ |
462 | ␉␉const unsigned char *us1 = (const u_char *)s1,␊ |
463 | ␉␉*us2 = (const u_char *)s2;␊ |
464 | ␉␉␊ |
465 | ␉␉do {␊ |
466 | ␉␉␉if (tolower(*us1) != tolower(*us2++))␊ |
467 | ␉␉␉␉return (tolower(*us1) - tolower(*--us2));␊ |
468 | ␉␉␉if (*us1++ == '\0')␊ |
469 | ␉␉␉␉break;␊ |
470 | ␉␉} while (--n != 0);␊ |
471 | }␊ |
472 | return (0);␊ |
473 | }␊ |
474 | #endif␊ |
475 | /*␊ |
476 | *␊ |
477 | */␊ |
478 | ␊ |
479 | char *strchr(const char *str, int ch)␊ |
480 | {␊ |
481 | do {␊ |
482 | ␉␉if (*str == ch)␊ |
483 | ␉␉␉return(__CAST_AWAY_QUALIFIER(str, const, char *));␊ |
484 | } while (*str++);␊ |
485 | return ((char *) 0);␊ |
486 | } ␊ |
487 | ␊ |
488 | char* strbreak(const char *str, char **next, long *len)␊ |
489 | {␊ |
490 | char *start = (char*)str, *end;␊ |
491 | bool quoted = false;␊ |
492 | ␊ |
493 | if ( !start || !len )␊ |
494 | return 0;␊ |
495 | ␊ |
496 | *len = 0;␊ |
497 | ␊ |
498 | while ( isspace(*start) )␊ |
499 | start++;␊ |
500 | ␊ |
501 | if (*start == '"')␊ |
502 | {␊ |
503 | start++;␊ |
504 | ␊ |
505 | end = strchr(start, '"');␊ |
506 | if(end)␊ |
507 | quoted = true;␊ |
508 | else␊ |
509 | end = strchr(start, '\0');␊ |
510 | }␊ |
511 | else␊ |
512 | {␊ |
513 | for ( end = start; *end && !isspace(*end); end++ )␊ |
514 | {}␊ |
515 | }␊ |
516 | ␊ |
517 | *len = end - start;␊ |
518 | ␊ |
519 | if(next)␊ |
520 | *next = quoted ? end+1 : end;␊ |
521 | ␊ |
522 | return start;␊ |
523 | }␊ |
524 | ␊ |
525 | unsigned long␊ |
526 | local_adler32( unsigned char * buffer, long length )␊ |
527 | {␊ |
528 | long cnt;␊ |
529 | unsigned long result, lowHalf, highHalf;␊ |
530 | ␊ |
531 | lowHalf = 1;␊ |
532 | highHalf = 0;␊ |
533 | ␉␊ |
534 | ␉for ( cnt = 0; cnt < length; cnt++ )␊ |
535 | {␊ |
536 | if ((cnt % 5000) == 0)␊ |
537 | {␊ |
538 | lowHalf %= 65521L;␊ |
539 | highHalf %= 65521L;␊ |
540 | }␊ |
541 | ␉␉␊ |
542 | lowHalf += buffer[cnt];␊ |
543 | highHalf += lowHalf;␊ |
544 | }␊ |
545 | ␉␊ |
546 | ␉lowHalf %= 65521L;␊ |
547 | ␉highHalf %= 65521L;␊ |
548 | ␉␊ |
549 | ␉result = (highHalf << 16) | lowHalf;␊ |
550 | ␉␊ |
551 | ␉return result;␊ |
552 | }␊ |
553 | ␊ |
554 | /*-␊ |
555 | * For memcmp, bsearch, memchr , memcpy, memmove, bcopy.␊ |
556 | * Copyright (c) 1990, 1993␊ |
557 | *␉The Regents of the University of California. All rights reserved.␊ |
558 | *␊ |
559 | * This code is derived from software contributed to Berkeley by␊ |
560 | * Chris Torek.␊ |
561 | *␊ |
562 | * Redistribution and use in source and binary forms, with or without␊ |
563 | * modification, are permitted provided that the following conditions␊ |
564 | * are met:␊ |
565 | * 1. Redistributions of source code must retain the above copyright␊ |
566 | * notice, this list of conditions and the following disclaimer.␊ |
567 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
568 | * notice, this list of conditions and the following disclaimer in the␊ |
569 | * documentation and/or other materials provided with the distribution.␊ |
570 | * 4. Neither the name of the University nor the names of its contributors␊ |
571 | * may be used to endorse or promote products derived from this software␊ |
572 | * without specific prior written permission.␊ |
573 | *␊ |
574 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND␊ |
575 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
576 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
577 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE␊ |
578 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
579 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
580 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
581 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
582 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
583 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
584 | * SUCH DAMAGE.␊ |
585 | */␊ |
586 | ␊ |
587 | /*␊ |
588 | * Compare memory regions.␊ |
589 | */␊ |
590 | int␊ |
591 | memcmp(const void *s1, const void *s2, size_t n)␊ |
592 | {␊ |
593 | ␉if (n != 0) {␊ |
594 | ␉␉const unsigned char *p1 = s1, *p2 = s2;␊ |
595 | ␉␉␊ |
596 | ␉␉do {␊ |
597 | ␉␉␉if (*p1++ != *p2++)␊ |
598 | ␉␉␉␉return (*--p1 - *--p2);␊ |
599 | ␉␉} while (--n != 0);␊ |
600 | ␉}␊ |
601 | ␉return (0);␊ |
602 | }␊ |
603 | ␊ |
604 | /*␊ |
605 | * Perform a binary search.␊ |
606 | *␊ |
607 | * The code below is a bit sneaky. After a comparison fails, we␊ |
608 | * divide the work in half by moving either left or right. If lim␊ |
609 | * is odd, moving left simply involves halving lim: e.g., when lim␊ |
610 | * is 5 we look at item 2, so we change lim to 2 so that we will␊ |
611 | * look at items 0 & 1. If lim is even, the same applies. If lim␊ |
612 | * is odd, moving right again involes halving lim, this time moving␊ |
613 | * the base up one item past p: e.g., when lim is 5 we change base␊ |
614 | * to item 3 and make lim 2 so that we will look at items 3 and 4.␊ |
615 | * If lim is even, however, we have to shrink it by one before␊ |
616 | * halving: e.g., when lim is 4, we still looked at item 2, so we␊ |
617 | * have to make lim 3, then halve, obtaining 1, so that we will only␊ |
618 | * look at item 3.␊ |
619 | */␊ |
620 | void *␊ |
621 | bsearch(key, base0, nmemb, size, compar)␊ |
622 | register const void *key;␊ |
623 | const void *base0;␊ |
624 | size_t nmemb;␊ |
625 | register size_t size;␊ |
626 | register int (*compar)(const void *, const void *);␊ |
627 | {␊ |
628 | ␉register const char *base = base0;␊ |
629 | ␉register size_t lim;␊ |
630 | ␉register int cmp;␊ |
631 | ␉register const void *p;␊ |
632 | ␊ |
633 | ␉for (lim = nmemb; lim != 0; lim >>= 1) {␊ |
634 | ␉␉p = base + (lim >> 1) * size;␊ |
635 | ␉␉cmp = (*compar)(key, p);␊ |
636 | ␉␉if (cmp == 0)␊ |
637 | ␉␉␉return ((void *)(uintptr_t)p);␊ |
638 | ␉␉if (cmp > 0) {␉/* key > p: move right */␊ |
639 | ␉␉␉base = (const char *)p + size;␊ |
640 | ␉␉␉lim--;␊ |
641 | ␉␉}␉␉/* else move left */␊ |
642 | ␉}␊ |
643 | ␉return (NULL);␊ |
644 | }␊ |
645 | ␊ |
646 | void *␊ |
647 | memchr(const void *s, int c, size_t n)␊ |
648 | {␊ |
649 | ␉if (n != 0) {␊ |
650 | ␉␉const unsigned char *p = s;␊ |
651 | ␉␉␊ |
652 | ␉␉do {␊ |
653 | ␉␉␉if (*p++ == (unsigned char)c)␊ |
654 | ␉␉␉␉return ((void *)(p - 1));␊ |
655 | ␉␉} while (--n != 0);␊ |
656 | ␉}␊ |
657 | ␉return (NULL);␊ |
658 | }␊ |
659 | ␊ |
660 | #if 1␊ |
661 | /*␊ |
662 | * sizeof(word) MUST BE A POWER OF TWO␊ |
663 | * SO THAT wmask BELOW IS ALL ONES␊ |
664 | */␊ |
665 | typedef int word; /* "word" used for optimal copy speed */␊ |
666 | ␊ |
667 | #define wsize sizeof(word)␊ |
668 | #define wmask (wsize - 1)␊ |
669 | ␊ |
670 | /*␊ |
671 | * Copy a block of memory, handling overlap.␊ |
672 | * This is the routine that actually implements␊ |
673 | * (the portable versions of) bcopy, memcpy, and memmove.␊ |
674 | */␊ |
675 | ␊ |
676 | void␊ |
677 | bcopy(const void *src0, void *dst0, size_t length)␊ |
678 | {␊ |
679 | ␉memcpy(dst0,src0,length);␊ |
680 | }␊ |
681 | ␊ |
682 | void *memcpy(void *dst0, const void *src0, size_t length)␊ |
683 | {␊ |
684 | ␉char *dst = dst0;␊ |
685 | ␉const char *src = src0;␊ |
686 | ␉size_t t;␊ |
687 | ␉␊ |
688 | ␉if (length == 0 || dst == src) /* nothing to do */␊ |
689 | ␉␉goto done;␊ |
690 | ␉␊ |
691 | ␉/*␊ |
692 | ␉ * Macros: loop-t-times; and loop-t-times, t>0␊ |
693 | ␉ */␊ |
694 | #define TLOOP(s) if (t) TLOOP1(s)␊ |
695 | #define TLOOP1(s) do { s; } while (--t)␊ |
696 | ␉␊ |
697 | ␉if ((unsigned long)dst < (unsigned long)src) {␊ |
698 | ␉␉/*␊ |
699 | ␉␉ * Copy forward.␊ |
700 | ␉␉ */␊ |
701 | ␉␉t = (uintptr_t)src; /* only need low bits */␊ |
702 | ␉␉if ((t | (uintptr_t)dst) & wmask) {␊ |
703 | ␉␉␉/*␊ |
704 | ␉␉␉ * Try to align operands. This cannot be done␊ |
705 | ␉␉␉ * unless the low bits match.␊ |
706 | ␉␉␉ */␊ |
707 | ␉␉␉if ((t ^ (uintptr_t)dst) & wmask || length < wsize)␊ |
708 | ␉␉␉␉t = length;␊ |
709 | ␉␉␉else␊ |
710 | ␉␉␉␉t = wsize - (t & wmask);␊ |
711 | ␉␉␉length -= t;␊ |
712 | ␉␉␉TLOOP1(*dst++ = *src++);␊ |
713 | ␉␉}␊ |
714 | ␉␉/*␊ |
715 | ␉␉ * Copy whole words, then mop up any trailing bytes.␊ |
716 | ␉␉ */␊ |
717 | ␉␉t = length / wsize;␊ |
718 | ␉␉TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);␊ |
719 | ␉␉t = length & wmask;␊ |
720 | ␉␉TLOOP(*dst++ = *src++);␊ |
721 | ␉} else {␊ |
722 | ␉␉/*␊ |
723 | ␉␉ * Copy backwards. Otherwise essentially the same.␊ |
724 | ␉␉ * Alignment works as before, except that it takes␊ |
725 | ␉␉ * (t&wmask) bytes to align, not wsize-(t&wmask).␊ |
726 | ␉␉ */␊ |
727 | ␉␉src += length;␊ |
728 | ␉␉dst += length;␊ |
729 | ␉␉t = (uintptr_t)src;␊ |
730 | ␉␉if ((t | (uintptr_t)dst) & wmask) {␊ |
731 | ␉␉␉if ((t ^ (uintptr_t)dst) & wmask || length <= wsize)␊ |
732 | ␉␉␉␉t = length;␊ |
733 | ␉␉␉else␊ |
734 | ␉␉␉␉t &= wmask;␊ |
735 | ␉␉␉length -= t;␊ |
736 | ␉␉␉TLOOP1(*--dst = *--src);␊ |
737 | ␉␉}␊ |
738 | ␉␉t = length / wsize;␊ |
739 | ␉␉TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);␊ |
740 | ␉␉t = length & wmask;␊ |
741 | ␉␉TLOOP(*--dst = *--src);␊ |
742 | ␉}␊ |
743 | done:␊ |
744 | ␉return (dst0);␊ |
745 | }␊ |
746 | ␊ |
747 | ␊ |
748 | #ifdef wsize␊ |
749 | #undef wsize␊ |
750 | #endif␊ |
751 | #ifdef wmask␊ |
752 | #undef wmask␊ |
753 | #endif␊ |
754 | #define wsize sizeof(u_int)␊ |
755 | #define wmask (wsize - 1)␊ |
756 | ␊ |
757 | ␊ |
758 | void bzero(void *dst0, size_t length)␊ |
759 | {␉␊ |
760 | #ifdef RETURN␊ |
761 | #undef RETURN␊ |
762 | #endif␊ |
763 | #ifdef VAL␊ |
764 | #undef VAL␊ |
765 | #endif␊ |
766 | #ifdef WIDEVAL␊ |
767 | #undef WIDEVAL␊ |
768 | #endif␊ |
769 | #define RETURN return␊ |
770 | #define VAL 0␊ |
771 | #define WIDEVAL 0␊ |
772 | ␉␊ |
773 | ␉size_t t;␊ |
774 | ␉u_char *dst;␊ |
775 | ␉␊ |
776 | ␉dst = dst0;␊ |
777 | ␉/*␊ |
778 | ␉ * If not enough words, just fill bytes. A length >= 2 words␊ |
779 | ␉ * guarantees that at least one of them is `complete' after␊ |
780 | ␉ * any necessary alignment. For instance:␊ |
781 | ␉ *␊ |
782 | ␉ * |-----------|-----------|-----------|␊ |
783 | ␉ * |00|01|02|03|04|05|06|07|08|09|0A|00|␊ |
784 | ␉ * ^---------------------^␊ |
785 | ␉ * dst dst+length-1␊ |
786 | ␉ *␊ |
787 | ␉ * but we use a minimum of 3 here since the overhead of the code␊ |
788 | ␉ * to do word writes is substantial.␊ |
789 | ␉ */␊ |
790 | ␉if (length < 3 * wsize) {␊ |
791 | ␉␉while (length != 0) {␊ |
792 | ␉␉␉*dst++ = VAL;␊ |
793 | ␉␉␉--length;␊ |
794 | ␉␉}␊ |
795 | ␉␉RETURN;␊ |
796 | ␉}␊ |
797 | ␉␊ |
798 | ␉/* Align destination by filling in bytes. */␊ |
799 | ␉if ((t = (long)dst & wmask) != 0) {␊ |
800 | ␉␉t = wsize - t;␊ |
801 | ␉␉length -= t;␊ |
802 | ␉␉do {␊ |
803 | ␉␉␉*dst++ = VAL;␊ |
804 | ␉␉} while (--t != 0);␊ |
805 | ␉}␊ |
806 | ␉␊ |
807 | ␉/* Fill words. Length was >= 2*words so we know t >= 1 here. */␊ |
808 | ␉t = length / wsize;␊ |
809 | ␉do {␊ |
810 | ␉␉*(u_int *)dst = WIDEVAL;␊ |
811 | ␉␉dst += wsize;␊ |
812 | ␉} while (--t != 0);␊ |
813 | ␉␊ |
814 | ␉/* Mop up trailing bytes, if any. */␊ |
815 | ␉t = length & wmask;␊ |
816 | ␉if (t != 0)␊ |
817 | ␉␉do {␊ |
818 | ␉␉␉*dst++ = VAL;␊ |
819 | ␉␉} while (--t != 0);␊ |
820 | ␉RETURN;␊ |
821 | }␊ |
822 | ␊ |
823 | ␊ |
824 | void *␊ |
825 | memset(void *dst0, int c0, size_t length)␊ |
826 | {␊ |
827 | #ifdef RETURN␊ |
828 | #undef RETURN␊ |
829 | #endif␉␊ |
830 | #ifdef VAL␊ |
831 | #undef VAL␊ |
832 | #endif␊ |
833 | #ifdef WIDEVAL␊ |
834 | #undef WIDEVAL␊ |
835 | #endif␊ |
836 | ␉␊ |
837 | #define VAL c0␊ |
838 | #define WIDEVAL c␊ |
839 | #define RETURN return (dst0)␊ |
840 | ␉␊ |
841 | ␉size_t t;␊ |
842 | ␉u_int c;␊ |
843 | ␉u_char *dst;␊ |
844 | ␉␊ |
845 | ␉dst = dst0;␊ |
846 | ␉/*␊ |
847 | ␉ * If not enough words, just fill bytes. A length >= 2 words␊ |
848 | ␉ * guarantees that at least one of them is `complete' after␊ |
849 | ␉ * any necessary alignment. For instance:␊ |
850 | ␉ *␊ |
851 | ␉ * |-----------|-----------|-----------|␊ |
852 | ␉ * |00|01|02|03|04|05|06|07|08|09|0A|00|␊ |
853 | ␉ * ^---------------------^␊ |
854 | ␉ * dst dst+length-1␊ |
855 | ␉ *␊ |
856 | ␉ * but we use a minimum of 3 here since the overhead of the code␊ |
857 | ␉ * to do word writes is substantial.␊ |
858 | ␉ */␊ |
859 | ␉if (length < 3 * wsize) {␊ |
860 | ␉␉while (length != 0) {␊ |
861 | ␉␉␉*dst++ = VAL;␊ |
862 | ␉␉␉--length;␊ |
863 | ␉␉}␊ |
864 | ␉␉RETURN;␊ |
865 | ␉}␊ |
866 | ␉␊ |
867 | ␉if ((c = (u_char)c0) != 0) { /* Fill the word. */␊ |
868 | ␉␉c = (c << 8) | c; /* u_int is 16 bits. */␊ |
869 | #if UINT_MAX > 0xffff␊ |
870 | ␉␉c = (c << 16) | c; /* u_int is 32 bits. */␊ |
871 | #endif␊ |
872 | #if UINT_MAX > 0xffffffff␊ |
873 | ␉␉c = (c << 32) | c; /* u_int is 64 bits. */␊ |
874 | #endif␊ |
875 | ␉}␊ |
876 | ␉␊ |
877 | ␉/* Align destination by filling in bytes. */␊ |
878 | ␉if ((t = (long)dst & wmask) != 0) {␊ |
879 | ␉␉t = wsize - t;␊ |
880 | ␉␉length -= t;␊ |
881 | ␉␉do {␊ |
882 | ␉␉␉*dst++ = VAL;␊ |
883 | ␉␉} while (--t != 0);␊ |
884 | ␉}␊ |
885 | ␉␊ |
886 | ␉/* Fill words. Length was >= 2*words so we know t >= 1 here. */␊ |
887 | ␉t = length / wsize;␊ |
888 | ␉do {␊ |
889 | ␉␉*(u_int *)dst = WIDEVAL;␊ |
890 | ␉␉dst += wsize;␊ |
891 | ␉} while (--t != 0);␊ |
892 | ␉␊ |
893 | ␉/* Mop up trailing bytes, if any. */␊ |
894 | ␉t = length & wmask;␊ |
895 | ␉if (t != 0)␊ |
896 | ␉␉do {␊ |
897 | ␉␉␉*dst++ = VAL;␊ |
898 | ␉␉} while (--t != 0);␊ |
899 | ␉RETURN;␊ |
900 | }␊ |
901 | ␊ |
902 | #endif |