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 | /*␊ |
96 | * Abstract:␊ |
97 | * strcpy copies the contents of the string "from" including␊ |
98 | * the null terminator to the string "to". A pointer to "to"␊ |
99 | * is returned.␊ |
100 | * Deprecation Warning: ␊ |
101 | *␉strcpy() is being deprecated. Please use strlcpy() instead.␊ |
102 | */␊ |
103 | char *␊ |
104 | strcpy(␊ |
105 | ␉ char *to,␊ |
106 | ␉ const char *from)␊ |
107 | {␊ |
108 | ␉char *ret = to;␊ |
109 | ␉␊ |
110 | ␉while ((*to++ = *from++) != '\0')␊ |
111 | ␉␉continue;␊ |
112 | ␉␊ |
113 | ␉return ret;␊ |
114 | }␊ |
115 | ␊ |
116 | /*␊ |
117 | * Abstract:␊ |
118 | * strncpy copies "count" characters from the "from" string to␊ |
119 | * the "to" string. If "from" contains less than "count" characters␊ |
120 | * "to" will be padded with null characters until exactly "count"␊ |
121 | * characters have been written. The return value is a pointer␊ |
122 | * to the "to" string.␊ |
123 | */␊ |
124 | ␊ |
125 | char *␊ |
126 | strncpy(␊ |
127 | ␉␉char *s1, ␊ |
128 | ␉␉const char *s2,␊ |
129 | ␉␉size_t n)␊ |
130 | {␊ |
131 | ␉char *os1 = s1;␊ |
132 | ␉unsigned long i;␊ |
133 | ␉␊ |
134 | ␉for (i = 0; i < n;)␊ |
135 | ␉␉if ((*s1++ = *s2++) == '\0')␊ |
136 | ␉␉␉for (i++; i < n; i++)␊ |
137 | ␉␉␉␉*s1++ = '\0';␊ |
138 | ␉␉else␊ |
139 | ␉␉␉i++;␊ |
140 | ␉return (os1);␊ |
141 | }␊ |
142 | ␊ |
143 | /*␊ |
144 | * Copy src to string dst of size siz. At most siz-1 characters␊ |
145 | * will be copied. Always NUL terminates (unless siz == 0).␊ |
146 | * Returns strlen(src); if retval >= siz, truncation occurred.␊ |
147 | */␊ |
148 | size_t␊ |
149 | strlcpy(char *dst, const char *src, size_t siz)␊ |
150 | {␊ |
151 | ␉char *d = dst;␊ |
152 | ␉const char *s = src;␊ |
153 | ␉size_t n = siz;␊ |
154 | ␉␊ |
155 | ␉/* Copy as many bytes as will fit */␊ |
156 | ␉if (n != 0 && --n != 0) {␊ |
157 | ␉␉do {␊ |
158 | ␉␉␉if ((*d++ = *s++) == 0)␊ |
159 | ␉␉␉␉break;␊ |
160 | ␉␉} while (--n != 0);␊ |
161 | ␉}␊ |
162 | ␉␊ |
163 | ␉/* Not enough room in dst, add NUL and traverse rest of src */␊ |
164 | ␉if (n == 0) {␊ |
165 | ␉␉if (siz != 0)␊ |
166 | ␉␉␉*d = '\0';␉␉/* NUL-terminate dst */␊ |
167 | ␉␉while (*s++)␊ |
168 | ␉␉␉;␊ |
169 | ␉}␊ |
170 | ␉␊ |
171 | ␉return(s - src - 1);␉/* count does not include NUL */␊ |
172 | }␊ |
173 | ␊ |
174 | /*␊ |
175 | * History:␊ |
176 | * 2002-01-24 ␉gvdl␉Initial implementation of strstr␊ |
177 | */␊ |
178 | ␊ |
179 | const char *␊ |
180 | strstr(const char *in, const char *str)␊ |
181 | {␊ |
182 | char c;␊ |
183 | size_t len;␊ |
184 | ␉␊ |
185 | c = *str++;␊ |
186 | if (!c)␊ |
187 | return (const char *) in;␉// Trivial empty string case␊ |
188 | ␉␊ |
189 | len = strlen(str);␊ |
190 | do {␊ |
191 | char sc;␊ |
192 | ␉␉␊ |
193 | do {␊ |
194 | sc = *in++;␊ |
195 | if (!sc)␊ |
196 | return (char *) 0;␊ |
197 | } while (sc != c);␊ |
198 | } while (strncmp(in, str, len) != 0);␊ |
199 | ␉␊ |
200 | return (const char *) (in - 1);␊ |
201 | }␊ |
202 | ␊ |
203 | int␊ |
204 | ptol(const char *str)␊ |
205 | {␊ |
206 | ␉register int c = *str;␊ |
207 | ␉␊ |
208 | ␉if (c <= '7' && c >= '0')␊ |
209 | ␉␉c -= '0';␊ |
210 | ␉else if (c <= 'h' && c >= 'a')␊ |
211 | ␉␉c -= 'a';␊ |
212 | ␉else c = 0;␊ |
213 | ␉return c;␊ |
214 | }␊ |
215 | ␊ |
216 | /*␊ |
217 | * atoi:␊ |
218 | *␊ |
219 | * This function converts an ascii string into an integer.␊ |
220 | *␊ |
221 | * input : string␊ |
222 | * output : a number␊ |
223 | */␊ |
224 | ␊ |
225 | int␊ |
226 | atoi(const char *cp)␊ |
227 | {␊ |
228 | ␉int number;␊ |
229 | ␉␊ |
230 | ␉for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++)␊ |
231 | ␉␉number = (number * 10) + (*cp - '0');␊ |
232 | ␉␊ |
233 | ␉return( number );␊ |
234 | }␊ |
235 | ␊ |
236 | /*␊ |
237 | * convert an integer to an ASCII string.␊ |
238 | * inputs:␊ |
239 | *␉num␉integer to be converted␊ |
240 | *␉str␉string pointer.␊ |
241 | *␊ |
242 | * outputs:␊ |
243 | *␉pointer to string start.␊ |
244 | */␊ |
245 | ␊ |
246 | char *␊ |
247 | itoa(␊ |
248 | ␉ int␉num,␊ |
249 | ␉ char␉*str)␊ |
250 | {␊ |
251 | ␉char digits[11];␊ |
252 | ␉char *dp;␊ |
253 | ␉char *cp = str;␊ |
254 | ␉␊ |
255 | ␉if (num == 0) {␊ |
256 | ␉␉*cp++ = '0';␊ |
257 | ␉}␊ |
258 | ␉else {␊ |
259 | ␉␉dp = digits;␊ |
260 | ␉␉while (num) {␊ |
261 | ␉␉␉*dp++ = '0' + num % 10;␊ |
262 | ␉␉␉num /= 10;␊ |
263 | ␉␉}␊ |
264 | ␉␉while (dp != digits) {␊ |
265 | ␉␉␉*cp++ = *--dp;␊ |
266 | ␉␉}␊ |
267 | ␉}␊ |
268 | ␉*cp++ = '\0';␊ |
269 | ␉␊ |
270 | ␉return str;␊ |
271 | }␊ |
272 | ␊ |
273 | /*␊ |
274 | * Appends src to string dst of size siz (unlike strncat, siz is the␊ |
275 | * full size of dst, not space left). At most siz-1 characters␊ |
276 | * will be copied. Always NUL terminates (unless siz <= strlen(dst)).␊ |
277 | * Returns strlen(src) + MIN(siz, strlen(initial dst)).␊ |
278 | * If retval >= siz, truncation occurred.␊ |
279 | */␊ |
280 | size_t␊ |
281 | strlcat(char *dst, const char *src, size_t siz)␊ |
282 | {␊ |
283 | ␉char *d = dst;␊ |
284 | ␉const char *s = src;␊ |
285 | ␉size_t n = siz;␊ |
286 | ␉size_t dlen;␊ |
287 | ␉␊ |
288 | ␉/* Find the end of dst and adjust bytes left but don't go past end */␊ |
289 | ␉while (n-- != 0 && *d != '\0')␊ |
290 | ␉␉d++;␊ |
291 | ␉dlen = d - dst;␊ |
292 | ␉n = siz - dlen;␊ |
293 | ␉␊ |
294 | ␉if (n == 0)␊ |
295 | ␉␉return(dlen + strlen(s));␊ |
296 | ␉while (*s != '\0') {␊ |
297 | ␉␉if (n != 1) {␊ |
298 | ␉␉␉*d++ = *s;␊ |
299 | ␉␉␉n--;␊ |
300 | ␉␉}␊ |
301 | ␉␉s++;␊ |
302 | ␉}␊ |
303 | ␉*d = '\0';␊ |
304 | ␉␊ |
305 | ␉return(dlen + (s - src)); /* count does not include NUL */␊ |
306 | }␊ |
307 | ␊ |
308 | /*␊ |
309 | *␊ |
310 | */␊ |
311 | ␊ |
312 | char *␊ |
313 | strncat(char *s1, const char *s2, unsigned long n)␊ |
314 | {␊ |
315 | ␉char *os1;␊ |
316 | ␉int i = n;␊ |
317 | ␉␊ |
318 | ␉os1 = s1;␊ |
319 | ␉while (*s1++)␊ |
320 | ␉␉;␊ |
321 | ␉--s1;␊ |
322 | ␉while ((*s1++ = *s2++))␊ |
323 | ␉␉if (--i < 0) {␊ |
324 | ␉␉␉*--s1 = '\0';␊ |
325 | ␉␉␉break;␊ |
326 | ␉␉}␊ |
327 | ␉return(os1);␊ |
328 | }␊ |
329 | ␊ |
330 | static int␊ |
331 | _mach_strlen(const char *str)␊ |
332 | {␊ |
333 | ␉const char *p;␊ |
334 | ␉for (p = str; p; p++) {␊ |
335 | ␉␉if (*p == '\0') {␊ |
336 | ␉␉␉return (p - str);␊ |
337 | ␉␉}␊ |
338 | ␉}␊ |
339 | ␉/* NOTREACHED */␊ |
340 | ␉return 0;␊ |
341 | }␊ |
342 | ␊ |
343 | size_t strlen(const char * str)␊ |
344 | {␉␊ |
345 | ␉return (size_t)_mach_strlen(str);␊ |
346 | }␊ |
347 | ␊ |
348 | /*␊ |
349 | * Does the same thing as strlen, except only looks up␊ |
350 | * to max chars inside the buffer. ␊ |
351 | * Taken from archive/kern-stuff/sbf_machine.c in ␊ |
352 | * seatbelt. ␊ |
353 | * inputs:␊ |
354 | * ␉s␉string whose length is to be measured␊ |
355 | *␉max␉maximum length of string to search for null␊ |
356 | * outputs:␊ |
357 | *␉length of s or max; whichever is smaller␊ |
358 | */␊ |
359 | size_t ␊ |
360 | strnlen(const char *s, size_t max) {␊ |
361 | ␉const char *es = s + max, *p = s;␊ |
362 | ␉while(*p && p != es) ␊ |
363 | ␉␉p++;␊ |
364 | ␉␊ |
365 | ␉return p - s;␊ |
366 | }␊ |
367 | ␊ |
368 | /* ␊ |
369 | * Deprecation Warning:␊ |
370 | *␉strcat() is being deprecated. Please use strlcat() instead.␊ |
371 | */␊ |
372 | char *␊ |
373 | strcat(␊ |
374 | ␉ char *dest,␊ |
375 | ␉ const char *src)␊ |
376 | {␊ |
377 | ␉char *old = dest;␊ |
378 | ␉␊ |
379 | ␉while (*dest)␊ |
380 | ␉␉++dest;␊ |
381 | ␉while ((*dest++ = *src++))␊ |
382 | ␉␉;␊ |
383 | ␉return (old);␊ |
384 | }␊ |
385 | ␊ |
386 | /*␊ |
387 | * STRDUP␊ |
388 | *␊ |
389 | * Description: The STRDUP function allocates sufficient memory for a copy␊ |
390 | * of the string "string", does the copy, and returns a pointer␊ |
391 | * it. The pointer may subsequently be used as an argument to␊ |
392 | * the macro FREE().␊ |
393 | *␊ |
394 | * Parameters: string␉␉String to be duplicated␊ |
395 | *␊ |
396 | * Returns: char * A pointer to the newly allocated string with␊ |
397 | * duplicated contents in it.␊ |
398 | *␊ |
399 | * NULL␉␉If MALLOC() fails.␊ |
400 | * ␊ |
401 | */␊ |
402 | static char *␊ |
403 | STRDUP(const char *string)␊ |
404 | {␊ |
405 | ␉size_t len;␊ |
406 | ␉char *copy; ␊ |
407 | ␉␊ |
408 | ␉len = strlen(string) + 1;␊ |
409 | ␉copy = malloc(len);␊ |
410 | ␉if (copy == NULL)␊ |
411 | ␉␉return (NULL);␊ |
412 | ␉bcopy(string, copy, len);␊ |
413 | ␉return (copy); ␊ |
414 | }␊ |
415 | ␊ |
416 | char *strdup(const char *string)␊ |
417 | {␊ |
418 | ␉if (string) {␊ |
419 | ␉␉return STRDUP(string);␊ |
420 | ␉}␊ |
421 | ␉return (NULL);␊ |
422 | }␊ |
423 | ␊ |
424 | #if STRNCASECMP␊ |
425 | ␊ |
426 | //␊ |
427 | // Lame implementation just for use by strcasecmp/strncasecmp␊ |
428 | //␊ |
429 | static int␊ |
430 | tolower(unsigned char ch)␊ |
431 | {␊ |
432 | if (ch >= 'A' && ch <= 'Z')␊ |
433 | ␉␉ch = 'a' + (ch - 'A');␊ |
434 | ␉␊ |
435 | return ch;␊ |
436 | }␊ |
437 | ␊ |
438 | int␊ |
439 | strcasecmp(const char *s1, const char *s2)␊ |
440 | {␊ |
441 | const unsigned char *us1 = (const u_char *)s1,␊ |
442 | ␉*us2 = (const u_char *)s2;␊ |
443 | ␉␊ |
444 | while (tolower(*us1) == tolower(*us2++))␊ |
445 | ␉␉if (*us1++ == '\0')␊ |
446 | ␉␉␉return (0);␊ |
447 | return (tolower(*us1) - tolower(*--us2));␊ |
448 | }␊ |
449 | ␊ |
450 | int␊ |
451 | strncasecmp(const char *s1, const char *s2, size_t n)␊ |
452 | {␊ |
453 | if (n != 0) {␊ |
454 | ␉␉const unsigned char *us1 = (const u_char *)s1,␊ |
455 | ␉␉*us2 = (const u_char *)s2;␊ |
456 | ␉␉␊ |
457 | ␉␉do {␊ |
458 | ␉␉␉if (tolower(*us1) != tolower(*us2++))␊ |
459 | ␉␉␉␉return (tolower(*us1) - tolower(*--us2));␊ |
460 | ␉␉␉if (*us1++ == '\0')␊ |
461 | ␉␉␉␉break;␊ |
462 | ␉␉} while (--n != 0);␊ |
463 | }␊ |
464 | return (0);␊ |
465 | }␊ |
466 | #endif␊ |
467 | ␊ |
468 | /*␊ |
469 | *␊ |
470 | */␊ |
471 | ␊ |
472 | char *strchr(const char *str, int ch)␊ |
473 | {␊ |
474 | do {␊ |
475 | ␉␉if (*str == ch)␊ |
476 | ␉␉␉return(__CAST_AWAY_QUALIFIER(str, const, char *));␊ |
477 | } while (*str++);␊ |
478 | return ((char *) 0);␊ |
479 | } ␊ |
480 | ␊ |
481 | char* strbreak(const char *str, char **next, long *len)␊ |
482 | {␊ |
483 | char *start = (char*)str, *end;␊ |
484 | bool quoted = false;␊ |
485 | ␊ |
486 | if ( !start || !len )␊ |
487 | return 0;␊ |
488 | ␊ |
489 | *len = 0;␊ |
490 | ␊ |
491 | while ( isspace(*start) )␊ |
492 | start++;␊ |
493 | ␊ |
494 | if (*start == '"')␊ |
495 | {␊ |
496 | start++;␊ |
497 | ␊ |
498 | end = strchr(start, '"');␊ |
499 | if(end)␊ |
500 | quoted = true;␊ |
501 | else␊ |
502 | end = strchr(start, '\0');␊ |
503 | }␊ |
504 | else␊ |
505 | {␊ |
506 | for ( end = start; *end && !isspace(*end); end++ )␊ |
507 | {}␊ |
508 | }␊ |
509 | ␊ |
510 | *len = end - start;␊ |
511 | ␊ |
512 | if(next)␊ |
513 | *next = quoted ? end+1 : end;␊ |
514 | ␊ |
515 | return start;␊ |
516 | }␊ |
517 | ␊ |
518 | /* COPYRIGHT NOTICE: checksum8 from AppleSMBIOS */␊ |
519 | uint8_t checksum8( void * start, unsigned int length )␊ |
520 | {␊ |
521 | uint8_t csum = 0;␊ |
522 | uint8_t * cp = (uint8_t *) start;␊ |
523 | unsigned int i;␊ |
524 | ␉␊ |
525 | for ( i = 0; i < length; i++)␊ |
526 | csum += *cp++;␊ |
527 | ␉␊ |
528 | return csum;␊ |
529 | }␊ |
530 | ␊ |
531 | unsigned long␊ |
532 | adler32( unsigned char * buffer, long length )␊ |
533 | {␊ |
534 | long cnt;␊ |
535 | unsigned long result, lowHalf, highHalf;␊ |
536 | ␊ |
537 | lowHalf = 1;␊ |
538 | highHalf = 0;␊ |
539 | ␉␊ |
540 | ␉for ( cnt = 0; cnt < length; cnt++ )␊ |
541 | {␊ |
542 | if ((cnt % 5000) == 0)␊ |
543 | {␊ |
544 | lowHalf %= 65521L;␊ |
545 | highHalf %= 65521L;␊ |
546 | }␊ |
547 | ␉␉␊ |
548 | lowHalf += buffer[cnt];␊ |
549 | highHalf += lowHalf;␊ |
550 | }␊ |
551 | ␉␊ |
552 | ␉lowHalf %= 65521L;␊ |
553 | ␉highHalf %= 65521L;␊ |
554 | ␉␊ |
555 | ␉result = (highHalf << 16) | lowHalf;␊ |
556 | ␉␊ |
557 | ␉return result;␊ |
558 | }␊ |
559 | ␊ |
560 | static long holdrand = 1L;␊ |
561 | #define␉RAND_MAX␉0x7fffffff␊ |
562 | ␊ |
563 | void srand (unsigned int seed)␊ |
564 | {␊ |
565 | ␉holdrand = (long)seed;␊ |
566 | }␊ |
567 | ␊ |
568 | int rand (void)␊ |
569 | {␉␊ |
570 | ␉holdrand = holdrand * 214013L + 2531011L;␊ |
571 | ␉return ((holdrand >> 16) & RAND_MAX);␊ |
572 | }␊ |
573 | ␊ |
574 | /*-␊ |
575 | * For memcmp.␊ |
576 | * Copyright (c) 1990, 1993␊ |
577 | *␉The Regents of the University of California. All rights reserved.␊ |
578 | *␊ |
579 | * This code is derived from software contributed to Berkeley by␊ |
580 | * Chris Torek.␊ |
581 | *␊ |
582 | * Redistribution and use in source and binary forms, with or without␊ |
583 | * modification, are permitted provided that the following conditions␊ |
584 | * are met:␊ |
585 | * 1. Redistributions of source code must retain the above copyright␊ |
586 | * notice, this list of conditions and the following disclaimer.␊ |
587 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
588 | * notice, this list of conditions and the following disclaimer in the␊ |
589 | * documentation and/or other materials provided with the distribution.␊ |
590 | * 4. Neither the name of the University nor the names of its contributors␊ |
591 | * may be used to endorse or promote products derived from this software␊ |
592 | * without specific prior written permission.␊ |
593 | *␊ |
594 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND␊ |
595 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
596 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
597 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE␊ |
598 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
599 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
600 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
601 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
602 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
603 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
604 | * SUCH DAMAGE.␊ |
605 | */␊ |
606 | ␊ |
607 | /*␊ |
608 | * Compare memory regions.␊ |
609 | */␊ |
610 | int␊ |
611 | memcmp(const void *s1, const void *s2, size_t n)␊ |
612 | {␊ |
613 | ␉if (n != 0) {␊ |
614 | ␉␉const unsigned char *p1 = s1, *p2 = s2;␊ |
615 | ␉␉␊ |
616 | ␉␉do {␊ |
617 | ␉␉␉if (*p1++ != *p2++)␊ |
618 | ␉␉␉␉return (*--p1 - *--p2);␊ |
619 | ␉␉} while (--n != 0);␊ |
620 | ␉}␊ |
621 | ␉return (0);␊ |
622 | } |