Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsa/string.c

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
28static int _mach_strlen(const char *str);
29static 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
45int
46strcmp(
47 const char *s1,
48 const char *s2)
49{
50unsigned int a, b;
51
52do {
53a = *s1++;
54b = *s2++;
55if (a != b)
56return a-b; /* includes case when
57 'a' is zero and 'b' is not zero
58 or vice versa */
59} while (a != '\0');
60
61return 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
71int
72strncmp(
73 const char *s1,
74 const char *s2,
75 size_t n)
76{
77unsigned int a, b;
78
79while (n != 0) {
80a = *s1++;
81b = *s2++;
82if (a != b)
83return a-b; /* includes case when
84 'a' is zero and 'b' is not zero
85 or vice versa */
86if (a == '\0')
87return 0; /* both are zero */
88n--;
89}
90
91return 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 */
103char *
104strcpy(
105 char *to,
106 const char *from)
107{
108char *ret = to;
109
110while ((*to++ = *from++) != '\0')
111continue;
112
113return 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
125char *
126strncpy(
127char *s1,
128const char *s2,
129size_t n)
130{
131char *os1 = s1;
132unsigned long i;
133
134for (i = 0; i < n;)
135if ((*s1++ = *s2++) == '\0')
136for (i++; i < n; i++)
137*s1++ = '\0';
138else
139i++;
140return (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 */
148size_t
149strlcpy(char *dst, const char *src, size_t siz)
150{
151char *d = dst;
152const char *s = src;
153size_t n = siz;
154
155/* Copy as many bytes as will fit */
156if (n != 0 && --n != 0) {
157do {
158if ((*d++ = *s++) == 0)
159break;
160} while (--n != 0);
161}
162
163/* Not enough room in dst, add NUL and traverse rest of src */
164if (n == 0) {
165if (siz != 0)
166*d = '\0';/* NUL-terminate dst */
167while (*s++)
168;
169}
170
171return(s - src - 1);/* count does not include NUL */
172}
173
174/*
175 * History:
176 * 2002-01-24 gvdlInitial implementation of strstr
177 */
178
179const char *
180strstr(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
203int
204ptol(const char *str)
205{
206register int c = *str;
207
208if (c <= '7' && c >= '0')
209c -= '0';
210else if (c <= 'h' && c >= 'a')
211c -= 'a';
212else c = 0;
213return 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
225int
226atoi(const char *cp)
227{
228int number;
229
230for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++)
231number = (number * 10) + (*cp - '0');
232
233return( number );
234}
235
236/*
237 * convert an integer to an ASCII string.
238 * inputs:
239 *numinteger to be converted
240 *strstring pointer.
241 *
242 * outputs:
243 *pointer to string start.
244 */
245
246char *
247itoa(
248 intnum,
249 char*str)
250{
251char digits[11];
252char *dp;
253char *cp = str;
254
255if (num == 0) {
256*cp++ = '0';
257}
258else {
259dp = digits;
260while (num) {
261*dp++ = '0' + num % 10;
262num /= 10;
263}
264while (dp != digits) {
265*cp++ = *--dp;
266}
267}
268*cp++ = '\0';
269
270return 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 */
280size_t
281strlcat(char *dst, const char *src, size_t siz)
282{
283char *d = dst;
284const char *s = src;
285size_t n = siz;
286size_t dlen;
287
288/* Find the end of dst and adjust bytes left but don't go past end */
289while (n-- != 0 && *d != '\0')
290d++;
291dlen = d - dst;
292n = siz - dlen;
293
294if (n == 0)
295return(dlen + strlen(s));
296while (*s != '\0') {
297if (n != 1) {
298*d++ = *s;
299n--;
300}
301s++;
302}
303*d = '\0';
304
305return(dlen + (s - src)); /* count does not include NUL */
306}
307
308/*
309 *
310 */
311
312char *
313strncat(char *s1, const char *s2, unsigned long n)
314{
315char *os1;
316int i = n;
317
318os1 = s1;
319while (*s1++)
320;
321--s1;
322while ((*s1++ = *s2++))
323if (--i < 0) {
324*--s1 = '\0';
325break;
326}
327return(os1);
328}
329
330static int
331_mach_strlen(const char *str)
332{
333const char *p;
334for (p = str; p; p++) {
335if (*p == '\0') {
336return (p - str);
337}
338}
339/* NOTREACHED */
340return 0;
341}
342
343size_t strlen(const char * str)
344{
345return (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 * sstring whose length is to be measured
355 *maxmaximum length of string to search for null
356 * outputs:
357 *length of s or max; whichever is smaller
358 */
359size_t
360strnlen(const char *s, size_t max) {
361const char *es = s + max, *p = s;
362while(*p && p != es)
363p++;
364
365return p - s;
366}
367
368/*
369 * Deprecation Warning:
370 *strcat() is being deprecated. Please use strlcat() instead.
371 */
372char *
373strcat(
374 char *dest,
375 const char *src)
376{
377char *old = dest;
378
379while (*dest)
380++dest;
381while ((*dest++ = *src++))
382;
383return (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: stringString to be duplicated
395 *
396 * Returns: char * A pointer to the newly allocated string with
397 * duplicated contents in it.
398 *
399 * NULLIf MALLOC() fails.
400 *
401 */
402static char *
403STRDUP(const char *string)
404{
405size_t len;
406char *copy;
407
408len = strlen(string) + 1;
409copy = malloc(len);
410if (copy == NULL)
411return (NULL);
412bcopy(string, copy, len);
413return (copy);
414}
415
416char *strdup(const char *string)
417{
418if (string) {
419return STRDUP(string);
420}
421return (NULL);
422}
423
424#if STRNCASECMP
425
426//
427// Lame implementation just for use by strcasecmp/strncasecmp
428//
429static int
430tolower(unsigned char ch)
431{
432 if (ch >= 'A' && ch <= 'Z')
433ch = 'a' + (ch - 'A');
434
435 return ch;
436}
437
438int
439strcasecmp(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++))
445if (*us1++ == '\0')
446return (0);
447 return (tolower(*us1) - tolower(*--us2));
448}
449
450int
451strncasecmp(const char *s1, const char *s2, size_t n)
452{
453 if (n != 0) {
454const unsigned char *us1 = (const u_char *)s1,
455*us2 = (const u_char *)s2;
456
457do {
458if (tolower(*us1) != tolower(*us2++))
459return (tolower(*us1) - tolower(*--us2));
460if (*us1++ == '\0')
461break;
462} while (--n != 0);
463 }
464 return (0);
465}
466#endif
467
468/*
469 *
470 */
471
472char *strchr(const char *str, int ch)
473{
474 do {
475if (*str == ch)
476return(__CAST_AWAY_QUALIFIER(str, const, char *));
477 } while (*str++);
478 return ((char *) 0);
479}
480
481char* 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 */
519uint8_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
531unsigned long
532adler32( unsigned char * buffer, long length )
533{
534 long cnt;
535 unsigned long result, lowHalf, highHalf;
536
537 lowHalf = 1;
538 highHalf = 0;
539
540for ( 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
552lowHalf %= 65521L;
553highHalf %= 65521L;
554
555result = (highHalf << 16) | lowHalf;
556
557return result;
558}
559
560static long holdrand = 1L;
561#defineRAND_MAX0x7fffffff
562
563void srand (unsigned int seed)
564{
565holdrand = (long)seed;
566}
567
568int rand (void)
569{
570holdrand = holdrand * 214013L + 2531011L;
571return ((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 */
610int
611memcmp(const void *s1, const void *s2, size_t n)
612{
613if (n != 0) {
614const unsigned char *p1 = s1, *p2 = s2;
615
616do {
617if (*p1++ != *p2++)
618return (*--p1 - *--p2);
619} while (--n != 0);
620}
621return (0);
622}

Archive Download this file

Revision: 1804